Jeremie Courreges-Anglas <[email protected]> writes:

> Landry Breuil <[email protected]> writes:
>
>> Hi,
>>
>> i know we don't really have an ntfs maintainer, and that nobody should
>> use ntfs, but interoperability...
>>
>> i have a 8Tb 'seagate backup plus hub' appearing as:
>>
>> uhub8 at uhub1 port 5 configuration 1 interface 0 "Seagate Backup+ Hub" rev 
>> 2.10/48.85 addr 2
>> umass0 at uhub8 port 1 configuration 1 interface 0 "Seagate Backup+ Hub BK" 
>> rev 2.10/1.00 addr 3
>> umass0: using SCSI over Bulk-Only
>> scsibus4 at umass0: 2 targets, initiator 0
>> sd2 at scsibus4 targ 1 lun 0: <Seagate, Backup+ Hub BK, D781> SCSI4 0/direct 
>> fixed
>>
>> which just has a huge ntfs partition:
>>
>> # /dev/rsd2c:
>> type: SCSI
>> disk: SCSI disk
>> label: Backup+ Hub BK  
>> duid: 0000000000000000
>> flags:
>> bytes/sector: 512
>> sectors/track: 63
>> tracks/cylinder: 255
>> sectors/cylinder: 16065
>> cylinders: 972801
>> total sectors: 15628053167
>> boundstart: 0
>> boundend: 15628053167
>> drivedata: 0 
>>
>> 16 partitions:
>> #                size           offset  fstype [fsize bsize   cpg]
>>   c:      15628053167                0  unused                    
>>   i:           262144               34 unknown                    # /mnt/sd2
>>   j:      15627788288           264192   MSDOS              
>>
>> (with -pG)
>> total sectors: 15628053167 # total bytes: 7452.0G
>>   c:          7452.0G                0  unused                    
>>   i:             0.1G               34 unknown                    # /mnt/sd2
>>   j:          7451.9G           264192   MSDOS      
>>
>> Trying to mount it (dev/sd2j, of course) immediately panics the kernel
>> (hand-written):
>>
>> panic: out of space in kmem_map
>> panic
>> malloc
>> ntfs_calccfree
>> ntfs_mountfs
>> ntfs_mount
>> sys_mount
>> syscall
>>
>> I suppose pointing at
>> https://github.com/openbsd/src/blob/master/sys/ntfs/ntfs_vfsops.c#L567
>>
>> So, what can be done to 1) avoid the panic and 2) eventually find a way to
>> support those partitions sizes ?
>
> I guess that we should not allocate memory for the whole bitmap file,
> but instead split it in chunks.
>
> I have only tested with dummy ntfs volumes on vnd devices, but this
> fixes landry's panic and allows him to browse his NTFS filesystem.
>
> Concerns:
> - what would be a better chunk size than 1MB?
> - uint64_t vs off_t: add more tests
>
> Input welcome.

No opinion on that one?

> Index: ntfs/ntfs_vfsops.c
> ===================================================================
> RCS file: /d/cvs/src/sys/ntfs/ntfs_vfsops.c,v
> retrieving revision 1.55
> diff -u -p -r1.55 ntfs_vfsops.c
> --- ntfs/ntfs_vfsops.c        7 Sep 2016 17:30:12 -0000       1.55
> +++ ntfs/ntfs_vfsops.c        3 Mar 2017 17:52:18 -0000
> @@ -558,22 +558,35 @@ ntfs_calccfree(struct ntfsmount *ntmp, c
>       u_int8_t *tmp;
>       int j, error;
>       cn_t cfree = 0;
> -     size_t bmsize, i;
> +     uint64_t bmsize, offset;
> +     size_t chunksize, i;
>  
>       vp = ntmp->ntm_sysvn[NTFS_BITMAPINO];
>  
>       bmsize = VTOF(vp)->f_size;
>  
> -     tmp = malloc(bmsize, M_TEMP, M_WAITOK);
> +     if (bmsize > 1024 * 1024)
> +             chunksize = 1024 * 1024;
> +     else
> +             chunksize = bmsize;
> +
> +     tmp = malloc(chunksize, M_TEMP, M_WAITOK);
> +
> +     for (offset = 0; offset < bmsize; offset += chunksize) {
> +             if (chunksize > bmsize - offset)
> +                     chunksize = bmsize - offset;
> +
> +             error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
> +                 offset, chunksize, tmp, NULL);
> +             if (error)
> +                     goto out;
> +
> +             for (i = 0; i < chunksize; i++)
> +                     for (j = 0; j < 8; j++)
> +                             if (~tmp[i] & (1 << j))
> +                                     cfree++;
> +     }
>  
> -     error = ntfs_readattr(ntmp, VTONT(vp), NTFS_A_DATA, NULL,
> -                            0, bmsize, tmp, NULL);
> -     if (error)
> -             goto out;
> -
> -     for(i=0;i<bmsize;i++)
> -             for(j=0;j<8;j++)
> -                     if(~tmp[i] & (1 << j)) cfree++;
>       *cfreep = cfree;
>  
>      out:

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to