|
@@ -117,11 +117,33 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode,
|
|
|
struct ext4_extent *ex;
|
|
|
depth = path->p_depth;
|
|
|
|
|
|
- /* try to predict block placement */
|
|
|
+ /*
|
|
|
+ * Try to predict block placement assuming that we are
|
|
|
+ * filling in a file which will eventually be
|
|
|
+ * non-sparse --- i.e., in the case of libbfd writing
|
|
|
+ * an ELF object sections out-of-order but in a way
|
|
|
+ * the eventually results in a contiguous object or
|
|
|
+ * executable file, or some database extending a table
|
|
|
+ * space file. However, this is actually somewhat
|
|
|
+ * non-ideal if we are writing a sparse file such as
|
|
|
+ * qemu or KVM writing a raw image file that is going
|
|
|
+ * to stay fairly sparse, since it will end up
|
|
|
+ * fragmenting the file system's free space. Maybe we
|
|
|
+ * should have some hueristics or some way to allow
|
|
|
+ * userspace to pass a hint to file system,
|
|
|
+ * especiially if the latter case turns out to be
|
|
|
+ * common.
|
|
|
+ */
|
|
|
ex = path[depth].p_ext;
|
|
|
- if (ex)
|
|
|
- return (ext4_ext_pblock(ex) +
|
|
|
- (block - le32_to_cpu(ex->ee_block)));
|
|
|
+ if (ex) {
|
|
|
+ ext4_fsblk_t ext_pblk = ext4_ext_pblock(ex);
|
|
|
+ ext4_lblk_t ext_block = le32_to_cpu(ex->ee_block);
|
|
|
+
|
|
|
+ if (block > ext_block)
|
|
|
+ return ext_pblk + (block - ext_block);
|
|
|
+ else
|
|
|
+ return ext_pblk - (ext_block - block);
|
|
|
+ }
|
|
|
|
|
|
/* it looks like index is empty;
|
|
|
* try to find starting block from index itself */
|