aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
authorAllison Henderson <achender@linux.vnet.ibm.com>2011-05-25 07:41:26 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-05-25 07:41:26 -0400
commit55f020db66ce187fb8c8e4002a94b0eb714da450 (patch)
treee98214511542f57fa93074be12e27c4819520333 /fs/ext4/extents.c
parentae81230686282af745ebb7a74c0332349cb9131a (diff)
ext4: add flag to ext4_has_free_blocks
This patch adds an allocation request flag to the ext4_has_free_blocks function which enables the use of reserved blocks. This will allow a punch hole to proceed even if the disk is full. Punching a hole may require additional blocks to first split the extents. Because ext4_has_free_blocks is a low level function, the flag needs to be passed down through several functions listed below: ext4_ext_insert_extent ext4_ext_create_new_leaf ext4_ext_grow_indepth ext4_ext_split ext4_ext_new_meta_block ext4_mb_new_blocks ext4_claim_free_blocks ext4_has_free_blocks [ext4 punch hole patch series 1/5 v7] Signed-off-by: Allison Henderson <achender@us.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Reviewed-by: Mingming Cao <cmm@us.ibm.com>
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index ca62d748cc6..aa3a2601bad 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -192,12 +192,13 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode,
192static ext4_fsblk_t 192static ext4_fsblk_t
193ext4_ext_new_meta_block(handle_t *handle, struct inode *inode, 193ext4_ext_new_meta_block(handle_t *handle, struct inode *inode,
194 struct ext4_ext_path *path, 194 struct ext4_ext_path *path,
195 struct ext4_extent *ex, int *err) 195 struct ext4_extent *ex, int *err, unsigned int flags)
196{ 196{
197 ext4_fsblk_t goal, newblock; 197 ext4_fsblk_t goal, newblock;
198 198
199 goal = ext4_ext_find_goal(inode, path, le32_to_cpu(ex->ee_block)); 199 goal = ext4_ext_find_goal(inode, path, le32_to_cpu(ex->ee_block));
200 newblock = ext4_new_meta_blocks(handle, inode, goal, NULL, err); 200 newblock = ext4_new_meta_blocks(handle, inode, goal, flags,
201 NULL, err);
201 return newblock; 202 return newblock;
202} 203}
203 204
@@ -792,8 +793,9 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
792 * - initializes subtree 793 * - initializes subtree
793 */ 794 */
794static int ext4_ext_split(handle_t *handle, struct inode *inode, 795static int ext4_ext_split(handle_t *handle, struct inode *inode,
795 struct ext4_ext_path *path, 796 unsigned int flags,
796 struct ext4_extent *newext, int at) 797 struct ext4_ext_path *path,
798 struct ext4_extent *newext, int at)
797{ 799{
798 struct buffer_head *bh = NULL; 800 struct buffer_head *bh = NULL;
799 int depth = ext_depth(inode); 801 int depth = ext_depth(inode);
@@ -847,7 +849,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
847 ext_debug("allocate %d blocks for indexes/leaf\n", depth - at); 849 ext_debug("allocate %d blocks for indexes/leaf\n", depth - at);
848 for (a = 0; a < depth - at; a++) { 850 for (a = 0; a < depth - at; a++) {
849 newblock = ext4_ext_new_meta_block(handle, inode, path, 851 newblock = ext4_ext_new_meta_block(handle, inode, path,
850 newext, &err); 852 newext, &err, flags);
851 if (newblock == 0) 853 if (newblock == 0)
852 goto cleanup; 854 goto cleanup;
853 ablocks[a] = newblock; 855 ablocks[a] = newblock;
@@ -1056,8 +1058,9 @@ cleanup:
1056 * just created block 1058 * just created block
1057 */ 1059 */
1058static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, 1060static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
1059 struct ext4_ext_path *path, 1061 unsigned int flags,
1060 struct ext4_extent *newext) 1062 struct ext4_ext_path *path,
1063 struct ext4_extent *newext)
1061{ 1064{
1062 struct ext4_ext_path *curp = path; 1065 struct ext4_ext_path *curp = path;
1063 struct ext4_extent_header *neh; 1066 struct ext4_extent_header *neh;
@@ -1065,7 +1068,8 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
1065 ext4_fsblk_t newblock; 1068 ext4_fsblk_t newblock;
1066 int err = 0; 1069 int err = 0;
1067 1070
1068 newblock = ext4_ext_new_meta_block(handle, inode, path, newext, &err); 1071 newblock = ext4_ext_new_meta_block(handle, inode, path,
1072 newext, &err, flags);
1069 if (newblock == 0) 1073 if (newblock == 0)
1070 return err; 1074 return err;
1071 1075
@@ -1140,8 +1144,9 @@ out:
1140 * if no free index is found, then it requests in-depth growing. 1144 * if no free index is found, then it requests in-depth growing.
1141 */ 1145 */
1142static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode, 1146static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode,
1143 struct ext4_ext_path *path, 1147 unsigned int flags,
1144 struct ext4_extent *newext) 1148 struct ext4_ext_path *path,
1149 struct ext4_extent *newext)
1145{ 1150{
1146 struct ext4_ext_path *curp; 1151 struct ext4_ext_path *curp;
1147 int depth, i, err = 0; 1152 int depth, i, err = 0;
@@ -1161,7 +1166,7 @@ repeat:
1161 if (EXT_HAS_FREE_INDEX(curp)) { 1166 if (EXT_HAS_FREE_INDEX(curp)) {
1162 /* if we found index with free entry, then use that 1167 /* if we found index with free entry, then use that
1163 * entry: create all needed subtree and add new leaf */ 1168 * entry: create all needed subtree and add new leaf */
1164 err = ext4_ext_split(handle, inode, path, newext, i); 1169 err = ext4_ext_split(handle, inode, flags, path, newext, i);
1165 if (err) 1170 if (err)
1166 goto out; 1171 goto out;
1167 1172
@@ -1174,7 +1179,8 @@ repeat:
1174 err = PTR_ERR(path); 1179 err = PTR_ERR(path);
1175 } else { 1180 } else {
1176 /* tree is full, time to grow in depth */ 1181 /* tree is full, time to grow in depth */
1177 err = ext4_ext_grow_indepth(handle, inode, path, newext); 1182 err = ext4_ext_grow_indepth(handle, inode, flags,
1183 path, newext);
1178 if (err) 1184 if (err)
1179 goto out; 1185 goto out;
1180 1186
@@ -1693,6 +1699,7 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
1693 int depth, len, err; 1699 int depth, len, err;
1694 ext4_lblk_t next; 1700 ext4_lblk_t next;
1695 unsigned uninitialized = 0; 1701 unsigned uninitialized = 0;
1702 int flags = 0;
1696 1703
1697 if (unlikely(ext4_ext_get_actual_len(newext) == 0)) { 1704 if (unlikely(ext4_ext_get_actual_len(newext) == 0)) {
1698 EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0"); 1705 EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0");
@@ -1767,7 +1774,9 @@ repeat:
1767 * There is no free space in the found leaf. 1774 * There is no free space in the found leaf.
1768 * We're gonna add a new leaf in the tree. 1775 * We're gonna add a new leaf in the tree.
1769 */ 1776 */
1770 err = ext4_ext_create_new_leaf(handle, inode, path, newext); 1777 if (flag & EXT4_GET_BLOCKS_PUNCH_OUT_EXT)
1778 flags = EXT4_MB_USE_ROOT_BLOCKS;
1779 err = ext4_ext_create_new_leaf(handle, inode, flags, path, newext);
1771 if (err) 1780 if (err)
1772 goto cleanup; 1781 goto cleanup;
1773 depth = ext_depth(inode); 1782 depth = ext_depth(inode);