diff options
| -rw-r--r-- | sys/gnu/ext2fs/ext2_vnops.c | 57 | ||||
| -rw-r--r-- | sys/gnu/fs/ext2fs/ext2_vnops.c | 57 | ||||
| -rw-r--r-- | sys/kern/vfs_extattr.c | 10 | ||||
| -rw-r--r-- | sys/kern/vfs_syscalls.c | 10 | ||||
| -rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 58 |
5 files changed, 24 insertions, 168 deletions
diff --git a/sys/gnu/ext2fs/ext2_vnops.c b/sys/gnu/ext2fs/ext2_vnops.c index 8c93c0778cbff..22030b58ecea2 100644 --- a/sys/gnu/ext2fs/ext2_vnops.c +++ b/sys/gnu/ext2fs/ext2_vnops.c @@ -925,60 +925,15 @@ abortit: } /* - * Check if just deleting a link name or if we've lost a race. - * If another process completes the same rename after we've looked - * up the source and have blocked looking up the target, then the - * source and target inodes may be identical now although the - * names were never linked. + * Renaming a file to itself has no effect. The upper layers should + * not call us in that case. Temporarily just warn if they do. */ if (fvp == tvp) { - if (fvp->v_type == VDIR) { - /* - * Linked directories are impossible, so we must - * have lost the race. Pretend that the rename - * completed before the lookup. - */ -#ifdef UFS_RENAME_DEBUG - printf("ext2_rename: fvp == tvp for directories\n"); -#endif - error = ENOENT; - goto abortit; - } - - /* Release destination completely. */ - vput(tdvp); - vput(tvp); - - /* - * Delete source. There is another race now that everything - * is unlocked, but this doesn't cause any new complications. - * Relookup() may find a file that is unrelated to the - * original one, or it may fail. Too bad. - */ - vrele(fdvp); - vrele(fvp); - fcnp->cn_flags &= ~MODMASK; - fcnp->cn_flags |= LOCKPARENT | LOCKLEAF; - fcnp->cn_nameiop = DELETE; - VREF(fdvp); - error = relookup(fdvp, &fvp, fcnp); - if (error == 0) - vrele(fdvp); - if (fvp == NULL) { -#ifdef UFS_RENAME_DEBUG - printf("ext2_rename: from name disappeared\n"); -#endif - return (ENOENT); - } - error = VOP_REMOVE(fdvp, fvp, fcnp); - if (fdvp == fvp) - vrele(fdvp); - else - vput(fdvp); - if (fvp != NULLVP) - vput(fvp); - return (error); + printf("ext2_rename: fvp == tvp (can't happen)\n"); + error = 0; + goto abortit; } + if ((error = vn_lock(fvp, LK_EXCLUSIVE, td)) != 0) goto abortit; dp = VTOI(fdvp); diff --git a/sys/gnu/fs/ext2fs/ext2_vnops.c b/sys/gnu/fs/ext2fs/ext2_vnops.c index 8c93c0778cbff..22030b58ecea2 100644 --- a/sys/gnu/fs/ext2fs/ext2_vnops.c +++ b/sys/gnu/fs/ext2fs/ext2_vnops.c @@ -925,60 +925,15 @@ abortit: } /* - * Check if just deleting a link name or if we've lost a race. - * If another process completes the same rename after we've looked - * up the source and have blocked looking up the target, then the - * source and target inodes may be identical now although the - * names were never linked. + * Renaming a file to itself has no effect. The upper layers should + * not call us in that case. Temporarily just warn if they do. */ if (fvp == tvp) { - if (fvp->v_type == VDIR) { - /* - * Linked directories are impossible, so we must - * have lost the race. Pretend that the rename - * completed before the lookup. - */ -#ifdef UFS_RENAME_DEBUG - printf("ext2_rename: fvp == tvp for directories\n"); -#endif - error = ENOENT; - goto abortit; - } - - /* Release destination completely. */ - vput(tdvp); - vput(tvp); - - /* - * Delete source. There is another race now that everything - * is unlocked, but this doesn't cause any new complications. - * Relookup() may find a file that is unrelated to the - * original one, or it may fail. Too bad. - */ - vrele(fdvp); - vrele(fvp); - fcnp->cn_flags &= ~MODMASK; - fcnp->cn_flags |= LOCKPARENT | LOCKLEAF; - fcnp->cn_nameiop = DELETE; - VREF(fdvp); - error = relookup(fdvp, &fvp, fcnp); - if (error == 0) - vrele(fdvp); - if (fvp == NULL) { -#ifdef UFS_RENAME_DEBUG - printf("ext2_rename: from name disappeared\n"); -#endif - return (ENOENT); - } - error = VOP_REMOVE(fdvp, fvp, fcnp); - if (fdvp == fvp) - vrele(fdvp); - else - vput(fdvp); - if (fvp != NULLVP) - vput(fvp); - return (error); + printf("ext2_rename: fvp == tvp (can't happen)\n"); + error = 0; + goto abortit; } + if ((error = vn_lock(fvp, LK_EXCLUSIVE, td)) != 0) goto abortit; dp = VTOI(fdvp); diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 3015105a31c76..e1b2d7f4ca2bf 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -2744,14 +2744,10 @@ kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) if (fvp == tdvp) error = EINVAL; /* - * If source is the same as the destination (that is the - * same inode number with the same name in the same directory), - * then there is nothing to do. + * If the source is the same as the destination (that is, if they + * are links to the same vnode), then there is nothing to do. */ - if (fvp == tvp && fromnd.ni_dvp == tdvp && - fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen && - !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr, - fromnd.ni_cnd.cn_namelen)) + if (fvp == tvp) error = -1; out: if (!error) { diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 3015105a31c76..e1b2d7f4ca2bf 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -2744,14 +2744,10 @@ kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) if (fvp == tdvp) error = EINVAL; /* - * If source is the same as the destination (that is the - * same inode number with the same name in the same directory), - * then there is nothing to do. + * If the source is the same as the destination (that is, if they + * are links to the same vnode), then there is nothing to do. */ - if (fvp == tvp && fromnd.ni_dvp == tdvp && - fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen && - !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr, - fromnd.ni_cnd.cn_namelen)) + if (fvp == tvp) error = -1; out: if (!error) { diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 6ce6d02ae4324..93621bb2756ac 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -1000,61 +1000,15 @@ abortit: } /* - * Check if just deleting a link name or if we've lost a race. - * If another process completes the same rename after we've looked - * up the source and have blocked looking up the target, then the - * source and target inodes may be identical now although the - * names were never linked. + * Renaming a file to itself has no effect. The upper layers should + * not call us in that case. Temporarily just warn if they do. */ if (fvp == tvp) { - if (fvp->v_type == VDIR) { - /* - * Linked directories are impossible, so we must - * have lost the race. Pretend that the rename - * completed before the lookup. - */ -#ifdef UFS_RENAME_DEBUG - printf("ufs_rename: fvp == tvp for directories\n"); -#endif - error = ENOENT; - goto abortit; - } - - /* Release destination completely. */ - vput(tdvp); - vput(tvp); - - /* - * Delete source. There is another race now that everything - * is unlocked, but this doesn't cause any new complications. - * Relookup() may find a file that is unrelated to the - * original one, or it may fail. Too bad. - */ - vrele(fdvp); - vrele(fvp); - fcnp->cn_flags &= ~MODMASK; - fcnp->cn_flags |= LOCKPARENT | LOCKLEAF; - if ((fcnp->cn_flags & SAVESTART) == 0) - panic("ufs_rename: lost from startdir"); - fcnp->cn_nameiop = DELETE; - VREF(fdvp); - error = relookup(fdvp, &fvp, fcnp); - if (error == 0) - vrele(fdvp); - if (fvp == NULL) { -#ifdef UFS_RENAME_DEBUG - printf("ufs_rename: from name disappeared\n"); -#endif - return (ENOENT); - } - error = VOP_REMOVE(fdvp, fvp, fcnp); - if (fdvp == fvp) - vrele(fdvp); - else - vput(fdvp); - vput(fvp); - return (error); + printf("ufs_rename: fvp == tvp (can't happen)\n"); + error = 0; + goto abortit; } + if ((error = vn_lock(fvp, LK_EXCLUSIVE, td)) != 0) goto abortit; dp = VTOI(fdvp); |
