From f38282d2bf3b74a666651a77f1ae30806208110e Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Thu, 10 Apr 2014 14:37:23 +0000 Subject: [PATCH 04/14] Omit needless lock dances in ufs_lookup. --- sys/ufs/ufs/ufs_lookup.c | 95 +++--------------------------------------------- 1 file changed, 5 insertions(+), 90 deletions(-) diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index bc98f44..8c6d627 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -137,7 +137,6 @@ ufs_lookup(void *v) int numdirpasses; /* strategy for directory search */ doff_t endsearch; /* offset to end directory search */ doff_t prevoff; /* previous value of ulr_offset */ - struct vnode *pdp; /* saved dp during symlink work */ struct vnode *tdp; /* returned by VFS_VGET */ doff_t enduseful; /* pointer past last used dir slot. used for directory truncation. */ @@ -566,35 +565,16 @@ found: vref(vdp); tdp = vdp; } else { - if (flags & ISDOTDOT) - VOP_UNLOCK(vdp); /* race to get the inode */ error = VFS_VGET(vdp->v_mount, foundino, 0, &tdp); - if (error) { - if (flags & ISDOTDOT) - vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY); - goto out; - } - /* XXX Omit needless lock/unlock. */ - error = vn_lock(tdp, LK_EXCLUSIVE); - if (error) { - vrele(tdp); - tdp = NULL; - if (flags & ISDOTDOT) - vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY); + if (error) goto out; - } - if (flags & ISDOTDOT) - vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY); } /* * Write access to directory required to delete files. */ error = VOP_ACCESS(vdp, VWRITE, cred); if (error) { - if (dp->i_number == foundino) - vrele(tdp); - else - vput(tdp); + vrele(tdp); goto out; } /* @@ -608,10 +588,7 @@ found: tdp, vdp, genfs_can_sticky(cred, dp->i_uid, VTOI(tdp)->i_uid)); if (error) { - if (dp->i_number == foundino) - vrele(tdp); - else - vput(tdp); + vrele(tdp); error = EPERM; goto out; } @@ -639,81 +616,21 @@ found: error = EISDIR; goto out; } - if (flags & ISDOTDOT) - VOP_UNLOCK(vdp); /* race to get the inode */ error = VFS_VGET(vdp->v_mount, foundino, 0, &tdp); - if (error) { - if (flags & ISDOTDOT) - vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY); - goto out; - } - /* XXX Omit needless lock/unlock. */ - error = vn_lock(tdp, LK_EXCLUSIVE); - if (error) { - vrele(tdp); - tdp = NULL; - if (flags & ISDOTDOT) - vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY); + if (error) goto out; - } - if (flags & ISDOTDOT) - vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY); *vpp = tdp; error = 0; goto out; } - /* - * Step through the translation in the name. We do not `vput' the - * directory because we may need it again if a symbolic link - * is relative to the current directory. Instead we save it - * unlocked as "pdp". We must get the target inode before unlocking - * the directory to insure that the inode will not be removed - * before we get it. We prevent deadlock by always fetching - * inodes from the root, moving down the directory tree. Thus - * when following backward pointers ".." we must unlock the - * parent directory before getting the requested directory. - * There is a potential race condition here if both the current - * and parent directories are removed before the VFS_VGET for the - * inode associated with ".." returns. We hope that this occurs - * infrequently since we cannot avoid this race condition without - * implementing a sophisticated deadlock detection algorithm. - * Note also that this simple deadlock detection scheme will not - * work if the file system has any hard links other than ".." - * that point backwards in the directory structure. - */ - pdp = vdp; - if (flags & ISDOTDOT) { - VOP_UNLOCK(pdp); /* race to get the inode */ - error = VFS_VGET(vdp->v_mount, foundino, 0, &tdp); - if (error) { - vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY); - goto out; - } - /* XXX Omit needless lock/unlock. */ - error = vn_lock(tdp, LK_EXCLUSIVE); - if (error) { - vrele(tdp); - tdp = NULL; - vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY); - goto out; - } - vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY); - *vpp = tdp; - } else if (dp->i_number == foundino) { + if (dp->i_number == foundino) { vref(vdp); /* we want ourself, ie "." */ *vpp = vdp; } else { error = VFS_VGET(vdp->v_mount, foundino, 0, &tdp); if (error) goto out; - /* XXX Omit needless lock/unlock. */ - error = vn_lock(tdp, LK_EXCLUSIVE); - if (error) { - vrele(tdp); - tdp = NULL; - goto out; - } *vpp = tdp; } @@ -724,8 +641,6 @@ found: error = 0; out: - if (error == 0 && *vpp != vdp) - VOP_UNLOCK(*vpp); fstrans_done(vdp->v_mount); return error; } -- 1.8.3.1