diff --git a/sbin/mount_msdosfs/mount_msdosfs.8 b/sbin/mount_msdosfs/mount_msdosfs.8 index 445a9fce9d9d..2c3db364eaf8 100644 --- a/sbin/mount_msdosfs/mount_msdosfs.8 +++ b/sbin/mount_msdosfs/mount_msdosfs.8 @@ -30,7 +30,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 3, 2017 +.Dd May 28, 2017 .Dt MOUNT_MSDOSFS 8 .Os .Sh NAME @@ -73,11 +73,6 @@ as described in .Xr mount 8 . The following MSDOS file system-specific options are available: .Bl -tag -width indent -.It Cm large -Support file systems larger than 128 gigabytes at the expense -of 32 bytes of kernel memory for each file on disk. -This memory will not be reclaimed until the file system has -been unmounted. .It Cm longnames Force Windows 95 long filenames to be visible. .It Cm shortnames diff --git a/sys/conf/files b/sys/conf/files index 6c55ca5bb71f..082d0cbcaccb 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3323,7 +3323,6 @@ fs/fuse/fuse_vnops.c optional fuse fs/msdosfs/msdosfs_conv.c optional msdosfs fs/msdosfs/msdosfs_denode.c optional msdosfs fs/msdosfs/msdosfs_fat.c optional msdosfs -fs/msdosfs/msdosfs_fileno.c optional msdosfs fs/msdosfs/msdosfs_iconv.c optional msdosfs_iconv fs/msdosfs/msdosfs_lookup.c optional msdosfs fs/msdosfs/msdosfs_vfsops.c optional msdosfs diff --git a/sys/fs/msdosfs/msdosfs_fileno.c b/sys/fs/msdosfs/msdosfs_fileno.c deleted file mode 100644 index f49e20f6e916..000000000000 --- a/sys/fs/msdosfs/msdosfs_fileno.c +++ /dev/null @@ -1,152 +0,0 @@ -/*- - * Copyright (c) 2003-2004 Tim J. Robbins. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * Compress 64-bit file numbers into temporary, unique 32-bit file numbers. - * This is needed because the algorithm we use to calculate these numbers - * generates 64-bit quantities, but struct dirent's d_fileno member and - * struct vnodeattr's va_fileid member only have space for 32 bits. - * - * 32-bit file numbers are generated sequentially, and stored in a - * red-black tree, indexed on 64-bit file number. The mappings do not - * persist across reboots (or unmounts); anything that relies on this - * (e.g. NFS) will not work correctly. This scheme consumes 32 bytes - * of kernel memory per file (on i386), and it may be possible for a user - * to cause a panic by creating millions of tiny files. - * - * As an optimization, we split the file number space between statically - * allocated and dynamically allocated. File numbers less than - * FILENO_FIRST_DYN are left unchanged and do not have any tree nodes - * allocated to them. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static MALLOC_DEFINE(M_MSDOSFSFILENO, "msdosfs_fileno", "MSDOSFS fileno mapping node"); - -RB_PROTOTYPE(msdosfs_filenotree, msdosfs_fileno, mf_tree, - msdosfs_fileno_compare) - -static int msdosfs_fileno_compare(struct msdosfs_fileno *, - struct msdosfs_fileno *); - -#define FILENO_FIRST_DYN 0xf0000000 - -/* Initialize file number mapping structures. */ -void -msdosfs_fileno_init(struct mount *mp) -{ - struct msdosfsmount *pmp = VFSTOMSDOSFS(mp); - - RB_INIT(&pmp->pm_filenos); - pmp->pm_nfileno = FILENO_FIRST_DYN; - if (pmp->pm_HugeSectors > 0xffffffff / - (pmp->pm_BytesPerSec / sizeof(struct direntry)) + 1) - pmp->pm_flags |= MSDOSFS_LARGEFS; -} - -/* Free 32-bit file number generation structures. */ -void -msdosfs_fileno_free(struct mount *mp) -{ - struct msdosfsmount *pmp = VFSTOMSDOSFS(mp); - struct msdosfs_fileno *mf, *next; - - for (mf = RB_MIN(msdosfs_filenotree, &pmp->pm_filenos); mf != NULL; - mf = next) { - next = RB_NEXT(msdosfs_filenotree, &pmp->pm_filenos, mf); - RB_REMOVE(msdosfs_filenotree, &pmp->pm_filenos, mf); - free(mf, M_MSDOSFSFILENO); - } -} - -/* Map a 64-bit file number into a 32-bit one. */ -uint32_t -msdosfs_fileno_map(struct mount *mp, uint64_t fileno) -{ - struct msdosfsmount *pmp = VFSTOMSDOSFS(mp); - struct msdosfs_fileno key, *mf, *tmf; - uint32_t mapped; - - if ((pmp->pm_flags & MSDOSFS_LARGEFS) == 0) { - KASSERT((uint32_t)fileno == fileno, - ("fileno >32 bits but not a large fs?")); - return ((uint32_t)fileno); - } - if (fileno < FILENO_FIRST_DYN) - return ((uint32_t)fileno); - MSDOSFS_LOCK_MP(pmp); - key.mf_fileno64 = fileno; - mf = RB_FIND(msdosfs_filenotree, &pmp->pm_filenos, &key); - if (mf != NULL) { - mapped = mf->mf_fileno32; - MSDOSFS_UNLOCK_MP(pmp); - return (mapped); - } - if (pmp->pm_nfileno < FILENO_FIRST_DYN) - panic("msdosfs_fileno_map: wraparound"); - MSDOSFS_UNLOCK_MP(pmp); - mf = malloc(sizeof(*mf), M_MSDOSFSFILENO, M_WAITOK); - MSDOSFS_LOCK_MP(pmp); - tmf = RB_FIND(msdosfs_filenotree, &pmp->pm_filenos, &key); - if (tmf != NULL) { - mapped = tmf->mf_fileno32; - MSDOSFS_UNLOCK_MP(pmp); - free(mf, M_MSDOSFSFILENO); - return (mapped); - } - mf->mf_fileno64 = fileno; - mapped = mf->mf_fileno32 = pmp->pm_nfileno++; - RB_INSERT(msdosfs_filenotree, &pmp->pm_filenos, mf); - MSDOSFS_UNLOCK_MP(pmp); - return (mapped); -} - -/* Compare by 64-bit file number. */ -static int -msdosfs_fileno_compare(struct msdosfs_fileno *fa, struct msdosfs_fileno *fb) -{ - - if (fa->mf_fileno64 > fb->mf_fileno64) - return (1); - else if (fa->mf_fileno64 < fb->mf_fileno64) - return (-1); - return (0); -} - -RB_GENERATE(msdosfs_filenotree, msdosfs_fileno, mf_tree, - msdosfs_fileno_compare) diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c index d1c71f4a8ffb..30b463c46083 100644 --- a/sys/fs/msdosfs/msdosfs_vfsops.c +++ b/sys/fs/msdosfs/msdosfs_vfsops.c @@ -82,7 +82,7 @@ static const char *msdosfs_opts[] = { "async", "noatime", "noclusterr", "noclusterw", "export", "force", "from", "sync", "cs_dos", "cs_local", "cs_win", "dirmask", - "gid", "kiconv", "large", "longname", + "gid", "kiconv", "longname", "longnames", "mask", "shortname", "shortnames", "uid", "win95", "nowin95", NULL @@ -242,17 +242,6 @@ msdosfs_mount(struct mount *mp) */ if (mp->mnt_flag & MNT_UPDATE) { pmp = VFSTOMSDOSFS(mp); - if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0)) { - /* - * Forbid export requests if filesystem has - * MSDOSFS_LARGEFS flag set. - */ - if ((pmp->pm_flags & MSDOSFS_LARGEFS) != 0) { - vfs_mount_error(mp, - "MSDOSFS_LARGEFS flag set, cannot export"); - return (EOPNOTSUPP); - } - } if (!(pmp->pm_flags & MSDOSFSMNT_RONLY) && vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) { error = VFS_SYNC(mp, MNT_WAIT); @@ -466,20 +455,6 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp) pmp->pm_mask = pmp->pm_dirmask = S_IXUSR | S_IXGRP | S_IXOTH | S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR; - /* - * Experimental support for large MS-DOS filesystems. - * WARNING: This uses at least 32 bytes of kernel memory (which is not - * reclaimed until the FS is unmounted) for each file on disk to map - * between the 32-bit inode numbers used by VFS and the 64-bit - * pseudo-inode numbers used internally by msdosfs. This is only - * safe to use in certain controlled situations (e.g. read-only FS - * with less than 1 million files). - * Since the mappings do not persist across unmounts (or reboots), these - * filesystems are not suitable for exporting through NFS, or any other - * application that requires fixed inode numbers. - */ - vfs_flagopt(mp->mnt_optnew, "large", &pmp->pm_flags, MSDOSFS_LARGEFS); - /* * Compute several useful quantities from the bpb in the * bootsector. Copy in the dos 5 variant of the bpb then fix up @@ -521,20 +496,6 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp) pmp->pm_HiddenSects = getushort(b33->bpbHiddenSecs); pmp->pm_HugeSectors = pmp->pm_Sectors; } - if (!(pmp->pm_flags & MSDOSFS_LARGEFS)) { - if (pmp->pm_HugeSectors > 0xffffffff / - (pmp->pm_BytesPerSec / sizeof(struct direntry)) + 1) { - /* - * We cannot deal currently with this size of disk - * due to fileid limitations (see msdosfs_getattr and - * msdosfs_readdir) - */ - error = EINVAL; - vfs_mount_error(mp, - "Disk too big, try '-o large' mount option"); - goto error_exit; - } - } if (pmp->pm_RootDirEnts == 0) { if (pmp->pm_FATsecs @@ -745,10 +706,7 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp) mp->mnt_kern_flag |= MNTK_USES_BCACHE | MNTK_NO_IOPF; MNT_IUNLOCK(mp); - if (pmp->pm_flags & MSDOSFS_LARGEFS) - msdosfs_fileno_init(mp); - - return 0; + return (0); error_exit: if (bp) @@ -835,8 +793,6 @@ msdosfs_unmount(struct mount *mp, int mntflags) vrele(pmp->pm_devvp); dev_rel(pmp->pm_dev); free(pmp->pm_inusemap, M_MSDOSFSFAT); - if (pmp->pm_flags & MSDOSFS_LARGEFS) - msdosfs_fileno_free(mp); lockdestroy(&pmp->pm_fatlock); free(pmp, M_MSDOSFSMNT); mp->mnt_data = NULL; diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index db6add7ce528..a37fabe5cbd2 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -284,11 +284,7 @@ msdosfs_getattr(struct vop_getattr_args *ap) fileid = (uint64_t)roottobn(pmp, 0) * dirsperblk; fileid += (uoff_t)dep->de_diroffset / sizeof(struct direntry); } - - if (pmp->pm_flags & MSDOSFS_LARGEFS) - vap->va_fileid = msdosfs_fileno_map(pmp->pm_mountp, fileid); - else - vap->va_fileid = (long)fileid; + vap->va_fileid = fileid; mode = S_IRWXU|S_IRWXG|S_IRWXO; vap->va_mode = mode & @@ -1472,7 +1468,6 @@ msdosfs_readdir(struct vop_readdir_args *ap) int blsize; long on; u_long cn; - uint64_t fileno; u_long dirsperblk; long bias = 0; daddr_t bn, lbn; @@ -1543,20 +1538,9 @@ msdosfs_readdir(struct vop_readdir_args *ap) if (offset < bias) { for (n = (int)offset / sizeof(struct direntry); n < 2; n++) { - if (FAT32(pmp)) - fileno = (uint64_t)cntobn(pmp, - pmp->pm_rootdirblk) - * dirsperblk; - else - fileno = 1; - if (pmp->pm_flags & MSDOSFS_LARGEFS) { - dirbuf.d_fileno = - msdosfs_fileno_map(pmp->pm_mountp, - fileno); - } else { - - dirbuf.d_fileno = (uint32_t)fileno; - } + dirbuf.d_fileno = FAT32(pmp) ? + (uint64_t)cntobn(pmp, pmp->pm_rootdirblk) * + dirsperblk : 1; dirbuf.d_type = DT_DIR; switch (n) { case 0: @@ -1661,31 +1645,24 @@ msdosfs_readdir(struct vop_readdir_args *ap) * msdosfs_getattr. */ if (dentp->deAttributes & ATTR_DIRECTORY) { - fileno = getushort(dentp->deStartCluster); - if (FAT32(pmp)) - fileno |= getushort(dentp->deHighClust) << 16; - /* if this is the root directory */ - if (fileno == MSDOSFSROOT) - if (FAT32(pmp)) - fileno = (uint64_t)cntobn(pmp, - pmp->pm_rootdirblk) - * dirsperblk; - else - fileno = 1; + cn = getushort(dentp->deStartCluster); + if (FAT32(pmp)) { + cn |= getushort(dentp->deHighClust) << + 16; + if (cn == MSDOSFSROOT) + cn = pmp->pm_rootdirblk; + } + if (cn == MSDOSFSROOT && !FAT32(pmp)) + dirbuf.d_fileno = 1; else - fileno = (uint64_t)cntobn(pmp, fileno) * + dirbuf.d_fileno = cntobn(pmp, cn) * dirsperblk; dirbuf.d_type = DT_DIR; } else { - fileno = (uoff_t)offset / + dirbuf.d_fileno = (uoff_t)offset / sizeof(struct direntry); dirbuf.d_type = DT_REG; } - if (pmp->pm_flags & MSDOSFS_LARGEFS) { - dirbuf.d_fileno = - msdosfs_fileno_map(pmp->pm_mountp, fileno); - } else - dirbuf.d_fileno = (uint32_t)fileno; if (chksum != winChksum(dentp->deName)) { dirbuf.d_namlen = dos2unixfn(dentp->deName, diff --git a/sys/fs/msdosfs/msdosfsmount.h b/sys/fs/msdosfs/msdosfsmount.h index dcc4f1dafc36..f8476d5f319a 100644 --- a/sys/fs/msdosfs/msdosfsmount.h +++ b/sys/fs/msdosfs/msdosfsmount.h @@ -108,10 +108,7 @@ struct msdosfsmount { void *pm_w2u; /* Unicode->Local iconv handle */ void *pm_u2d; /* Unicode->DOS iconv handle */ void *pm_d2u; /* DOS->Local iconv handle */ - uint32_t pm_nfileno; /* next 32-bit fileno */ - RB_HEAD(msdosfs_filenotree, msdosfs_fileno) - pm_filenos; /* 64<->32-bit fileno mapping */ - struct lock pm_fatlock; /* lockmgr protecting allocations and rb tree */ + struct lock pm_fatlock; /* lockmgr protecting allocations */ }; /* @@ -216,10 +213,6 @@ struct msdosfs_fileno { ? roottobn((pmp), (dirofs)) \ : cntobn((pmp), (dirclu))) -void msdosfs_fileno_init(struct mount *); -void msdosfs_fileno_free(struct mount *); -uint32_t msdosfs_fileno_map(struct mount *, uint64_t); - #define MSDOSFS_LOCK_MP(pmp) \ lockmgr(&(pmp)->pm_fatlock, LK_EXCLUSIVE, NULL) #define MSDOSFS_UNLOCK_MP(pmp) \ @@ -261,7 +254,6 @@ struct msdosfs_args { #define MSDOSFSMNT_RONLY 0x80000000 /* mounted read-only */ #define MSDOSFSMNT_WAITONFAT 0x40000000 /* mounted synchronous */ #define MSDOSFS_FATMIRROR 0x20000000 /* FAT is mirrored */ -#define MSDOSFS_LARGEFS 0x10000000 /* perform fileno mapping */ #define MSDOSFS_FSIMOD 0x01000000 #endif /* !_MSDOSFS_MSDOSFSMOUNT_H_ */ diff --git a/sys/modules/msdosfs/Makefile b/sys/modules/msdosfs/Makefile index 0ba4e47e9c3f..3a0f478cfd57 100644 --- a/sys/modules/msdosfs/Makefile +++ b/sys/modules/msdosfs/Makefile @@ -4,7 +4,7 @@ KMOD= msdosfs SRCS= vnode_if.h \ - msdosfs_conv.c msdosfs_denode.c msdosfs_fat.c msdosfs_fileno.c \ + msdosfs_conv.c msdosfs_denode.c msdosfs_fat.c \ msdosfs_lookup.c msdosfs_vfsops.c msdosfs_vnops.c EXPORT_SYMS= msdosfs_iconv