@@ -3699,6 +3699,8 @@ extern int ext4_swap_extents(handle_t *handle, struct inode *inode1,
ext4_lblk_t lblk2, ext4_lblk_t count,
int mark_unwritten,int *err);
extern int ext4_clu_mapped(struct inode *inode, ext4_lblk_t lclu);
+extern unsigned int ext4_map_worst_ext_blocks(struct inode *inode,
+ unsigned int len);
extern int ext4_datasem_ensure_credits(handle_t *handle, struct inode *inode,
int check_cred, int restart_cred,
int revoke_cred);
@@ -5797,6 +5797,34 @@ int ext4_clu_mapped(struct inode *inode, ext4_lblk_t lclu)
return err ? err : mapped;
}
+/*
+ * Calculate the worst case of extents blocks needed while mapping 'len'
+ * data blocks.
+ */
+unsigned int ext4_map_worst_ext_blocks(struct inode *inode, unsigned int len)
+{
+ unsigned int ext_blocks = 0;
+ int max_entries;
+ int depth, max_depth;
+
+ if (!len)
+ return 0;
+
+ max_entries = ext4_ext_space_block(inode, 0);
+ max_depth = EXT4_MAX_EXTENT_DEPTH;
+
+ for (depth = 0; depth < max_depth; depth++) {
+ len = DIV_ROUND_UP(len, max_entries);
+ ext_blocks += len;
+ if (len == 1)
+ break;
+ if (depth == 0)
+ max_entries = ext4_ext_space_block_idx(inode, 0);
+ }
+
+ return ext_blocks + max_depth - depth - 1;
+}
+
/*
* Updates physical block address and unwritten status of extent
* starting at lblk start and of len. If such an extent doesn't exist,