Page MenuHomeFreeBSD

D38987.id118604.diff
No OneTemporary

D38987.id118604.diff

diff --git a/sys/fs/msdosfs/msdosfs_lookup.c b/sys/fs/msdosfs/msdosfs_lookup.c
--- a/sys/fs/msdosfs/msdosfs_lookup.c
+++ b/sys/fs/msdosfs/msdosfs_lookup.c
@@ -684,6 +684,7 @@
return error;
}
ndep = bptoep(pmp, bp, ddep->de_fndoffset);
+ rootde_alloced(ddep);
DE_EXTERNALIZE(ndep, dep);
@@ -721,6 +722,7 @@
ndep--;
ddep->de_fndoffset -= sizeof(struct direntry);
}
+ rootde_alloced(ddep);
if (!unix2winfn(un, unlen, (struct winentry *)ndep,
cnt++, chksum, pmp))
break;
@@ -1015,6 +1017,7 @@
*/
offset -= sizeof(struct direntry);
ep--->deName[0] = SLOT_DELETED;
+ rootde_freed(pdep);
if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95)
|| !(offset & pmp->pm_crbomask)
|| ep->deAttributes != ATTR_WIN95)
diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
--- a/sys/fs/msdosfs/msdosfs_vfsops.c
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c
@@ -409,6 +409,67 @@
return (0);
}
+static int
+rootdir_free(struct msdosfsmount* pmp)
+{
+ struct buf *bp;
+ struct direntry *dep;
+ u_long readsize;
+ int dirclu;
+ int diridx;
+ int dirmax;
+ int dirleft;
+ int ffree;
+
+ dirclu = pmp->pm_firstcluster - pmp->pm_rootdirsize;
+ dirleft = pmp->pm_RootDirEnts;
+ readsize = MAXBCACHEBUF;
+
+#ifdef MSDOSFS_DEBUG
+ printf("rootdir_free: blkpersec=%lu fatblksize=%lu readsize=%lu firstclu=%lu dirclu=%lu rootdirsize=%lu\n",
+ pmp->pm_BlkPerSec, pmp->pm_fatblocksize, readsize, pmp->pm_firstcluster, dirclu, pmp->pm_rootdirsize);
+#endif
+ ffree = pmp->pm_RootDirEnts;
+ while (dirleft > 0 && ffree > 0) {
+ if (readsize > dirleft * sizeof(struct direntry))
+ readsize = roundup(dirleft * sizeof(struct direntry), DEV_BSIZE);
+#ifdef MSDOSFS_DEBUG
+ printf("rootdir_free: dirclu=%lu readsize=%lu\n", dirclu, readsize);
+#endif
+ if (bread(pmp->pm_devvp, dirclu, readsize, NOCRED, &bp) != 0) {
+ dirleft = 0;
+ ffree = -1;
+ printf("rootdir_free: read error\n");
+ }
+ dirmax = readsize / sizeof(struct direntry);
+ for (diridx = 0; diridx < dirmax && dirleft > 0; diridx++, dirleft--) {
+ dep = (struct direntry*)bp->b_data + diridx;
+#ifdef MSDOSFS_DEBUG
+ if (dep->deName[0] == SLOT_DELETED)
+ printf("rootdir_free: idx=%d <deleted>\n", diridx);
+ else if (dep->deName[0] == SLOT_EMPTY)
+ printf("rootdir_free: idx=%d <end marker>\n", diridx);
+ else if (dep->deAttributes == ATTR_WIN95)
+ printf("rootdir_free: idx=%d <long file name>\n", diridx);
+ else if (dep->deAttributes & ATTR_VOLUME)
+ printf("rootdir_free: idx=%d label='%11.11s'\n", diridx, dep->deName);
+ else if (dep->deAttributes & ATTR_DIRECTORY)
+ printf("rootdir_free: idx=%d dir='%11.11s'\n", diridx, dep->deName);
+ else
+ printf("rootdir_free: idx=%d file='%11.11s'\n", diridx, dep->deName);
+#endif
+ if (dep->deName[0] == SLOT_EMPTY)
+ dirleft = 0;
+ else if (dep->deName[0] != SLOT_DELETED)
+ ffree--;
+ }
+ brelse(bp);
+ bp = NULL;
+ dirclu += readsize / DEV_BSIZE;
+ }
+ return (ffree);
+}
+
static int
mountmsdosfs(struct vnode *odevvp, struct mount *mp)
{
@@ -747,6 +808,15 @@
goto error_exit;
pmp->pm_fmod = 1;
}
+
+ if (FAT32(pmp)) {
+ pmp->pm_rootdirfree = 0;
+ } else {
+ pmp->pm_rootdirfree = rootdir_free(pmp);
+ if (pmp->pm_rootdirfree < 0)
+ goto error_exit;
+ }
+
mp->mnt_data = pmp;
mp->mnt_stat.f_fsid.val[0] = dev2udev(dev);
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
@@ -948,8 +1018,8 @@
sbp->f_blocks = pmp->pm_maxcluster + 1;
sbp->f_bfree = pmp->pm_freeclustercount;
sbp->f_bavail = pmp->pm_freeclustercount;
- sbp->f_files = pmp->pm_RootDirEnts; /* XXX */
- sbp->f_ffree = 0; /* what to put in here? */
+ sbp->f_files = pmp->pm_RootDirEnts;
+ sbp->f_ffree = pmp->pm_rootdirfree;
return (0);
}
diff --git a/sys/fs/msdosfs/msdosfsmount.h b/sys/fs/msdosfs/msdosfsmount.h
--- a/sys/fs/msdosfs/msdosfsmount.h
+++ b/sys/fs/msdosfs/msdosfsmount.h
@@ -114,6 +114,7 @@
void *pm_w2u; /* Unicode->Local iconv handle */
void *pm_u2d; /* Unicode->DOS iconv handle */
void *pm_d2u; /* DOS->Local iconv handle */
+ u_short pm_rootdirfree; /* number of free slots in FAT12/16 root directory */
#ifndef MAKEFS
struct lock pm_fatlock; /* lockmgr protecting allocations */
struct lock pm_checkpath_lock; /* protects doscheckpath result */
@@ -222,6 +223,22 @@
? roottobn((pmp), (dirofs)) \
: cntobn((pmp), (dirclu)))
+/*
+ * Decrement the number of used entries in a fixed size FAT12/16 root
+ * directory
+ */
+#define rootde_alloced(dep) \
+ if ((dep)->de_StartCluster == MSDOSFSROOT) \
+ (dep)->de_pmp->pm_rootdirfree--;
+
+/*
+ * Increment the number of used entries in a fixed size FAT12/16 root
+ * directory
+ */
+#define rootde_freed(dep) \
+ if ((dep)->de_StartCluster == MSDOSFSROOT) \
+ (dep)->de_pmp->pm_rootdirfree++;
+
#define MSDOSFS_LOCK_MP(pmp) \
lockmgr(&(pmp)->pm_fatlock, LK_EXCLUSIVE, NULL)
#define MSDOSFS_UNLOCK_MP(pmp) \

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 19, 5:34 AM (12 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31748496
Default Alt Text
D38987.id118604.diff (4 KB)

Event Timeline