diff options
Diffstat (limited to 'fs/ocfs2/alloc.c')
-rw-r--r-- | fs/ocfs2/alloc.c | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 9a0fd494fe74..77cbd1e3c950 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -3131,6 +3131,30 @@ out: | |||
3131 | return ret; | 3131 | return ret; |
3132 | } | 3132 | } |
3133 | 3133 | ||
3134 | static int ocfs2_remove_rightmost_empty_extent(struct ocfs2_super *osb, | ||
3135 | struct ocfs2_extent_tree *et, | ||
3136 | struct ocfs2_path *path, | ||
3137 | struct ocfs2_cached_dealloc_ctxt *dealloc) | ||
3138 | { | ||
3139 | handle_t *handle; | ||
3140 | int ret; | ||
3141 | int credits = path->p_tree_depth * 2 + 1; | ||
3142 | |||
3143 | handle = ocfs2_start_trans(osb, credits); | ||
3144 | if (IS_ERR(handle)) { | ||
3145 | ret = PTR_ERR(handle); | ||
3146 | mlog_errno(ret); | ||
3147 | return ret; | ||
3148 | } | ||
3149 | |||
3150 | ret = ocfs2_remove_rightmost_path(handle, et, path, dealloc); | ||
3151 | if (ret) | ||
3152 | mlog_errno(ret); | ||
3153 | |||
3154 | ocfs2_commit_trans(osb, handle); | ||
3155 | return ret; | ||
3156 | } | ||
3157 | |||
3134 | /* | 3158 | /* |
3135 | * Left rotation of btree records. | 3159 | * Left rotation of btree records. |
3136 | * | 3160 | * |
@@ -7108,15 +7132,23 @@ start: | |||
7108 | * to check it up here before changing the tree. | 7132 | * to check it up here before changing the tree. |
7109 | */ | 7133 | */ |
7110 | if (root_el->l_tree_depth && rec->e_int_clusters == 0) { | 7134 | if (root_el->l_tree_depth && rec->e_int_clusters == 0) { |
7111 | ocfs2_error(inode->i_sb, "Inode %lu has an empty " | 7135 | mlog(ML_ERROR, "Inode %lu has an empty " |
7112 | "extent record, depth %u\n", inode->i_ino, | 7136 | "extent record, depth %u\n", inode->i_ino, |
7113 | le16_to_cpu(root_el->l_tree_depth)); | 7137 | le16_to_cpu(root_el->l_tree_depth)); |
7114 | status = -EROFS; | 7138 | status = ocfs2_remove_rightmost_empty_extent(osb, |
7115 | goto bail; | 7139 | &et, path, &dealloc); |
7140 | if (status) { | ||
7141 | mlog_errno(status); | ||
7142 | goto bail; | ||
7143 | } | ||
7144 | |||
7145 | ocfs2_reinit_path(path, 1); | ||
7146 | goto start; | ||
7147 | } else { | ||
7148 | trunc_cpos = le32_to_cpu(rec->e_cpos); | ||
7149 | trunc_len = 0; | ||
7150 | blkno = 0; | ||
7116 | } | 7151 | } |
7117 | trunc_cpos = le32_to_cpu(rec->e_cpos); | ||
7118 | trunc_len = 0; | ||
7119 | blkno = 0; | ||
7120 | } else if (le32_to_cpu(rec->e_cpos) >= new_highest_cpos) { | 7152 | } else if (le32_to_cpu(rec->e_cpos) >= new_highest_cpos) { |
7121 | /* | 7153 | /* |
7122 | * Truncate entire record. | 7154 | * Truncate entire record. |