summaryrefslogtreecommitdiffstats
path: root/sys/fs/ext2fs
diff options
context:
space:
mode:
authorpfg <pfg@FreeBSD.org>2013-06-29 01:35:28 +0000
committerpfg <pfg@FreeBSD.org>2013-06-29 01:35:28 +0000
commit7e708941c45b3e65112108d8fa7fdc7f83a53eb6 (patch)
treebfb6f4faa79defe5b78c41507260206aceb453ea /sys/fs/ext2fs
parentcea740e055253d28645996001e38af68a43c8d1a (diff)
downloadFreeBSD-src-7e708941c45b3e65112108d8fa7fdc7f83a53eb6.zip
FreeBSD-src-7e708941c45b3e65112108d8fa7fdc7f83a53eb6.tar.gz
Bring some updates from ufs_lookup to ext2fs.
r156418: Don't set IN_CHANGE and IN_UPDATE on inodes for potentially suspended file systems. This could cause deadlocks when creating snapshots. (We can't do snapshots on ext2fs but it is useful to keep things in sync). r183079: - 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. r187528: Move the code from ufs_lookup.c used to do dotdot lookup, into the helper function. It is supposed to be useful for any filesystem that has to unlock dvp to walk to the ".." entry in lookup routine. MFC after: 5 days
Diffstat (limited to 'sys/fs/ext2fs')
-rw-r--r--sys/fs/ext2fs/ext2_lookup.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/sys/fs/ext2fs/ext2_lookup.c b/sys/fs/ext2fs/ext2_lookup.c
index 75b11a8..623260d 100644
--- a/sys/fs/ext2fs/ext2_lookup.c
+++ b/sys/fs/ext2fs/ext2_lookup.c
@@ -289,9 +289,9 @@ ext2_lookup_ino(struct vnode *vdp, struct vnode **vpp, struct componentname *cnp
int entryoffsetinblock; /* offset of ep in bp's buffer */
enum {NONE, COMPACT, FOUND} slotstatus;
doff_t slotoffset; /* offset of area with free space */
- int slotsize; /* size of area at slotoffset */
doff_t i_diroff; /* cached i_diroff value */
doff_t i_offset; /* cached i_offset value */
+ int slotsize; /* size of area at slotoffset */
int slotfreespace; /* amount of space free in slot */
int slotneeded; /* size of the entry we're seeking */
int numdirpasses; /* strategy for directory search */
@@ -476,7 +476,6 @@ searchloop:
endsearch = i_diroff;
goto searchloop;
}
- dp->i_offset = i_offset;
if (bp != NULL)
brelse(bp);
/*
@@ -512,7 +511,6 @@ searchloop:
enduseful = slotoffset + slotsize;
}
dp->i_endoff = roundup2(enduseful, DIRBLKSIZ);
- dp->i_flag |= IN_CHANGE | IN_UPDATE;
/*
* We return with the directory locked, so that
* the parameters we set up above will still be
@@ -560,12 +558,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)) {
+ if (flags & LOCKPARENT)
+ ASSERT_VOP_ELOCKED(vdp, __FUNCTION__);
/*
* Write access to directory required to delete files.
*/
@@ -576,7 +575,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
@@ -621,6 +626,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 (dd_ino != NULL)
@@ -656,10 +662,7 @@ found:
*/
pdp = vdp;
if (flags & ISDOTDOT) {
- ltype = VOP_ISLOCKED(pdp);
- VOP_UNLOCK(pdp, 0); /* race to get the inode */
- error = VFS_VGET(vdp->v_mount, ino, cnp->cn_lkflags, &tdp);
- vn_lock(pdp, ltype | LK_RETRY);
+ error = vn_vget_ino(pdp, ino, cnp->cn_lkflags, &tdp);
if (pdp->v_iflag & VI_DOOMED) {
if (error == 0)
vput(tdp);
OpenPOWER on IntegriCloud