svn commit: r196309 -
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Pawel Jakub Dawidek
pjd at FreeBSD.org
Mon Aug 17 10:00:19 UTC 2009
Author: pjd
Date: Mon Aug 17 10:00:18 2009
New Revision: 196309
URL: http://svn.freebsd.org/changeset/base/196309
Log:
getcwd() (when __getcwd() fails) works by stating current directory, going up
(..), calling readdir and looking for previous directory inode. In case of
.zfs/ directory this doesn't work, because .zfs/ is hidden by default, so it
won't be visible in readdir output.
Fix this by implementing VPTOCNP for snapshot directories, so __getcwd()
doesn't fail and getcwd() doesn't have to use readdir method.
This fixes /bin/pwd from within .zfs/snapshot/<name>/.
Suggested by: kib
Approved by: re (rwatson)
Modified:
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c Mon Aug 17 09:55:58 2009 (r196308)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c Mon Aug 17 10:00:18 2009 (r196309)
@@ -1195,6 +1195,48 @@ zfsctl_snapshot_lookup(ap)
return (error);
}
+static int
+zfsctl_snapshot_vptocnp(struct vop_vptocnp_args *ap)
+{
+ zfsvfs_t *zfsvfs = ap->a_vp->v_vfsp->vfs_data;
+ vnode_t *dvp, *vp;
+ zfsctl_snapdir_t *sdp;
+ zfs_snapentry_t *sep;
+ int error;
+
+ ASSERT(zfsvfs->z_ctldir != NULL);
+ error = zfsctl_root_lookup(zfsvfs->z_ctldir, "snapshot", &dvp,
+ NULL, 0, NULL, kcred, NULL, NULL, NULL);
+ if (error != 0)
+ return (error);
+ sdp = dvp->v_data;
+
+ mutex_enter(&sdp->sd_lock);
+ sep = avl_first(&sdp->sd_snaps);
+ while (sep != NULL) {
+ vp = sep->se_root;
+ if (vp == ap->a_vp)
+ break;
+ sep = AVL_NEXT(&sdp->sd_snaps, sep);
+ }
+ if (sep == NULL) {
+ mutex_exit(&sdp->sd_lock);
+ error = ENOENT;
+ } else {
+ size_t len;
+
+ len = strlen(sep->se_name);
+ *ap->a_buflen -= len;
+ bcopy(sep->se_name, ap->a_buf + *ap->a_buflen, len);
+ mutex_exit(&sdp->sd_lock);
+ vhold(dvp);
+ *ap->a_vpp = dvp;
+ }
+ VN_RELE(dvp);
+
+ return (error);
+}
+
/*
* These VP's should never see the light of day. They should always
* be covered.
@@ -1206,6 +1248,7 @@ static struct vop_vector zfsctl_ops_snap
.vop_reclaim = zfsctl_common_reclaim,
.vop_getattr = zfsctl_snapshot_getattr,
.vop_fid = zfsctl_snapshot_fid,
+ .vop_vptocnp = zfsctl_snapshot_vptocnp,
};
int
More information about the svn-src-head
mailing list