diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/nilfs2/inode.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'fs/nilfs2/inode.c')
-rw-r--r-- | fs/nilfs2/inode.c | 439 |
1 files changed, 341 insertions, 98 deletions
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index eccb2f2e2315..b9b45fc2903e 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -34,6 +34,30 @@ | |||
34 | #include "cpfile.h" | 34 | #include "cpfile.h" |
35 | #include "ifile.h" | 35 | #include "ifile.h" |
36 | 36 | ||
37 | struct nilfs_iget_args { | ||
38 | u64 ino; | ||
39 | __u64 cno; | ||
40 | struct nilfs_root *root; | ||
41 | int for_gc; | ||
42 | }; | ||
43 | |||
44 | void nilfs_inode_add_blocks(struct inode *inode, int n) | ||
45 | { | ||
46 | struct nilfs_root *root = NILFS_I(inode)->i_root; | ||
47 | |||
48 | inode_add_bytes(inode, (1 << inode->i_blkbits) * n); | ||
49 | if (root) | ||
50 | atomic_add(n, &root->blocks_count); | ||
51 | } | ||
52 | |||
53 | void nilfs_inode_sub_blocks(struct inode *inode, int n) | ||
54 | { | ||
55 | struct nilfs_root *root = NILFS_I(inode)->i_root; | ||
56 | |||
57 | inode_sub_bytes(inode, (1 << inode->i_blkbits) * n); | ||
58 | if (root) | ||
59 | atomic_sub(n, &root->blocks_count); | ||
60 | } | ||
37 | 61 | ||
38 | /** | 62 | /** |
39 | * nilfs_get_block() - get a file block on the filesystem (callback function) | 63 | * nilfs_get_block() - get a file block on the filesystem (callback function) |
@@ -50,14 +74,14 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff, | |||
50 | struct buffer_head *bh_result, int create) | 74 | struct buffer_head *bh_result, int create) |
51 | { | 75 | { |
52 | struct nilfs_inode_info *ii = NILFS_I(inode); | 76 | struct nilfs_inode_info *ii = NILFS_I(inode); |
77 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; | ||
53 | __u64 blknum = 0; | 78 | __u64 blknum = 0; |
54 | int err = 0, ret; | 79 | int err = 0, ret; |
55 | struct inode *dat = nilfs_dat_inode(NILFS_I_NILFS(inode)); | ||
56 | unsigned maxblocks = bh_result->b_size >> inode->i_blkbits; | 80 | unsigned maxblocks = bh_result->b_size >> inode->i_blkbits; |
57 | 81 | ||
58 | down_read(&NILFS_MDT(dat)->mi_sem); | 82 | down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); |
59 | ret = nilfs_bmap_lookup_contig(ii->i_bmap, blkoff, &blknum, maxblocks); | 83 | ret = nilfs_bmap_lookup_contig(ii->i_bmap, blkoff, &blknum, maxblocks); |
60 | up_read(&NILFS_MDT(dat)->mi_sem); | 84 | up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); |
61 | if (ret >= 0) { /* found */ | 85 | if (ret >= 0) { /* found */ |
62 | map_bh(bh_result, inode->i_sb, blknum); | 86 | map_bh(bh_result, inode->i_sb, blknum); |
63 | if (ret > 0) | 87 | if (ret > 0) |
@@ -90,11 +114,6 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff, | |||
90 | inode->i_ino, | 114 | inode->i_ino, |
91 | (unsigned long long)blkoff); | 115 | (unsigned long long)blkoff); |
92 | err = 0; | 116 | err = 0; |
93 | } else if (err == -EINVAL) { | ||
94 | nilfs_error(inode->i_sb, __func__, | ||
95 | "broken bmap (inode=%lu)\n", | ||
96 | inode->i_ino); | ||
97 | err = -EIO; | ||
98 | } | 117 | } |
99 | nilfs_transaction_abort(inode->i_sb); | 118 | nilfs_transaction_abort(inode->i_sb); |
100 | goto out; | 119 | goto out; |
@@ -103,6 +122,7 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff, | |||
103 | nilfs_transaction_commit(inode->i_sb); /* never fails */ | 122 | nilfs_transaction_commit(inode->i_sb); /* never fails */ |
104 | /* Error handling should be detailed */ | 123 | /* Error handling should be detailed */ |
105 | set_buffer_new(bh_result); | 124 | set_buffer_new(bh_result); |
125 | set_buffer_delay(bh_result); | ||
106 | map_bh(bh_result, inode->i_sb, 0); /* dbn must be changed | 126 | map_bh(bh_result, inode->i_sb, 0); /* dbn must be changed |
107 | to proper value */ | 127 | to proper value */ |
108 | } else if (ret == -ENOENT) { | 128 | } else if (ret == -ENOENT) { |
@@ -179,10 +199,9 @@ static int nilfs_set_page_dirty(struct page *page) | |||
179 | 199 | ||
180 | if (ret) { | 200 | if (ret) { |
181 | struct inode *inode = page->mapping->host; | 201 | struct inode *inode = page->mapping->host; |
182 | struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb); | ||
183 | unsigned nr_dirty = 1 << (PAGE_SHIFT - inode->i_blkbits); | 202 | unsigned nr_dirty = 1 << (PAGE_SHIFT - inode->i_blkbits); |
184 | 203 | ||
185 | nilfs_set_file_dirty(sbi, inode, nr_dirty); | 204 | nilfs_set_file_dirty(inode, nr_dirty); |
186 | } | 205 | } |
187 | return ret; | 206 | return ret; |
188 | } | 207 | } |
@@ -223,7 +242,7 @@ static int nilfs_write_end(struct file *file, struct address_space *mapping, | |||
223 | start + copied); | 242 | start + copied); |
224 | copied = generic_write_end(file, mapping, pos, len, copied, page, | 243 | copied = generic_write_end(file, mapping, pos, len, copied, page, |
225 | fsdata); | 244 | fsdata); |
226 | nilfs_set_file_dirty(NILFS_SB(inode->i_sb), inode, nr_dirty); | 245 | nilfs_set_file_dirty(inode, nr_dirty); |
227 | err = nilfs_transaction_commit(inode->i_sb); | 246 | err = nilfs_transaction_commit(inode->i_sb); |
228 | return err ? : copied; | 247 | return err ? : copied; |
229 | } | 248 | } |
@@ -261,7 +280,6 @@ nilfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
261 | const struct address_space_operations nilfs_aops = { | 280 | const struct address_space_operations nilfs_aops = { |
262 | .writepage = nilfs_writepage, | 281 | .writepage = nilfs_writepage, |
263 | .readpage = nilfs_readpage, | 282 | .readpage = nilfs_readpage, |
264 | .sync_page = block_sync_page, | ||
265 | .writepages = nilfs_writepages, | 283 | .writepages = nilfs_writepages, |
266 | .set_page_dirty = nilfs_set_page_dirty, | 284 | .set_page_dirty = nilfs_set_page_dirty, |
267 | .readpages = nilfs_readpages, | 285 | .readpages = nilfs_readpages, |
@@ -276,9 +294,10 @@ const struct address_space_operations nilfs_aops = { | |||
276 | struct inode *nilfs_new_inode(struct inode *dir, int mode) | 294 | struct inode *nilfs_new_inode(struct inode *dir, int mode) |
277 | { | 295 | { |
278 | struct super_block *sb = dir->i_sb; | 296 | struct super_block *sb = dir->i_sb; |
279 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 297 | struct the_nilfs *nilfs = sb->s_fs_info; |
280 | struct inode *inode; | 298 | struct inode *inode; |
281 | struct nilfs_inode_info *ii; | 299 | struct nilfs_inode_info *ii; |
300 | struct nilfs_root *root; | ||
282 | int err = -ENOMEM; | 301 | int err = -ENOMEM; |
283 | ino_t ino; | 302 | ino_t ino; |
284 | 303 | ||
@@ -289,15 +308,17 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) | |||
289 | mapping_set_gfp_mask(inode->i_mapping, | 308 | mapping_set_gfp_mask(inode->i_mapping, |
290 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | 309 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); |
291 | 310 | ||
311 | root = NILFS_I(dir)->i_root; | ||
292 | ii = NILFS_I(inode); | 312 | ii = NILFS_I(inode); |
293 | ii->i_state = 1 << NILFS_I_NEW; | 313 | ii->i_state = 1 << NILFS_I_NEW; |
314 | ii->i_root = root; | ||
294 | 315 | ||
295 | err = nilfs_ifile_create_inode(sbi->s_ifile, &ino, &ii->i_bh); | 316 | err = nilfs_ifile_create_inode(root->ifile, &ino, &ii->i_bh); |
296 | if (unlikely(err)) | 317 | if (unlikely(err)) |
297 | goto failed_ifile_create_inode; | 318 | goto failed_ifile_create_inode; |
298 | /* reference count of i_bh inherits from nilfs_mdt_read_block() */ | 319 | /* reference count of i_bh inherits from nilfs_mdt_read_block() */ |
299 | 320 | ||
300 | atomic_inc(&sbi->s_inodes_count); | 321 | atomic_inc(&root->inodes_count); |
301 | inode_init_owner(inode, dir, mode); | 322 | inode_init_owner(inode, dir, mode); |
302 | inode->i_ino = ino; | 323 | inode->i_ino = ino; |
303 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 324 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
@@ -311,20 +332,16 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) | |||
311 | /* No lock is needed; iget() ensures it. */ | 332 | /* No lock is needed; iget() ensures it. */ |
312 | } | 333 | } |
313 | 334 | ||
314 | ii->i_flags = NILFS_I(dir)->i_flags; | 335 | ii->i_flags = nilfs_mask_flags( |
315 | if (S_ISLNK(mode)) | 336 | mode, NILFS_I(dir)->i_flags & NILFS_FL_INHERITED); |
316 | ii->i_flags &= ~(NILFS_IMMUTABLE_FL | NILFS_APPEND_FL); | ||
317 | if (!S_ISDIR(mode)) | ||
318 | ii->i_flags &= ~NILFS_DIRSYNC_FL; | ||
319 | 337 | ||
320 | /* ii->i_file_acl = 0; */ | 338 | /* ii->i_file_acl = 0; */ |
321 | /* ii->i_dir_acl = 0; */ | 339 | /* ii->i_dir_acl = 0; */ |
322 | ii->i_dir_start_lookup = 0; | 340 | ii->i_dir_start_lookup = 0; |
323 | ii->i_cno = 0; | ||
324 | nilfs_set_inode_flags(inode); | 341 | nilfs_set_inode_flags(inode); |
325 | spin_lock(&sbi->s_next_gen_lock); | 342 | spin_lock(&nilfs->ns_next_gen_lock); |
326 | inode->i_generation = sbi->s_next_generation++; | 343 | inode->i_generation = nilfs->ns_next_generation++; |
327 | spin_unlock(&sbi->s_next_gen_lock); | 344 | spin_unlock(&nilfs->ns_next_gen_lock); |
328 | insert_inode_hash(inode); | 345 | insert_inode_hash(inode); |
329 | 346 | ||
330 | err = nilfs_init_acl(inode, dir); | 347 | err = nilfs_init_acl(inode, dir); |
@@ -350,33 +367,21 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) | |||
350 | return ERR_PTR(err); | 367 | return ERR_PTR(err); |
351 | } | 368 | } |
352 | 369 | ||
353 | void nilfs_free_inode(struct inode *inode) | ||
354 | { | ||
355 | struct super_block *sb = inode->i_sb; | ||
356 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | ||
357 | |||
358 | /* XXX: check error code? Is there any thing I can do? */ | ||
359 | (void) nilfs_ifile_delete_inode(sbi->s_ifile, inode->i_ino); | ||
360 | atomic_dec(&sbi->s_inodes_count); | ||
361 | } | ||
362 | |||
363 | void nilfs_set_inode_flags(struct inode *inode) | 370 | void nilfs_set_inode_flags(struct inode *inode) |
364 | { | 371 | { |
365 | unsigned int flags = NILFS_I(inode)->i_flags; | 372 | unsigned int flags = NILFS_I(inode)->i_flags; |
366 | 373 | ||
367 | inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | | 374 | inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | |
368 | S_DIRSYNC); | 375 | S_DIRSYNC); |
369 | if (flags & NILFS_SYNC_FL) | 376 | if (flags & FS_SYNC_FL) |
370 | inode->i_flags |= S_SYNC; | 377 | inode->i_flags |= S_SYNC; |
371 | if (flags & NILFS_APPEND_FL) | 378 | if (flags & FS_APPEND_FL) |
372 | inode->i_flags |= S_APPEND; | 379 | inode->i_flags |= S_APPEND; |
373 | if (flags & NILFS_IMMUTABLE_FL) | 380 | if (flags & FS_IMMUTABLE_FL) |
374 | inode->i_flags |= S_IMMUTABLE; | 381 | inode->i_flags |= S_IMMUTABLE; |
375 | #ifndef NILFS_ATIME_DISABLE | 382 | if (flags & FS_NOATIME_FL) |
376 | if (flags & NILFS_NOATIME_FL) | ||
377 | #endif | ||
378 | inode->i_flags |= S_NOATIME; | 383 | inode->i_flags |= S_NOATIME; |
379 | if (flags & NILFS_DIRSYNC_FL) | 384 | if (flags & FS_DIRSYNC_FL) |
380 | inode->i_flags |= S_DIRSYNC; | 385 | inode->i_flags |= S_DIRSYNC; |
381 | mapping_set_gfp_mask(inode->i_mapping, | 386 | mapping_set_gfp_mask(inode->i_mapping, |
382 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | 387 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); |
@@ -410,7 +415,6 @@ int nilfs_read_inode_common(struct inode *inode, | |||
410 | 0 : le32_to_cpu(raw_inode->i_dir_acl); | 415 | 0 : le32_to_cpu(raw_inode->i_dir_acl); |
411 | #endif | 416 | #endif |
412 | ii->i_dir_start_lookup = 0; | 417 | ii->i_dir_start_lookup = 0; |
413 | ii->i_cno = 0; | ||
414 | inode->i_generation = le32_to_cpu(raw_inode->i_generation); | 418 | inode->i_generation = le32_to_cpu(raw_inode->i_generation); |
415 | 419 | ||
416 | if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 420 | if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || |
@@ -424,21 +428,21 @@ int nilfs_read_inode_common(struct inode *inode, | |||
424 | return 0; | 428 | return 0; |
425 | } | 429 | } |
426 | 430 | ||
427 | static int __nilfs_read_inode(struct super_block *sb, unsigned long ino, | 431 | static int __nilfs_read_inode(struct super_block *sb, |
432 | struct nilfs_root *root, unsigned long ino, | ||
428 | struct inode *inode) | 433 | struct inode *inode) |
429 | { | 434 | { |
430 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 435 | struct the_nilfs *nilfs = sb->s_fs_info; |
431 | struct inode *dat = nilfs_dat_inode(sbi->s_nilfs); | ||
432 | struct buffer_head *bh; | 436 | struct buffer_head *bh; |
433 | struct nilfs_inode *raw_inode; | 437 | struct nilfs_inode *raw_inode; |
434 | int err; | 438 | int err; |
435 | 439 | ||
436 | down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ | 440 | down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); |
437 | err = nilfs_ifile_get_inode_block(sbi->s_ifile, ino, &bh); | 441 | err = nilfs_ifile_get_inode_block(root->ifile, ino, &bh); |
438 | if (unlikely(err)) | 442 | if (unlikely(err)) |
439 | goto bad_inode; | 443 | goto bad_inode; |
440 | 444 | ||
441 | raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, bh); | 445 | raw_inode = nilfs_ifile_map_inode(root->ifile, ino, bh); |
442 | 446 | ||
443 | err = nilfs_read_inode_common(inode, raw_inode); | 447 | err = nilfs_read_inode_common(inode, raw_inode); |
444 | if (err) | 448 | if (err) |
@@ -461,33 +465,110 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino, | |||
461 | inode, inode->i_mode, | 465 | inode, inode->i_mode, |
462 | huge_decode_dev(le64_to_cpu(raw_inode->i_device_code))); | 466 | huge_decode_dev(le64_to_cpu(raw_inode->i_device_code))); |
463 | } | 467 | } |
464 | nilfs_ifile_unmap_inode(sbi->s_ifile, ino, bh); | 468 | nilfs_ifile_unmap_inode(root->ifile, ino, bh); |
465 | brelse(bh); | 469 | brelse(bh); |
466 | up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ | 470 | up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); |
467 | nilfs_set_inode_flags(inode); | 471 | nilfs_set_inode_flags(inode); |
468 | return 0; | 472 | return 0; |
469 | 473 | ||
470 | failed_unmap: | 474 | failed_unmap: |
471 | nilfs_ifile_unmap_inode(sbi->s_ifile, ino, bh); | 475 | nilfs_ifile_unmap_inode(root->ifile, ino, bh); |
472 | brelse(bh); | 476 | brelse(bh); |
473 | 477 | ||
474 | bad_inode: | 478 | bad_inode: |
475 | up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ | 479 | up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); |
476 | return err; | 480 | return err; |
477 | } | 481 | } |
478 | 482 | ||
479 | struct inode *nilfs_iget(struct super_block *sb, unsigned long ino) | 483 | static int nilfs_iget_test(struct inode *inode, void *opaque) |
484 | { | ||
485 | struct nilfs_iget_args *args = opaque; | ||
486 | struct nilfs_inode_info *ii; | ||
487 | |||
488 | if (args->ino != inode->i_ino || args->root != NILFS_I(inode)->i_root) | ||
489 | return 0; | ||
490 | |||
491 | ii = NILFS_I(inode); | ||
492 | if (!test_bit(NILFS_I_GCINODE, &ii->i_state)) | ||
493 | return !args->for_gc; | ||
494 | |||
495 | return args->for_gc && args->cno == ii->i_cno; | ||
496 | } | ||
497 | |||
498 | static int nilfs_iget_set(struct inode *inode, void *opaque) | ||
499 | { | ||
500 | struct nilfs_iget_args *args = opaque; | ||
501 | |||
502 | inode->i_ino = args->ino; | ||
503 | if (args->for_gc) { | ||
504 | NILFS_I(inode)->i_state = 1 << NILFS_I_GCINODE; | ||
505 | NILFS_I(inode)->i_cno = args->cno; | ||
506 | NILFS_I(inode)->i_root = NULL; | ||
507 | } else { | ||
508 | if (args->root && args->ino == NILFS_ROOT_INO) | ||
509 | nilfs_get_root(args->root); | ||
510 | NILFS_I(inode)->i_root = args->root; | ||
511 | } | ||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | struct inode *nilfs_ilookup(struct super_block *sb, struct nilfs_root *root, | ||
516 | unsigned long ino) | ||
517 | { | ||
518 | struct nilfs_iget_args args = { | ||
519 | .ino = ino, .root = root, .cno = 0, .for_gc = 0 | ||
520 | }; | ||
521 | |||
522 | return ilookup5(sb, ino, nilfs_iget_test, &args); | ||
523 | } | ||
524 | |||
525 | struct inode *nilfs_iget_locked(struct super_block *sb, struct nilfs_root *root, | ||
526 | unsigned long ino) | ||
527 | { | ||
528 | struct nilfs_iget_args args = { | ||
529 | .ino = ino, .root = root, .cno = 0, .for_gc = 0 | ||
530 | }; | ||
531 | |||
532 | return iget5_locked(sb, ino, nilfs_iget_test, nilfs_iget_set, &args); | ||
533 | } | ||
534 | |||
535 | struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, | ||
536 | unsigned long ino) | ||
480 | { | 537 | { |
481 | struct inode *inode; | 538 | struct inode *inode; |
482 | int err; | 539 | int err; |
483 | 540 | ||
484 | inode = iget_locked(sb, ino); | 541 | inode = nilfs_iget_locked(sb, root, ino); |
485 | if (unlikely(!inode)) | 542 | if (unlikely(!inode)) |
486 | return ERR_PTR(-ENOMEM); | 543 | return ERR_PTR(-ENOMEM); |
487 | if (!(inode->i_state & I_NEW)) | 544 | if (!(inode->i_state & I_NEW)) |
488 | return inode; | 545 | return inode; |
489 | 546 | ||
490 | err = __nilfs_read_inode(sb, ino, inode); | 547 | err = __nilfs_read_inode(sb, root, ino, inode); |
548 | if (unlikely(err)) { | ||
549 | iget_failed(inode); | ||
550 | return ERR_PTR(err); | ||
551 | } | ||
552 | unlock_new_inode(inode); | ||
553 | return inode; | ||
554 | } | ||
555 | |||
556 | struct inode *nilfs_iget_for_gc(struct super_block *sb, unsigned long ino, | ||
557 | __u64 cno) | ||
558 | { | ||
559 | struct nilfs_iget_args args = { | ||
560 | .ino = ino, .root = NULL, .cno = cno, .for_gc = 1 | ||
561 | }; | ||
562 | struct inode *inode; | ||
563 | int err; | ||
564 | |||
565 | inode = iget5_locked(sb, ino, nilfs_iget_test, nilfs_iget_set, &args); | ||
566 | if (unlikely(!inode)) | ||
567 | return ERR_PTR(-ENOMEM); | ||
568 | if (!(inode->i_state & I_NEW)) | ||
569 | return inode; | ||
570 | |||
571 | err = nilfs_init_gcinode(inode); | ||
491 | if (unlikely(err)) { | 572 | if (unlikely(err)) { |
492 | iget_failed(inode); | 573 | iget_failed(inode); |
493 | return ERR_PTR(err); | 574 | return ERR_PTR(err); |
@@ -515,6 +596,16 @@ void nilfs_write_inode_common(struct inode *inode, | |||
515 | raw_inode->i_flags = cpu_to_le32(ii->i_flags); | 596 | raw_inode->i_flags = cpu_to_le32(ii->i_flags); |
516 | raw_inode->i_generation = cpu_to_le32(inode->i_generation); | 597 | raw_inode->i_generation = cpu_to_le32(inode->i_generation); |
517 | 598 | ||
599 | if (NILFS_ROOT_METADATA_FILE(inode->i_ino)) { | ||
600 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; | ||
601 | |||
602 | /* zero-fill unused portion in the case of super root block */ | ||
603 | raw_inode->i_xattr = 0; | ||
604 | raw_inode->i_pad = 0; | ||
605 | memset((void *)raw_inode + sizeof(*raw_inode), 0, | ||
606 | nilfs->ns_inode_size - sizeof(*raw_inode)); | ||
607 | } | ||
608 | |||
518 | if (has_bmap) | 609 | if (has_bmap) |
519 | nilfs_bmap_write(ii->i_bmap, raw_inode); | 610 | nilfs_bmap_write(ii->i_bmap, raw_inode); |
520 | else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) | 611 | else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) |
@@ -528,21 +619,20 @@ void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh) | |||
528 | { | 619 | { |
529 | ino_t ino = inode->i_ino; | 620 | ino_t ino = inode->i_ino; |
530 | struct nilfs_inode_info *ii = NILFS_I(inode); | 621 | struct nilfs_inode_info *ii = NILFS_I(inode); |
531 | struct super_block *sb = inode->i_sb; | 622 | struct inode *ifile = ii->i_root->ifile; |
532 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | ||
533 | struct nilfs_inode *raw_inode; | 623 | struct nilfs_inode *raw_inode; |
534 | 624 | ||
535 | raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, ibh); | 625 | raw_inode = nilfs_ifile_map_inode(ifile, ino, ibh); |
536 | 626 | ||
537 | if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state)) | 627 | if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state)) |
538 | memset(raw_inode, 0, NILFS_MDT(sbi->s_ifile)->mi_entry_size); | 628 | memset(raw_inode, 0, NILFS_MDT(ifile)->mi_entry_size); |
539 | set_bit(NILFS_I_INODE_DIRTY, &ii->i_state); | 629 | set_bit(NILFS_I_INODE_DIRTY, &ii->i_state); |
540 | 630 | ||
541 | nilfs_write_inode_common(inode, raw_inode, 0); | 631 | nilfs_write_inode_common(inode, raw_inode, 0); |
542 | /* XXX: call with has_bmap = 0 is a workaround to avoid | 632 | /* XXX: call with has_bmap = 0 is a workaround to avoid |
543 | deadlock of bmap. This delays update of i_bmap to just | 633 | deadlock of bmap. This delays update of i_bmap to just |
544 | before writing */ | 634 | before writing */ |
545 | nilfs_ifile_unmap_inode(sbi->s_ifile, ino, ibh); | 635 | nilfs_ifile_unmap_inode(ifile, ino, ibh); |
546 | } | 636 | } |
547 | 637 | ||
548 | #define NILFS_MAX_TRUNCATE_BLOCKS 16384 /* 64MB for 4KB block */ | 638 | #define NILFS_MAX_TRUNCATE_BLOCKS 16384 /* 64MB for 4KB block */ |
@@ -555,7 +645,7 @@ static void nilfs_truncate_bmap(struct nilfs_inode_info *ii, | |||
555 | 645 | ||
556 | if (!test_bit(NILFS_I_BMAP, &ii->i_state)) | 646 | if (!test_bit(NILFS_I_BMAP, &ii->i_state)) |
557 | return; | 647 | return; |
558 | repeat: | 648 | repeat: |
559 | ret = nilfs_bmap_last_key(ii->i_bmap, &b); | 649 | ret = nilfs_bmap_last_key(ii->i_bmap, &b); |
560 | if (ret == -ENOENT) | 650 | if (ret == -ENOENT) |
561 | return; | 651 | return; |
@@ -572,14 +662,10 @@ static void nilfs_truncate_bmap(struct nilfs_inode_info *ii, | |||
572 | nilfs_bmap_truncate(ii->i_bmap, b) == 0)) | 662 | nilfs_bmap_truncate(ii->i_bmap, b) == 0)) |
573 | goto repeat; | 663 | goto repeat; |
574 | 664 | ||
575 | failed: | 665 | failed: |
576 | if (ret == -EINVAL) | 666 | nilfs_warning(ii->vfs_inode.i_sb, __func__, |
577 | nilfs_error(ii->vfs_inode.i_sb, __func__, | 667 | "failed to truncate bmap (ino=%lu, err=%d)", |
578 | "bmap is broken (ino=%lu)", ii->vfs_inode.i_ino); | 668 | ii->vfs_inode.i_ino, ret); |
579 | else | ||
580 | nilfs_warning(ii->vfs_inode.i_sb, __func__, | ||
581 | "failed to truncate bmap (ino=%lu, err=%d)", | ||
582 | ii->vfs_inode.i_ino, ret); | ||
583 | } | 669 | } |
584 | 670 | ||
585 | void nilfs_truncate(struct inode *inode) | 671 | void nilfs_truncate(struct inode *inode) |
@@ -608,7 +694,7 @@ void nilfs_truncate(struct inode *inode) | |||
608 | nilfs_set_transaction_flag(NILFS_TI_SYNC); | 694 | nilfs_set_transaction_flag(NILFS_TI_SYNC); |
609 | 695 | ||
610 | nilfs_mark_inode_dirty(inode); | 696 | nilfs_mark_inode_dirty(inode); |
611 | nilfs_set_file_dirty(NILFS_SB(sb), inode, 0); | 697 | nilfs_set_file_dirty(inode, 0); |
612 | nilfs_transaction_commit(sb); | 698 | nilfs_transaction_commit(sb); |
613 | /* May construct a logical segment and may fail in sync mode. | 699 | /* May construct a logical segment and may fail in sync mode. |
614 | But truncate has no return value. */ | 700 | But truncate has no return value. */ |
@@ -617,6 +703,7 @@ void nilfs_truncate(struct inode *inode) | |||
617 | static void nilfs_clear_inode(struct inode *inode) | 703 | static void nilfs_clear_inode(struct inode *inode) |
618 | { | 704 | { |
619 | struct nilfs_inode_info *ii = NILFS_I(inode); | 705 | struct nilfs_inode_info *ii = NILFS_I(inode); |
706 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); | ||
620 | 707 | ||
621 | /* | 708 | /* |
622 | * Free resources allocated in nilfs_read_inode(), here. | 709 | * Free resources allocated in nilfs_read_inode(), here. |
@@ -625,10 +712,16 @@ static void nilfs_clear_inode(struct inode *inode) | |||
625 | brelse(ii->i_bh); | 712 | brelse(ii->i_bh); |
626 | ii->i_bh = NULL; | 713 | ii->i_bh = NULL; |
627 | 714 | ||
715 | if (mdi && mdi->mi_palloc_cache) | ||
716 | nilfs_palloc_destroy_cache(inode); | ||
717 | |||
628 | if (test_bit(NILFS_I_BMAP, &ii->i_state)) | 718 | if (test_bit(NILFS_I_BMAP, &ii->i_state)) |
629 | nilfs_bmap_clear(ii->i_bmap); | 719 | nilfs_bmap_clear(ii->i_bmap); |
630 | 720 | ||
631 | nilfs_btnode_cache_clear(&ii->i_btnode_cache); | 721 | nilfs_btnode_cache_clear(&ii->i_btnode_cache); |
722 | |||
723 | if (ii->i_root && inode->i_ino == NILFS_ROOT_INO) | ||
724 | nilfs_put_root(ii->i_root); | ||
632 | } | 725 | } |
633 | 726 | ||
634 | void nilfs_evict_inode(struct inode *inode) | 727 | void nilfs_evict_inode(struct inode *inode) |
@@ -636,8 +729,9 @@ void nilfs_evict_inode(struct inode *inode) | |||
636 | struct nilfs_transaction_info ti; | 729 | struct nilfs_transaction_info ti; |
637 | struct super_block *sb = inode->i_sb; | 730 | struct super_block *sb = inode->i_sb; |
638 | struct nilfs_inode_info *ii = NILFS_I(inode); | 731 | struct nilfs_inode_info *ii = NILFS_I(inode); |
732 | int ret; | ||
639 | 733 | ||
640 | if (inode->i_nlink || unlikely(is_bad_inode(inode))) { | 734 | if (inode->i_nlink || !ii->i_root || unlikely(is_bad_inode(inode))) { |
641 | if (inode->i_data.nrpages) | 735 | if (inode->i_data.nrpages) |
642 | truncate_inode_pages(&inode->i_data, 0); | 736 | truncate_inode_pages(&inode->i_data, 0); |
643 | end_writeback(inode); | 737 | end_writeback(inode); |
@@ -649,12 +743,17 @@ void nilfs_evict_inode(struct inode *inode) | |||
649 | if (inode->i_data.nrpages) | 743 | if (inode->i_data.nrpages) |
650 | truncate_inode_pages(&inode->i_data, 0); | 744 | truncate_inode_pages(&inode->i_data, 0); |
651 | 745 | ||
746 | /* TODO: some of the following operations may fail. */ | ||
652 | nilfs_truncate_bmap(ii, 0); | 747 | nilfs_truncate_bmap(ii, 0); |
653 | nilfs_mark_inode_dirty(inode); | 748 | nilfs_mark_inode_dirty(inode); |
654 | end_writeback(inode); | 749 | end_writeback(inode); |
750 | |||
751 | ret = nilfs_ifile_delete_inode(ii->i_root->ifile, inode->i_ino); | ||
752 | if (!ret) | ||
753 | atomic_dec(&ii->i_root->inodes_count); | ||
754 | |||
655 | nilfs_clear_inode(inode); | 755 | nilfs_clear_inode(inode); |
656 | nilfs_free_inode(inode); | 756 | |
657 | /* nilfs_free_inode() marks inode buffer dirty */ | ||
658 | if (IS_SYNC(inode)) | 757 | if (IS_SYNC(inode)) |
659 | nilfs_set_transaction_flag(NILFS_TI_SYNC); | 758 | nilfs_set_transaction_flag(NILFS_TI_SYNC); |
660 | nilfs_transaction_commit(sb); | 759 | nilfs_transaction_commit(sb); |
@@ -700,20 +799,30 @@ out_err: | |||
700 | return err; | 799 | return err; |
701 | } | 800 | } |
702 | 801 | ||
703 | int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode, | 802 | int nilfs_permission(struct inode *inode, int mask, unsigned int flags) |
704 | struct buffer_head **pbh) | ||
705 | { | 803 | { |
804 | struct nilfs_root *root = NILFS_I(inode)->i_root; | ||
805 | if ((mask & MAY_WRITE) && root && | ||
806 | root->cno != NILFS_CPTREE_CURRENT_CNO) | ||
807 | return -EROFS; /* snapshot is not writable */ | ||
808 | |||
809 | return generic_permission(inode, mask, flags, NULL); | ||
810 | } | ||
811 | |||
812 | int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh) | ||
813 | { | ||
814 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; | ||
706 | struct nilfs_inode_info *ii = NILFS_I(inode); | 815 | struct nilfs_inode_info *ii = NILFS_I(inode); |
707 | int err; | 816 | int err; |
708 | 817 | ||
709 | spin_lock(&sbi->s_inode_lock); | 818 | spin_lock(&nilfs->ns_inode_lock); |
710 | if (ii->i_bh == NULL) { | 819 | if (ii->i_bh == NULL) { |
711 | spin_unlock(&sbi->s_inode_lock); | 820 | spin_unlock(&nilfs->ns_inode_lock); |
712 | err = nilfs_ifile_get_inode_block(sbi->s_ifile, inode->i_ino, | 821 | err = nilfs_ifile_get_inode_block(ii->i_root->ifile, |
713 | pbh); | 822 | inode->i_ino, pbh); |
714 | if (unlikely(err)) | 823 | if (unlikely(err)) |
715 | return err; | 824 | return err; |
716 | spin_lock(&sbi->s_inode_lock); | 825 | spin_lock(&nilfs->ns_inode_lock); |
717 | if (ii->i_bh == NULL) | 826 | if (ii->i_bh == NULL) |
718 | ii->i_bh = *pbh; | 827 | ii->i_bh = *pbh; |
719 | else { | 828 | else { |
@@ -724,36 +833,36 @@ int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode, | |||
724 | *pbh = ii->i_bh; | 833 | *pbh = ii->i_bh; |
725 | 834 | ||
726 | get_bh(*pbh); | 835 | get_bh(*pbh); |
727 | spin_unlock(&sbi->s_inode_lock); | 836 | spin_unlock(&nilfs->ns_inode_lock); |
728 | return 0; | 837 | return 0; |
729 | } | 838 | } |
730 | 839 | ||
731 | int nilfs_inode_dirty(struct inode *inode) | 840 | int nilfs_inode_dirty(struct inode *inode) |
732 | { | 841 | { |
733 | struct nilfs_inode_info *ii = NILFS_I(inode); | 842 | struct nilfs_inode_info *ii = NILFS_I(inode); |
734 | struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb); | 843 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; |
735 | int ret = 0; | 844 | int ret = 0; |
736 | 845 | ||
737 | if (!list_empty(&ii->i_dirty)) { | 846 | if (!list_empty(&ii->i_dirty)) { |
738 | spin_lock(&sbi->s_inode_lock); | 847 | spin_lock(&nilfs->ns_inode_lock); |
739 | ret = test_bit(NILFS_I_DIRTY, &ii->i_state) || | 848 | ret = test_bit(NILFS_I_DIRTY, &ii->i_state) || |
740 | test_bit(NILFS_I_BUSY, &ii->i_state); | 849 | test_bit(NILFS_I_BUSY, &ii->i_state); |
741 | spin_unlock(&sbi->s_inode_lock); | 850 | spin_unlock(&nilfs->ns_inode_lock); |
742 | } | 851 | } |
743 | return ret; | 852 | return ret; |
744 | } | 853 | } |
745 | 854 | ||
746 | int nilfs_set_file_dirty(struct nilfs_sb_info *sbi, struct inode *inode, | 855 | int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty) |
747 | unsigned nr_dirty) | ||
748 | { | 856 | { |
749 | struct nilfs_inode_info *ii = NILFS_I(inode); | 857 | struct nilfs_inode_info *ii = NILFS_I(inode); |
858 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; | ||
750 | 859 | ||
751 | atomic_add(nr_dirty, &sbi->s_nilfs->ns_ndirtyblks); | 860 | atomic_add(nr_dirty, &nilfs->ns_ndirtyblks); |
752 | 861 | ||
753 | if (test_and_set_bit(NILFS_I_DIRTY, &ii->i_state)) | 862 | if (test_and_set_bit(NILFS_I_DIRTY, &ii->i_state)) |
754 | return 0; | 863 | return 0; |
755 | 864 | ||
756 | spin_lock(&sbi->s_inode_lock); | 865 | spin_lock(&nilfs->ns_inode_lock); |
757 | if (!test_bit(NILFS_I_QUEUED, &ii->i_state) && | 866 | if (!test_bit(NILFS_I_QUEUED, &ii->i_state) && |
758 | !test_bit(NILFS_I_BUSY, &ii->i_state)) { | 867 | !test_bit(NILFS_I_BUSY, &ii->i_state)) { |
759 | /* Because this routine may race with nilfs_dispose_list(), | 868 | /* Because this routine may race with nilfs_dispose_list(), |
@@ -761,36 +870,34 @@ int nilfs_set_file_dirty(struct nilfs_sb_info *sbi, struct inode *inode, | |||
761 | if (list_empty(&ii->i_dirty) && igrab(inode) == NULL) { | 870 | if (list_empty(&ii->i_dirty) && igrab(inode) == NULL) { |
762 | /* This will happen when somebody is freeing | 871 | /* This will happen when somebody is freeing |
763 | this inode. */ | 872 | this inode. */ |
764 | nilfs_warning(sbi->s_super, __func__, | 873 | nilfs_warning(inode->i_sb, __func__, |
765 | "cannot get inode (ino=%lu)\n", | 874 | "cannot get inode (ino=%lu)\n", |
766 | inode->i_ino); | 875 | inode->i_ino); |
767 | spin_unlock(&sbi->s_inode_lock); | 876 | spin_unlock(&nilfs->ns_inode_lock); |
768 | return -EINVAL; /* NILFS_I_DIRTY may remain for | 877 | return -EINVAL; /* NILFS_I_DIRTY may remain for |
769 | freeing inode */ | 878 | freeing inode */ |
770 | } | 879 | } |
771 | list_del(&ii->i_dirty); | 880 | list_move_tail(&ii->i_dirty, &nilfs->ns_dirty_files); |
772 | list_add_tail(&ii->i_dirty, &sbi->s_dirty_files); | ||
773 | set_bit(NILFS_I_QUEUED, &ii->i_state); | 881 | set_bit(NILFS_I_QUEUED, &ii->i_state); |
774 | } | 882 | } |
775 | spin_unlock(&sbi->s_inode_lock); | 883 | spin_unlock(&nilfs->ns_inode_lock); |
776 | return 0; | 884 | return 0; |
777 | } | 885 | } |
778 | 886 | ||
779 | int nilfs_mark_inode_dirty(struct inode *inode) | 887 | int nilfs_mark_inode_dirty(struct inode *inode) |
780 | { | 888 | { |
781 | struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb); | ||
782 | struct buffer_head *ibh; | 889 | struct buffer_head *ibh; |
783 | int err; | 890 | int err; |
784 | 891 | ||
785 | err = nilfs_load_inode_block(sbi, inode, &ibh); | 892 | err = nilfs_load_inode_block(inode, &ibh); |
786 | if (unlikely(err)) { | 893 | if (unlikely(err)) { |
787 | nilfs_warning(inode->i_sb, __func__, | 894 | nilfs_warning(inode->i_sb, __func__, |
788 | "failed to reget inode block.\n"); | 895 | "failed to reget inode block.\n"); |
789 | return err; | 896 | return err; |
790 | } | 897 | } |
791 | nilfs_update_inode(inode, ibh); | 898 | nilfs_update_inode(inode, ibh); |
792 | nilfs_mdt_mark_buffer_dirty(ibh); | 899 | mark_buffer_dirty(ibh); |
793 | nilfs_mdt_mark_dirty(sbi->s_ifile); | 900 | nilfs_mdt_mark_dirty(NILFS_I(inode)->i_root->ifile); |
794 | brelse(ibh); | 901 | brelse(ibh); |
795 | return 0; | 902 | return 0; |
796 | } | 903 | } |
@@ -805,9 +912,10 @@ int nilfs_mark_inode_dirty(struct inode *inode) | |||
805 | * construction. This function can be called both as a single operation | 912 | * construction. This function can be called both as a single operation |
806 | * and as a part of indivisible file operations. | 913 | * and as a part of indivisible file operations. |
807 | */ | 914 | */ |
808 | void nilfs_dirty_inode(struct inode *inode) | 915 | void nilfs_dirty_inode(struct inode *inode, int flags) |
809 | { | 916 | { |
810 | struct nilfs_transaction_info ti; | 917 | struct nilfs_transaction_info ti; |
918 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); | ||
811 | 919 | ||
812 | if (is_bad_inode(inode)) { | 920 | if (is_bad_inode(inode)) { |
813 | nilfs_warning(inode->i_sb, __func__, | 921 | nilfs_warning(inode->i_sb, __func__, |
@@ -815,7 +923,142 @@ void nilfs_dirty_inode(struct inode *inode) | |||
815 | dump_stack(); | 923 | dump_stack(); |
816 | return; | 924 | return; |
817 | } | 925 | } |
926 | if (mdi) { | ||
927 | nilfs_mdt_mark_dirty(inode); | ||
928 | return; | ||
929 | } | ||
818 | nilfs_transaction_begin(inode->i_sb, &ti, 0); | 930 | nilfs_transaction_begin(inode->i_sb, &ti, 0); |
819 | nilfs_mark_inode_dirty(inode); | 931 | nilfs_mark_inode_dirty(inode); |
820 | nilfs_transaction_commit(inode->i_sb); /* never fails */ | 932 | nilfs_transaction_commit(inode->i_sb); /* never fails */ |
821 | } | 933 | } |
934 | |||
935 | int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | ||
936 | __u64 start, __u64 len) | ||
937 | { | ||
938 | struct the_nilfs *nilfs = inode->i_sb->s_fs_info; | ||
939 | __u64 logical = 0, phys = 0, size = 0; | ||
940 | __u32 flags = 0; | ||
941 | loff_t isize; | ||
942 | sector_t blkoff, end_blkoff; | ||
943 | sector_t delalloc_blkoff; | ||
944 | unsigned long delalloc_blklen; | ||
945 | unsigned int blkbits = inode->i_blkbits; | ||
946 | int ret, n; | ||
947 | |||
948 | ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC); | ||
949 | if (ret) | ||
950 | return ret; | ||
951 | |||
952 | mutex_lock(&inode->i_mutex); | ||
953 | |||
954 | isize = i_size_read(inode); | ||
955 | |||
956 | blkoff = start >> blkbits; | ||
957 | end_blkoff = (start + len - 1) >> blkbits; | ||
958 | |||
959 | delalloc_blklen = nilfs_find_uncommitted_extent(inode, blkoff, | ||
960 | &delalloc_blkoff); | ||
961 | |||
962 | do { | ||
963 | __u64 blkphy; | ||
964 | unsigned int maxblocks; | ||
965 | |||
966 | if (delalloc_blklen && blkoff == delalloc_blkoff) { | ||
967 | if (size) { | ||
968 | /* End of the current extent */ | ||
969 | ret = fiemap_fill_next_extent( | ||
970 | fieinfo, logical, phys, size, flags); | ||
971 | if (ret) | ||
972 | break; | ||
973 | } | ||
974 | if (blkoff > end_blkoff) | ||
975 | break; | ||
976 | |||
977 | flags = FIEMAP_EXTENT_MERGED | FIEMAP_EXTENT_DELALLOC; | ||
978 | logical = blkoff << blkbits; | ||
979 | phys = 0; | ||
980 | size = delalloc_blklen << blkbits; | ||
981 | |||
982 | blkoff = delalloc_blkoff + delalloc_blklen; | ||
983 | delalloc_blklen = nilfs_find_uncommitted_extent( | ||
984 | inode, blkoff, &delalloc_blkoff); | ||
985 | continue; | ||
986 | } | ||
987 | |||
988 | /* | ||
989 | * Limit the number of blocks that we look up so as | ||
990 | * not to get into the next delayed allocation extent. | ||
991 | */ | ||
992 | maxblocks = INT_MAX; | ||
993 | if (delalloc_blklen) | ||
994 | maxblocks = min_t(sector_t, delalloc_blkoff - blkoff, | ||
995 | maxblocks); | ||
996 | blkphy = 0; | ||
997 | |||
998 | down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); | ||
999 | n = nilfs_bmap_lookup_contig( | ||
1000 | NILFS_I(inode)->i_bmap, blkoff, &blkphy, maxblocks); | ||
1001 | up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); | ||
1002 | |||
1003 | if (n < 0) { | ||
1004 | int past_eof; | ||
1005 | |||
1006 | if (unlikely(n != -ENOENT)) | ||
1007 | break; /* error */ | ||
1008 | |||
1009 | /* HOLE */ | ||
1010 | blkoff++; | ||
1011 | past_eof = ((blkoff << blkbits) >= isize); | ||
1012 | |||
1013 | if (size) { | ||
1014 | /* End of the current extent */ | ||
1015 | |||
1016 | if (past_eof) | ||
1017 | flags |= FIEMAP_EXTENT_LAST; | ||
1018 | |||
1019 | ret = fiemap_fill_next_extent( | ||
1020 | fieinfo, logical, phys, size, flags); | ||
1021 | if (ret) | ||
1022 | break; | ||
1023 | size = 0; | ||
1024 | } | ||
1025 | if (blkoff > end_blkoff || past_eof) | ||
1026 | break; | ||
1027 | } else { | ||
1028 | if (size) { | ||
1029 | if (phys && blkphy << blkbits == phys + size) { | ||
1030 | /* The current extent goes on */ | ||
1031 | size += n << blkbits; | ||
1032 | } else { | ||
1033 | /* Terminate the current extent */ | ||
1034 | ret = fiemap_fill_next_extent( | ||
1035 | fieinfo, logical, phys, size, | ||
1036 | flags); | ||
1037 | if (ret || blkoff > end_blkoff) | ||
1038 | break; | ||
1039 | |||
1040 | /* Start another extent */ | ||
1041 | flags = FIEMAP_EXTENT_MERGED; | ||
1042 | logical = blkoff << blkbits; | ||
1043 | phys = blkphy << blkbits; | ||
1044 | size = n << blkbits; | ||
1045 | } | ||
1046 | } else { | ||
1047 | /* Start a new extent */ | ||
1048 | flags = FIEMAP_EXTENT_MERGED; | ||
1049 | logical = blkoff << blkbits; | ||
1050 | phys = blkphy << blkbits; | ||
1051 | size = n << blkbits; | ||
1052 | } | ||
1053 | blkoff += n; | ||
1054 | } | ||
1055 | cond_resched(); | ||
1056 | } while (true); | ||
1057 | |||
1058 | /* If ret is 1 then we just hit the end of the extent array */ | ||
1059 | if (ret == 1) | ||
1060 | ret = 0; | ||
1061 | |||
1062 | mutex_unlock(&inode->i_mutex); | ||
1063 | return ret; | ||
1064 | } | ||