aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <david@fromorbit.com>2015-03-24 23:29:13 -0400
committerDave Chinner <david@fromorbit.com>2015-03-24 23:29:13 -0400
commitd41bb03444147305e955cdd53753f0493e4d9e28 (patch)
tree37535eb32e725933b0c24df5c52c123b187fa910 /fs/xfs
parent88e8fda99a4c99a1a6482510655dbd88cccd221b (diff)
parent7dcf5c3e4527cfa2807567b00387cf2ed5e07f00 (diff)
Merge branch 'xfs-rename-whiteout' into for-next
Conflicts: fs/xfs/xfs_inode.c
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_inode.c408
-rw-r--r--fs/xfs/xfs_iops.c2
2 files changed, 239 insertions, 171 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 5a44f1cc820c..8394f6f17120 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)
391} 391}
392 392
393/* 393/*
394 * The following routine will lock n inodes in exclusive mode. 394 * The following routine will lock n inodes in exclusive mode. We assume the
395 * We assume the caller calls us with the inodes in i_ino order. 395 * caller calls us with the inodes in i_ino order.
396 * 396 *
397 * We need to detect deadlock where an inode that we lock 397 * We need to detect deadlock where an inode that we lock is in the AIL and we
398 * is in the AIL and we start waiting for another inode that is locked 398 * start waiting for another inode that is locked by a thread in a long running
399 * by a thread in a long running transaction (such as truncate). This can 399 * transaction (such as truncate). This can result in deadlock since the long
400 * result in deadlock since the long running trans might need to wait 400 * running trans might need to wait for the inode we just locked in order to
401 * for the inode we just locked in order to push the tail and free space 401 * push the tail and free space in the log.
402 * in the log.
403 */ 402 */
404void 403void
405xfs_lock_inodes( 404xfs_lock_inodes(
@@ -410,30 +409,27 @@ xfs_lock_inodes(
410 int attempts = 0, i, j, try_lock; 409 int attempts = 0, i, j, try_lock;
411 xfs_log_item_t *lp; 410 xfs_log_item_t *lp;
412 411
413 ASSERT(ips && (inodes >= 2)); /* we need at least two */ 412 /* currently supports between 2 and 5 inodes */
413 ASSERT(ips && inodes >= 2 && inodes <= 5);
414 414
415 try_lock = 0; 415 try_lock = 0;
416 i = 0; 416 i = 0;
417
418again: 417again:
419 for (; i < inodes; i++) { 418 for (; i < inodes; i++) {
420 ASSERT(ips[i]); 419 ASSERT(ips[i]);
421 420
422 if (i && (ips[i] == ips[i-1])) /* Already locked */ 421 if (i && (ips[i] == ips[i - 1])) /* Already locked */
423 continue; 422 continue;
424 423
425 /* 424 /*
426 * If try_lock is not set yet, make sure all locked inodes 425 * If try_lock is not set yet, make sure all locked inodes are
427 * are not in the AIL. 426 * not in the AIL. If any are, set try_lock to be used later.
428 * If any are, set try_lock to be used later.
429 */ 427 */
430
431 if (!try_lock) { 428 if (!try_lock) {
432 for (j = (i - 1); j >= 0 && !try_lock; j--) { 429 for (j = (i - 1); j >= 0 && !try_lock; j--) {
433 lp = (xfs_log_item_t *)ips[j]->i_itemp; 430 lp = (xfs_log_item_t *)ips[j]->i_itemp;
434 if (lp && (lp->li_flags & XFS_LI_IN_AIL)) { 431 if (lp && (lp->li_flags & XFS_LI_IN_AIL))
435 try_lock++; 432 try_lock++;
436 }
437 } 433 }
438 } 434 }
439 435
@@ -443,51 +439,42 @@ again:
443 * we can't get any, we must release all we have 439 * we can't get any, we must release all we have
444 * and try again. 440 * and try again.
445 */ 441 */
442 if (!try_lock) {
443 xfs_ilock(ips[i], xfs_lock_inumorder(lock_mode, i));
444 continue;
445 }
446
447 /* try_lock means we have an inode locked that is in the AIL. */
448 ASSERT(i != 0);
449 if (xfs_ilock_nowait(ips[i], xfs_lock_inumorder(lock_mode, i)))
450 continue;
446 451
447 if (try_lock) { 452 /*
448 /* try_lock must be 0 if i is 0. */ 453 * Unlock all previous guys and try again. xfs_iunlock will try
454 * to push the tail if the inode is in the AIL.
455 */
456 attempts++;
457 for (j = i - 1; j >= 0; j--) {
449 /* 458 /*
450 * try_lock means we have an inode locked 459 * Check to see if we've already unlocked this one. Not
451 * that is in the AIL. 460 * the first one going back, and the inode ptr is the
461 * same.
452 */ 462 */
453 ASSERT(i != 0); 463 if (j != (i - 1) && ips[j] == ips[j + 1])
454 if (!xfs_ilock_nowait(ips[i], xfs_lock_inumorder(lock_mode, i))) { 464 continue;
455 attempts++;
456
457 /*
458 * Unlock all previous guys and try again.
459 * xfs_iunlock will try to push the tail
460 * if the inode is in the AIL.
461 */
462
463 for(j = i - 1; j >= 0; j--) {
464
465 /*
466 * Check to see if we've already
467 * unlocked this one.
468 * Not the first one going back,
469 * and the inode ptr is the same.
470 */
471 if ((j != (i - 1)) && ips[j] ==
472 ips[j+1])
473 continue;
474
475 xfs_iunlock(ips[j], lock_mode);
476 }
477 465
478 if ((attempts % 5) == 0) { 466 xfs_iunlock(ips[j], lock_mode);
479 delay(1); /* Don't just spin the CPU */ 467 }
468
469 if ((attempts % 5) == 0) {
470 delay(1); /* Don't just spin the CPU */
480#ifdef DEBUG 471#ifdef DEBUG
481 xfs_lock_delays++; 472 xfs_lock_delays++;
482#endif 473#endif
483 }
484 i = 0;
485 try_lock = 0;
486 goto again;
487 }
488 } else {
489 xfs_ilock(ips[i], xfs_lock_inumorder(lock_mode, i));
490 } 474 }
475 i = 0;
476 try_lock = 0;
477 goto again;
491 } 478 }
492 479
493#ifdef DEBUG 480#ifdef DEBUG
@@ -2681,19 +2668,22 @@ xfs_remove(
2681/* 2668/*
2682 * Enter all inodes for a rename transaction into a sorted array. 2669 * Enter all inodes for a rename transaction into a sorted array.
2683 */ 2670 */
2671#define __XFS_SORT_INODES 5
2684STATIC void 2672STATIC void
2685xfs_sort_for_rename( 2673xfs_sort_for_rename(
2686 xfs_inode_t *dp1, /* in: old (source) directory inode */ 2674 struct xfs_inode *dp1, /* in: old (source) directory inode */
2687 xfs_inode_t *dp2, /* in: new (target) directory inode */ 2675 struct xfs_inode *dp2, /* in: new (target) directory inode */
2688 xfs_inode_t *ip1, /* in: inode of old entry */ 2676 struct xfs_inode *ip1, /* in: inode of old entry */
2689 xfs_inode_t *ip2, /* in: inode of new entry, if it 2677 struct xfs_inode *ip2, /* in: inode of new entry */
2690 already exists, NULL otherwise. */ 2678 struct xfs_inode *wip, /* in: whiteout inode */
2691 xfs_inode_t **i_tab,/* out: array of inode returned, sorted */ 2679 struct xfs_inode **i_tab,/* out: sorted array of inodes */
2692 int *num_inodes) /* out: number of inodes in array */ 2680 int *num_inodes) /* in/out: inodes in array */
2693{ 2681{
2694 xfs_inode_t *temp;
2695 int i, j; 2682 int i, j;
2696 2683
2684 ASSERT(*num_inodes == __XFS_SORT_INODES);
2685 memset(i_tab, 0, *num_inodes * sizeof(struct xfs_inode *));
2686
2697 /* 2687 /*
2698 * i_tab contains a list of pointers to inodes. We initialize 2688 * i_tab contains a list of pointers to inodes. We initialize
2699 * the table here & we'll sort it. We will then use it to 2689 * the table here & we'll sort it. We will then use it to
@@ -2701,25 +2691,24 @@ xfs_sort_for_rename(
2701 * 2691 *
2702 * Note that the table may contain duplicates. e.g., dp1 == dp2. 2692 * Note that the table may contain duplicates. e.g., dp1 == dp2.
2703 */ 2693 */
2704 i_tab[0] = dp1; 2694 i = 0;
2705 i_tab[1] = dp2; 2695 i_tab[i++] = dp1;
2706 i_tab[2] = ip1; 2696 i_tab[i++] = dp2;
2707 if (ip2) { 2697 i_tab[i++] = ip1;
2708 *num_inodes = 4; 2698 if (ip2)
2709 i_tab[3] = ip2; 2699 i_tab[i++] = ip2;
2710 } else { 2700 if (wip)
2711 *num_inodes = 3; 2701 i_tab[i++] = wip;
2712 i_tab[3] = NULL; 2702 *num_inodes = i;
2713 }
2714 2703
2715 /* 2704 /*
2716 * Sort the elements via bubble sort. (Remember, there are at 2705 * Sort the elements via bubble sort. (Remember, there are at
2717 * most 4 elements to sort, so this is adequate.) 2706 * most 5 elements to sort, so this is adequate.)
2718 */ 2707 */
2719 for (i = 0; i < *num_inodes; i++) { 2708 for (i = 0; i < *num_inodes; i++) {
2720 for (j = 1; j < *num_inodes; j++) { 2709 for (j = 1; j < *num_inodes; j++) {
2721 if (i_tab[j]->i_ino < i_tab[j-1]->i_ino) { 2710 if (i_tab[j]->i_ino < i_tab[j-1]->i_ino) {
2722 temp = i_tab[j]; 2711 struct xfs_inode *temp = i_tab[j];
2723 i_tab[j] = i_tab[j-1]; 2712 i_tab[j] = i_tab[j-1];
2724 i_tab[j-1] = temp; 2713 i_tab[j-1] = temp;
2725 } 2714 }
@@ -2727,6 +2716,31 @@ xfs_sort_for_rename(
2727 } 2716 }
2728} 2717}
2729 2718
2719static int
2720xfs_finish_rename(
2721 struct xfs_trans *tp,
2722 struct xfs_bmap_free *free_list)
2723{
2724 int committed = 0;
2725 int error;
2726
2727 /*
2728 * If this is a synchronous mount, make sure that the rename transaction
2729 * goes to disk before returning to the user.
2730 */
2731 if (tp->t_mountp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
2732 xfs_trans_set_sync(tp);
2733
2734 error = xfs_bmap_finish(&tp, free_list, &committed);
2735 if (error) {
2736 xfs_bmap_cancel(free_list);
2737 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
2738 return error;
2739 }
2740
2741 return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
2742}
2743
2730/* 2744/*
2731 * xfs_cross_rename() 2745 * xfs_cross_rename()
2732 * 2746 *
@@ -2755,14 +2769,14 @@ xfs_cross_rename(
2755 ip2->i_ino, 2769 ip2->i_ino,
2756 first_block, free_list, spaceres); 2770 first_block, free_list, spaceres);
2757 if (error) 2771 if (error)
2758 goto out; 2772 goto out_trans_abort;
2759 2773
2760 /* Swap inode number for dirent in second parent */ 2774 /* Swap inode number for dirent in second parent */
2761 error = xfs_dir_replace(tp, dp2, name2, 2775 error = xfs_dir_replace(tp, dp2, name2,
2762 ip1->i_ino, 2776 ip1->i_ino,
2763 first_block, free_list, spaceres); 2777 first_block, free_list, spaceres);
2764 if (error) 2778 if (error)
2765 goto out; 2779 goto out_trans_abort;
2766 2780
2767 /* 2781 /*
2768 * If we're renaming one or more directories across different parents, 2782 * If we're renaming one or more directories across different parents,
@@ -2777,16 +2791,16 @@ xfs_cross_rename(
2777 dp1->i_ino, first_block, 2791 dp1->i_ino, first_block,
2778 free_list, spaceres); 2792 free_list, spaceres);
2779 if (error) 2793 if (error)
2780 goto out; 2794 goto out_trans_abort;
2781 2795
2782 /* transfer ip2 ".." reference to dp1 */ 2796 /* transfer ip2 ".." reference to dp1 */
2783 if (!S_ISDIR(ip1->i_d.di_mode)) { 2797 if (!S_ISDIR(ip1->i_d.di_mode)) {
2784 error = xfs_droplink(tp, dp2); 2798 error = xfs_droplink(tp, dp2);
2785 if (error) 2799 if (error)
2786 goto out; 2800 goto out_trans_abort;
2787 error = xfs_bumplink(tp, dp1); 2801 error = xfs_bumplink(tp, dp1);
2788 if (error) 2802 if (error)
2789 goto out; 2803 goto out_trans_abort;
2790 } 2804 }
2791 2805
2792 /* 2806 /*
@@ -2804,16 +2818,16 @@ xfs_cross_rename(
2804 dp2->i_ino, first_block, 2818 dp2->i_ino, first_block,
2805 free_list, spaceres); 2819 free_list, spaceres);
2806 if (error) 2820 if (error)
2807 goto out; 2821 goto out_trans_abort;
2808 2822
2809 /* transfer ip1 ".." reference to dp2 */ 2823 /* transfer ip1 ".." reference to dp2 */
2810 if (!S_ISDIR(ip2->i_d.di_mode)) { 2824 if (!S_ISDIR(ip2->i_d.di_mode)) {
2811 error = xfs_droplink(tp, dp1); 2825 error = xfs_droplink(tp, dp1);
2812 if (error) 2826 if (error)
2813 goto out; 2827 goto out_trans_abort;
2814 error = xfs_bumplink(tp, dp2); 2828 error = xfs_bumplink(tp, dp2);
2815 if (error) 2829 if (error)
2816 goto out; 2830 goto out_trans_abort;
2817 } 2831 }
2818 2832
2819 /* 2833 /*
@@ -2841,66 +2855,108 @@ xfs_cross_rename(
2841 } 2855 }
2842 xfs_trans_ichgtime(tp, dp1, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 2856 xfs_trans_ichgtime(tp, dp1, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
2843 xfs_trans_log_inode(tp, dp1, XFS_ILOG_CORE); 2857 xfs_trans_log_inode(tp, dp1, XFS_ILOG_CORE);
2844out: 2858 return xfs_finish_rename(tp, free_list);
2859
2860out_trans_abort:
2861 xfs_bmap_cancel(free_list);
2862 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
2845 return error; 2863 return error;
2846} 2864}
2847 2865
2848/* 2866/*
2867 * xfs_rename_alloc_whiteout()
2868 *
2869 * Return a referenced, unlinked, unlocked inode that that can be used as a
2870 * whiteout in a rename transaction. We use a tmpfile inode here so that if we
2871 * crash between allocating the inode and linking it into the rename transaction
2872 * recovery will free the inode and we won't leak it.
2873 */
2874static int
2875xfs_rename_alloc_whiteout(
2876 struct xfs_inode *dp,
2877 struct xfs_inode **wip)
2878{
2879 struct xfs_inode *tmpfile;
2880 int error;
2881
2882 error = xfs_create_tmpfile(dp, NULL, S_IFCHR | WHITEOUT_MODE, &tmpfile);
2883 if (error)
2884 return error;
2885
2886 /* Satisfy xfs_bumplink that this is a real tmpfile */
2887 xfs_finish_inode_setup(tmpfile);
2888 VFS_I(tmpfile)->i_state |= I_LINKABLE;
2889
2890 *wip = tmpfile;
2891 return 0;
2892}
2893
2894/*
2849 * xfs_rename 2895 * xfs_rename
2850 */ 2896 */
2851int 2897int
2852xfs_rename( 2898xfs_rename(
2853 xfs_inode_t *src_dp, 2899 struct xfs_inode *src_dp,
2854 struct xfs_name *src_name, 2900 struct xfs_name *src_name,
2855 xfs_inode_t *src_ip, 2901 struct xfs_inode *src_ip,
2856 xfs_inode_t *target_dp, 2902 struct xfs_inode *target_dp,
2857 struct xfs_name *target_name, 2903 struct xfs_name *target_name,
2858 xfs_inode_t *target_ip, 2904 struct xfs_inode *target_ip,
2859 unsigned int flags) 2905 unsigned int flags)
2860{ 2906{
2861 xfs_trans_t *tp = NULL; 2907 struct xfs_mount *mp = src_dp->i_mount;
2862 xfs_mount_t *mp = src_dp->i_mount; 2908 struct xfs_trans *tp;
2863 int new_parent; /* moving to a new dir */ 2909 struct xfs_bmap_free free_list;
2864 int src_is_directory; /* src_name is a directory */ 2910 xfs_fsblock_t first_block;
2865 int error; 2911 struct xfs_inode *wip = NULL; /* whiteout inode */
2866 xfs_bmap_free_t free_list; 2912 struct xfs_inode *inodes[__XFS_SORT_INODES];
2867 xfs_fsblock_t first_block; 2913 int num_inodes = __XFS_SORT_INODES;
2868 int cancel_flags; 2914 int new_parent = (src_dp != target_dp);
2869 int committed; 2915 int src_is_directory = S_ISDIR(src_ip->i_d.di_mode);
2870 xfs_inode_t *inodes[4]; 2916 int cancel_flags = 0;
2871 int spaceres; 2917 int spaceres;
2872 int num_inodes; 2918 int error;
2873 2919
2874 trace_xfs_rename(src_dp, target_dp, src_name, target_name); 2920 trace_xfs_rename(src_dp, target_dp, src_name, target_name);
2875 2921
2876 new_parent = (src_dp != target_dp); 2922 if ((flags & RENAME_EXCHANGE) && !target_ip)
2877 src_is_directory = S_ISDIR(src_ip->i_d.di_mode); 2923 return -EINVAL;
2924
2925 /*
2926 * If we are doing a whiteout operation, allocate the whiteout inode
2927 * we will be placing at the target and ensure the type is set
2928 * appropriately.
2929 */
2930 if (flags & RENAME_WHITEOUT) {
2931 ASSERT(!(flags & (RENAME_NOREPLACE | RENAME_EXCHANGE)));
2932 error = xfs_rename_alloc_whiteout(target_dp, &wip);
2933 if (error)
2934 return error;
2935
2936 /* setup target dirent info as whiteout */
2937 src_name->type = XFS_DIR3_FT_CHRDEV;
2938 }
2878 2939
2879 xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, 2940 xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, wip,
2880 inodes, &num_inodes); 2941 inodes, &num_inodes);
2881 2942
2882 xfs_bmap_init(&free_list, &first_block);
2883 tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME); 2943 tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME);
2884 cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
2885 spaceres = XFS_RENAME_SPACE_RES(mp, target_name->len); 2944 spaceres = XFS_RENAME_SPACE_RES(mp, target_name->len);
2886 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, spaceres, 0); 2945 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, spaceres, 0);
2887 if (error == -ENOSPC) { 2946 if (error == -ENOSPC) {
2888 spaceres = 0; 2947 spaceres = 0;
2889 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, 0, 0); 2948 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, 0, 0);
2890 } 2949 }
2891 if (error) { 2950 if (error)
2892 xfs_trans_cancel(tp, 0); 2951 goto out_trans_cancel;
2893 goto std_return; 2952 cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
2894 }
2895 2953
2896 /* 2954 /*
2897 * Attach the dquots to the inodes 2955 * Attach the dquots to the inodes
2898 */ 2956 */
2899 error = xfs_qm_vop_rename_dqattach(inodes); 2957 error = xfs_qm_vop_rename_dqattach(inodes);
2900 if (error) { 2958 if (error)
2901 xfs_trans_cancel(tp, cancel_flags); 2959 goto out_trans_cancel;
2902 goto std_return;
2903 }
2904 2960
2905 /* 2961 /*
2906 * Lock all the participating inodes. Depending upon whether 2962 * Lock all the participating inodes. Depending upon whether
@@ -2921,6 +2977,8 @@ xfs_rename(
2921 xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL); 2977 xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL);
2922 if (target_ip) 2978 if (target_ip)
2923 xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL); 2979 xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL);
2980 if (wip)
2981 xfs_trans_ijoin(tp, wip, XFS_ILOCK_EXCL);
2924 2982
2925 /* 2983 /*
2926 * If we are using project inheritance, we only allow renames 2984 * If we are using project inheritance, we only allow renames
@@ -2930,24 +2988,16 @@ xfs_rename(
2930 if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && 2988 if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
2931 (xfs_get_projid(target_dp) != xfs_get_projid(src_ip)))) { 2989 (xfs_get_projid(target_dp) != xfs_get_projid(src_ip)))) {
2932 error = -EXDEV; 2990 error = -EXDEV;
2933 goto error_return; 2991 goto out_trans_cancel;
2934 } 2992 }
2935 2993
2936 /* 2994 xfs_bmap_init(&free_list, &first_block);
2937 * Handle RENAME_EXCHANGE flags 2995
2938 */ 2996 /* RENAME_EXCHANGE is unique from here on. */
2939 if (flags & RENAME_EXCHANGE) { 2997 if (flags & RENAME_EXCHANGE)
2940 if (target_ip == NULL) { 2998 return xfs_cross_rename(tp, src_dp, src_name, src_ip,
2941 error = -EINVAL; 2999 target_dp, target_name, target_ip,
2942 goto error_return; 3000 &free_list, &first_block, spaceres);
2943 }
2944 error = xfs_cross_rename(tp, src_dp, src_name, src_ip,
2945 target_dp, target_name, target_ip,
2946 &free_list, &first_block, spaceres);
2947 if (error)
2948 goto abort_return;
2949 goto finish_rename;
2950 }
2951 3001
2952 /* 3002 /*
2953 * Set up the target. 3003 * Set up the target.
@@ -2960,7 +3010,7 @@ xfs_rename(
2960 if (!spaceres) { 3010 if (!spaceres) {
2961 error = xfs_dir_canenter(tp, target_dp, target_name); 3011 error = xfs_dir_canenter(tp, target_dp, target_name);
2962 if (error) 3012 if (error)
2963 goto error_return; 3013 goto out_trans_cancel;
2964 } 3014 }
2965 /* 3015 /*
2966 * If target does not exist and the rename crosses 3016 * If target does not exist and the rename crosses
@@ -2971,9 +3021,9 @@ xfs_rename(
2971 src_ip->i_ino, &first_block, 3021 src_ip->i_ino, &first_block,
2972 &free_list, spaceres); 3022 &free_list, spaceres);
2973 if (error == -ENOSPC) 3023 if (error == -ENOSPC)
2974 goto error_return; 3024 goto out_bmap_cancel;
2975 if (error) 3025 if (error)
2976 goto abort_return; 3026 goto out_trans_abort;
2977 3027
2978 xfs_trans_ichgtime(tp, target_dp, 3028 xfs_trans_ichgtime(tp, target_dp,
2979 XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 3029 XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -2981,7 +3031,7 @@ xfs_rename(
2981 if (new_parent && src_is_directory) { 3031 if (new_parent && src_is_directory) {
2982 error = xfs_bumplink(tp, target_dp); 3032 error = xfs_bumplink(tp, target_dp);
2983 if (error) 3033 if (error)
2984 goto abort_return; 3034 goto out_trans_abort;
2985 } 3035 }
2986 } else { /* target_ip != NULL */ 3036 } else { /* target_ip != NULL */
2987 /* 3037 /*
@@ -2996,7 +3046,7 @@ xfs_rename(
2996 if (!(xfs_dir_isempty(target_ip)) || 3046 if (!(xfs_dir_isempty(target_ip)) ||
2997 (target_ip->i_d.di_nlink > 2)) { 3047 (target_ip->i_d.di_nlink > 2)) {
2998 error = -EEXIST; 3048 error = -EEXIST;
2999 goto error_return; 3049 goto out_trans_cancel;
3000 } 3050 }
3001 } 3051 }
3002 3052
@@ -3013,7 +3063,7 @@ xfs_rename(
3013 src_ip->i_ino, 3063 src_ip->i_ino,
3014 &first_block, &free_list, spaceres); 3064 &first_block, &free_list, spaceres);
3015 if (error) 3065 if (error)
3016 goto abort_return; 3066 goto out_trans_abort;
3017 3067
3018 xfs_trans_ichgtime(tp, target_dp, 3068 xfs_trans_ichgtime(tp, target_dp,
3019 XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 3069 XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -3024,7 +3074,7 @@ xfs_rename(
3024 */ 3074 */
3025 error = xfs_droplink(tp, target_ip); 3075 error = xfs_droplink(tp, target_ip);
3026 if (error) 3076 if (error)
3027 goto abort_return; 3077 goto out_trans_abort;
3028 3078
3029 if (src_is_directory) { 3079 if (src_is_directory) {
3030 /* 3080 /*
@@ -3032,7 +3082,7 @@ xfs_rename(
3032 */ 3082 */
3033 error = xfs_droplink(tp, target_ip); 3083 error = xfs_droplink(tp, target_ip);
3034 if (error) 3084 if (error)
3035 goto abort_return; 3085 goto out_trans_abort;
3036 } 3086 }
3037 } /* target_ip != NULL */ 3087 } /* target_ip != NULL */
3038 3088
@@ -3049,7 +3099,7 @@ xfs_rename(
3049 &first_block, &free_list, spaceres); 3099 &first_block, &free_list, spaceres);
3050 ASSERT(error != -EEXIST); 3100 ASSERT(error != -EEXIST);
3051 if (error) 3101 if (error)
3052 goto abort_return; 3102 goto out_trans_abort;
3053 } 3103 }
3054 3104
3055 /* 3105 /*
@@ -3075,49 +3125,67 @@ xfs_rename(
3075 */ 3125 */
3076 error = xfs_droplink(tp, src_dp); 3126 error = xfs_droplink(tp, src_dp);
3077 if (error) 3127 if (error)
3078 goto abort_return; 3128 goto out_trans_abort;
3079 } 3129 }
3080 3130
3081 error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino, 3131 /*
3132 * For whiteouts, we only need to update the source dirent with the
3133 * inode number of the whiteout inode rather than removing it
3134 * altogether.
3135 */
3136 if (wip) {
3137 error = xfs_dir_replace(tp, src_dp, src_name, wip->i_ino,
3082 &first_block, &free_list, spaceres); 3138 &first_block, &free_list, spaceres);
3139 } else
3140 error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino,
3141 &first_block, &free_list, spaceres);
3083 if (error) 3142 if (error)
3084 goto abort_return; 3143 goto out_trans_abort;
3085
3086 xfs_trans_ichgtime(tp, src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
3087 xfs_trans_log_inode(tp, src_dp, XFS_ILOG_CORE);
3088 if (new_parent)
3089 xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE);
3090 3144
3091finish_rename:
3092 /* 3145 /*
3093 * If this is a synchronous mount, make sure that the 3146 * For whiteouts, we need to bump the link count on the whiteout inode.
3094 * rename transaction goes to disk before returning to 3147 * This means that failures all the way up to this point leave the inode
3095 * the user. 3148 * on the unlinked list and so cleanup is a simple matter of dropping
3149 * the remaining reference to it. If we fail here after bumping the link
3150 * count, we're shutting down the filesystem so we'll never see the
3151 * intermediate state on disk.
3096 */ 3152 */
3097 if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) { 3153 if (wip) {
3098 xfs_trans_set_sync(tp); 3154 ASSERT(wip->i_d.di_nlink == 0);
3099 } 3155 error = xfs_bumplink(tp, wip);
3156 if (error)
3157 goto out_trans_abort;
3158 error = xfs_iunlink_remove(tp, wip);
3159 if (error)
3160 goto out_trans_abort;
3161 xfs_trans_log_inode(tp, wip, XFS_ILOG_CORE);
3100 3162
3101 error = xfs_bmap_finish(&tp, &free_list, &committed); 3163 /*
3102 if (error) { 3164 * Now we have a real link, clear the "I'm a tmpfile" state
3103 xfs_bmap_cancel(&free_list); 3165 * flag from the inode so it doesn't accidentally get misused in
3104 xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | 3166 * future.
3105 XFS_TRANS_ABORT)); 3167 */
3106 goto std_return; 3168 VFS_I(wip)->i_state &= ~I_LINKABLE;
3107 } 3169 }
3108 3170
3109 /* 3171 xfs_trans_ichgtime(tp, src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
3110 * trans_commit will unlock src_ip, target_ip & decrement 3172 xfs_trans_log_inode(tp, src_dp, XFS_ILOG_CORE);
3111 * the vnode references. 3173 if (new_parent)
3112 */ 3174 xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE);
3113 return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
3114 3175
3115 abort_return: 3176 error = xfs_finish_rename(tp, &free_list);
3177 if (wip)
3178 IRELE(wip);
3179 return error;
3180
3181out_trans_abort:
3116 cancel_flags |= XFS_TRANS_ABORT; 3182 cancel_flags |= XFS_TRANS_ABORT;
3117 error_return: 3183out_bmap_cancel:
3118 xfs_bmap_cancel(&free_list); 3184 xfs_bmap_cancel(&free_list);
3185out_trans_cancel:
3119 xfs_trans_cancel(tp, cancel_flags); 3186 xfs_trans_cancel(tp, cancel_flags);
3120 std_return: 3187 if (wip)
3188 IRELE(wip);
3121 return error; 3189 return error;
3122} 3190}
3123 3191
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 8b9e6887e315..015d6a366b16 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -394,7 +394,7 @@ xfs_vn_rename(
394 struct xfs_name oname; 394 struct xfs_name oname;
395 struct xfs_name nname; 395 struct xfs_name nname;
396 396
397 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE)) 397 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
398 return -EINVAL; 398 return -EINVAL;
399 399
400 /* if we are exchanging files, we need to set i_mode of both files */ 400 /* if we are exchanging files, we need to set i_mode of both files */