From b98752e61b1650b936fff8c86b9e247d1216920a Mon Sep 17 00:00:00 2001 From: mckusick Date: Sun, 29 Jan 2012 08:03:45 +0000 Subject: [PATCH 143/175] MFC r230249: Make sure all intermediate variables holding mount flags (mnt_flag) and that all internal kernel calls passing mount flags are declared as uint64_t so that flags in the top 32-bits are not lost. MFC r230250: There are several bugs/hangs when trying to take a snapshot on a UFS/FFS filesystem running with journaled soft updates. Until these problems have been tracked down, return ENOTSUPP when an attempt is made to take a snapshot on a filesystem running with journaled soft updates. git-svn-id: http://svn.freebsd.org/base/stable/9@230725 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f (cherry picked from commit 3d3eaecb36aa26eb50df3dee901b9c552f41201a) Signed-off-by: Xin Li --- sys/compat/freebsd32/freebsd32_misc.c | 14 +++++++-- sys/fs/cd9660/cd9660_vfsops.c | 2 +- sys/fs/fdescfs/fdesc_vfsops.c | 2 +- sys/fs/hpfs/hpfs_vfsops.c | 2 +- sys/fs/msdosfs/msdosfs_vfsops.c | 2 +- sys/fs/nfsclient/nfs_clvfsops.c | 2 +- sys/fs/ntfs/ntfs_vfsops.c | 2 +- sys/fs/nwfs/nwfs_vfsops.c | 2 +- sys/fs/portalfs/portal_vfsops.c | 2 +- sys/fs/pseudofs/pseudofs.c | 2 +- sys/fs/pseudofs/pseudofs.h | 2 +- sys/fs/smbfs/smbfs_vfsops.c | 2 +- sys/gnu/fs/reiserfs/reiserfs_vfsops.c | 2 +- sys/kern/vfs_mount.c | 55 +++++++++++++++++++++------------ sys/kern/vfs_subr.c | 11 ++++--- sys/nfsclient/nfs_vfsops.c | 2 +- sys/sys/mount.h | 7 +++-- sys/ufs/ffs/ffs_snapshot.c | 10 +++++- sys/ufs/ffs/ffs_vfsops.c | 4 +-- 19 files changed, 81 insertions(+), 46 deletions(-) diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index def9f33..5237c70 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -2465,9 +2465,17 @@ freebsd32_nmount(struct thread *td, } */ *uap) { struct uio *auio; + uint64_t flags; int error; - AUDIT_ARG_FFLAGS(uap->flags); + /* + * Mount flags are now 64-bits. On 32-bit archtectures only + * 32-bits are passed in, but from here on everything handles + * 64-bit flags correctly. + */ + flags = uap->flags; + + AUDIT_ARG_FFLAGS(flags); /* * Filter out MNT_ROOTFS. We do not want clients of nmount() in @@ -2476,7 +2484,7 @@ freebsd32_nmount(struct thread *td, * MNT_ROOTFS should only be set by the kernel when mounting its * root file system. */ - uap->flags &= ~MNT_ROOTFS; + flags &= ~MNT_ROOTFS; /* * check that we have an even number of iovec's @@ -2488,7 +2496,7 @@ freebsd32_nmount(struct thread *td, error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); if (error) return (error); - error = vfs_donmount(td, uap->flags, auio); + error = vfs_donmount(td, flags, auio); free(auio, M_IOV); return error; diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c index 0ad57ec..d3e360d 100644 --- a/sys/fs/cd9660/cd9660_vfsops.c +++ b/sys/fs/cd9660/cd9660_vfsops.c @@ -95,7 +95,7 @@ static int iso_mountfs(struct vnode *devvp, struct mount *mp); */ static int -cd9660_cmount(struct mntarg *ma, void *data, int flags) +cd9660_cmount(struct mntarg *ma, void *data, uint64_t flags) { struct iso_args args; struct export_args exp; diff --git a/sys/fs/fdescfs/fdesc_vfsops.c b/sys/fs/fdescfs/fdesc_vfsops.c index ade38fe28..2f29f68 100644 --- a/sys/fs/fdescfs/fdesc_vfsops.c +++ b/sys/fs/fdescfs/fdesc_vfsops.c @@ -65,7 +65,7 @@ static vfs_root_t fdesc_root; * Compatibility shim for old mount(2) system call. */ int -fdesc_cmount(struct mntarg *ma, void *data, int flags) +fdesc_cmount(struct mntarg *ma, void *data, uint64_t flags) { return kernel_mount(ma, flags); } diff --git a/sys/fs/hpfs/hpfs_vfsops.c b/sys/fs/hpfs/hpfs_vfsops.c index 866004e..c0564ad 100644 --- a/sys/fs/hpfs/hpfs_vfsops.c +++ b/sys/fs/hpfs/hpfs_vfsops.c @@ -73,7 +73,7 @@ static int hpfs_cmount ( struct mntarg *ma, void *data, - int flags) + uint64_t flags) { struct hpfs_args args; struct export_args exp; diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c index e347640..a31f9cf 100644 --- a/sys/fs/msdosfs/msdosfs_vfsops.c +++ b/sys/fs/msdosfs/msdosfs_vfsops.c @@ -197,7 +197,7 @@ update_mp(struct mount *mp, struct thread *td) } static int -msdosfs_cmount(struct mntarg *ma, void *data, int flags) +msdosfs_cmount(struct mntarg *ma, void *data, uint64_t flags) { struct msdosfs_args args; struct export_args exp; diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 3339428..748ab9d 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -1122,7 +1122,7 @@ out: */ /* ARGSUSED */ static int -nfs_cmount(struct mntarg *ma, void *data, int flags) +nfs_cmount(struct mntarg *ma, void *data, uint64_t flags) { int error; struct nfs_args args; diff --git a/sys/fs/ntfs/ntfs_vfsops.c b/sys/fs/ntfs/ntfs_vfsops.c index d3468af..8ec5fe6 100644 --- a/sys/fs/ntfs/ntfs_vfsops.c +++ b/sys/fs/ntfs/ntfs_vfsops.c @@ -117,7 +117,7 @@ static int ntfs_cmount ( struct mntarg *ma, void *data, - int flags) + uint64_t flags) { struct ntfs_args args; struct export_args exp; diff --git a/sys/fs/nwfs/nwfs_vfsops.c b/sys/fs/nwfs/nwfs_vfsops.c index c20159f..d0dddc1 100644 --- a/sys/fs/nwfs/nwfs_vfsops.c +++ b/sys/fs/nwfs/nwfs_vfsops.c @@ -123,7 +123,7 @@ nwfs_initnls(struct nwmount *nmp) { return 0; } -static int nwfs_cmount(struct mntarg *ma, void *data, int flags) +static int nwfs_cmount(struct mntarg *ma, void *data, uint64_t flags) { struct nwfs_args args; /* will hold data from mount request */ int error; diff --git a/sys/fs/portalfs/portal_vfsops.c b/sys/fs/portalfs/portal_vfsops.c index 04e7a3d..6542090 100644 --- a/sys/fs/portalfs/portal_vfsops.c +++ b/sys/fs/portalfs/portal_vfsops.c @@ -69,7 +69,7 @@ static const char *portal_opts[] = { }; static int -portal_cmount(struct mntarg *ma, void *data, int flags) +portal_cmount(struct mntarg *ma, void *data, uint64_t flags) { struct portal_args args; int error; diff --git a/sys/fs/pseudofs/pseudofs.c b/sys/fs/pseudofs/pseudofs.c index f13aa83..d0c9023 100644 --- a/sys/fs/pseudofs/pseudofs.c +++ b/sys/fs/pseudofs/pseudofs.c @@ -330,7 +330,7 @@ pfs_mount(struct pfs_info *pi, struct mount *mp) * Compatibility shim for old mount(2) system call */ int -pfs_cmount(struct mntarg *ma, void *data, int flags) +pfs_cmount(struct mntarg *ma, void *data, uint64_t flags) { int error; diff --git a/sys/fs/pseudofs/pseudofs.h b/sys/fs/pseudofs/pseudofs.h index 836c8bc..0ee57e7 100644 --- a/sys/fs/pseudofs/pseudofs.h +++ b/sys/fs/pseudofs/pseudofs.h @@ -244,7 +244,7 @@ struct pfs_node { * VFS interface */ int pfs_mount (struct pfs_info *pi, struct mount *mp); -int pfs_cmount (struct mntarg *ma, void *data, int flags); +int pfs_cmount (struct mntarg *ma, void *data, uint64_t flags); int pfs_unmount (struct mount *mp, int mntflags); int pfs_root (struct mount *mp, int flags, struct vnode **vpp); diff --git a/sys/fs/smbfs/smbfs_vfsops.c b/sys/fs/smbfs/smbfs_vfsops.c index ac0c5e7..d492fb4 100644 --- a/sys/fs/smbfs/smbfs_vfsops.c +++ b/sys/fs/smbfs/smbfs_vfsops.c @@ -98,7 +98,7 @@ MODULE_DEPEND(smbfs, libmchain, 1, 1, 1); int smbfs_pbuf_freecnt = -1; /* start out unlimited */ static int -smbfs_cmount(struct mntarg *ma, void * data, int flags) +smbfs_cmount(struct mntarg *ma, void * data, uint64_t flags) { struct smbfs_args args; int error; diff --git a/sys/gnu/fs/reiserfs/reiserfs_vfsops.c b/sys/gnu/fs/reiserfs/reiserfs_vfsops.c index 9b7ccd9..208ece0 100644 --- a/sys/gnu/fs/reiserfs/reiserfs_vfsops.c +++ b/sys/gnu/fs/reiserfs/reiserfs_vfsops.c @@ -49,7 +49,7 @@ MALLOC_DEFINE(M_REISERFSNODE, "reiserfs_node", "ReiserFS vnode private part"); * -------------------------------------------------------------------*/ static int -reiserfs_cmount(struct mntarg *ma, void *data, int flags) +reiserfs_cmount(struct mntarg *ma, void *data, uint64_t flags) { struct reiserfs_args args; struct export_args exp; diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 41a6411..7f63917 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -70,8 +70,8 @@ __FBSDID("$FreeBSD$"); #define VFS_MOUNTARG_SIZE_MAX (1024 * 64) -static int vfs_domount(struct thread *td, const char *fstype, - char *fspath, int fsflags, struct vfsoptlist **optlist); +static int vfs_domount(struct thread *td, const char *fstype, char *fspath, + uint64_t fsflags, struct vfsoptlist **optlist); static void free_mntarg(struct mntarg *ma); static int usermount = 0; @@ -376,10 +376,18 @@ sys_nmount(td, uap) struct uio *auio; int error; u_int iovcnt; + uint64_t flags; - AUDIT_ARG_FFLAGS(uap->flags); + /* + * Mount flags are now 64-bits. On 32-bit archtectures only + * 32-bits are passed in, but from here on everything handles + * 64-bit flags correctly. + */ + flags = uap->flags; + + AUDIT_ARG_FFLAGS(flags); CTR4(KTR_VFS, "%s: iovp %p with iovcnt %d and flags %d", __func__, - uap->iovp, uap->iovcnt, uap->flags); + uap->iovp, uap->iovcnt, flags); /* * Filter out MNT_ROOTFS. We do not want clients of nmount() in @@ -388,7 +396,7 @@ sys_nmount(td, uap) * MNT_ROOTFS should only be set by the kernel when mounting its * root file system. */ - uap->flags &= ~MNT_ROOTFS; + flags &= ~MNT_ROOTFS; iovcnt = uap->iovcnt; /* @@ -407,7 +415,7 @@ sys_nmount(td, uap) __func__, error); return (error); } - error = vfs_donmount(td, uap->flags, auio); + error = vfs_donmount(td, flags, auio); free(auio, M_IOV); return (error); @@ -518,7 +526,7 @@ vfs_mount_destroy(struct mount *mp) } int -vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions) +vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions) { struct vfsoptlist *optlist; struct vfsopt *opt, *tmp_opt; @@ -694,9 +702,17 @@ sys_mount(td, uap) char *fstype; struct vfsconf *vfsp = NULL; struct mntarg *ma = NULL; + uint64_t flags; int error; - AUDIT_ARG_FFLAGS(uap->flags); + /* + * Mount flags are now 64-bits. On 32-bit archtectures only + * 32-bits are passed in, but from here on everything handles + * 64-bit flags correctly. + */ + flags = uap->flags; + + AUDIT_ARG_FFLAGS(flags); /* * Filter out MNT_ROOTFS. We do not want clients of mount() in @@ -705,7 +721,7 @@ sys_mount(td, uap) * MNT_ROOTFS should only be set by the kernel when mounting its * root file system. */ - uap->flags &= ~MNT_ROOTFS; + flags &= ~MNT_ROOTFS; fstype = malloc(MFSNAMELEN, M_TEMP, M_WAITOK); error = copyinstr(uap->type, fstype, MFSNAMELEN, NULL); @@ -729,11 +745,11 @@ sys_mount(td, uap) ma = mount_argsu(ma, "fstype", uap->type, MNAMELEN); ma = mount_argsu(ma, "fspath", uap->path, MNAMELEN); - ma = mount_argb(ma, uap->flags & MNT_RDONLY, "noro"); - ma = mount_argb(ma, !(uap->flags & MNT_NOSUID), "nosuid"); - ma = mount_argb(ma, !(uap->flags & MNT_NOEXEC), "noexec"); + ma = mount_argb(ma, flags & MNT_RDONLY, "noro"); + ma = mount_argb(ma, !(flags & MNT_NOSUID), "nosuid"); + ma = mount_argb(ma, !(flags & MNT_NOEXEC), "noexec"); - error = vfsp->vfc_vfsops->vfs_cmount(ma, uap->data, uap->flags); + error = vfsp->vfc_vfsops->vfs_cmount(ma, uap->data, flags); mtx_unlock(&Giant); return (error); } @@ -747,7 +763,7 @@ vfs_domount_first( struct vfsconf *vfsp, /* File system type. */ char *fspath, /* Mount path. */ struct vnode *vp, /* Vnode to be covered. */ - int fsflags, /* Flags common to all filesystems. */ + uint64_t fsflags, /* Flags common to all filesystems. */ struct vfsoptlist **optlist /* Options local to the filesystem. */ ) { @@ -856,14 +872,15 @@ static int vfs_domount_update( struct thread *td, /* Calling thread. */ struct vnode *vp, /* Mount point vnode. */ - int fsflags, /* Flags common to all filesystems. */ + uint64_t fsflags, /* Flags common to all filesystems. */ struct vfsoptlist **optlist /* Options local to the filesystem. */ ) { struct oexport_args oexport; struct export_args export; struct mount *mp; - int error, export_error, flag; + int error, export_error; + uint64_t flag; mtx_assert(&Giant, MA_OWNED); ASSERT_VOP_ELOCKED(vp, __func__); @@ -1000,7 +1017,7 @@ vfs_domount( struct thread *td, /* Calling thread. */ const char *fstype, /* Filesystem type. */ char *fspath, /* Mount path. */ - int fsflags, /* Flags common to all filesystems. */ + uint64_t fsflags, /* Flags common to all filesystems. */ struct vfsoptlist **optlist /* Options local to the filesystem. */ ) { @@ -1205,7 +1222,7 @@ dounmount(mp, flags, td) { struct vnode *coveredvp, *fsrootvp; int error; - int async_flag; + uint64_t async_flag; int mnt_gen_r; mtx_assert(&Giant, MA_OWNED); @@ -1914,7 +1931,7 @@ free_mntarg(struct mntarg *ma) * Mount a filesystem */ int -kernel_mount(struct mntarg *ma, int flags) +kernel_mount(struct mntarg *ma, uint64_t flags) { struct uio auio; int error; diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index f016375..4a45823 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2836,6 +2836,7 @@ DB_SHOW_COMMAND(mount, db_show_mount) struct statfs *sp; struct vnode *vp; char buf[512]; + uint64_t mflags; u_int flags; if (!have_addr) { @@ -2857,13 +2858,13 @@ DB_SHOW_COMMAND(mount, db_show_mount) mp->mnt_stat.f_mntonname, mp->mnt_stat.f_fstypename); buf[0] = '\0'; - flags = mp->mnt_flag; + mflags = mp->mnt_flag; #define MNT_FLAG(flag) do { \ - if (flags & (flag)) { \ + if (mflags & (flag)) { \ if (buf[0] != '\0') \ strlcat(buf, ", ", sizeof(buf)); \ strlcat(buf, (#flag) + 4, sizeof(buf)); \ - flags &= ~(flag); \ + mflags &= ~(flag); \ } \ } while (0) MNT_FLAG(MNT_RDONLY); @@ -2901,11 +2902,11 @@ DB_SHOW_COMMAND(mount, db_show_mount) MNT_FLAG(MNT_SNAPSHOT); MNT_FLAG(MNT_BYFSID); #undef MNT_FLAG - if (flags != 0) { + if (mflags != 0) { if (buf[0] != '\0') strlcat(buf, ", ", sizeof(buf)); snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "0x%08x", flags); + "0x%016jx", mflags); } db_printf(" mnt_flag = %s\n", buf); diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c index 6bcc9b5..02a501d 100644 --- a/sys/nfsclient/nfs_vfsops.c +++ b/sys/nfsclient/nfs_vfsops.c @@ -1178,7 +1178,7 @@ out: */ /* ARGSUSED */ static int -nfs_cmount(struct mntarg *ma, void *data, int flags) +nfs_cmount(struct mntarg *ma, void *data, uint64_t flags) { int error; struct nfs_args args; diff --git a/sys/sys/mount.h b/sys/sys/mount.h index ecaf7b8..f68a046 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -557,7 +557,7 @@ struct nameidata; struct sysctl_req; struct mntarg; -typedef int vfs_cmount_t(struct mntarg *ma, void *data, int flags); +typedef int vfs_cmount_t(struct mntarg *ma, void *data, uint64_t flags); typedef int vfs_unmount_t(struct mount *mp, int mntflags); typedef int vfs_root_t(struct mount *mp, int flags, struct vnode **vpp); typedef int vfs_quotactl_t(struct mount *mp, int cmds, uid_t uid, void *arg); @@ -700,7 +700,7 @@ extern char *mountrootfsname; int dounmount(struct mount *, int, struct thread *); -int kernel_mount(struct mntarg *ma, int flags); +int kernel_mount(struct mntarg *ma, uint64_t flags); int kernel_vmount(int flags, ...); struct mntarg *mount_arg(struct mntarg *ma, const char *name, const void *val, int len); struct mntarg *mount_argb(struct mntarg *ma, int flag, const char *name); @@ -737,7 +737,8 @@ int vfs_export /* process mount export info */ (struct mount *, struct export_args *); void vfs_allocate_syncvnode(struct mount *); void vfs_deallocate_syncvnode(struct mount *); -int vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions); +int vfs_donmount(struct thread *td, uint64_t fsflags, + struct uio *fsoptions); void vfs_getnewfsid(struct mount *); struct cdev *vfs_getrootfsid(struct mount *); struct mount *vfs_getvfs(fsid_t *); /* return vfs given fsid */ diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c index c8d8969..adc1d78 100644 --- a/sys/ufs/ffs/ffs_snapshot.c +++ b/sys/ufs/ffs/ffs_snapshot.c @@ -225,10 +225,18 @@ ffs_snapshot(mp, snapfile) ump = VFSTOUFS(mp); fs = ump->um_fs; sn = NULL; + /* + * At the moment, journaled soft updates cannot support + * taking snapshots. + */ + if (MOUNTEDSUJ(mp)) { + vfs_mount_error(mp, "%s: Snapshots are not yet supported when " + "running with journaled soft updates", fs->fs_fsmnt); + return (EOPNOTSUPP); + } MNT_ILOCK(mp); flag = mp->mnt_flag; MNT_IUNLOCK(mp); - /* * Need to serialize access to snapshot code per filesystem. */ diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 4f688a2..27e6bbc 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -144,7 +144,7 @@ ffs_mount(struct mount *mp) struct fs *fs; pid_t fsckpid = 0; int error, flags; - u_int mntorflags; + uint64_t mntorflags; accmode_t accmode; struct nameidata ndp; char *fspec; @@ -564,7 +564,7 @@ ffs_mount(struct mount *mp) */ static int -ffs_cmount(struct mntarg *ma, void *data, int flags) +ffs_cmount(struct mntarg *ma, void *data, uint64_t flags) { struct ufs_args args; struct export_args exp; -- 1.7.9.4