svn commit: r242575 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Andriy Gapon
avg at FreeBSD.org
Sun Nov 4 14:50:09 UTC 2012
Author: avg
Date: Sun Nov 4 14:50:08 2012
New Revision: 242575
URL: http://svn.freebsd.org/changeset/base/242575
Log:
zfs_dirlook: bailout early if directory is unlinked
Otherwise we could fail with an incorrect error if e.g. parent
object id is removed too or we can even return a wrong vnode if
parent object has been already re-used.
Discussed with: pjd
Also see: http://article.gmane.org/gmane.os.freebsd.devel.file-systems/13863
MFC after: 26 days
Modified:
head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c Sun Nov 4 14:43:15 2012 (r242574)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c Sun Nov 4 14:50:08 2012 (r242575)
@@ -374,8 +374,15 @@ zfs_dirlook(znode_t *dzp, char *name, vn
znode_t *zp;
int error = 0;
uint64_t parent;
+ int unlinked;
if (name[0] == 0 || (name[0] == '.' && name[1] == 0)) {
+ mutex_enter(&dzp->z_lock);
+ unlinked = dzp->z_unlinked;
+ mutex_exit(&dzp->z_lock);
+ if (unlinked)
+ return (ENOENT);
+
*vpp = ZTOV(dzp);
VN_HOLD(*vpp);
} else if (name[0] == '.' && name[1] == '.' && name[2] == 0) {
@@ -394,6 +401,13 @@ zfs_dirlook(znode_t *dzp, char *name, vn
NULL, NULL, NULL);
return (error);
}
+
+ mutex_enter(&dzp->z_lock);
+ unlinked = dzp->z_unlinked;
+ mutex_exit(&dzp->z_lock);
+ if (unlinked)
+ return (ENOENT);
+
rw_enter(&dzp->z_parent_lock, RW_READER);
error = zfs_zget(zfsvfs, parent, &zp);
if (error == 0)
More information about the svn-src-all
mailing list