summaryrefslogtreecommitdiffstats
path: root/sys/fs/msdosfs/msdosfs_vfsops.c
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2004-07-03 13:22:38 +0000
committertjr <tjr@FreeBSD.org>2004-07-03 13:22:38 +0000
commitab16560f3305829961b71dbe71233abcd50f0aba (patch)
tree651a802dbc4eb055206f7c5ccba7348f998b53bd /sys/fs/msdosfs/msdosfs_vfsops.c
parent158b00dfc0a2916d3a3e23aa2bd11bd84d6c0841 (diff)
downloadFreeBSD-src-ab16560f3305829961b71dbe71233abcd50f0aba.zip
FreeBSD-src-ab16560f3305829961b71dbe71233abcd50f0aba.tar.gz
By popular request, add a workaround that allows large (>128GB or so)
FAT32 filesystems to be mounted, subject to some fairly serious limitations. This works by extending the internal pseudo-inode-numbers generated from the file's starting cluster number to 64-bits, then creating a table mapping these into arbitrary 32-bit inode numbers, which can fit in struct dirent's d_fileno and struct vattr's va_fileid fields. The mappings do not persist across unmounts or reboots, so it's not possible to export these filesystems through NFS. The mapping table may grow to be rather large, and may grow large enough to exhaust kernel memory on filesystems with millions of files. Don't enable this option unless you understand the consequences.
Diffstat (limited to 'sys/fs/msdosfs/msdosfs_vfsops.c')
-rw-r--r--sys/fs/msdosfs/msdosfs_vfsops.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
index 3ac0fb6..5d0b3c5 100644
--- a/sys/fs/msdosfs/msdosfs_vfsops.c
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c
@@ -71,6 +71,8 @@
#include <fs/msdosfs/denode.h>
#include <fs/msdosfs/fat.h>
+#include "opt_msdosfs.h"
+
#define MSDOSFS_DFLTBSIZE 4096
#if 1 /*def PC98*/
@@ -227,6 +229,9 @@ msdosfs_mount(mp, path, data, ndp, td)
/*
* Process export requests.
*/
+ if ((args.export.ex_flags & MNT_EXPORTED) != 0 &&
+ (pmp->pm_flags & MSDOSFS_LARGEFS) != 0)
+ return (EOPNOTSUPP);
return (vfs_export(mp, &args.export));
}
}
@@ -415,6 +420,7 @@ mountmsdosfs(devvp, mp, td, argp)
pmp->pm_HiddenSects = getushort(b33->bpbHiddenSecs);
pmp->pm_HugeSectors = pmp->pm_Sectors;
}
+#ifndef MSDOSFS_LARGE
if (pmp->pm_HugeSectors > 0xffffffff /
(pmp->pm_BytesPerSec / sizeof(struct direntry)) + 1) {
/*
@@ -426,6 +432,7 @@ mountmsdosfs(devvp, mp, td, argp)
printf("mountmsdosfs(): disk too big, sorry\n");
goto error_exit;
}
+#endif /* !MSDOSFS_LARGE */
if (pmp->pm_RootDirEnts == 0) {
if (bsp->bs710.bsBootSectSig2 != BOOTSIG2
@@ -628,6 +635,10 @@ mountmsdosfs(devvp, mp, td, argp)
mp->mnt_flag |= MNT_LOCAL;
devvp->v_rdev->si_mountpoint = mp;
+#ifdef MSDOSFS_LARGE
+ msdosfs_fileno_init(mp);
+#endif
+
return 0;
error_exit:
@@ -720,6 +731,9 @@ msdosfs_unmount(mp, mntflags, td)
#endif
vrele(pmp->pm_devvp);
free(pmp->pm_inusemap, M_MSDOSFSFAT);
+#ifdef MSDOSFS_LARGE
+ msdosfs_fileno_free(mp);
+#endif
free(pmp, M_MSDOSFSMNT);
mp->mnt_data = (qaddr_t)0;
mp->mnt_flag &= ~MNT_LOCAL;
OpenPOWER on IntegriCloud