Commit 3a3076f4d6e2fa31338a0b007df42a3b32f079e0

Authored by Josef Bacik
Committed by Linus Torvalds
1 parent 1918ad77f7

Cleanup generic block based fiemap

This cleans up a few of the complaints of __generic_block_fiemap.  I've
fixed all the typing stuff, used inline functions instead of macros,
gotten rid of a couple of variables, and made sure the size and block
requests are all block aligned.  It also fixes a problem where sometimes
FIEMAP_EXTENT_LAST wasn't being set properly.

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 2 changed files with 56 additions and 41 deletions Side-by-side Diff

... ... @@ -228,14 +228,23 @@
228 228  
229 229 #ifdef CONFIG_BLOCK
230 230  
231   -#define blk_to_logical(inode, blk) (blk << (inode)->i_blkbits)
232   -#define logical_to_blk(inode, offset) (offset >> (inode)->i_blkbits);
  231 +static inline sector_t logical_to_blk(struct inode *inode, loff_t offset)
  232 +{
  233 + return (offset >> inode->i_blkbits);
  234 +}
233 235  
  236 +static inline loff_t blk_to_logical(struct inode *inode, sector_t blk)
  237 +{
  238 + return (blk << inode->i_blkbits);
  239 +}
  240 +
234 241 /**
235 242 * __generic_block_fiemap - FIEMAP for block based inodes (no locking)
236   - * @inode - the inode to map
237   - * @arg - the pointer to userspace where we copy everything to
238   - * @get_block - the fs's get_block function
  243 + * @inode: the inode to map
  244 + * @fieinfo: the fiemap info struct that will be passed back to userspace
  245 + * @start: where to start mapping in the inode
  246 + * @len: how much space to map
  247 + * @get_block: the fs's get_block function
239 248 *
240 249 * This does FIEMAP for block based inodes. Basically it will just loop
241 250 * through get_block until we hit the number of extents we want to map, or we
242 251  
243 252  
244 253  
245 254  
246 255  
247 256  
248 257  
249 258  
250 259  
251 260  
252 261  
253 262  
... ... @@ -250,58 +259,63 @@
250 259 */
251 260  
252 261 int __generic_block_fiemap(struct inode *inode,
253   - struct fiemap_extent_info *fieinfo, u64 start,
254   - u64 len, get_block_t *get_block)
  262 + struct fiemap_extent_info *fieinfo, loff_t start,
  263 + loff_t len, get_block_t *get_block)
255 264 {
256   - struct buffer_head tmp;
257   - unsigned long long start_blk;
258   - long long length = 0, map_len = 0;
  265 + struct buffer_head map_bh;
  266 + sector_t start_blk, last_blk;
  267 + loff_t isize = i_size_read(inode);
259 268 u64 logical = 0, phys = 0, size = 0;
260 269 u32 flags = FIEMAP_EXTENT_MERGED;
261   - int ret = 0, past_eof = 0, whole_file = 0;
  270 + bool past_eof = false, whole_file = false;
  271 + int ret = 0;
262 272  
263   - if ((ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC)))
  273 + ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC);
  274 + if (ret)
264 275 return ret;
265 276  
  277 + /*
  278 + * Either the i_mutex or other appropriate locking needs to be held
  279 + * since we expect isize to not change at all through the duration of
  280 + * this call.
  281 + */
  282 + if (len >= isize) {
  283 + whole_file = true;
  284 + len = isize;
  285 + }
  286 +
266 287 start_blk = logical_to_blk(inode, start);
  288 + last_blk = logical_to_blk(inode, start + len - 1);
267 289  
268   - length = (long long)min_t(u64, len, i_size_read(inode));
269   - if (length < len)
270   - whole_file = 1;
271   -
272   - map_len = length;
273   -
274 290 do {
275 291 /*
276 292 * we set b_size to the total size we want so it will map as
277 293 * many contiguous blocks as possible at once
278 294 */
279   - memset(&tmp, 0, sizeof(struct buffer_head));
280   - tmp.b_size = map_len;
  295 + memset(&map_bh, 0, sizeof(struct buffer_head));
  296 + map_bh.b_size = len;
281 297  
282   - ret = get_block(inode, start_blk, &tmp, 0);
  298 + ret = get_block(inode, start_blk, &map_bh, 0);
283 299 if (ret)
284 300 break;
285 301  
286 302 /* HOLE */
287   - if (!buffer_mapped(&tmp)) {
288   - length -= blk_to_logical(inode, 1);
  303 + if (!buffer_mapped(&map_bh)) {
289 304 start_blk++;
290 305  
291 306 /*
292   - * we want to handle the case where there is an
  307 + * We want to handle the case where there is an
293 308 * allocated block at the front of the file, and then
294 309 * nothing but holes up to the end of the file properly,
295 310 * to make sure that extent at the front gets properly
296 311 * marked with FIEMAP_EXTENT_LAST
297 312 */
298 313 if (!past_eof &&
299   - blk_to_logical(inode, start_blk) >=
300   - blk_to_logical(inode, 0)+i_size_read(inode))
  314 + blk_to_logical(inode, start_blk) >= isize)
301 315 past_eof = 1;
302 316  
303 317 /*
304   - * first hole after going past the EOF, this is our
  318 + * First hole after going past the EOF, this is our
305 319 * last extent
306 320 */
307 321 if (past_eof && size) {
308 322  
309 323  
... ... @@ -309,15 +323,18 @@
309 323 ret = fiemap_fill_next_extent(fieinfo, logical,
310 324 phys, size,
311 325 flags);
312   - break;
  326 + } else if (size) {
  327 + ret = fiemap_fill_next_extent(fieinfo, logical,
  328 + phys, size, flags);
  329 + size = 0;
313 330 }
314 331  
315 332 /* if we have holes up to/past EOF then we're done */
316   - if (length <= 0 || past_eof)
  333 + if (start_blk > last_blk || past_eof || ret)
317 334 break;
318 335 } else {
319 336 /*
320   - * we have gone over the length of what we wanted to
  337 + * We have gone over the length of what we wanted to
321 338 * map, and it wasn't the entire file, so add the extent
322 339 * we got last time and exit.
323 340 *
... ... @@ -331,7 +348,7 @@
331 348 * are good to go, just add the extent to the fieinfo
332 349 * and break
333 350 */
334   - if (length <= 0 && !whole_file) {
  351 + if (start_blk > last_blk && !whole_file) {
335 352 ret = fiemap_fill_next_extent(fieinfo, logical,
336 353 phys, size,
337 354 flags);
338 355  
... ... @@ -351,11 +368,10 @@
351 368 }
352 369  
353 370 logical = blk_to_logical(inode, start_blk);
354   - phys = blk_to_logical(inode, tmp.b_blocknr);
355   - size = tmp.b_size;
  371 + phys = blk_to_logical(inode, map_bh.b_blocknr);
  372 + size = map_bh.b_size;
356 373 flags = FIEMAP_EXTENT_MERGED;
357 374  
358   - length -= tmp.b_size;
359 375 start_blk += logical_to_blk(inode, size);
360 376  
361 377 /*
362 378  
... ... @@ -363,15 +379,13 @@
363 379 * soon as we find a hole that the last extent we found
364 380 * is marked with FIEMAP_EXTENT_LAST
365 381 */
366   - if (!past_eof &&
367   - logical+size >=
368   - blk_to_logical(inode, 0)+i_size_read(inode))
369   - past_eof = 1;
  382 + if (!past_eof && logical + size >= isize)
  383 + past_eof = true;
370 384 }
371 385 cond_resched();
372 386 } while (1);
373 387  
374   - /* if ret is 1 then we just hit the end of the extent array */
  388 + /* If ret is 1 then we just hit the end of the extent array */
375 389 if (ret == 1)
376 390 ret = 0;
377 391  
... ... @@ -2315,8 +2315,9 @@
2315 2315 extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
2316 2316 unsigned long arg);
2317 2317 extern int __generic_block_fiemap(struct inode *inode,
2318   - struct fiemap_extent_info *fieinfo, u64 start,
2319   - u64 len, get_block_t *get_block);
  2318 + struct fiemap_extent_info *fieinfo,
  2319 + loff_t start, loff_t len,
  2320 + get_block_t *get_block);
2320 2321 extern int generic_block_fiemap(struct inode *inode,
2321 2322 struct fiemap_extent_info *fieinfo, u64 start,
2322 2323 u64 len, get_block_t *get_block);