* [PATCH 1/5] xfs: clean up inode locking for RENAME_WHITEOUT
2015-03-24 10:59 [PATCH 0/5 V2] xfs: RENAME_WHITEOUT support Dave Chinner
@ 2015-03-24 10:59 ` Dave Chinner
2015-03-24 21:11 ` Eric Sandeen
2015-03-24 10:59 ` [PATCH 2/5] xfs: cleanup xfs_rename error handling Dave Chinner
` (5 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Dave Chinner @ 2015-03-24 10:59 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
When doing RENAME_WHITEOUT, we now have to lock 5 inodes into the
rename transaction. This means we need to update
xfs_sort_for_rename() and xfs_lock_inodes() to handle up to 5
inodes. Because of the vagaries of rename, this means we could have
anywhere between 3 and 5 inodes locked into the transaction....
While xfs_lock_inodes() does not need anything other than an assert
telling us we are passing more inodes that we ever thought we should
see, it could do with a logic rework to remove all the indenting.
This is not a functional change - it just makes the code a lot
easier to read.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
fs/xfs/xfs_inode.c | 145 +++++++++++++++++++++++++----------------------------
1 file changed, 67 insertions(+), 78 deletions(-)
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 5a44f1c..e38bc40 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -391,15 +391,14 @@ xfs_lock_inumorder(int lock_mode, int subclass)
}
/*
- * The following routine will lock n inodes in exclusive mode.
- * We assume the caller calls us with the inodes in i_ino order.
+ * The following routine will lock n inodes in exclusive mode. We assume the
+ * caller calls us with the inodes in i_ino order.
*
- * We need to detect deadlock where an inode that we lock
- * is in the AIL and we start waiting for another inode that is locked
- * by a thread in a long running transaction (such as truncate). This can
- * result in deadlock since the long running trans might need to wait
- * for the inode we just locked in order to push the tail and free space
- * in the log.
+ * We need to detect deadlock where an inode that we lock is in the AIL and we
+ * start waiting for another inode that is locked by a thread in a long running
+ * transaction (such as truncate). This can result in deadlock since the long
+ * running trans might need to wait for the inode we just locked in order to
+ * push the tail and free space in the log.
*/
void
xfs_lock_inodes(
@@ -410,30 +409,27 @@ xfs_lock_inodes(
int attempts = 0, i, j, try_lock;
xfs_log_item_t *lp;
- ASSERT(ips && (inodes >= 2)); /* we need at least two */
+ /* currently supports between 2 and 5 inodes */
+ ASSERT(ips && inodes >= 2 && inodes <= 5);
try_lock = 0;
i = 0;
-
again:
for (; i < inodes; i++) {
ASSERT(ips[i]);
- if (i && (ips[i] == ips[i-1])) /* Already locked */
+ if (i && (ips[i] == ips[i - 1])) /* Already locked */
continue;
/*
- * If try_lock is not set yet, make sure all locked inodes
- * are not in the AIL.
- * If any are, set try_lock to be used later.
+ * If try_lock is not set yet, make sure all locked inodes are
+ * not in the AIL. If any are, set try_lock to be used later.
*/
-
if (!try_lock) {
for (j = (i - 1); j >= 0 && !try_lock; j--) {
lp = (xfs_log_item_t *)ips[j]->i_itemp;
- if (lp && (lp->li_flags & XFS_LI_IN_AIL)) {
+ if (lp && (lp->li_flags & XFS_LI_IN_AIL))
try_lock++;
- }
}
}
@@ -443,51 +439,42 @@ again:
* we can't get any, we must release all we have
* and try again.
*/
+ if (!try_lock) {
+ xfs_ilock(ips[i], xfs_lock_inumorder(lock_mode, i));
+ continue;
+ }
+
+ /* try_lock means we have an inode locked that is in the AIL. */
+ ASSERT(i != 0);
+ if (xfs_ilock_nowait(ips[i], xfs_lock_inumorder(lock_mode, i)))
+ continue;
- if (try_lock) {
- /* try_lock must be 0 if i is 0. */
+ /*
+ * Unlock all previous guys and try again. xfs_iunlock will try
+ * to push the tail if the inode is in the AIL.
+ */
+ attempts++;
+ for (j = i - 1; j >= 0; j--) {
/*
- * try_lock means we have an inode locked
- * that is in the AIL.
+ * Check to see if we've already unlocked this one. Not
+ * the first one going back, and the inode ptr is the
+ * same.
*/
- ASSERT(i != 0);
- if (!xfs_ilock_nowait(ips[i], xfs_lock_inumorder(lock_mode, i))) {
- attempts++;
-
- /*
- * Unlock all previous guys and try again.
- * xfs_iunlock will try to push the tail
- * if the inode is in the AIL.
- */
-
- for(j = i - 1; j >= 0; j--) {
-
- /*
- * Check to see if we've already
- * unlocked this one.
- * Not the first one going back,
- * and the inode ptr is the same.
- */
- if ((j != (i - 1)) && ips[j] ==
- ips[j+1])
- continue;
-
- xfs_iunlock(ips[j], lock_mode);
- }
+ if (j != (i - 1) && ips[j] == ips[j + 1])
+ continue;
+
+ xfs_iunlock(ips[j], lock_mode);
+ }
- if ((attempts % 5) == 0) {
- delay(1); /* Don't just spin the CPU */
+ if ((attempts % 5) == 0) {
+ delay(1); /* Don't just spin the CPU */
#ifdef DEBUG
- xfs_lock_delays++;
+ xfs_lock_delays++;
#endif
- }
- i = 0;
- try_lock = 0;
- goto again;
- }
- } else {
- xfs_ilock(ips[i], xfs_lock_inumorder(lock_mode, i));
}
+ i = 0;
+ try_lock = 0;
+ goto again;
}
#ifdef DEBUG
@@ -2681,19 +2668,22 @@ xfs_remove(
/*
* Enter all inodes for a rename transaction into a sorted array.
*/
+#define __XFS_SORT_INODES 5
STATIC void
xfs_sort_for_rename(
- xfs_inode_t *dp1, /* in: old (source) directory inode */
- xfs_inode_t *dp2, /* in: new (target) directory inode */
- xfs_inode_t *ip1, /* in: inode of old entry */
- xfs_inode_t *ip2, /* in: inode of new entry, if it
- already exists, NULL otherwise. */
- xfs_inode_t **i_tab,/* out: array of inode returned, sorted */
- int *num_inodes) /* out: number of inodes in array */
+ struct xfs_inode *dp1, /* in: old (source) directory inode */
+ struct xfs_inode *dp2, /* in: new (target) directory inode */
+ struct xfs_inode *ip1, /* in: inode of old entry */
+ struct xfs_inode *ip2, /* in: inode of new entry */
+ struct xfs_inode *wino, /* in: whiteout inode */
+ struct xfs_inode **i_tab,/* out: sorted array of inodes */
+ int *num_inodes) /* in/out: inodes in array */
{
- xfs_inode_t *temp;
int i, j;
+ ASSERT(*num_inodes == __XFS_SORT_INODES);
+ memset(i_tab, 0, *num_inodes * sizeof(struct xfs_inode *));
+
/*
* i_tab contains a list of pointers to inodes. We initialize
* the table here & we'll sort it. We will then use it to
@@ -2701,25 +2691,24 @@ xfs_sort_for_rename(
*
* Note that the table may contain duplicates. e.g., dp1 == dp2.
*/
- i_tab[0] = dp1;
- i_tab[1] = dp2;
- i_tab[2] = ip1;
- if (ip2) {
- *num_inodes = 4;
- i_tab[3] = ip2;
- } else {
- *num_inodes = 3;
- i_tab[3] = NULL;
- }
+ i = 0;
+ i_tab[i++] = dp1;
+ i_tab[i++] = dp2;
+ i_tab[i++] = ip1;
+ if (ip2)
+ i_tab[i++] = ip2;
+ if (wino)
+ i_tab[i++] = wino;
+ *num_inodes = i;
/*
* Sort the elements via bubble sort. (Remember, there are at
- * most 4 elements to sort, so this is adequate.)
+ * most 5 elements to sort, so this is adequate.)
*/
for (i = 0; i < *num_inodes; i++) {
for (j = 1; j < *num_inodes; j++) {
if (i_tab[j]->i_ino < i_tab[j-1]->i_ino) {
- temp = i_tab[j];
+ struct xfs_inode *temp = i_tab[j];
i_tab[j] = i_tab[j-1];
i_tab[j-1] = temp;
}
@@ -2867,16 +2856,16 @@ xfs_rename(
xfs_fsblock_t first_block;
int cancel_flags;
int committed;
- xfs_inode_t *inodes[4];
+ xfs_inode_t *inodes[__XFS_SORT_INODES];
+ int num_inodes = __XFS_SORT_INODES;
int spaceres;
- int num_inodes;
trace_xfs_rename(src_dp, target_dp, src_name, target_name);
new_parent = (src_dp != target_dp);
src_is_directory = S_ISDIR(src_ip->i_d.di_mode);
- xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip,
+ xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, NULL,
inodes, &num_inodes);
xfs_bmap_init(&free_list, &first_block);
--
2.0.0
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH 1/5] xfs: clean up inode locking for RENAME_WHITEOUT
2015-03-24 10:59 ` [PATCH 1/5] xfs: clean up inode locking for RENAME_WHITEOUT Dave Chinner
@ 2015-03-24 21:11 ` Eric Sandeen
2015-03-24 21:26 ` Dave Chinner
0 siblings, 1 reply; 12+ messages in thread
From: Eric Sandeen @ 2015-03-24 21:11 UTC (permalink / raw)
To: Dave Chinner, xfs
On 3/24/15 5:59 AM, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
>
> When doing RENAME_WHITEOUT, we now have to lock 5 inodes into the
> rename transaction. This means we need to update
> xfs_sort_for_rename() and xfs_lock_inodes() to handle up to 5
> inodes. Because of the vagaries of rename, this means we could have
> anywhere between 3 and 5 inodes locked into the transaction....
>
> While xfs_lock_inodes() does not need anything other than an assert
> telling us we are passing more inodes that we ever thought we should
> see, it could do with a logic rework to remove all the indenting.
> This is not a functional change - it just makes the code a lot
> easier to read.
>
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
...
> @@ -2681,19 +2668,22 @@ xfs_remove(
> /*
> * Enter all inodes for a rename transaction into a sorted array.
> */
> +#define __XFS_SORT_INODES 5
> STATIC void
> xfs_sort_for_rename(
> - xfs_inode_t *dp1, /* in: old (source) directory inode */
> - xfs_inode_t *dp2, /* in: new (target) directory inode */
> - xfs_inode_t *ip1, /* in: inode of old entry */
> - xfs_inode_t *ip2, /* in: inode of new entry, if it
> - already exists, NULL otherwise. */
> - xfs_inode_t **i_tab,/* out: array of inode returned, sorted */
> - int *num_inodes) /* out: number of inodes in array */
> + struct xfs_inode *dp1, /* in: old (source) directory inode */
> + struct xfs_inode *dp2, /* in: new (target) directory inode */
> + struct xfs_inode *ip1, /* in: inode of old entry */
> + struct xfs_inode *ip2, /* in: inode of new entry */
> + struct xfs_inode *wino, /* in: whiteout inode */
I'm not 100% morally opposed, but you still have a wino lurking around here ;)
Patch5 uses *wip, so if you want consistency, might consider that.
-Eric
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/5] xfs: clean up inode locking for RENAME_WHITEOUT
2015-03-24 21:11 ` Eric Sandeen
@ 2015-03-24 21:26 ` Dave Chinner
0 siblings, 0 replies; 12+ messages in thread
From: Dave Chinner @ 2015-03-24 21:26 UTC (permalink / raw)
To: Eric Sandeen; +Cc: xfs
On Tue, Mar 24, 2015 at 04:11:24PM -0500, Eric Sandeen wrote:
> On 3/24/15 5:59 AM, Dave Chinner wrote:
> > From: Dave Chinner <dchinner@redhat.com>
> >
> > When doing RENAME_WHITEOUT, we now have to lock 5 inodes into the
> > rename transaction. This means we need to update
> > xfs_sort_for_rename() and xfs_lock_inodes() to handle up to 5
> > inodes. Because of the vagaries of rename, this means we could have
> > anywhere between 3 and 5 inodes locked into the transaction....
> >
> > While xfs_lock_inodes() does not need anything other than an assert
> > telling us we are passing more inodes that we ever thought we should
> > see, it could do with a logic rework to remove all the indenting.
> > This is not a functional change - it just makes the code a lot
> > easier to read.
> >
> > Signed-off-by: Dave Chinner <dchinner@redhat.com>
>
> ...
>
> > @@ -2681,19 +2668,22 @@ xfs_remove(
> > /*
> > * Enter all inodes for a rename transaction into a sorted array.
> > */
> > +#define __XFS_SORT_INODES 5
> > STATIC void
> > xfs_sort_for_rename(
> > - xfs_inode_t *dp1, /* in: old (source) directory inode */
> > - xfs_inode_t *dp2, /* in: new (target) directory inode */
> > - xfs_inode_t *ip1, /* in: inode of old entry */
> > - xfs_inode_t *ip2, /* in: inode of new entry, if it
> > - already exists, NULL otherwise. */
> > - xfs_inode_t **i_tab,/* out: array of inode returned, sorted */
> > - int *num_inodes) /* out: number of inodes in array */
> > + struct xfs_inode *dp1, /* in: old (source) directory inode */
> > + struct xfs_inode *dp2, /* in: new (target) directory inode */
> > + struct xfs_inode *ip1, /* in: inode of old entry */
> > + struct xfs_inode *ip2, /* in: inode of new entry */
> > + struct xfs_inode *wino, /* in: whiteout inode */
>
> I'm not 100% morally opposed, but you still have a wino lurking around here ;)
Ah, I missed that one when splitting the patch. Will fix.
-Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/5] xfs: cleanup xfs_rename error handling
2015-03-24 10:59 [PATCH 0/5 V2] xfs: RENAME_WHITEOUT support Dave Chinner
2015-03-24 10:59 ` [PATCH 1/5] xfs: clean up inode locking for RENAME_WHITEOUT Dave Chinner
@ 2015-03-24 10:59 ` Dave Chinner
2015-03-24 10:59 ` [PATCH 3/5] xfs: factor out xfs_rename_finish() Dave Chinner
` (4 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Dave Chinner @ 2015-03-24 10:59 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
The jump labels are ambiguous and unclear and some of the error
paths are used inconsistently. Rules for error jumps are:
- use out_trans_cancel for unmodified transaction context
- use out_bmap_cancel on ENOSPC errors
- use out_trans_abort when transaction is likely to be dirty.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
fs/xfs/xfs_inode.c | 61 ++++++++++++++++++++++++------------------------------
1 file changed, 27 insertions(+), 34 deletions(-)
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index e38bc40..981e036 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2854,7 +2854,7 @@ xfs_rename(
int error;
xfs_bmap_free_t free_list;
xfs_fsblock_t first_block;
- int cancel_flags;
+ int cancel_flags = 0;
int committed;
xfs_inode_t *inodes[__XFS_SORT_INODES];
int num_inodes = __XFS_SORT_INODES;
@@ -2868,28 +2868,23 @@ xfs_rename(
xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, NULL,
inodes, &num_inodes);
- xfs_bmap_init(&free_list, &first_block);
tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME);
- cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
spaceres = XFS_RENAME_SPACE_RES(mp, target_name->len);
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, spaceres, 0);
if (error == -ENOSPC) {
spaceres = 0;
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, 0, 0);
}
- if (error) {
- xfs_trans_cancel(tp, 0);
- goto std_return;
- }
+ if (error)
+ goto out_trans_cancel;
+ cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
/*
* Attach the dquots to the inodes
*/
error = xfs_qm_vop_rename_dqattach(inodes);
- if (error) {
- xfs_trans_cancel(tp, cancel_flags);
- goto std_return;
- }
+ if (error)
+ goto out_trans_cancel;
/*
* Lock all the participating inodes. Depending upon whether
@@ -2919,22 +2914,24 @@ xfs_rename(
if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
(xfs_get_projid(target_dp) != xfs_get_projid(src_ip)))) {
error = -EXDEV;
- goto error_return;
+ goto out_trans_cancel;
}
+ xfs_bmap_init(&free_list, &first_block);
+
/*
* Handle RENAME_EXCHANGE flags
*/
if (flags & RENAME_EXCHANGE) {
if (target_ip == NULL) {
error = -EINVAL;
- goto error_return;
+ goto out_trans_cancel;
}
error = xfs_cross_rename(tp, src_dp, src_name, src_ip,
target_dp, target_name, target_ip,
&free_list, &first_block, spaceres);
if (error)
- goto abort_return;
+ goto out_trans_abort;
goto finish_rename;
}
@@ -2949,7 +2946,7 @@ xfs_rename(
if (!spaceres) {
error = xfs_dir_canenter(tp, target_dp, target_name);
if (error)
- goto error_return;
+ goto out_trans_cancel;
}
/*
* If target does not exist and the rename crosses
@@ -2960,9 +2957,9 @@ xfs_rename(
src_ip->i_ino, &first_block,
&free_list, spaceres);
if (error == -ENOSPC)
- goto error_return;
+ goto out_bmap_cancel;
if (error)
- goto abort_return;
+ goto out_trans_abort;
xfs_trans_ichgtime(tp, target_dp,
XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -2970,7 +2967,7 @@ xfs_rename(
if (new_parent && src_is_directory) {
error = xfs_bumplink(tp, target_dp);
if (error)
- goto abort_return;
+ goto out_trans_abort;
}
} else { /* target_ip != NULL */
/*
@@ -2985,7 +2982,7 @@ xfs_rename(
if (!(xfs_dir_isempty(target_ip)) ||
(target_ip->i_d.di_nlink > 2)) {
error = -EEXIST;
- goto error_return;
+ goto out_trans_cancel;
}
}
@@ -3002,7 +2999,7 @@ xfs_rename(
src_ip->i_ino,
&first_block, &free_list, spaceres);
if (error)
- goto abort_return;
+ goto out_trans_abort;
xfs_trans_ichgtime(tp, target_dp,
XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -3013,7 +3010,7 @@ xfs_rename(
*/
error = xfs_droplink(tp, target_ip);
if (error)
- goto abort_return;
+ goto out_trans_abort;
if (src_is_directory) {
/*
@@ -3021,7 +3018,7 @@ xfs_rename(
*/
error = xfs_droplink(tp, target_ip);
if (error)
- goto abort_return;
+ goto out_trans_abort;
}
} /* target_ip != NULL */
@@ -3038,7 +3035,7 @@ xfs_rename(
&first_block, &free_list, spaceres);
ASSERT(error != -EEXIST);
if (error)
- goto abort_return;
+ goto out_trans_abort;
}
/*
@@ -3064,13 +3061,13 @@ xfs_rename(
*/
error = xfs_droplink(tp, src_dp);
if (error)
- goto abort_return;
+ goto out_trans_abort;
}
error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino,
&first_block, &free_list, spaceres);
if (error)
- goto abort_return;
+ goto out_trans_abort;
xfs_trans_ichgtime(tp, src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
xfs_trans_log_inode(tp, src_dp, XFS_ILOG_CORE);
@@ -3088,12 +3085,8 @@ finish_rename:
}
error = xfs_bmap_finish(&tp, &free_list, &committed);
- if (error) {
- xfs_bmap_cancel(&free_list);
- xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES |
- XFS_TRANS_ABORT));
- goto std_return;
- }
+ if (error)
+ goto out_trans_abort;
/*
* trans_commit will unlock src_ip, target_ip & decrement
@@ -3101,12 +3094,12 @@ finish_rename:
*/
return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
- abort_return:
+out_trans_abort:
cancel_flags |= XFS_TRANS_ABORT;
- error_return:
+out_bmap_cancel:
xfs_bmap_cancel(&free_list);
+out_trans_cancel:
xfs_trans_cancel(tp, cancel_flags);
- std_return:
return error;
}
--
2.0.0
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 3/5] xfs: factor out xfs_rename_finish()
2015-03-24 10:59 [PATCH 0/5 V2] xfs: RENAME_WHITEOUT support Dave Chinner
2015-03-24 10:59 ` [PATCH 1/5] xfs: clean up inode locking for RENAME_WHITEOUT Dave Chinner
2015-03-24 10:59 ` [PATCH 2/5] xfs: cleanup xfs_rename error handling Dave Chinner
@ 2015-03-24 10:59 ` Dave Chinner
2015-03-24 21:04 ` Eric Sandeen
2015-03-24 10:59 ` [PATCH 4/5] xfs: make xfs_cross_rename() complete fully Dave Chinner
` (3 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Dave Chinner @ 2015-03-24 10:59 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Rather than use a jump label for the final transaction commit in
the rename, factor it into a simple helper function and call it
appropriately. This slightly reduces the spaghetti nature of
xfs_rename.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
fs/xfs/xfs_inode.c | 48 +++++++++++++++++++++++++++---------------------
1 file changed, 27 insertions(+), 21 deletions(-)
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 981e036..4a13a48 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2716,6 +2716,31 @@ xfs_sort_for_rename(
}
}
+static int
+xfs_finish_rename(
+ struct xfs_trans *tp,
+ struct xfs_bmap_free *free_list)
+{
+ int committed = 0;
+ int error;
+
+ /*
+ * If this is a synchronous mount, make sure that the rename transaction
+ * goes to disk before returning to the user.
+ */
+ if (tp->t_mountp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
+ xfs_trans_set_sync(tp);
+
+ error = xfs_bmap_finish(&tp, free_list, &committed);
+ if (error) {
+ xfs_bmap_cancel(free_list);
+ xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
+ return error;
+ }
+
+ return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
+}
+
/*
* xfs_cross_rename()
*
@@ -2855,7 +2880,6 @@ xfs_rename(
xfs_bmap_free_t free_list;
xfs_fsblock_t first_block;
int cancel_flags = 0;
- int committed;
xfs_inode_t *inodes[__XFS_SORT_INODES];
int num_inodes = __XFS_SORT_INODES;
int spaceres;
@@ -2932,7 +2956,7 @@ xfs_rename(
&free_list, &first_block, spaceres);
if (error)
goto out_trans_abort;
- goto finish_rename;
+ return xfs_finish_rename(tp, &free_list);
}
/*
@@ -3074,25 +3098,7 @@ xfs_rename(
if (new_parent)
xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE);
-finish_rename:
- /*
- * If this is a synchronous mount, make sure that the
- * rename transaction goes to disk before returning to
- * the user.
- */
- if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
- xfs_trans_set_sync(tp);
- }
-
- error = xfs_bmap_finish(&tp, &free_list, &committed);
- if (error)
- goto out_trans_abort;
-
- /*
- * trans_commit will unlock src_ip, target_ip & decrement
- * the vnode references.
- */
- return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
+ return xfs_finish_rename(tp, &free_list);
out_trans_abort:
cancel_flags |= XFS_TRANS_ABORT;
--
2.0.0
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH 3/5] xfs: factor out xfs_rename_finish()
2015-03-24 10:59 ` [PATCH 3/5] xfs: factor out xfs_rename_finish() Dave Chinner
@ 2015-03-24 21:04 ` Eric Sandeen
2015-03-24 21:27 ` Dave Chinner
0 siblings, 1 reply; 12+ messages in thread
From: Eric Sandeen @ 2015-03-24 21:04 UTC (permalink / raw)
To: Dave Chinner, xfs
On 3/24/15 5:59 AM, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
>
> Rather than use a jump label for the final transaction commit in
> the rename, factor it into a simple helper function and call it
> appropriately. This slightly reduces the spaghetti nature of
> xfs_rename.
Nit, subject should be "xfs_finish_rename" not "xfs_rename_finish"
-Eric
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---
> fs/xfs/xfs_inode.c | 48 +++++++++++++++++++++++++++---------------------
> 1 file changed, 27 insertions(+), 21 deletions(-)
>
> diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
> index 981e036..4a13a48 100644
> --- a/fs/xfs/xfs_inode.c
> +++ b/fs/xfs/xfs_inode.c
> @@ -2716,6 +2716,31 @@ xfs_sort_for_rename(
> }
> }
>
> +static int
> +xfs_finish_rename(
> + struct xfs_trans *tp,
> + struct xfs_bmap_free *free_list)
> +{
> + int committed = 0;
> + int error;
> +
> + /*
> + * If this is a synchronous mount, make sure that the rename transaction
> + * goes to disk before returning to the user.
> + */
> + if (tp->t_mountp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
> + xfs_trans_set_sync(tp);
> +
> + error = xfs_bmap_finish(&tp, free_list, &committed);
> + if (error) {
> + xfs_bmap_cancel(free_list);
> + xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
> + return error;
> + }
> +
> + return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
> +}
> +
> /*
> * xfs_cross_rename()
> *
> @@ -2855,7 +2880,6 @@ xfs_rename(
> xfs_bmap_free_t free_list;
> xfs_fsblock_t first_block;
> int cancel_flags = 0;
> - int committed;
> xfs_inode_t *inodes[__XFS_SORT_INODES];
> int num_inodes = __XFS_SORT_INODES;
> int spaceres;
> @@ -2932,7 +2956,7 @@ xfs_rename(
> &free_list, &first_block, spaceres);
> if (error)
> goto out_trans_abort;
> - goto finish_rename;
> + return xfs_finish_rename(tp, &free_list);
> }
>
> /*
> @@ -3074,25 +3098,7 @@ xfs_rename(
> if (new_parent)
> xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE);
>
> -finish_rename:
> - /*
> - * If this is a synchronous mount, make sure that the
> - * rename transaction goes to disk before returning to
> - * the user.
> - */
> - if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
> - xfs_trans_set_sync(tp);
> - }
> -
> - error = xfs_bmap_finish(&tp, &free_list, &committed);
> - if (error)
> - goto out_trans_abort;
> -
> - /*
> - * trans_commit will unlock src_ip, target_ip & decrement
> - * the vnode references.
> - */
> - return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
> + return xfs_finish_rename(tp, &free_list);
>
> out_trans_abort:
> cancel_flags |= XFS_TRANS_ABORT;
>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH 3/5] xfs: factor out xfs_rename_finish()
2015-03-24 21:04 ` Eric Sandeen
@ 2015-03-24 21:27 ` Dave Chinner
0 siblings, 0 replies; 12+ messages in thread
From: Dave Chinner @ 2015-03-24 21:27 UTC (permalink / raw)
To: Eric Sandeen; +Cc: xfs
On Tue, Mar 24, 2015 at 04:04:38PM -0500, Eric Sandeen wrote:
> On 3/24/15 5:59 AM, Dave Chinner wrote:
> > From: Dave Chinner <dchinner@redhat.com>
> >
> > Rather than use a jump label for the final transaction commit in
> > the rename, factor it into a simple helper function and call it
> > appropriately. This slightly reduces the spaghetti nature of
> > xfs_rename.
>
> Nit, subject should be "xfs_finish_rename" not "xfs_rename_finish"
Will fix.
-Dave
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 4/5] xfs: make xfs_cross_rename() complete fully
2015-03-24 10:59 [PATCH 0/5 V2] xfs: RENAME_WHITEOUT support Dave Chinner
` (2 preceding siblings ...)
2015-03-24 10:59 ` [PATCH 3/5] xfs: factor out xfs_rename_finish() Dave Chinner
@ 2015-03-24 10:59 ` Dave Chinner
2015-03-24 10:59 ` [PATCH 5/5] xfs: add RENAME_WHITEOUT support Dave Chinner
` (2 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Dave Chinner @ 2015-03-24 10:59 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Now that xfs_finish_rename() exists, there is no reason for
xfs_cross_rename() to return to xfs_rename() to finish off the
rename transaction. Drive the completion code into
xfs_cross_rename() and handle all errors there so as to simplify
the xfs_rename() code.
Further, push the rename exchange target_ip check to early in the
rename code so as to make the error handling easy and obviously
correct.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
fs/xfs/xfs_inode.c | 45 +++++++++++++++++++++------------------------
1 file changed, 21 insertions(+), 24 deletions(-)
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 4a13a48..1ea05be 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2769,14 +2769,14 @@ xfs_cross_rename(
ip2->i_ino,
first_block, free_list, spaceres);
if (error)
- goto out;
+ goto out_trans_abort;
/* Swap inode number for dirent in second parent */
error = xfs_dir_replace(tp, dp2, name2,
ip1->i_ino,
first_block, free_list, spaceres);
if (error)
- goto out;
+ goto out_trans_abort;
/*
* If we're renaming one or more directories across different parents,
@@ -2791,16 +2791,16 @@ xfs_cross_rename(
dp1->i_ino, first_block,
free_list, spaceres);
if (error)
- goto out;
+ goto out_trans_abort;
/* transfer ip2 ".." reference to dp1 */
if (!S_ISDIR(ip1->i_d.di_mode)) {
error = xfs_droplink(tp, dp2);
if (error)
- goto out;
+ goto out_trans_abort;
error = xfs_bumplink(tp, dp1);
if (error)
- goto out;
+ goto out_trans_abort;
}
/*
@@ -2818,16 +2818,16 @@ xfs_cross_rename(
dp2->i_ino, first_block,
free_list, spaceres);
if (error)
- goto out;
+ goto out_trans_abort;
/* transfer ip1 ".." reference to dp2 */
if (!S_ISDIR(ip2->i_d.di_mode)) {
error = xfs_droplink(tp, dp1);
if (error)
- goto out;
+ goto out_trans_abort;
error = xfs_bumplink(tp, dp2);
if (error)
- goto out;
+ goto out_trans_abort;
}
/*
@@ -2855,7 +2855,11 @@ xfs_cross_rename(
}
xfs_trans_ichgtime(tp, dp1, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
xfs_trans_log_inode(tp, dp1, XFS_ILOG_CORE);
-out:
+ return xfs_finish_rename(tp, free_list);
+
+out_trans_abort:
+ xfs_bmap_cancel(free_list);
+ xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
return error;
}
@@ -2886,6 +2890,9 @@ xfs_rename(
trace_xfs_rename(src_dp, target_dp, src_name, target_name);
+ if ((flags & RENAME_EXCHANGE) && !target_ip)
+ return -EINVAL;
+
new_parent = (src_dp != target_dp);
src_is_directory = S_ISDIR(src_ip->i_d.di_mode);
@@ -2943,21 +2950,11 @@ xfs_rename(
xfs_bmap_init(&free_list, &first_block);
- /*
- * Handle RENAME_EXCHANGE flags
- */
- if (flags & RENAME_EXCHANGE) {
- if (target_ip == NULL) {
- error = -EINVAL;
- goto out_trans_cancel;
- }
- error = xfs_cross_rename(tp, src_dp, src_name, src_ip,
- target_dp, target_name, target_ip,
- &free_list, &first_block, spaceres);
- if (error)
- goto out_trans_abort;
- return xfs_finish_rename(tp, &free_list);
- }
+ /* RENAME_EXCHANGE is unique from here on. */
+ if (flags & RENAME_EXCHANGE)
+ return xfs_cross_rename(tp, src_dp, src_name, src_ip,
+ target_dp, target_name, target_ip,
+ &free_list, &first_block, spaceres);
/*
* Set up the target.
--
2.0.0
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 5/5] xfs: add RENAME_WHITEOUT support
2015-03-24 10:59 [PATCH 0/5 V2] xfs: RENAME_WHITEOUT support Dave Chinner
` (3 preceding siblings ...)
2015-03-24 10:59 ` [PATCH 4/5] xfs: make xfs_cross_rename() complete fully Dave Chinner
@ 2015-03-24 10:59 ` Dave Chinner
2015-03-24 19:41 ` [PATCH 0/5 V2] xfs: " Brian Foster
2015-03-24 21:12 ` Eric Sandeen
6 siblings, 0 replies; 12+ messages in thread
From: Dave Chinner @ 2015-03-24 10:59 UTC (permalink / raw)
To: xfs
From: Dave Chinner <dchinner@redhat.com>
Whiteouts are used by overlayfs - it has a crazy convention that a
whiteout is a character device inode with a major:minor of 0:0.
Because it's not documented anywhere, here's an example of what
RENAME_WHITEOUT does on ext4:
# echo foo > /mnt/scratch/foo
# echo bar > /mnt/scratch/bar
# ls -l /mnt/scratch
total 24
-rw-r--r-- 1 root root 4 Feb 11 20:22 bar
-rw-r--r-- 1 root root 4 Feb 11 20:22 foo
drwx------ 2 root root 16384 Feb 11 20:18 lost+found
# src/renameat2 -w /mnt/scratch/foo /mnt/scratch/bar
# ls -l /mnt/scratch
total 20
-rw-r--r-- 1 root root 4 Feb 11 20:22 bar
c--------- 1 root root 0, 0 Feb 11 20:23 foo
drwx------ 2 root root 16384 Feb 11 20:18 lost+found
# cat /mnt/scratch/bar
foo
#
In XFS rename terms, the operation that has been done is that source
(foo) has been moved to the target (bar), which is like a nomal
rename operation, but rather than the source being removed, it have
been replaced with a whiteout.
We can't allocate whiteout inodes within the rename transaction due
to allocation being a multi-commit transaction: rename needs to
be a single, atomic commit. Hence we have several options here, form
most efficient to least efficient:
- use DT_WHT in the target dirent and do no whiteout inode
allocation. The main issue with this approach is that we need
hooks in lookup to create a virtual chardev inode to present
to userspace and in places where we might need to modify the
dirent e.g. unlink. Overlayfs also needs to be taught about
DT_WHT. Most invasive change, lowest overhead.
- create a special whiteout inode in the root directory (e.g. a
".wino" dirent) and then hardlink every new whiteout to it.
This means we only need to create a single whiteout inode, and
rename simply creates a hardlink to it. We can use DT_WHT for
these, though using DT_CHR means we won't have to modify
overlayfs, nor anything in userspace. Downside is we have to
look up the whiteout inode on every operation and create it if
it doesn't exist.
- copy ext4: create a special whiteout chardev inode for every
whiteout. This is more complex than the above options because
of the lack of atomicity between inode creation and the rename
operation, requiring us to create a tmpfile inode and then
linking it into the directory structure during the rename. At
least with a tmpfile inode crashes between the create and
rename doesn't leave unreferenced inodes or directory
pollution around.
By far the simplest thing to do in the short term is to copy ext4.
While it is the most inefficient way of supporting whiteouts, but as
an initial implementation we can simply reuse existing functions and
add a small amount of extra code the the rename operation.
When we get full whiteout support in the VFS (via the dentry cache)
we can then look to supporting DT_WHT method outlined as the first
method of supporting whiteouts. But until then, we'll stick with
what overlayfs expects us to be: dumb and stupid.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
fs/xfs/xfs_inode.c | 129 +++++++++++++++++++++++++++++++++++++++++++----------
fs/xfs/xfs_iops.c | 2 +-
2 files changed, 107 insertions(+), 24 deletions(-)
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 1ea05be..7915f68 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2864,39 +2864,80 @@ out_trans_abort:
}
/*
+ * xfs_rename_alloc_whiteout()
+ *
+ * Return a referenced, unlinked, unlocked inode that that can be used as a
+ * whiteout in a rename transaction. We use a tmpfile inode here so that if we
+ * crash between allocating the inode and linking it into the rename transaction
+ * recovery will free the inode and we won't leak it.
+ */
+static int
+xfs_rename_alloc_whiteout(
+ struct xfs_inode *dp,
+ struct xfs_inode **wip)
+{
+ struct xfs_inode *tmpfile;
+ int error;
+
+ error = xfs_create_tmpfile(dp, NULL, S_IFCHR | WHITEOUT_MODE, &tmpfile);
+ if (error)
+ return error;
+
+ /* Satisfy xfs_bumplink that this is a real tmpfile */
+ xfs_finish_inode_setup(tmpfile);
+ VFS_I(tmpfile)->i_state |= I_LINKABLE;
+
+ *wip = tmpfile;
+ return 0;
+}
+
+/*
* xfs_rename
*/
int
xfs_rename(
- xfs_inode_t *src_dp,
- struct xfs_name *src_name,
- xfs_inode_t *src_ip,
- xfs_inode_t *target_dp,
- struct xfs_name *target_name,
- xfs_inode_t *target_ip,
- unsigned int flags)
+ struct xfs_inode *src_dp,
+ struct xfs_name *src_name,
+ struct xfs_inode *src_ip,
+ struct xfs_inode *target_dp,
+ struct xfs_name *target_name,
+ struct xfs_inode *target_ip,
+ unsigned int flags)
{
- xfs_trans_t *tp = NULL;
- xfs_mount_t *mp = src_dp->i_mount;
- int new_parent; /* moving to a new dir */
- int src_is_directory; /* src_name is a directory */
- int error;
- xfs_bmap_free_t free_list;
- xfs_fsblock_t first_block;
- int cancel_flags = 0;
- xfs_inode_t *inodes[__XFS_SORT_INODES];
- int num_inodes = __XFS_SORT_INODES;
- int spaceres;
+ struct xfs_mount *mp = src_dp->i_mount;
+ struct xfs_trans *tp;
+ struct xfs_bmap_free free_list;
+ xfs_fsblock_t first_block;
+ struct xfs_inode *wip = NULL; /* whiteout inode */
+ struct xfs_inode *inodes[__XFS_SORT_INODES];
+ int num_inodes = __XFS_SORT_INODES;
+ int new_parent = (src_dp != target_dp);
+ int src_is_directory = S_ISDIR(src_ip->i_d.di_mode);
+ int cancel_flags = 0;
+ int spaceres;
+ int error;
trace_xfs_rename(src_dp, target_dp, src_name, target_name);
if ((flags & RENAME_EXCHANGE) && !target_ip)
return -EINVAL;
- new_parent = (src_dp != target_dp);
- src_is_directory = S_ISDIR(src_ip->i_d.di_mode);
+ /*
+ * If we are doing a whiteout operation, allocate the whiteout inode
+ * we will be placing at the target and ensure the type is set
+ * appropriately.
+ */
+ if (flags & RENAME_WHITEOUT) {
+ ASSERT(!(flags & (RENAME_NOREPLACE | RENAME_EXCHANGE)));
+ error = xfs_rename_alloc_whiteout(target_dp, &wip);
+ if (error)
+ return error;
+
+ /* setup target dirent info as whiteout */
+ src_name->type = XFS_DIR3_FT_CHRDEV;
+ }
- xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, NULL,
+ xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, wip,
inodes, &num_inodes);
tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME);
@@ -2936,6 +2977,8 @@ xfs_rename(
xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL);
if (target_ip)
xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL);
+ if (wip)
+ xfs_trans_ijoin(tp, wip, XFS_ILOCK_EXCL);
/*
* If we are using project inheritance, we only allow renames
@@ -3085,17 +3128,55 @@ xfs_rename(
goto out_trans_abort;
}
- error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino,
+ /*
+ * For whiteouts, we only need to update the source dirent with the
+ * inode number of the whiteout inode rather than removing it
+ * altogether.
+ */
+ if (wip) {
+ error = xfs_dir_replace(tp, src_dp, src_name, wip->i_ino,
&first_block, &free_list, spaceres);
+ } else
+ error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino,
+ &first_block, &free_list, spaceres);
if (error)
goto out_trans_abort;
+ /*
+ * For whiteouts, we need to bump the link count on the whiteout inode.
+ * This means that failures all the way up to this point leave the inode
+ * on the unlinked list and so cleanup is a simple matter of dropping
+ * the remaining reference to it. If we fail here after bumping the link
+ * count, we're shutting down the filesystem so we'll never see the
+ * intermediate state on disk.
+ */
+ if (wip) {
+ ASSERT(wip->i_d.di_nlink == 0);
+ error = xfs_bumplink(tp, wip);
+ if (error)
+ goto out_trans_abort;
+ error = xfs_iunlink_remove(tp, wip);
+ if (error)
+ goto out_trans_abort;
+ xfs_trans_log_inode(tp, wip, XFS_ILOG_CORE);
+
+ /*
+ * Now we have a real link, clear the "I'm a tmpfile" state
+ * flag from the inode so it doesn't accidentally get misused in
+ * future.
+ */
+ VFS_I(wip)->i_state &= ~I_LINKABLE;
+ }
+
xfs_trans_ichgtime(tp, src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
xfs_trans_log_inode(tp, src_dp, XFS_ILOG_CORE);
if (new_parent)
xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE);
- return xfs_finish_rename(tp, &free_list);
+ error = xfs_finish_rename(tp, &free_list);
+ if (wip)
+ IRELE(wip);
+ return error;
out_trans_abort:
cancel_flags |= XFS_TRANS_ABORT;
@@ -3103,6 +3184,8 @@ out_bmap_cancel:
xfs_bmap_cancel(&free_list);
out_trans_cancel:
xfs_trans_cancel(tp, cancel_flags);
+ if (wip)
+ IRELE(wip);
return error;
}
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 695d857..8db469b 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -394,7 +394,7 @@ xfs_vn_rename(
struct xfs_name oname;
struct xfs_name nname;
- if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
+ if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
return -EINVAL;
/* if we are exchanging files, we need to set i_mode of both files */
--
2.0.0
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH 0/5 V2] xfs: RENAME_WHITEOUT support
2015-03-24 10:59 [PATCH 0/5 V2] xfs: RENAME_WHITEOUT support Dave Chinner
` (4 preceding siblings ...)
2015-03-24 10:59 ` [PATCH 5/5] xfs: add RENAME_WHITEOUT support Dave Chinner
@ 2015-03-24 19:41 ` Brian Foster
2015-03-24 21:12 ` Eric Sandeen
6 siblings, 0 replies; 12+ messages in thread
From: Brian Foster @ 2015-03-24 19:41 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs
On Tue, Mar 24, 2015 at 09:59:26PM +1100, Dave Chinner wrote:
> Hi folks,
>
> This is the second version of the RENAME_WHITEOUT patchset that I
> originally posted here:
>
> http://oss.sgi.com/pipermail/xfs/2015-February/040378.html
>
> This is mainly the breakup and restructuring of the patchset I
> mention that needed to be done, as well as addressing the comments
> that were made at the time (e.g. wino -> wip).
>
> The patchset has been split into 5 patches, the first four are
> really cleanup and factoring patches to make the rename and inode
> locking code a bit simpler and easier to understand. The last patch
> then introduces the RENAME_WHITEOUT functionality, which ends up
> being surprisingly little code....
>
> The changes pass xfstests, but I have not run them on overlayfs at
> all yet, so I don't know if that's going to result in smoke and
> tears yet. Still, getting the patch set out for review now is more
> important that waiting for testing because there is relatively
> little time left before the 4.1 merge window opens up....
>
> So, comments, thoughts and flames are more than welcome.
>
These all look pretty good to me. I ran a quick rename test on top of
overlayfs as well and it seems to do what it's supposed to (e.g., rename
of a file on the lower dir is hidden via whiteout on the upper). For the
set...
Reviewed-by: Brian Foster <bfoster@redhat.com>
> -Dave.
>
> Diffstat:
>
> fs/xfs/xfs_inode.c | 408 ++++++++++++++++++++++++++++++++-----------------------
> fs/xfs/xfs_iops.c | 2 +-
> 2 files changed, 239 insertions(+), 171 deletions(-)
>
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [PATCH 0/5 V2] xfs: RENAME_WHITEOUT support
2015-03-24 10:59 [PATCH 0/5 V2] xfs: RENAME_WHITEOUT support Dave Chinner
` (5 preceding siblings ...)
2015-03-24 19:41 ` [PATCH 0/5 V2] xfs: " Brian Foster
@ 2015-03-24 21:12 ` Eric Sandeen
6 siblings, 0 replies; 12+ messages in thread
From: Eric Sandeen @ 2015-03-24 21:12 UTC (permalink / raw)
To: Dave Chinner, xfs
On 3/24/15 5:59 AM, Dave Chinner wrote:
> Hi folks,
>
> This is the second version of the RENAME_WHITEOUT patchset that I
> originally posted here:
>
> http://oss.sgi.com/pipermail/xfs/2015-February/040378.html
>
> This is mainly the breakup and restructuring of the patchset I
> mention that needed to be done, as well as addressing the comments
> that were made at the time (e.g. wino -> wip).
>
> The patchset has been split into 5 patches, the first four are
> really cleanup and factoring patches to make the rename and inode
> locking code a bit simpler and easier to understand. The last patch
> then introduces the RENAME_WHITEOUT functionality, which ends up
> being surprisingly little code....
>
> The changes pass xfstests, but I have not run them on overlayfs at
> all yet, so I don't know if that's going to result in smoke and
> tears yet. Still, getting the patch set out for review now is more
> important that waiting for testing because there is relatively
> little time left before the 4.1 merge window opens up....
>
> So, comments, thoughts and flames are more than welcome.
I mentioned little editorial nits on patches 3 and 5, otherwise looks fine;
fix them or not, you can add:
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Thanks,
-Eric
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 12+ messages in thread