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