fs: if block_map clears buffer_holesize bit skip hole size from b_size
Subsystems (2)
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/1 fs: if block_map clears buffer_holesize bit skip hole size from b_size
Hi,
This patch changes function __generic_block_fiemap so that it sets a new buffer_holesize bit. The new bit signals to the underlying file system to return a hole size from its block_map function (if possible) in the event that a hole is encountered at the requested block. If the block_map function encounters a hole, and clears buffer_holesize, fiemap takes the returned b_size to be the size of the hole, in bytes. It then skips the hole and moves to the next block. This may be repeated several times in a row, especially for large holes, due to possible limitations of the fs-specific block_map function. This is still much faster than trying each block individually when large holes are encountered. If the block_map function does not clear buffer_holesize, the request for holesize has been ignored, and it falls back to today's method of doing a block-by-block search for the next valid block.
Regards,
Bob Peterson
Red Hat File Systems
---
fs/ioctl.c +6 -1
@@ -291,13 +291,18 @@ int __generic_block_fiemap(struct inode *inode,memset (&map_bh,0 ,sizeof (struct buffer_head )); map_bh.b_size = len; +set_buffer_holesize (&map_bh);/* return hole size if able */ ret =get_block (inode, start_blk, &map_bh,0 );if (ret)break ;/* HOLE */ if (!buffer_mapped (&map_bh)) { - start_blk++; +if (buffer_holesize (&map_bh))/* holesize ignored */ + start_blk++; +else + start_blk +=logical_to_blk (inode, + map_bh.b_size);/* * We want to handle the case where there is an
include/linux/buffer_head.h +3 -0
@@ -37,6 +37,7 @@ enum bh_state_bits { BH_Meta,/* Buffer contains metadata */ BH_Prio,/* Buffer should be submitted with REQ_PRIO */ BH_Defer_Completion,/* Defer AIO completion to workqueue */ + BH_Holesize,/* Return hole size (and clear) if possible */ BH_PrivateStart,/* not a state bit, but the first bit available* for private allocation by other entities
@@ -128,6 +129,8 @@ BUFFER_FNS(Boundary, boundary) BUFFER_FNS(Write_EIO, write_io_error) BUFFER_FNS(Unwritten, unwritten) BUFFER_FNS(Meta, meta) +BUFFER_FNS(Holesize, holesize) +TAS_BUFFER_FNS(Holesize, holesize) BUFFER_FNS(Prio, prio)BUFFER_FNS (Defer_Completion, defer_completion)