summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1998-08-12 20:46:47 +0000
committerjulian <julian@FreeBSD.org>1998-08-12 20:46:47 +0000
commit4c11bd9897e055091c31d225100831676b915dd4 (patch)
treed1b8a9724102b36859cf6ff6a37d4d6f3a95768b /sys/ufs
parent3a1c25125ab1bb81d181b5f5b565afc299d837d9 (diff)
downloadFreeBSD-src-4c11bd9897e055091c31d225100831676b915dd4.zip
FreeBSD-src-4c11bd9897e055091c31d225100831676b915dd4.tar.gz
Handle the case of moving a directory onto the top of a sibling's
child of the same name. Submitted by: Kirk Mckusick with fixes from luoqi Chen Obtained from: Whistle test tree.
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ffs/ffs_softdep.c29
-rw-r--r--sys/ufs/ufs/ufs_vnops.c7
2 files changed, 31 insertions, 5 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 64b0c9f..72104c7 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -53,8 +53,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * from: @(#)ffs_softdep.c 9.27 (McKusick) 6/12/98
- * $Id: ffs_softdep.c,v 1.11 1998/06/12 20:48:30 julian Exp $
+ * from: @(#)ffs_softdep.c 9.28 (McKusick) 8/8/98
+ * $Id: ffs_softdep.c,v 1.12 1998/06/12 21:21:26 julian Exp $
*/
/*
@@ -2258,6 +2258,7 @@ free_diradd(dap)
} else {
dirrem = dap->da_previous;
pagedep = dirrem->dm_pagedep;
+ dirrem->dm_dirinum = pagedep->pd_ino;
add_to_worklist(&dirrem->dm_list);
}
if (inodedep_lookup(VFSTOUFS(pagedep->pd_mnt)->um_fs, dap->da_newinum,
@@ -2437,6 +2438,20 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir)
*/
dirrem = newdirrem(bp, dp, ip, isrmdir);
pagedep = dirrem->dm_pagedep;
+ /*
+ * The possible values for isrmdir:
+ * 0 - non-directory file rename
+ * 1 - directory rename within same directory
+ * inum - directory rename to new directory of given inode number
+ * When renaming to a new directory, we are both deleting and
+ * creating a new directory entry, so the link count on the new
+ * directory should not change. Thus we do not need the followup
+ * dirrem which is usually done in handle_workitem_remove. We set
+ * the DIRCHG flag to tell handle_workitem_remove to skip the
+ * followup dirrem.
+ */
+ if (isrmdir > 1)
+ dirrem->dm_state |= DIRCHG;
/*
* Whiteouts have no additional dependencies,
@@ -2546,6 +2561,16 @@ handle_workitem_remove(dirrem)
ip->i_flag |= IN_CHANGE;
if ((error = UFS_TRUNCATE(vp, (off_t)0, 0, p->p_ucred, p)) != 0)
softdep_error("handle_workitem_remove: truncate", error);
+ /*
+ * Rename a directory to a new parent. Since, we are both deleting
+ * and creating a new directory entry, the link count on the new
+ * directory should not change. Thus we skip the followup dirrem.
+ */
+ if (dirrem->dm_state & DIRCHG) {
+ vput(vp);
+ WORKITEM_FREE(dirrem, D_DIRREM);
+ return;
+ }
ACQUIRE_LOCK(&lk);
(void) inodedep_lookup(ip->i_fs, dirrem->dm_oldinum, DEPALLOC,
&inodedep);
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 28d2634..ea3b0b3 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
- * $Id: ufs_vnops.c,v 1.96 1998/07/11 07:46:08 bde Exp $
+ * $Id: ufs_vnops.c,v 1.97 1998/07/27 15:37:00 bde Exp $
*/
#include "opt_quota.h"
@@ -995,7 +995,7 @@ abortit:
}
ip->i_flag |= IN_RENAME;
oldparent = dp->i_number;
- doingdirectory++;
+ doingdirectory = 1;
}
VN_POLLEVENT(fdvp, POLLWRITE);
vrele(fdvp);
@@ -1143,7 +1143,8 @@ abortit:
goto bad;
}
error = ufs_dirrewrite(dp, xp, ip->i_number,
- IFTODT(ip->i_mode), doingdirectory);
+ IFTODT(ip->i_mode),
+ (doingdirectory && newparent) ? newparent : doingdirectory);
if (error)
goto bad;
if (doingdirectory) {
OpenPOWER on IntegriCloud