1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-01 12:19:28 +00:00

- Mount ZFS snapshots with MNT_IGNORE flag, so they are not visible in regular

df(1) and mount(8) output. This is a bit smilar to OpenSolaris and follows
  ZFS route of not listing snapshots by default with 'zfs list' command.
- Add UPDATING entry to note that ZFS snapshots are no longer visible in
  mount(8) and df(1) output by default.

Reviewed by:	kib
MFC after:	3 days
This commit is contained in:
Pawel Jakub Dawidek 2009-09-14 21:10:40 +00:00
parent 8abb2a6ed9
commit 63e1d3df27
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=197201
4 changed files with 40 additions and 53 deletions

View File

@ -22,6 +22,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 9.x IS SLOW:
machines to maximize performance. (To disable malloc debugging, run
ln -s aj /etc/malloc.conf.)
20090910:
ZFS snapshots are now mounted with MNT_IGNORE flag. Use -v option for
mount(8) and -a option for df(1) to see them.
20090825:
The old tunable hw.bus.devctl_disable has been superseded by
hw.bus.devctl_queue. hw.bus.devctl_disable=1 in loader.conf should be

View File

@ -112,12 +112,13 @@ vfs_optionisset(const vfs_t *vfsp, const char *opt, char **argp)
}
int
domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype, char *fspath,
char *fspec, int fsflags)
{
struct mount *mp;
struct vfsconf *vfsp;
struct ucred *cr;
vnode_t *vp;
int error;
/*
@ -132,23 +133,28 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
if (vfsp == NULL)
return (ENODEV);
vp = *vpp;
if (vp->v_type != VDIR)
return (ENOTDIR);
/*
* We need vnode lock to protect v_mountedhere and vnode interlock
* to protect v_iflag.
*/
vn_lock(vp, LK_SHARED | LK_RETRY);
VI_LOCK(vp);
if ((vp->v_iflag & VI_MOUNT) != 0 ||
vp->v_mountedhere != NULL) {
if ((vp->v_iflag & VI_MOUNT) != 0 || vp->v_mountedhere != NULL) {
VI_UNLOCK(vp);
VOP_UNLOCK(vp, 0);
return (EBUSY);
}
vp->v_iflag |= VI_MOUNT;
VI_UNLOCK(vp);
VOP_UNLOCK(vp, 0);
/*
* Allocate and initialize the filesystem.
*/
vn_lock(vp, LK_SHARED | LK_RETRY);
mp = vfs_mount_alloc(vp, vfsp, fspath, td->td_ucred);
VOP_UNLOCK(vp, 0);
mp->mnt_optnew = NULL;
vfs_setmntopt(mp, "from", fspec, 0);
@ -158,10 +164,17 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
/*
* Set the mount level flags.
*/
if (fsflags & MNT_RDONLY)
mp->mnt_flag |= MNT_RDONLY;
mp->mnt_flag &=~ MNT_UPDATEMASK;
mp->mnt_flag &= ~MNT_UPDATEMASK;
mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE | MNT_ROOTFS);
/*
* Snapshots are always read-only.
*/
mp->mnt_flag |= MNT_RDONLY;
/*
* We don't want snapshots to be visible in regular
* mount(8) and df(1) output.
*/
mp->mnt_flag |= MNT_IGNORE;
/*
* Unprivileged user can trigger mounting a snapshot, but we don't want
* him to unmount it, so we switch to privileged of original mount.
@ -169,11 +182,6 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
crfree(mp->mnt_cred);
mp->mnt_cred = crdup(vp->v_mount->mnt_cred);
mp->mnt_stat.f_owner = mp->mnt_cred->cr_uid;
/*
* Mount the filesystem.
* XXX The final recipients of VFS_MOUNT just overwrite the ndp they
* get. No freeing of cn_pnbuf.
*/
/*
* XXX: This is evil, but we can't mount a snapshot as a regular user.
* XXX: Is is safe when snapshot is mounted from within a jail?
@ -183,7 +191,7 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
error = VFS_MOUNT(mp);
td->td_ucred = cr;
if (!error) {
if (error == 0) {
if (mp->mnt_opt != NULL)
vfs_freeopts(mp->mnt_opt);
mp->mnt_opt = mp->mnt_optnew;
@ -195,42 +203,33 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
*/
mp->mnt_optnew = NULL;
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
/*
* Put the new filesystem on the mount list after root.
*/
#ifdef FREEBSD_NAMECACHE
cache_purge(vp);
#endif
if (!error) {
VI_LOCK(vp);
vp->v_iflag &= ~VI_MOUNT;
VI_UNLOCK(vp);
if (error == 0) {
vnode_t *mvp;
VI_LOCK(vp);
vp->v_iflag &= ~VI_MOUNT;
VI_UNLOCK(vp);
vp->v_mountedhere = mp;
/*
* Put the new filesystem on the mount list.
*/
mtx_lock(&mountlist_mtx);
TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
mtx_unlock(&mountlist_mtx);
vfs_event_signal(NULL, VQ_MOUNT, 0);
if (VFS_ROOT(mp, LK_EXCLUSIVE, &mvp))
panic("mount: lost mount");
mountcheckdirs(vp, mvp);
vput(mvp);
VOP_UNLOCK(vp, 0);
if ((mp->mnt_flag & MNT_RDONLY) == 0)
error = vfs_allocate_syncvnode(mp);
vput(vp);
vfs_unbusy(mp);
if (error)
vrele(vp);
else
vfs_mountedfrom(mp, fspec);
*vpp = mvp;
} else {
VI_LOCK(vp);
vp->v_iflag &= ~VI_MOUNT;
VI_UNLOCK(vp);
VOP_UNLOCK(vp, 0);
vput(vp);
vfs_unbusy(mp);
vfs_mount_destroy(mp);
*vpp = NULL;
}
return (error);
}

View File

@ -110,8 +110,8 @@ void vfs_setmntopt(vfs_t *vfsp, const char *name, const char *arg,
int flags __unused);
void vfs_clearmntopt(vfs_t *vfsp, const char *name);
int vfs_optionisset(const vfs_t *vfsp, const char *opt, char **argp);
int domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath,
char *fspec, int fsflags);
int mount_snapshot(kthread_t *td, vnode_t **vpp, const char *fstype,
char *fspath, char *fspec, int fsflags);
typedef uint64_t vfs_feature_t;

View File

@ -880,17 +880,9 @@ zfsctl_snapdir_lookup(ap)
mountpoint = kmem_alloc(mountpoint_len, KM_SLEEP);
(void) snprintf(mountpoint, mountpoint_len, "%s/.zfs/snapshot/%s",
dvp->v_vfsp->mnt_stat.f_mntonname, nm);
err = domount(curthread, *vpp, "zfs", mountpoint, snapname, 0);
err = mount_snapshot(curthread, vpp, "zfs", mountpoint, snapname, 0);
kmem_free(mountpoint, mountpoint_len);
if (err == 0) {
vnode_t *mvp;
ASSERT((*vpp)->v_mountedhere != NULL);
err = VFS_ROOT((*vpp)->v_mountedhere, LK_EXCLUSIVE, &mvp);
ASSERT(err == 0);
VN_RELE(*vpp);
*vpp = mvp;
/*
* Fix up the root vnode mounted on .zfs/snapshot/<snapname>.
*
@ -902,14 +894,6 @@ zfsctl_snapdir_lookup(ap)
VTOZ(*vpp)->z_zfsvfs->z_parent = zfsvfs;
}
mutex_exit(&sdp->sd_lock);
/*
* If we had an error, drop our hold on the vnode and
* zfsctl_snapshot_inactive() will clean up.
*/
if (err) {
VN_RELE(*vpp);
*vpp = NULL;
}
ZFS_EXIT(zfsvfs);
return (err);
}