Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/cddl/osnet/dist/uts/common/fs/zfs Fail lookup of .....



details:   https://anonhg.NetBSD.org/src/rev/7bba9b1fa7f4
branches:  trunk
changeset: 782102:7bba9b1fa7f4
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Mon Oct 15 23:51:11 2012 +0000

description:
Fail lookup of .. in a deleted directory with ENOENT.

Don't try to zget the parent, whose znode id may have been recycled
by now.

It's not clear to me how Solaris avoids this, but maybe I'm just
missing something obvious.

diffstat:

 external/cddl/osnet/dist/uts/common/fs/zfs/zfs_dir.c |  13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diffs (23 lines):

diff -r 4b8ef90f44a0 -r 7bba9b1fa7f4 external/cddl/osnet/dist/uts/common/fs/zfs/zfs_dir.c
--- a/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_dir.c      Mon Oct 15 23:08:19 2012 +0000
+++ b/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_dir.c      Mon Oct 15 23:51:11 2012 +0000
@@ -436,9 +436,16 @@
                        return (error);
                }
                rw_enter(&dzp->z_parent_lock, RW_READER);
-               error = zfs_zget(zfsvfs, dzp->z_phys->zp_parent, &zp);
-               if (error == 0)
-                       *vpp = ZTOV(zp);
+               mutex_enter(&dzp->z_lock);
+               if (dzp->z_phys->zp_links == 0) {
+                       /* Directory has been rmdir'd.  */
+                       error = ENOENT;
+               } else {
+                       error = zfs_zget(zfsvfs, dzp->z_phys->zp_parent, &zp);
+                       if (error == 0)
+                               *vpp = ZTOV(zp);
+               }
+               mutex_exit(&dzp->z_lock);
                rw_exit(&dzp->z_parent_lock);
        } else if (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) {
                *vpp = zfsctl_root(dzp);



Home | Main Index | Thread Index | Old Index