aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/gnu/ext2fs/ext2_vnops.c57
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vnops.c57
-rw-r--r--sys/kern/vfs_extattr.c10
-rw-r--r--sys/kern/vfs_syscalls.c10
-rw-r--r--sys/ufs/ufs/ufs_vnops.c58
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);