nilfs2: move recovery completion into load_nilfs function
[safe/jmp/linux-2.6] / fs / nilfs2 / mdt.c
index f632611..06713ff 100644 (file)
@@ -186,7 +186,7 @@ nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff,
 }
 
 static int nilfs_mdt_read_block(struct inode *inode, unsigned long block,
-                               struct buffer_head **out_bh)
+                               int readahead, struct buffer_head **out_bh)
 {
        struct buffer_head *first_bh, *bh;
        unsigned long blkoff;
@@ -200,16 +200,18 @@ static int nilfs_mdt_read_block(struct inode *inode, unsigned long block,
        if (unlikely(err))
                goto failed;
 
-       blkoff = block + 1;
-       for (i = 0; i < nr_ra_blocks; i++, blkoff++) {
-               err = nilfs_mdt_submit_block(inode, blkoff, READA, &bh);
-               if (likely(!err || err == -EEXIST))
-                       brelse(bh);
-               else if (err != -EBUSY)
-                       break; /* abort readahead if bmap lookup failed */
-
-               if (!buffer_locked(first_bh))
-                       goto out_no_wait;
+       if (readahead) {
+               blkoff = block + 1;
+               for (i = 0; i < nr_ra_blocks; i++, blkoff++) {
+                       err = nilfs_mdt_submit_block(inode, blkoff, READA, &bh);
+                       if (likely(!err || err == -EEXIST))
+                               brelse(bh);
+                       else if (err != -EBUSY)
+                               break;
+                               /* abort readahead if bmap lookup failed */
+                       if (!buffer_locked(first_bh))
+                               goto out_no_wait;
+               }
        }
 
        wait_on_buffer(first_bh);
@@ -263,7 +265,7 @@ int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create,
 
        /* Should be rewritten with merging nilfs_mdt_read_block() */
  retry:
-       ret = nilfs_mdt_read_block(inode, blkoff, out_bh);
+       ret = nilfs_mdt_read_block(inode, blkoff, !create, out_bh);
        if (!create || ret != -ENOENT)
                return ret;
 
@@ -371,7 +373,7 @@ int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block)
        struct buffer_head *bh;
        int err;
 
-       err = nilfs_mdt_read_block(inode, block, &bh);
+       err = nilfs_mdt_read_block(inode, block, 0, &bh);
        if (unlikely(err))
                return err;
        nilfs_mark_buffer_dirty(bh);
@@ -445,9 +447,17 @@ static const struct file_operations def_mdt_fops;
  * longer than those of the super block structs; they may continue for
  * several consecutive mounts/umounts.  This would need discussions.
  */
+/**
+ * nilfs_mdt_new_common - allocate a pseudo inode for metadata file
+ * @nilfs: nilfs object
+ * @sb: super block instance the metadata file belongs to
+ * @ino: inode number
+ * @gfp_mask: gfp mask for data pages
+ * @objsz: size of the private object attached to inode->i_private
+ */
 struct inode *
 nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb,
-                    ino_t ino, gfp_t gfp_mask)
+                    ino_t ino, gfp_t gfp_mask, size_t objsz)
 {
        struct inode *inode = nilfs_alloc_inode_common(nilfs);
 
@@ -455,8 +465,9 @@ nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb,
                return NULL;
        else {
                struct address_space * const mapping = &inode->i_data;
-               struct nilfs_mdt_info *mi = kzalloc(sizeof(*mi), GFP_NOFS);
+               struct nilfs_mdt_info *mi;
 
+               mi = kzalloc(max(sizeof(*mi), objsz), GFP_NOFS);
                if (!mi) {
                        nilfs_destroy_inode(inode);
                        return NULL;
@@ -513,11 +524,11 @@ nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb,
 }
 
 struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb,
-                           ino_t ino)
+                           ino_t ino, size_t objsz)
 {
-       struct inode *inode = nilfs_mdt_new_common(nilfs, sb, ino,
-                                                  NILFS_MDT_GFP);
+       struct inode *inode;
 
+       inode = nilfs_mdt_new_common(nilfs, sb, ino, NILFS_MDT_GFP, objsz);
        if (!inode)
                return NULL;
 
@@ -544,14 +555,15 @@ void nilfs_mdt_set_shadow(struct inode *orig, struct inode *shadow)
                &NILFS_I(orig)->i_btnode_cache;
 }
 
-void nilfs_mdt_clear(struct inode *inode)
+static void nilfs_mdt_clear(struct inode *inode)
 {
        struct nilfs_inode_info *ii = NILFS_I(inode);
 
        invalidate_mapping_pages(inode->i_mapping, 0, -1);
        truncate_inode_pages(inode->i_mapping, 0);
 
-       nilfs_bmap_clear(ii->i_bmap);
+       if (test_bit(NILFS_I_BMAP, &ii->i_state))
+               nilfs_bmap_clear(ii->i_bmap);
        nilfs_btnode_cache_clear(&ii->i_btnode_cache);
 }
 
@@ -559,6 +571,10 @@ void nilfs_mdt_destroy(struct inode *inode)
 {
        struct nilfs_mdt_info *mdi = NILFS_MDT(inode);
 
+       if (mdi->mi_palloc_cache)
+               nilfs_palloc_destroy_cache(inode);
+       nilfs_mdt_clear(inode);
+
        kfree(mdi->mi_bgl); /* kfree(NULL) is safe */
        kfree(mdi);
        nilfs_destroy_inode(inode);