summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2008-09-16 16:18:36 +0000
committerjhb <jhb@FreeBSD.org>2008-09-16 16:18:36 +0000
commit3a8bef861f0b1a62ad9f5e2e87a644b9cb5677ab (patch)
treeafd2b9a883055b9c631bd5eaf59d6734446a7f43 /sys/ufs
parent37890de0aac40567999d70fc1f3d94e8d6030d35 (diff)
downloadFreeBSD-src-3a8bef861f0b1a62ad9f5e2e87a644b9cb5677ab.zip
FreeBSD-src-3a8bef861f0b1a62ad9f5e2e87a644b9cb5677ab.tar.gz
- Only set i_offset in the parent directory's i-node during a lookup for
non-LOOKUP operations. - Relax a VOP assertion for a DELETE lookup. rename() uses WANTPARENT instead of LOCKPARENT when looking up the source pathname. ufs_rename() uses a relookup() to lock the parent directory when it decides to finally remove the source path. Thus, it is ok for a DELETE with WANTPARENT set instead of LOCKPARENT to use a shared vnode lock rather than an exclusive vnode lock. Reported by: kris (2) Reviewed by: jeff
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ufs/ufs_lookup.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c
index 8c68742..d296857 100644
--- a/sys/ufs/ufs/ufs_lookup.c
+++ b/sys/ufs/ufs/ufs_lookup.c
@@ -390,7 +390,6 @@ notfound:
endsearch = i_diroff;
goto searchloop;
}
- dp->i_offset = i_offset;
if (bp != NULL)
brelse(bp);
/*
@@ -482,13 +481,13 @@ found:
if ((flags & ISLASTCN) && nameiop == LOOKUP)
dp->i_diroff = i_offset &~ (DIRBLKSIZ - 1);
- dp->i_offset = i_offset;
/*
* If deleting, and at end of pathname, return
* parameters which can be used to remove file.
*/
if (nameiop == DELETE && (flags & ISLASTCN)) {
- ASSERT_VOP_ELOCKED(vdp, __FUNCTION__);
+ if (flags & LOCKPARENT)
+ ASSERT_VOP_ELOCKED(vdp, __FUNCTION__);
/*
* Write access to directory required to delete files.
*/
@@ -500,7 +499,13 @@ found:
* and distance past previous entry (if there
* is a previous entry in this block) in dp->i_count.
* Save directory inode pointer in ndp->ni_dvp for dirremove().
+ *
+ * Technically we shouldn't be setting these in the
+ * WANTPARENT case (first lookup in rename()), but any
+ * lookups that will result in directory changes will
+ * overwrite these.
*/
+ dp->i_offset = i_offset;
if ((dp->i_offset & (DIRBLKSIZ - 1)) == 0)
dp->i_count = 0;
else
@@ -542,6 +547,7 @@ found:
* Careful about locking second inode.
* This can only occur if the target is ".".
*/
+ dp->i_offset = i_offset;
if (dp->i_number == ino)
return (EISDIR);
if ((error = VFS_VGET(vdp->v_mount, ino,
OpenPOWER on IntegriCloud