diff options
author | jhb <jhb@FreeBSD.org> | 2008-09-16 16:18:36 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2008-09-16 16:18:36 +0000 |
commit | 3a8bef861f0b1a62ad9f5e2e87a644b9cb5677ab (patch) | |
tree | afd2b9a883055b9c631bd5eaf59d6734446a7f43 /sys | |
parent | 37890de0aac40567999d70fc1f3d94e8d6030d35 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/ufs/ufs/ufs_lookup.c | 12 |
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, |