Index: ffs_vfsops.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_vfsops.c,v retrieving revision 1.234 diff -u -r1.234 ffs_vfsops.c --- ffs_vfsops.c 4 Jul 2004 08:52:35 -0000 1.234 +++ ffs_vfsops.c 6 Jul 2004 05:06:15 -0000 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -148,6 +149,7 @@ struct fs *fs; int error, flags; mode_t accessmode; + struct vattr va; if (uma_inode == NULL) { uma_inode = uma_zcreate("FFS inode", @@ -189,6 +191,32 @@ ump = VFSTOUFS(mp); fs = ump->um_fs; devvp = ump->um_devvp; + /* + * Disallow write mounting on a UFS file system mounted from + * a UFS snapshot. + * + * XXX: This is almost certainly not the right place to do + * this check -- it's here because we ignore the VOP_ACCESS() + * for the root user. + * + * XXX: Note that this code is duplicated between the update + * and new mount paths, so remember to modify both if you + * change either. + */ + if ((mp->mnt_flag & MNT_RDONLY) == 0) { + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); + error = VOP_GETATTR(devvp, &va, td->td_ucred, td); + if (error != 0) { + vput(devvp); + return (error); + } + if ((va.va_flags & SF_SNAPSHOT) != 0) { + vput(devvp); + return (EACCES); + } + VOP_UNLOCK(devvp, 0, td); + } + if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0) return (error); @@ -322,6 +350,30 @@ } /* + * Disallow write mounting on a UFS file system mounted from a UFS + * snapshot. + * + * XXX: This is almost certainly not the right place to do this check + * -- it's here because we ignore the VOP_ACCESS() for the root user. + * + * XXX: Note that this code is duplicated between the update and new + * mount paths, so remember to modify both if you change either. + */ + if ((mp->mnt_flag & MNT_RDONLY) == 0) { + vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); + error = VOP_GETATTR(devvp, &va, td->td_ucred, td); + if (error != 0) { + vput(devvp); + return (error); + } + if ((va.va_flags & SF_SNAPSHOT) != 0) { + vput(devvp); + return (EACCES); + } + VOP_UNLOCK(devvp, 0, td); + } + + /* * If mount by non-root, then verify that user has necessary * permissions on the device. */