diff options
Diffstat (limited to 'fs/nilfs2/mdt.c')
-rw-r--r-- | fs/nilfs2/mdt.c | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index f6326112d647..024be8c35bb6 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/writeback.h> | 26 | #include <linux/writeback.h> |
27 | #include <linux/backing-dev.h> | 27 | #include <linux/backing-dev.h> |
28 | #include <linux/swap.h> | 28 | #include <linux/swap.h> |
29 | #include <linux/slab.h> | ||
29 | #include "nilfs.h" | 30 | #include "nilfs.h" |
30 | #include "segment.h" | 31 | #include "segment.h" |
31 | #include "page.h" | 32 | #include "page.h" |
@@ -186,7 +187,7 @@ nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff, | |||
186 | } | 187 | } |
187 | 188 | ||
188 | static int nilfs_mdt_read_block(struct inode *inode, unsigned long block, | 189 | static int nilfs_mdt_read_block(struct inode *inode, unsigned long block, |
189 | struct buffer_head **out_bh) | 190 | int readahead, struct buffer_head **out_bh) |
190 | { | 191 | { |
191 | struct buffer_head *first_bh, *bh; | 192 | struct buffer_head *first_bh, *bh; |
192 | unsigned long blkoff; | 193 | unsigned long blkoff; |
@@ -200,16 +201,18 @@ static int nilfs_mdt_read_block(struct inode *inode, unsigned long block, | |||
200 | if (unlikely(err)) | 201 | if (unlikely(err)) |
201 | goto failed; | 202 | goto failed; |
202 | 203 | ||
203 | blkoff = block + 1; | 204 | if (readahead) { |
204 | for (i = 0; i < nr_ra_blocks; i++, blkoff++) { | 205 | blkoff = block + 1; |
205 | err = nilfs_mdt_submit_block(inode, blkoff, READA, &bh); | 206 | for (i = 0; i < nr_ra_blocks; i++, blkoff++) { |
206 | if (likely(!err || err == -EEXIST)) | 207 | err = nilfs_mdt_submit_block(inode, blkoff, READA, &bh); |
207 | brelse(bh); | 208 | if (likely(!err || err == -EEXIST)) |
208 | else if (err != -EBUSY) | 209 | brelse(bh); |
209 | break; /* abort readahead if bmap lookup failed */ | 210 | else if (err != -EBUSY) |
210 | 211 | break; | |
211 | if (!buffer_locked(first_bh)) | 212 | /* abort readahead if bmap lookup failed */ |
212 | goto out_no_wait; | 213 | if (!buffer_locked(first_bh)) |
214 | goto out_no_wait; | ||
215 | } | ||
213 | } | 216 | } |
214 | 217 | ||
215 | wait_on_buffer(first_bh); | 218 | wait_on_buffer(first_bh); |
@@ -263,7 +266,7 @@ int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create, | |||
263 | 266 | ||
264 | /* Should be rewritten with merging nilfs_mdt_read_block() */ | 267 | /* Should be rewritten with merging nilfs_mdt_read_block() */ |
265 | retry: | 268 | retry: |
266 | ret = nilfs_mdt_read_block(inode, blkoff, out_bh); | 269 | ret = nilfs_mdt_read_block(inode, blkoff, !create, out_bh); |
267 | if (!create || ret != -ENOENT) | 270 | if (!create || ret != -ENOENT) |
268 | return ret; | 271 | return ret; |
269 | 272 | ||
@@ -371,7 +374,7 @@ int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block) | |||
371 | struct buffer_head *bh; | 374 | struct buffer_head *bh; |
372 | int err; | 375 | int err; |
373 | 376 | ||
374 | err = nilfs_mdt_read_block(inode, block, &bh); | 377 | err = nilfs_mdt_read_block(inode, block, 0, &bh); |
375 | if (unlikely(err)) | 378 | if (unlikely(err)) |
376 | return err; | 379 | return err; |
377 | nilfs_mark_buffer_dirty(bh); | 380 | nilfs_mark_buffer_dirty(bh); |
@@ -445,9 +448,17 @@ static const struct file_operations def_mdt_fops; | |||
445 | * longer than those of the super block structs; they may continue for | 448 | * longer than those of the super block structs; they may continue for |
446 | * several consecutive mounts/umounts. This would need discussions. | 449 | * several consecutive mounts/umounts. This would need discussions. |
447 | */ | 450 | */ |
451 | /** | ||
452 | * nilfs_mdt_new_common - allocate a pseudo inode for metadata file | ||
453 | * @nilfs: nilfs object | ||
454 | * @sb: super block instance the metadata file belongs to | ||
455 | * @ino: inode number | ||
456 | * @gfp_mask: gfp mask for data pages | ||
457 | * @objsz: size of the private object attached to inode->i_private | ||
458 | */ | ||
448 | struct inode * | 459 | struct inode * |
449 | nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb, | 460 | nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb, |
450 | ino_t ino, gfp_t gfp_mask) | 461 | ino_t ino, gfp_t gfp_mask, size_t objsz) |
451 | { | 462 | { |
452 | struct inode *inode = nilfs_alloc_inode_common(nilfs); | 463 | struct inode *inode = nilfs_alloc_inode_common(nilfs); |
453 | 464 | ||
@@ -455,8 +466,9 @@ nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb, | |||
455 | return NULL; | 466 | return NULL; |
456 | else { | 467 | else { |
457 | struct address_space * const mapping = &inode->i_data; | 468 | struct address_space * const mapping = &inode->i_data; |
458 | struct nilfs_mdt_info *mi = kzalloc(sizeof(*mi), GFP_NOFS); | 469 | struct nilfs_mdt_info *mi; |
459 | 470 | ||
471 | mi = kzalloc(max(sizeof(*mi), objsz), GFP_NOFS); | ||
460 | if (!mi) { | 472 | if (!mi) { |
461 | nilfs_destroy_inode(inode); | 473 | nilfs_destroy_inode(inode); |
462 | return NULL; | 474 | return NULL; |
@@ -513,11 +525,11 @@ nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb, | |||
513 | } | 525 | } |
514 | 526 | ||
515 | struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb, | 527 | struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb, |
516 | ino_t ino) | 528 | ino_t ino, size_t objsz) |
517 | { | 529 | { |
518 | struct inode *inode = nilfs_mdt_new_common(nilfs, sb, ino, | 530 | struct inode *inode; |
519 | NILFS_MDT_GFP); | ||
520 | 531 | ||
532 | inode = nilfs_mdt_new_common(nilfs, sb, ino, NILFS_MDT_GFP, objsz); | ||
521 | if (!inode) | 533 | if (!inode) |
522 | return NULL; | 534 | return NULL; |
523 | 535 | ||
@@ -544,14 +556,15 @@ void nilfs_mdt_set_shadow(struct inode *orig, struct inode *shadow) | |||
544 | &NILFS_I(orig)->i_btnode_cache; | 556 | &NILFS_I(orig)->i_btnode_cache; |
545 | } | 557 | } |
546 | 558 | ||
547 | void nilfs_mdt_clear(struct inode *inode) | 559 | static void nilfs_mdt_clear(struct inode *inode) |
548 | { | 560 | { |
549 | struct nilfs_inode_info *ii = NILFS_I(inode); | 561 | struct nilfs_inode_info *ii = NILFS_I(inode); |
550 | 562 | ||
551 | invalidate_mapping_pages(inode->i_mapping, 0, -1); | 563 | invalidate_mapping_pages(inode->i_mapping, 0, -1); |
552 | truncate_inode_pages(inode->i_mapping, 0); | 564 | truncate_inode_pages(inode->i_mapping, 0); |
553 | 565 | ||
554 | nilfs_bmap_clear(ii->i_bmap); | 566 | if (test_bit(NILFS_I_BMAP, &ii->i_state)) |
567 | nilfs_bmap_clear(ii->i_bmap); | ||
555 | nilfs_btnode_cache_clear(&ii->i_btnode_cache); | 568 | nilfs_btnode_cache_clear(&ii->i_btnode_cache); |
556 | } | 569 | } |
557 | 570 | ||
@@ -559,6 +572,10 @@ void nilfs_mdt_destroy(struct inode *inode) | |||
559 | { | 572 | { |
560 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); | 573 | struct nilfs_mdt_info *mdi = NILFS_MDT(inode); |
561 | 574 | ||
575 | if (mdi->mi_palloc_cache) | ||
576 | nilfs_palloc_destroy_cache(inode); | ||
577 | nilfs_mdt_clear(inode); | ||
578 | |||
562 | kfree(mdi->mi_bgl); /* kfree(NULL) is safe */ | 579 | kfree(mdi->mi_bgl); /* kfree(NULL) is safe */ |
563 | kfree(mdi); | 580 | kfree(mdi); |
564 | nilfs_destroy_inode(inode); | 581 | nilfs_destroy_inode(inode); |