diff options
| -rw-r--r-- | fs/btrfs/tree-log.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 1b7f04a8f168..fc9b87a7975b 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -2835,6 +2835,17 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans, | |||
| 2835 | int ret = 0; | 2835 | int ret = 0; |
| 2836 | struct btrfs_root *root; | 2836 | struct btrfs_root *root; |
| 2837 | 2837 | ||
| 2838 | /* | ||
| 2839 | * for regular files, if its inode is already on disk, we don't | ||
| 2840 | * have to worry about the parents at all. This is because | ||
| 2841 | * we can use the last_unlink_trans field to record renames | ||
| 2842 | * and other fun in this file. | ||
| 2843 | */ | ||
| 2844 | if (S_ISREG(inode->i_mode) && | ||
| 2845 | BTRFS_I(inode)->generation <= last_committed && | ||
| 2846 | BTRFS_I(inode)->last_unlink_trans <= last_committed) | ||
| 2847 | goto out; | ||
| 2848 | |||
| 2838 | if (!S_ISDIR(inode->i_mode)) { | 2849 | if (!S_ISDIR(inode->i_mode)) { |
| 2839 | if (!parent || !parent->d_inode || sb != parent->d_inode->i_sb) | 2850 | if (!parent || !parent->d_inode || sb != parent->d_inode->i_sb) |
| 2840 | goto out; | 2851 | goto out; |
| @@ -2904,8 +2915,19 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, | |||
| 2904 | 2915 | ||
| 2905 | ret = btrfs_log_inode(trans, root, inode, inode_only); | 2916 | ret = btrfs_log_inode(trans, root, inode, inode_only); |
| 2906 | BUG_ON(ret); | 2917 | BUG_ON(ret); |
| 2907 | inode_only = LOG_INODE_EXISTS; | ||
| 2908 | 2918 | ||
| 2919 | /* | ||
| 2920 | * for regular files, if its inode is already on disk, we don't | ||
| 2921 | * have to worry about the parents at all. This is because | ||
| 2922 | * we can use the last_unlink_trans field to record renames | ||
| 2923 | * and other fun in this file. | ||
| 2924 | */ | ||
| 2925 | if (S_ISREG(inode->i_mode) && | ||
| 2926 | BTRFS_I(inode)->generation <= last_committed && | ||
| 2927 | BTRFS_I(inode)->last_unlink_trans <= last_committed) | ||
| 2928 | goto no_parent; | ||
| 2929 | |||
| 2930 | inode_only = LOG_INODE_EXISTS; | ||
| 2909 | while (1) { | 2931 | while (1) { |
| 2910 | if (!parent || !parent->d_inode || sb != parent->d_inode->i_sb) | 2932 | if (!parent || !parent->d_inode || sb != parent->d_inode->i_sb) |
| 2911 | break; | 2933 | break; |
| @@ -2921,6 +2943,7 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, | |||
| 2921 | 2943 | ||
| 2922 | parent = parent->d_parent; | 2944 | parent = parent->d_parent; |
| 2923 | } | 2945 | } |
| 2946 | no_parent: | ||
| 2924 | ret = 0; | 2947 | ret = 0; |
| 2925 | btrfs_end_log_trans(root); | 2948 | btrfs_end_log_trans(root); |
| 2926 | end_no_trans: | 2949 | end_no_trans: |
| @@ -3070,6 +3093,19 @@ void btrfs_record_unlink_dir(struct btrfs_trans_handle *trans, | |||
| 3070 | int for_rename) | 3093 | int for_rename) |
| 3071 | { | 3094 | { |
| 3072 | /* | 3095 | /* |
| 3096 | * when we're logging a file, if it hasn't been renamed | ||
| 3097 | * or unlinked, and its inode is fully committed on disk, | ||
| 3098 | * we don't have to worry about walking up the directory chain | ||
| 3099 | * to log its parents. | ||
| 3100 | * | ||
| 3101 | * So, we use the last_unlink_trans field to put this transid | ||
| 3102 | * into the file. When the file is logged we check it and | ||
| 3103 | * don't log the parents if the file is fully on disk. | ||
| 3104 | */ | ||
| 3105 | if (S_ISREG(inode->i_mode)) | ||
| 3106 | BTRFS_I(inode)->last_unlink_trans = trans->transid; | ||
| 3107 | |||
| 3108 | /* | ||
| 3073 | * if this directory was already logged any new | 3109 | * if this directory was already logged any new |
| 3074 | * names for this file/dir will get recorded | 3110 | * names for this file/dir will get recorded |
| 3075 | */ | 3111 | */ |
| @@ -3115,6 +3151,13 @@ int btrfs_log_new_name(struct btrfs_trans_handle *trans, | |||
| 3115 | struct btrfs_root * root = BTRFS_I(inode)->root; | 3151 | struct btrfs_root * root = BTRFS_I(inode)->root; |
| 3116 | 3152 | ||
| 3117 | /* | 3153 | /* |
| 3154 | * this will force the logging code to walk the dentry chain | ||
| 3155 | * up for the file | ||
| 3156 | */ | ||
| 3157 | if (S_ISREG(inode->i_mode)) | ||
| 3158 | BTRFS_I(inode)->last_unlink_trans = trans->transid; | ||
| 3159 | |||
| 3160 | /* | ||
| 3118 | * if this inode hasn't been logged and directory we're renaming it | 3161 | * if this inode hasn't been logged and directory we're renaming it |
| 3119 | * from hasn't been logged, we don't need to log it | 3162 | * from hasn't been logged, we don't need to log it |
| 3120 | */ | 3163 | */ |
