Add new CLUST_END and use it as parameter to pcbmap() when searching for end cluster, instead of explicitly passing 0xffff. This fixes potential problem for FAT32, where cluster number may be legally bigger than 0xffff.
Also change clusteralloc() so that fillwith is not explicitly passed by caller anymore (there is no need to use anything other than CLUST_EOFE). >From NetBSD commit by [email protected] OK? diff --git a/sys/msdosfs/fat.h b/sys/msdosfs/fat.h index 1fd12af89d9..a6dead4bdf9 100644 --- a/sys/msdosfs/fat.h +++ b/sys/msdosfs/fat.h @@ -59,6 +59,7 @@ #define CLUST_BAD 0xfffffff7 /* a cluster with a defect */ #define CLUST_EOFS 0xfffffff8 /* start of eof cluster range */ #define CLUST_EOFE 0xffffffff /* end of eof cluster range */ +#define CLUST_END CLUST_EOFE /* bigger than any valid cluster */ #define FAT12_MASK 0x00000fff /* mask for 12 bit cluster numbers */ #define FAT16_MASK 0x0000ffff /* mask for 16 bit cluster numbers */ @@ -94,7 +95,7 @@ int pcbmap(struct denode *, uint32_t, daddr_t *, uint32_t *, int *); int clusterfree(struct msdosfsmount *, uint32_t, uint32_t *); -int clusteralloc(struct msdosfsmount *, uint32_t, uint32_t, uint32_t, uint32_t *, uint32_t *); +int clusteralloc(struct msdosfsmount *, uint32_t, uint32_t, uint32_t *, uint32_t *); int extendfile(struct denode *, uint32_t, struct buf **, uint32_t *, int); int fatentry(int, struct msdosfsmount *, uint32_t, uint32_t *, uint32_t); void fc_purge(struct denode *, u_int); diff --git a/sys/msdosfs/msdosfs_denode.c b/sys/msdosfs/msdosfs_denode.c index 018d4744cf7..470621313a7 100644 --- a/sys/msdosfs/msdosfs_denode.c +++ b/sys/msdosfs/msdosfs_denode.c @@ -324,7 +324,7 @@ retry: nvp->v_type = VDIR; if (ldep->de_StartCluster != MSDOSFSROOT) { - error = pcbmap(ldep, 0xffff, 0, &size, 0); + error = pcbmap(ldep, CLUST_END, 0, &size, 0); if (error == E2BIG) { ldep->de_FileSize = de_cn2off(pmp, size); error = 0; diff --git a/sys/msdosfs/msdosfs_fat.c b/sys/msdosfs/msdosfs_fat.c index aeb822d4be2..3b900102346 100644 --- a/sys/msdosfs/msdosfs_fat.c +++ b/sys/msdosfs/msdosfs_fat.c @@ -714,11 +714,12 @@ chainalloc(struct msdosfsmount *pmp, uint32_t start, uint32_t count, */ int clusteralloc(struct msdosfsmount *pmp, uint32_t start, uint32_t count, - uint32_t fillwith, uint32_t *retcluster, uint32_t *got) + uint32_t *retcluster, uint32_t *got) { uint32_t idx; uint32_t len, newst, foundl, cn, l; uint32_t foundcn = 0; /* XXX: foundcn could be used uninitialized */ + uint32_t fillwith = CLUST_EOFE; u_int map; #ifdef MSDOSFS_DEBUG @@ -949,7 +950,7 @@ extendfile(struct denode *dep, uint32_t count, struct buf **bpp, uint32_t *ncp, if (dep->de_fc[FC_LASTFC].fc_frcn == FCE_EMPTY && dep->de_StartCluster != 0) { fc_lfcempty++; - error = pcbmap(dep, 0xffff, 0, &cn, 0); + error = pcbmap(dep, CLUST_END, 0, &cn, 0); /* we expect it to return E2BIG */ if (error != E2BIG) return (error); @@ -976,7 +977,7 @@ extendfile(struct denode *dep, uint32_t count, struct buf **bpp, uint32_t *ncp, cn = 0; else cn = dep->de_fc[FC_LASTFC].fc_fsrcn + 1; - error = clusteralloc(pmp, cn, count, CLUST_EOFE, &cn, &got); + error = clusteralloc(pmp, cn, count, &cn, &got); if (error) return (error); diff --git a/sys/msdosfs/msdosfs_vnops.c b/sys/msdosfs/msdosfs_vnops.c index 4d50507c27d..0cfe9faddd4 100644 --- a/sys/msdosfs/msdosfs_vnops.c +++ b/sys/msdosfs/msdosfs_vnops.c @@ -1305,7 +1305,7 @@ msdosfs_mkdir(void *v) /* * Allocate a cluster to hold the about to be created directory. */ - error = clusteralloc(pmp, 0, 1, CLUST_EOFE, &newcluster, NULL); + error = clusteralloc(pmp, 0, 1, &newcluster, NULL); if (error) goto bad2;
