]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 14 Sep 2009 21:34:33 +0000 (14:34 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 14 Sep 2009 21:34:33 +0000 (14:34 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2: (21 commits)
  fs/Kconfig: move nilfs2 outside misc filesystems
  nilfs2: convert nilfs_bmap_lookup to an inline function
  nilfs2: allow btree code to directly call dat operations
  nilfs2: add update functions of virtual block address to dat
  nilfs2: remove individual gfp constants for each metadata file
  nilfs2: stop zero-fill of btree path just before free it
  nilfs2: remove unused btree argument from btree functions
  nilfs2: remove nilfs_dat_abort_start and nilfs_dat_abort_free
  nilfs2: shorten freeze period due to GC in write operation v3
  nilfs2: add more check routines in mount process
  nilfs2: An unassigned variable is assigned to a never used structure member
  nilfs2: use GFP_NOIO for bio_alloc instead of GFP_NOWAIT
  nilfs2: stop using periodic write_super callback
  nilfs2: clean up nilfs_write_super
  nilfs2: fix disorder of nilfs_write_super in nilfs_sync_fs
  nilfs2: remove redundant super block commit
  nilfs2: implement nilfs_show_options to display mount options in /proc/mounts
  nilfs2: always lookup disk block address before reading metadata block
  nilfs2: use semaphore to protect pointer to a writable FS-instance
  nilfs2: fix format string compile warning (ino_t)
  ...

22 files changed:
fs/Kconfig
fs/nilfs2/Kconfig
fs/nilfs2/bmap.c
fs/nilfs2/bmap.h
fs/nilfs2/btree.c
fs/nilfs2/cpfile.c
fs/nilfs2/cpfile.h
fs/nilfs2/dat.c
fs/nilfs2/dat.h
fs/nilfs2/direct.c
fs/nilfs2/ifile.h
fs/nilfs2/inode.c
fs/nilfs2/ioctl.c
fs/nilfs2/mdt.c
fs/nilfs2/mdt.h
fs/nilfs2/recovery.c
fs/nilfs2/segbuf.c
fs/nilfs2/segment.c
fs/nilfs2/sufile.h
fs/nilfs2/super.c
fs/nilfs2/the_nilfs.c
fs/nilfs2/the_nilfs.h

index 0e7da7bb5d9351756f691e4ced2e0df2c56a23f6..455aa207e67e84c0ab97b0e865d099e16b7317ce 100644 (file)
@@ -43,6 +43,7 @@ source "fs/xfs/Kconfig"
 source "fs/gfs2/Kconfig"
 source "fs/ocfs2/Kconfig"
 source "fs/btrfs/Kconfig"
+source "fs/nilfs2/Kconfig"
 
 endif # BLOCK
 
@@ -186,7 +187,6 @@ source "fs/romfs/Kconfig"
 source "fs/sysv/Kconfig"
 source "fs/ufs/Kconfig"
 source "fs/exofs/Kconfig"
-source "fs/nilfs2/Kconfig"
 
 endif # MISC_FILESYSTEMS
 
index 72da095d400980b5ec9599f3343af8004ba3c5e8..251da07b2a1ddab95bbfb1579ceb20845ddf3e6e 100644 (file)
@@ -1,6 +1,6 @@
 config NILFS2_FS
        tristate "NILFS2 file system support (EXPERIMENTAL)"
-       depends on BLOCK && EXPERIMENTAL
+       depends on EXPERIMENTAL
        select CRC32
        help
          NILFS2 is a log-structured file system (LFS) supporting continuous
index 99d58a028b94c3c9698661bac527e14ed2812a72..08834df6ec686911198ab4cc65d91b167109acc1 100644 (file)
@@ -36,6 +36,26 @@ struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap)
        return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode));
 }
 
+/**
+ * nilfs_bmap_lookup_at_level - find a data block or node block
+ * @bmap: bmap
+ * @key: key
+ * @level: level
+ * @ptrp: place to store the value associated to @key
+ *
+ * Description: nilfs_bmap_lookup_at_level() finds a record whose key
+ * matches @key in the block at @level of the bmap.
+ *
+ * Return Value: On success, 0 is returned and the record associated with @key
+ * is stored in the place pointed by @ptrp. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOENT - A record associated with @key does not exist.
+ */
 int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level,
                               __u64 *ptrp)
 {
@@ -69,39 +89,6 @@ int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp,
        return ret;
 }
 
-/**
- * nilfs_bmap_lookup - find a record
- * @bmap: bmap
- * @key: key
- * @recp: pointer to record
- *
- * Description: nilfs_bmap_lookup() finds a record whose key matches @key in
- * @bmap.
- *
- * Return Value: On success, 0 is returned and the record associated with @key
- * is stored in the place pointed by @recp. On error, one of the following
- * negative error codes is returned.
- *
- * %-EIO - I/O error.
- *
- * %-ENOMEM - Insufficient amount of memory available.
- *
- * %-ENOENT - A record associated with @key does not exist.
- */
-int nilfs_bmap_lookup(struct nilfs_bmap *bmap,
-                     unsigned long key,
-                     unsigned long *recp)
-{
-       __u64 ptr;
-       int ret;
-
-       /* XXX: use macro for level 1 */
-       ret = nilfs_bmap_lookup_at_level(bmap, key, 1, &ptr);
-       if (recp != NULL)
-               *recp = ptr;
-       return ret;
-}
-
 static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
 {
        __u64 keys[NILFS_BMAP_SMALL_HIGH + 1];
@@ -469,104 +456,6 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
                (entries_per_group / NILFS_BMAP_GROUP_DIV);
 }
 
-int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *bmap,
-                                union nilfs_bmap_ptr_req *req)
-{
-       return nilfs_dat_prepare_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
-}
-
-void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *bmap,
-                                union nilfs_bmap_ptr_req *req)
-{
-       nilfs_dat_commit_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
-}
-
-void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *bmap,
-                             union nilfs_bmap_ptr_req *req)
-{
-       nilfs_dat_abort_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
-}
-
-int nilfs_bmap_start_v(struct nilfs_bmap *bmap, union nilfs_bmap_ptr_req *req,
-                      sector_t blocknr)
-{
-       struct inode *dat = nilfs_bmap_get_dat(bmap);
-       int ret;
-
-       ret = nilfs_dat_prepare_start(dat, &req->bpr_req);
-       if (likely(!ret))
-               nilfs_dat_commit_start(dat, &req->bpr_req, blocknr);
-       return ret;
-}
-
-int nilfs_bmap_prepare_end_v(struct nilfs_bmap *bmap,
-                            union nilfs_bmap_ptr_req *req)
-{
-       return nilfs_dat_prepare_end(nilfs_bmap_get_dat(bmap), &req->bpr_req);
-}
-
-void nilfs_bmap_commit_end_v(struct nilfs_bmap *bmap,
-                            union nilfs_bmap_ptr_req *req)
-{
-       nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req,
-                            bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
-}
-
-void nilfs_bmap_abort_end_v(struct nilfs_bmap *bmap,
-                           union nilfs_bmap_ptr_req *req)
-{
-       nilfs_dat_abort_end(nilfs_bmap_get_dat(bmap), &req->bpr_req);
-}
-
-int nilfs_bmap_move_v(const struct nilfs_bmap *bmap, __u64 vblocknr,
-                     sector_t blocknr)
-{
-       return nilfs_dat_move(nilfs_bmap_get_dat(bmap), vblocknr, blocknr);
-}
-
-int nilfs_bmap_mark_dirty(const struct nilfs_bmap *bmap, __u64 vblocknr)
-{
-       return nilfs_dat_mark_dirty(nilfs_bmap_get_dat(bmap), vblocknr);
-}
-
-int nilfs_bmap_prepare_update_v(struct nilfs_bmap *bmap,
-                               union nilfs_bmap_ptr_req *oldreq,
-                               union nilfs_bmap_ptr_req *newreq)
-{
-       struct inode *dat = nilfs_bmap_get_dat(bmap);
-       int ret;
-
-       ret = nilfs_dat_prepare_end(dat, &oldreq->bpr_req);
-       if (ret < 0)
-               return ret;
-       ret = nilfs_dat_prepare_alloc(dat, &newreq->bpr_req);
-       if (ret < 0)
-               nilfs_dat_abort_end(dat, &oldreq->bpr_req);
-
-       return ret;
-}
-
-void nilfs_bmap_commit_update_v(struct nilfs_bmap *bmap,
-                               union nilfs_bmap_ptr_req *oldreq,
-                               union nilfs_bmap_ptr_req *newreq)
-{
-       struct inode *dat = nilfs_bmap_get_dat(bmap);
-
-       nilfs_dat_commit_end(dat, &oldreq->bpr_req,
-                            bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
-       nilfs_dat_commit_alloc(dat, &newreq->bpr_req);
-}
-
-void nilfs_bmap_abort_update_v(struct nilfs_bmap *bmap,
-                              union nilfs_bmap_ptr_req *oldreq,
-                              union nilfs_bmap_ptr_req *newreq)
-{
-       struct inode *dat = nilfs_bmap_get_dat(bmap);
-
-       nilfs_dat_abort_end(dat, &oldreq->bpr_req);
-       nilfs_dat_abort_alloc(dat, &newreq->bpr_req);
-}
-
 static struct lock_class_key nilfs_bmap_dat_lock_key;
 static struct lock_class_key nilfs_bmap_mdt_lock_key;
 
index b2890cdcef124883c8993d54f14a71c23c61863c..9980d7dbab9122c352b500bf813264a061f45b51 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/buffer_head.h>
 #include <linux/nilfs2_fs.h>
 #include "alloc.h"
+#include "dat.h"
 
 #define NILFS_BMAP_INVALID_PTR 0
 
@@ -141,7 +142,6 @@ struct nilfs_bmap {
 int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *);
 int nilfs_bmap_read(struct nilfs_bmap *, struct nilfs_inode *);
 void nilfs_bmap_write(struct nilfs_bmap *, struct nilfs_inode *);
-int nilfs_bmap_lookup(struct nilfs_bmap *, unsigned long, unsigned long *);
 int nilfs_bmap_lookup_contig(struct nilfs_bmap *, __u64, __u64 *, unsigned);
 int nilfs_bmap_insert(struct nilfs_bmap *, unsigned long, unsigned long);
 int nilfs_bmap_delete(struct nilfs_bmap *, unsigned long);
@@ -160,90 +160,76 @@ void nilfs_bmap_init_gcdat(struct nilfs_bmap *, struct nilfs_bmap *);
 void nilfs_bmap_commit_gcdat(struct nilfs_bmap *, struct nilfs_bmap *);
 
 
+static inline int nilfs_bmap_lookup(struct nilfs_bmap *bmap, __u64 key,
+                                   __u64 *ptr)
+{
+       return nilfs_bmap_lookup_at_level(bmap, key, 1, ptr);
+}
+
 /*
  * Internal use only
  */
 struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *);
-int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *,
-                              union nilfs_bmap_ptr_req *);
-void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *,
-                              union nilfs_bmap_ptr_req *);
-void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *,
-                             union nilfs_bmap_ptr_req *);
 
 static inline int nilfs_bmap_prepare_alloc_ptr(struct nilfs_bmap *bmap,
-                                              union nilfs_bmap_ptr_req *req)
+                                              union nilfs_bmap_ptr_req *req,
+                                              struct inode *dat)
 {
-       if (NILFS_BMAP_USE_VBN(bmap))
-               return nilfs_bmap_prepare_alloc_v(bmap, req);
+       if (dat)
+               return nilfs_dat_prepare_alloc(dat, &req->bpr_req);
        /* ignore target ptr */
        req->bpr_ptr = bmap->b_last_allocated_ptr++;
        return 0;
 }
 
 static inline void nilfs_bmap_commit_alloc_ptr(struct nilfs_bmap *bmap,
-                                              union nilfs_bmap_ptr_req *req)
+                                              union nilfs_bmap_ptr_req *req,
+                                              struct inode *dat)
 {
-       if (NILFS_BMAP_USE_VBN(bmap))
-               nilfs_bmap_commit_alloc_v(bmap, req);
+       if (dat)
+               nilfs_dat_commit_alloc(dat, &req->bpr_req);
 }
 
 static inline void nilfs_bmap_abort_alloc_ptr(struct nilfs_bmap *bmap,
-                                             union nilfs_bmap_ptr_req *req)
+                                             union nilfs_bmap_ptr_req *req,
+                                             struct inode *dat)
 {
-       if (NILFS_BMAP_USE_VBN(bmap))
-               nilfs_bmap_abort_alloc_v(bmap, req);
+       if (dat)
+               nilfs_dat_abort_alloc(dat, &req->bpr_req);
        else
                bmap->b_last_allocated_ptr--;
 }
 
-int nilfs_bmap_prepare_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *);
-void nilfs_bmap_commit_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *);
-void nilfs_bmap_abort_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *);
-
 static inline int nilfs_bmap_prepare_end_ptr(struct nilfs_bmap *bmap,
-                                            union nilfs_bmap_ptr_req *req)
+                                            union nilfs_bmap_ptr_req *req,
+                                            struct inode *dat)
 {
-       return NILFS_BMAP_USE_VBN(bmap) ?
-               nilfs_bmap_prepare_end_v(bmap, req) : 0;
+       return dat ? nilfs_dat_prepare_end(dat, &req->bpr_req) : 0;
 }
 
 static inline void nilfs_bmap_commit_end_ptr(struct nilfs_bmap *bmap,
-                                            union nilfs_bmap_ptr_req *req)
+                                            union nilfs_bmap_ptr_req *req,
+                                            struct inode *dat)
 {
-       if (NILFS_BMAP_USE_VBN(bmap))
-               nilfs_bmap_commit_end_v(bmap, req);
+       if (dat)
+               nilfs_dat_commit_end(dat, &req->bpr_req,
+                                    bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
 }
 
 static inline void nilfs_bmap_abort_end_ptr(struct nilfs_bmap *bmap,
-                                           union nilfs_bmap_ptr_req *req)
+                                           union nilfs_bmap_ptr_req *req,
+                                           struct inode *dat)
 {
-       if (NILFS_BMAP_USE_VBN(bmap))
-               nilfs_bmap_abort_end_v(bmap, req);
+       if (dat)
+               nilfs_dat_abort_end(dat, &req->bpr_req);
 }
 
-int nilfs_bmap_start_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *,
-                      sector_t);
-int nilfs_bmap_move_v(const struct nilfs_bmap *, __u64, sector_t);
-int nilfs_bmap_mark_dirty(const struct nilfs_bmap *, __u64);
-
-
 __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *,
                              const struct buffer_head *);
 
 __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *, __u64);
 __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *);
 
-int nilfs_bmap_prepare_update_v(struct nilfs_bmap *,
-                               union nilfs_bmap_ptr_req *,
-                               union nilfs_bmap_ptr_req *);
-void nilfs_bmap_commit_update_v(struct nilfs_bmap *,
-                               union nilfs_bmap_ptr_req *,
-                               union nilfs_bmap_ptr_req *);
-void nilfs_bmap_abort_update_v(struct nilfs_bmap *,
-                              union nilfs_bmap_ptr_req *,
-                              union nilfs_bmap_ptr_req *);
-
 void nilfs_bmap_add_blocks(const struct nilfs_bmap *, int);
 void nilfs_bmap_sub_blocks(const struct nilfs_bmap *, int);
 
index aa412724b64eb41ab297c029b166ea3849de4710..e25b507a474fc46c30f2ae84d2c5fb1521a0dbb3 100644 (file)
@@ -71,21 +71,17 @@ void nilfs_btree_path_cache_destroy(void)
        kmem_cache_destroy(nilfs_btree_path_cache);
 }
 
-static inline struct nilfs_btree_path *
-nilfs_btree_alloc_path(const struct nilfs_btree *btree)
+static inline struct nilfs_btree_path *nilfs_btree_alloc_path(void)
 {
-       return (struct nilfs_btree_path *)
-               kmem_cache_alloc(nilfs_btree_path_cache, GFP_NOFS);
+       return kmem_cache_alloc(nilfs_btree_path_cache, GFP_NOFS);
 }
 
-static inline void nilfs_btree_free_path(const struct nilfs_btree *btree,
-                                        struct nilfs_btree_path *path)
+static inline void nilfs_btree_free_path(struct nilfs_btree_path *path)
 {
        kmem_cache_free(nilfs_btree_path_cache, path);
 }
 
-static void nilfs_btree_init_path(const struct nilfs_btree *btree,
-                                 struct nilfs_btree_path *path)
+static void nilfs_btree_init_path(struct nilfs_btree_path *path)
 {
        int level;
 
@@ -101,26 +97,13 @@ static void nilfs_btree_init_path(const struct nilfs_btree *btree,
        }
 }
 
-static void nilfs_btree_clear_path(const struct nilfs_btree *btree,
-                                  struct nilfs_btree_path *path)
+static void nilfs_btree_release_path(struct nilfs_btree_path *path)
 {
        int level;
 
-       for (level = NILFS_BTREE_LEVEL_DATA;
-            level < NILFS_BTREE_LEVEL_MAX;
-            level++) {
-               if (path[level].bp_bh != NULL) {
-                       brelse(path[level].bp_bh);
-                       path[level].bp_bh = NULL;
-               }
-               /* sib_bh is released or deleted by prepare or commit
-                * operations. */
-               path[level].bp_sib_bh = NULL;
-               path[level].bp_index = 0;
-               path[level].bp_oldreq.bpr_ptr = NILFS_BMAP_INVALID_PTR;
-               path[level].bp_newreq.bpr_ptr = NILFS_BMAP_INVALID_PTR;
-               path[level].bp_op = NULL;
-       }
+       for (level = NILFS_BTREE_LEVEL_DATA; level < NILFS_BTREE_LEVEL_MAX;
+            level++)
+               brelse(path[level].bp_bh);
 }
 
 /*
@@ -148,129 +131,110 @@ static int nilfs_btree_get_new_block(const struct nilfs_btree *btree,
 }
 
 static inline int
-nilfs_btree_node_get_flags(const struct nilfs_btree *btree,
-                          const struct nilfs_btree_node *node)
+nilfs_btree_node_get_flags(const struct nilfs_btree_node *node)
 {
        return node->bn_flags;
 }
 
 static inline void
-nilfs_btree_node_set_flags(struct nilfs_btree *btree,
-                          struct nilfs_btree_node *node,
-                          int flags)
+nilfs_btree_node_set_flags(struct nilfs_btree_node *node, int flags)
 {
        node->bn_flags = flags;
 }
 
-static inline int nilfs_btree_node_root(const struct nilfs_btree *btree,
-                                       const struct nilfs_btree_node *node)
+static inline int nilfs_btree_node_root(const struct nilfs_btree_node *node)
 {
-       return nilfs_btree_node_get_flags(btree, node) & NILFS_BTREE_NODE_ROOT;
+       return nilfs_btree_node_get_flags(node) & NILFS_BTREE_NODE_ROOT;
 }
 
 static inline int
-nilfs_btree_node_get_level(const struct nilfs_btree *btree,
-                          const struct nilfs_btree_node *node)
+nilfs_btree_node_get_level(const struct nilfs_btree_node *node)
 {
        return node->bn_level;
 }
 
 static inline void
-nilfs_btree_node_set_level(struct nilfs_btree *btree,
-                          struct nilfs_btree_node *node,
-                          int level)
+nilfs_btree_node_set_level(struct nilfs_btree_node *node, int level)
 {
        node->bn_level = level;
 }
 
 static inline int
-nilfs_btree_node_get_nchildren(const struct nilfs_btree *btree,
-                              const struct nilfs_btree_node *node)
+nilfs_btree_node_get_nchildren(const struct nilfs_btree_node *node)
 {
        return le16_to_cpu(node->bn_nchildren);
 }
 
 static inline void
-nilfs_btree_node_set_nchildren(struct nilfs_btree *btree,
-                              struct nilfs_btree_node *node,
-                              int nchildren)
+nilfs_btree_node_set_nchildren(struct nilfs_btree_node *node, int nchildren)
 {
        node->bn_nchildren = cpu_to_le16(nchildren);
 }
 
-static inline int
-nilfs_btree_node_size(const struct nilfs_btree *btree)
+static inline int nilfs_btree_node_size(const struct nilfs_btree *btree)
 {
        return 1 << btree->bt_bmap.b_inode->i_blkbits;
 }
 
 static inline int
-nilfs_btree_node_nchildren_min(const struct nilfs_btree *btree,
-                              const struct nilfs_btree_node *node)
+nilfs_btree_node_nchildren_min(const struct nilfs_btree_node *node,
+                              const struct nilfs_btree *btree)
 {
-       return nilfs_btree_node_root(btree, node) ?
+       return nilfs_btree_node_root(node) ?
                NILFS_BTREE_ROOT_NCHILDREN_MIN :
                NILFS_BTREE_NODE_NCHILDREN_MIN(nilfs_btree_node_size(btree));
 }
 
 static inline int
-nilfs_btree_node_nchildren_max(const struct nilfs_btree *btree,
-                              const struct nilfs_btree_node *node)
+nilfs_btree_node_nchildren_max(const struct nilfs_btree_node *node,
+                              const struct nilfs_btree *btree)
 {
-       return nilfs_btree_node_root(btree, node) ?
+       return nilfs_btree_node_root(node) ?
                NILFS_BTREE_ROOT_NCHILDREN_MAX :
                NILFS_BTREE_NODE_NCHILDREN_MAX(nilfs_btree_node_size(btree));
 }
 
 static inline __le64 *
-nilfs_btree_node_dkeys(const struct nilfs_btree *btree,
-                      const struct nilfs_btree_node *node)
+nilfs_btree_node_dkeys(const struct nilfs_btree_node *node)
 {
        return (__le64 *)((char *)(node + 1) +
-                         (nilfs_btree_node_root(btree, node) ?
+                         (nilfs_btree_node_root(node) ?
                           0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE));
 }
 
 static inline __le64 *
-nilfs_btree_node_dptrs(const struct nilfs_btree *btree,
-                      const struct nilfs_btree_node *node)
+nilfs_btree_node_dptrs(const struct nilfs_btree_node *node,
+                      const struct nilfs_btree *btree)
 {
-       return (__le64 *)(nilfs_btree_node_dkeys(btree, node) +
-                         nilfs_btree_node_nchildren_max(btree, node));
+       return (__le64 *)(nilfs_btree_node_dkeys(node) +
+                         nilfs_btree_node_nchildren_max(node, btree));
 }
 
 static inline __u64
-nilfs_btree_node_get_key(const struct nilfs_btree *btree,
-                        const struct nilfs_btree_node *node, int index)
+nilfs_btree_node_get_key(const struct nilfs_btree_node *node, int index)
 {
-       return nilfs_bmap_dkey_to_key(*(nilfs_btree_node_dkeys(btree, node) +
-                                       index));
+       return nilfs_bmap_dkey_to_key(*(nilfs_btree_node_dkeys(node) + index));
 }
 
 static inline void
-nilfs_btree_node_set_key(struct nilfs_btree *btree,
-                        struct nilfs_btree_node *node, int index, __u64 key)
+nilfs_btree_node_set_key(struct nilfs_btree_node *node, int index, __u64 key)
 {
-       *(nilfs_btree_node_dkeys(btree, node) + index) =
-               nilfs_bmap_key_to_dkey(key);
+       *(nilfs_btree_node_dkeys(node) + index) = nilfs_bmap_key_to_dkey(key);
 }
 
 static inline __u64
 nilfs_btree_node_get_ptr(const struct nilfs_btree *btree,
-                        const struct nilfs_btree_node *node,
-                        int index)
+                        const struct nilfs_btree_node *node, int index)
 {
-       return nilfs_bmap_dptr_to_ptr(*(nilfs_btree_node_dptrs(btree, node) +
+       return nilfs_bmap_dptr_to_ptr(*(nilfs_btree_node_dptrs(node, btree) +
                                        index));
 }
 
 static inline void
 nilfs_btree_node_set_ptr(struct nilfs_btree *btree,
-                        struct nilfs_btree_node *node,
-                        int index,
-                        __u64 ptr)
+                        struct nilfs_btree_node *node, int index, __u64 ptr)
 {
-       *(nilfs_btree_node_dptrs(btree, node) + index) =
+       *(nilfs_btree_node_dptrs(node, btree) + index) =
                nilfs_bmap_ptr_to_dptr(ptr);
 }
 
@@ -283,12 +247,12 @@ static void nilfs_btree_node_init(struct nilfs_btree *btree,
        __le64 *dptrs;
        int i;
 
-       nilfs_btree_node_set_flags(btree, node, flags);
-       nilfs_btree_node_set_level(btree, node, level);
-       nilfs_btree_node_set_nchildren(btree, node, nchildren);
+       nilfs_btree_node_set_flags(node, flags);
+       nilfs_btree_node_set_level(node, level);
+       nilfs_btree_node_set_nchildren(node, nchildren);
 
-       dkeys = nilfs_btree_node_dkeys(btree, node);
-       dptrs = nilfs_btree_node_dptrs(btree, node);
+       dkeys = nilfs_btree_node_dkeys(node);
+       dptrs = nilfs_btree_node_dptrs(node, btree);
        for (i = 0; i < nchildren; i++) {
                dkeys[i] = nilfs_bmap_key_to_dkey(keys[i]);
                dptrs[i] = nilfs_bmap_ptr_to_dptr(ptrs[i]);
@@ -305,13 +269,13 @@ static void nilfs_btree_node_move_left(struct nilfs_btree *btree,
        __le64 *ldptrs, *rdptrs;
        int lnchildren, rnchildren;
 
-       ldkeys = nilfs_btree_node_dkeys(btree, left);
-       ldptrs = nilfs_btree_node_dptrs(btree, left);
-       lnchildren = nilfs_btree_node_get_nchildren(btree, left);
+       ldkeys = nilfs_btree_node_dkeys(left);
+       ldptrs = nilfs_btree_node_dptrs(left, btree);
+       lnchildren = nilfs_btree_node_get_nchildren(left);
 
-       rdkeys = nilfs_btree_node_dkeys(btree, right);
-       rdptrs = nilfs_btree_node_dptrs(btree, right);
-       rnchildren = nilfs_btree_node_get_nchildren(btree, right);
+       rdkeys = nilfs_btree_node_dkeys(right);
+       rdptrs = nilfs_btree_node_dptrs(right, btree);
+       rnchildren = nilfs_btree_node_get_nchildren(right);
 
        memcpy(ldkeys + lnchildren, rdkeys, n * sizeof(*rdkeys));
        memcpy(ldptrs + lnchildren, rdptrs, n * sizeof(*rdptrs));
@@ -320,8 +284,8 @@ static void nilfs_btree_node_move_left(struct nilfs_btree *btree,
 
        lnchildren += n;
        rnchildren -= n;
-       nilfs_btree_node_set_nchildren(btree, left, lnchildren);
-       nilfs_btree_node_set_nchildren(btree, right, rnchildren);
+       nilfs_btree_node_set_nchildren(left, lnchildren);
+       nilfs_btree_node_set_nchildren(right, rnchildren);
 }
 
 /* Assume that the buffer heads corresponding to left and right are locked. */
@@ -334,13 +298,13 @@ static void nilfs_btree_node_move_right(struct nilfs_btree *btree,
        __le64 *ldptrs, *rdptrs;
        int lnchildren, rnchildren;
 
-       ldkeys = nilfs_btree_node_dkeys(btree, left);
-       ldptrs = nilfs_btree_node_dptrs(btree, left);
-       lnchildren = nilfs_btree_node_get_nchildren(btree, left);
+       ldkeys = nilfs_btree_node_dkeys(left);
+       ldptrs = nilfs_btree_node_dptrs(left, btree);
+       lnchildren = nilfs_btree_node_get_nchildren(left);
 
-       rdkeys = nilfs_btree_node_dkeys(btree, right);
-       rdptrs = nilfs_btree_node_dptrs(btree, right);
-       rnchildren = nilfs_btree_node_get_nchildren(btree, right);
+       rdkeys = nilfs_btree_node_dkeys(right);
+       rdptrs = nilfs_btree_node_dptrs(right, btree);
+       rnchildren = nilfs_btree_node_get_nchildren(right);
 
        memmove(rdkeys + n, rdkeys, rnchildren * sizeof(*rdkeys));
        memmove(rdptrs + n, rdptrs, rnchildren * sizeof(*rdptrs));
@@ -349,8 +313,8 @@ static void nilfs_btree_node_move_right(struct nilfs_btree *btree,
 
        lnchildren -= n;
        rnchildren += n;
-       nilfs_btree_node_set_nchildren(btree, left, lnchildren);
-       nilfs_btree_node_set_nchildren(btree, right, rnchildren);
+       nilfs_btree_node_set_nchildren(left, lnchildren);
+       nilfs_btree_node_set_nchildren(right, rnchildren);
 }
 
 /* Assume that the buffer head corresponding to node is locked. */
@@ -362,9 +326,9 @@ static void nilfs_btree_node_insert(struct nilfs_btree *btree,
        __le64 *dptrs;
        int nchildren;
 
-       dkeys = nilfs_btree_node_dkeys(btree, node);
-       dptrs = nilfs_btree_node_dptrs(btree, node);
-       nchildren = nilfs_btree_node_get_nchildren(btree, node);
+       dkeys = nilfs_btree_node_dkeys(node);
+       dptrs = nilfs_btree_node_dptrs(node, btree);
+       nchildren = nilfs_btree_node_get_nchildren(node);
        if (index < nchildren) {
                memmove(dkeys + index + 1, dkeys + index,
                        (nchildren - index) * sizeof(*dkeys));
@@ -374,7 +338,7 @@ static void nilfs_btree_node_insert(struct nilfs_btree *btree,
        dkeys[index] = nilfs_bmap_key_to_dkey(key);
        dptrs[index] = nilfs_bmap_ptr_to_dptr(ptr);
        nchildren++;
-       nilfs_btree_node_set_nchildren(btree, node, nchildren);
+       nilfs_btree_node_set_nchildren(node, nchildren);
 }
 
 /* Assume that the buffer head corresponding to node is locked. */
@@ -388,11 +352,11 @@ static void nilfs_btree_node_delete(struct nilfs_btree *btree,
        __le64 *dptrs;
        int nchildren;
 
-       dkeys = nilfs_btree_node_dkeys(btree, node);
-       dptrs = nilfs_btree_node_dptrs(btree, node);
+       dkeys = nilfs_btree_node_dkeys(node);
+       dptrs = nilfs_btree_node_dptrs(node, btree);
        key = nilfs_bmap_dkey_to_key(dkeys[index]);
        ptr = nilfs_bmap_dptr_to_ptr(dptrs[index]);
-       nchildren = nilfs_btree_node_get_nchildren(btree, node);
+       nchildren = nilfs_btree_node_get_nchildren(node);
        if (keyp != NULL)
                *keyp = key;
        if (ptrp != NULL)
@@ -405,11 +369,10 @@ static void nilfs_btree_node_delete(struct nilfs_btree *btree,
                        (nchildren - index - 1) * sizeof(*dptrs));
        }
        nchildren--;
-       nilfs_btree_node_set_nchildren(btree, node, nchildren);
+       nilfs_btree_node_set_nchildren(node, nchildren);
 }
 
-static int nilfs_btree_node_lookup(const struct nilfs_btree *btree,
-                                  const struct nilfs_btree_node *node,
+static int nilfs_btree_node_lookup(const struct nilfs_btree_node *node,
                                   __u64 key, int *indexp)
 {
        __u64 nkey;
@@ -417,12 +380,12 @@ static int nilfs_btree_node_lookup(const struct nilfs_btree *btree,
 
        /* binary search */
        low = 0;
-       high = nilfs_btree_node_get_nchildren(btree, node) - 1;
+       high = nilfs_btree_node_get_nchildren(node) - 1;
        index = 0;
        s = 0;
        while (low <= high) {
                index = (low + high) / 2;
-               nkey = nilfs_btree_node_get_key(btree, node, index);
+               nkey = nilfs_btree_node_get_key(node, index);
                if (nkey == key) {
                        s = 0;
                        goto out;
@@ -436,9 +399,8 @@ static int nilfs_btree_node_lookup(const struct nilfs_btree *btree,
        }
 
        /* adjust index */
-       if (nilfs_btree_node_get_level(btree, node) >
-           NILFS_BTREE_LEVEL_NODE_MIN) {
-               if ((s > 0) && (index > 0))
+       if (nilfs_btree_node_get_level(node) > NILFS_BTREE_LEVEL_NODE_MIN) {
+               if (s > 0 && index > 0)
                        index--;
        } else if (s < 0)
                index++;
@@ -456,25 +418,20 @@ nilfs_btree_get_root(const struct nilfs_btree *btree)
 }
 
 static inline struct nilfs_btree_node *
-nilfs_btree_get_nonroot_node(const struct nilfs_btree *btree,
-                            const struct nilfs_btree_path *path,
-                            int level)
+nilfs_btree_get_nonroot_node(const struct nilfs_btree_path *path, int level)
 {
        return (struct nilfs_btree_node *)path[level].bp_bh->b_data;
 }
 
 static inline struct nilfs_btree_node *
-nilfs_btree_get_sib_node(const struct nilfs_btree *btree,
-                        const struct nilfs_btree_path *path,
-                        int level)
+nilfs_btree_get_sib_node(const struct nilfs_btree_path *path, int level)
 {
        return (struct nilfs_btree_node *)path[level].bp_sib_bh->b_data;
 }
 
 static inline int nilfs_btree_height(const struct nilfs_btree *btree)
 {
-       return nilfs_btree_node_get_level(btree, nilfs_btree_get_root(btree))
-               + 1;
+       return nilfs_btree_node_get_level(nilfs_btree_get_root(btree)) + 1;
 }
 
 static inline struct nilfs_btree_node *
@@ -484,7 +441,7 @@ nilfs_btree_get_node(const struct nilfs_btree *btree,
 {
        return (level == nilfs_btree_height(btree) - 1) ?
                nilfs_btree_get_root(btree) :
-               nilfs_btree_get_nonroot_node(btree, path, level);
+               nilfs_btree_get_nonroot_node(path, level);
 }
 
 static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
@@ -496,12 +453,11 @@ static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
        int level, index, found, ret;
 
        node = nilfs_btree_get_root(btree);
-       level = nilfs_btree_node_get_level(btree, node);
-       if ((level < minlevel) ||
-           (nilfs_btree_node_get_nchildren(btree, node) <= 0))
+       level = nilfs_btree_node_get_level(node);
+       if (level < minlevel || nilfs_btree_node_get_nchildren(node) <= 0)
                return -ENOENT;
 
-       found = nilfs_btree_node_lookup(btree, node, key, &index);
+       found = nilfs_btree_node_lookup(node, key, &index);
        ptr = nilfs_btree_node_get_ptr(btree, node, index);
        path[level].bp_bh = NULL;
        path[level].bp_index = index;
@@ -510,14 +466,13 @@ static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
                ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh);
                if (ret < 0)
                        return ret;
-               node = nilfs_btree_get_nonroot_node(btree, path, level);
-               BUG_ON(level != nilfs_btree_node_get_level(btree, node));
+               node = nilfs_btree_get_nonroot_node(path, level);
+               BUG_ON(level != nilfs_btree_node_get_level(node));
                if (!found)
-                       found = nilfs_btree_node_lookup(btree, node, key,
-                                                       &index);
+                       found = nilfs_btree_node_lookup(node, key, &index);
                else
                        index = 0;
-               if (index < nilfs_btree_node_nchildren_max(btree, node))
+               if (index < nilfs_btree_node_nchildren_max(node, btree))
                        ptr = nilfs_btree_node_get_ptr(btree, node, index);
                else {
                        WARN_ON(found || level != NILFS_BTREE_LEVEL_NODE_MIN);
@@ -544,10 +499,10 @@ static int nilfs_btree_do_lookup_last(const struct nilfs_btree *btree,
        int index, level, ret;
 
        node = nilfs_btree_get_root(btree);
-       index = nilfs_btree_node_get_nchildren(btree, node) - 1;
+       index = nilfs_btree_node_get_nchildren(node) - 1;
        if (index < 0)
                return -ENOENT;
-       level = nilfs_btree_node_get_level(btree, node);
+       level = nilfs_btree_node_get_level(node);
        ptr = nilfs_btree_node_get_ptr(btree, node, index);
        path[level].bp_bh = NULL;
        path[level].bp_index = index;
@@ -556,15 +511,15 @@ static int nilfs_btree_do_lookup_last(const struct nilfs_btree *btree,
                ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh);
                if (ret < 0)
                        return ret;
-               node = nilfs_btree_get_nonroot_node(btree, path, level);
-               BUG_ON(level != nilfs_btree_node_get_level(btree, node));
-               index = nilfs_btree_node_get_nchildren(btree, node) - 1;
+               node = nilfs_btree_get_nonroot_node(path, level);
+               BUG_ON(level != nilfs_btree_node_get_level(node));
+               index = nilfs_btree_node_get_nchildren(node) - 1;
                ptr = nilfs_btree_node_get_ptr(btree, node, index);
                path[level].bp_index = index;
        }
 
        if (keyp != NULL)
-               *keyp = nilfs_btree_node_get_key(btree, node, index);
+               *keyp = nilfs_btree_node_get_key(node, index);
        if (ptrp != NULL)
                *ptrp = ptr;
 
@@ -580,18 +535,18 @@ static int nilfs_btree_lookup(const struct nilfs_bmap *bmap,
        int ret;
 
        btree = (struct nilfs_btree *)bmap;
-       path = nilfs_btree_alloc_path(btree);
+       path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(btree, path);
+       nilfs_btree_init_path(path);
 
        ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level);
 
        if (ptrp != NULL)
                *ptrp = ptr;
 
-       nilfs_btree_clear_path(btree, path);
-       nilfs_btree_free_path(btree, path);
+       nilfs_btree_release_path(path);
+       nilfs_btree_free_path(path);
 
        return ret;
 }
@@ -608,10 +563,10 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
        int level = NILFS_BTREE_LEVEL_NODE_MIN;
        int ret, cnt, index, maxlevel;
 
-       path = nilfs_btree_alloc_path(btree);
+       path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(btree, path);
+       nilfs_btree_init_path(path);
        ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level);
        if (ret < 0)
                goto out;
@@ -631,8 +586,8 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
        node = nilfs_btree_get_node(btree, path, level);
        index = path[level].bp_index + 1;
        for (;;) {
-               while (index < nilfs_btree_node_get_nchildren(btree, node)) {
-                       if (nilfs_btree_node_get_key(btree, node, index) !=
+               while (index < nilfs_btree_node_get_nchildren(node)) {
+                       if (nilfs_btree_node_get_key(node, index) !=
                            key + cnt)
                                goto end;
                        ptr2 = nilfs_btree_node_get_ptr(btree, node, index);
@@ -653,8 +608,8 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
                /* look-up right sibling node */
                node = nilfs_btree_get_node(btree, path, level + 1);
                index = path[level + 1].bp_index + 1;
-               if (index >= nilfs_btree_node_get_nchildren(btree, node) ||
-                   nilfs_btree_node_get_key(btree, node, index) != key + cnt)
+               if (index >= nilfs_btree_node_get_nchildren(node) ||
+                   nilfs_btree_node_get_key(node, index) != key + cnt)
                        break;
                ptr2 = nilfs_btree_node_get_ptr(btree, node, index);
                path[level + 1].bp_index = index;
@@ -664,7 +619,7 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
                ret = nilfs_btree_get_block(btree, ptr2, &path[level].bp_bh);
                if (ret < 0)
                        goto out;
-               node = nilfs_btree_get_nonroot_node(btree, path, level);
+               node = nilfs_btree_get_nonroot_node(path, level);
                index = 0;
                path[level].bp_index = index;
        }
@@ -672,8 +627,8 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
        *ptrp = ptr;
        ret = cnt;
  out:
-       nilfs_btree_clear_path(btree, path);
-       nilfs_btree_free_path(btree, path);
+       nilfs_btree_release_path(path);
+       nilfs_btree_free_path(path);
        return ret;
 }
 
@@ -685,9 +640,7 @@ static void nilfs_btree_promote_key(struct nilfs_btree *btree,
                do {
                        lock_buffer(path[level].bp_bh);
                        nilfs_btree_node_set_key(
-                               btree,
-                               nilfs_btree_get_nonroot_node(
-                                       btree, path, level),
+                               nilfs_btree_get_nonroot_node(path, level),
                                path[level].bp_index, key);
                        if (!buffer_dirty(path[level].bp_bh))
                                nilfs_btnode_mark_dirty(path[level].bp_bh);
@@ -698,8 +651,7 @@ static void nilfs_btree_promote_key(struct nilfs_btree *btree,
 
        /* root */
        if (level == nilfs_btree_height(btree) - 1) {
-               nilfs_btree_node_set_key(btree,
-                                        nilfs_btree_get_root(btree),
+               nilfs_btree_node_set_key(nilfs_btree_get_root(btree),
                                         path[level].bp_index, key);
        }
 }
@@ -712,7 +664,7 @@ static void nilfs_btree_do_insert(struct nilfs_btree *btree,
 
        if (level < nilfs_btree_height(btree) - 1) {
                lock_buffer(path[level].bp_bh);
-               node = nilfs_btree_get_nonroot_node(btree, path, level);
+               node = nilfs_btree_get_nonroot_node(path, level);
                nilfs_btree_node_insert(btree, node, *keyp, *ptrp,
                                        path[level].bp_index);
                if (!buffer_dirty(path[level].bp_bh))
@@ -721,8 +673,8 @@ static void nilfs_btree_do_insert(struct nilfs_btree *btree,
 
                if (path[level].bp_index == 0)
                        nilfs_btree_promote_key(btree, path, level + 1,
-                                               nilfs_btree_node_get_key(
-                                                       btree, node, 0));
+                                               nilfs_btree_node_get_key(node,
+                                                                        0));
        } else {
                node = nilfs_btree_get_root(btree);
                nilfs_btree_node_insert(btree, node, *keyp, *ptrp,
@@ -740,10 +692,10 @@ static void nilfs_btree_carry_left(struct nilfs_btree *btree,
        lock_buffer(path[level].bp_bh);
        lock_buffer(path[level].bp_sib_bh);
 
-       node = nilfs_btree_get_nonroot_node(btree, path, level);
-       left = nilfs_btree_get_sib_node(btree, path, level);
-       nchildren = nilfs_btree_node_get_nchildren(btree, node);
-       lnchildren = nilfs_btree_node_get_nchildren(btree, left);
+       node = nilfs_btree_get_nonroot_node(path, level);
+       left = nilfs_btree_get_sib_node(path, level);
+       nchildren = nilfs_btree_node_get_nchildren(node);
+       lnchildren = nilfs_btree_node_get_nchildren(left);
        move = 0;
 
        n = (nchildren + lnchildren + 1) / 2 - lnchildren;
@@ -764,7 +716,7 @@ static void nilfs_btree_carry_left(struct nilfs_btree *btree,
        unlock_buffer(path[level].bp_sib_bh);
 
        nilfs_btree_promote_key(btree, path, level + 1,
-                               nilfs_btree_node_get_key(btree, node, 0));
+                               nilfs_btree_node_get_key(node, 0));
 
        if (move) {
                brelse(path[level].bp_bh);
@@ -791,10 +743,10 @@ static void nilfs_btree_carry_right(struct nilfs_btree *btree,
        lock_buffer(path[level].bp_bh);
        lock_buffer(path[level].bp_sib_bh);
 
-       node = nilfs_btree_get_nonroot_node(btree, path, level);
-       right = nilfs_btree_get_sib_node(btree, path, level);
-       nchildren = nilfs_btree_node_get_nchildren(btree, node);
-       rnchildren = nilfs_btree_node_get_nchildren(btree, right);
+       node = nilfs_btree_get_nonroot_node(path, level);
+       right = nilfs_btree_get_sib_node(path, level);
+       nchildren = nilfs_btree_node_get_nchildren(node);
+       rnchildren = nilfs_btree_node_get_nchildren(right);
        move = 0;
 
        n = (nchildren + rnchildren + 1) / 2 - rnchildren;
@@ -816,15 +768,14 @@ static void nilfs_btree_carry_right(struct nilfs_btree *btree,
 
        path[level + 1].bp_index++;
        nilfs_btree_promote_key(btree, path, level + 1,
-                               nilfs_btree_node_get_key(btree, right, 0));
+                               nilfs_btree_node_get_key(right, 0));
        path[level + 1].bp_index--;
 
        if (move) {
                brelse(path[level].bp_bh);
                path[level].bp_bh = path[level].bp_sib_bh;
                path[level].bp_sib_bh = NULL;
-               path[level].bp_index -=
-                       nilfs_btree_node_get_nchildren(btree, node);
+               path[level].bp_index -= nilfs_btree_node_get_nchildren(node);
                path[level + 1].bp_index++;
        } else {
                brelse(path[level].bp_sib_bh);
@@ -846,9 +797,9 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
        lock_buffer(path[level].bp_bh);
        lock_buffer(path[level].bp_sib_bh);
 
-       node = nilfs_btree_get_nonroot_node(btree, path, level);
-       right = nilfs_btree_get_sib_node(btree, path, level);
-       nchildren = nilfs_btree_node_get_nchildren(btree, node);
+       node = nilfs_btree_get_nonroot_node(path, level);
+       right = nilfs_btree_get_sib_node(path, level);
+       nchildren = nilfs_btree_node_get_nchildren(node);
        move = 0;
 
        n = (nchildren + 1) / 2;
@@ -867,16 +818,15 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
        unlock_buffer(path[level].bp_bh);
        unlock_buffer(path[level].bp_sib_bh);
 
-       newkey = nilfs_btree_node_get_key(btree, right, 0);
+       newkey = nilfs_btree_node_get_key(right, 0);
        newptr = path[level].bp_newreq.bpr_ptr;
 
        if (move) {
-               path[level].bp_index -=
-                       nilfs_btree_node_get_nchildren(btree, node);
+               path[level].bp_index -= nilfs_btree_node_get_nchildren(node);
                nilfs_btree_node_insert(btree, right, *keyp, *ptrp,
                                        path[level].bp_index);
 
-               *keyp = nilfs_btree_node_get_key(btree, right, 0);
+               *keyp = nilfs_btree_node_get_key(right, 0);
                *ptrp = path[level].bp_newreq.bpr_ptr;
 
                brelse(path[level].bp_bh);
@@ -885,7 +835,7 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
        } else {
                nilfs_btree_do_insert(btree, path, level, keyp, ptrp);
 
-               *keyp = nilfs_btree_node_get_key(btree, right, 0);
+               *keyp = nilfs_btree_node_get_key(right, 0);
                *ptrp = path[level].bp_newreq.bpr_ptr;
 
                brelse(path[level].bp_sib_bh);
@@ -905,12 +855,12 @@ static void nilfs_btree_grow(struct nilfs_btree *btree,
        lock_buffer(path[level].bp_sib_bh);
 
        root = nilfs_btree_get_root(btree);
-       child = nilfs_btree_get_sib_node(btree, path, level);
+       child = nilfs_btree_get_sib_node(path, level);
 
-       n = nilfs_btree_node_get_nchildren(btree, root);
+       n = nilfs_btree_node_get_nchildren(root);
 
        nilfs_btree_node_move_right(btree, root, child, n);
-       nilfs_btree_node_set_level(btree, root, level + 1);
+       nilfs_btree_node_set_level(root, level + 1);
 
        if (!buffer_dirty(path[level].bp_sib_bh))
                nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
@@ -922,7 +872,7 @@ static void nilfs_btree_grow(struct nilfs_btree *btree,
 
        nilfs_btree_do_insert(btree, path, level, keyp, ptrp);
 
-       *keyp = nilfs_btree_node_get_key(btree, child, 0);
+       *keyp = nilfs_btree_node_get_key(child, 0);
        *ptrp = path[level].bp_newreq.bpr_ptr;
 }
 
@@ -990,26 +940,29 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
        struct nilfs_btree_node *node, *parent, *sib;
        __u64 sibptr;
        int pindex, level, ret;
+       struct inode *dat = NULL;
 
        stats->bs_nblocks = 0;
        level = NILFS_BTREE_LEVEL_DATA;
 
        /* allocate a new ptr for data block */
-       if (NILFS_BMAP_USE_VBN(&btree->bt_bmap))
+       if (NILFS_BMAP_USE_VBN(&btree->bt_bmap)) {
                path[level].bp_newreq.bpr_ptr =
                        nilfs_btree_find_target_v(btree, path, key);
+               dat = nilfs_bmap_get_dat(&btree->bt_bmap);
+       }
 
        ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
-                                          &path[level].bp_newreq);
+                                          &path[level].bp_newreq, dat);
        if (ret < 0)
                goto err_out_data;
 
        for (level = NILFS_BTREE_LEVEL_NODE_MIN;
             level < nilfs_btree_height(btree) - 1;
             level++) {
-               node = nilfs_btree_get_nonroot_node(btree, path, level);
-               if (nilfs_btree_node_get_nchildren(btree, node) <
-                   nilfs_btree_node_nchildren_max(btree, node)) {
+               node = nilfs_btree_get_nonroot_node(path, level);
+               if (nilfs_btree_node_get_nchildren(node) <
+                   nilfs_btree_node_nchildren_max(node, btree)) {
                        path[level].bp_op = nilfs_btree_do_insert;
                        stats->bs_nblocks++;
                        goto out;
@@ -1026,8 +979,8 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
                        if (ret < 0)
                                goto err_out_child_node;
                        sib = (struct nilfs_btree_node *)bh->b_data;
-                       if (nilfs_btree_node_get_nchildren(btree, sib) <
-                           nilfs_btree_node_nchildren_max(btree, sib)) {
+                       if (nilfs_btree_node_get_nchildren(sib) <
+                           nilfs_btree_node_nchildren_max(sib, btree)) {
                                path[level].bp_sib_bh = bh;
                                path[level].bp_op = nilfs_btree_carry_left;
                                stats->bs_nblocks++;
@@ -1038,15 +991,15 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
 
                /* right sibling */
                if (pindex <
-                   nilfs_btree_node_get_nchildren(btree, parent) - 1) {
+                   nilfs_btree_node_get_nchildren(parent) - 1) {
                        sibptr = nilfs_btree_node_get_ptr(btree, parent,
                                                          pindex + 1);
                        ret = nilfs_btree_get_block(btree, sibptr, &bh);
                        if (ret < 0)
                                goto err_out_child_node;
                        sib = (struct nilfs_btree_node *)bh->b_data;
-                       if (nilfs_btree_node_get_nchildren(btree, sib) <
-                           nilfs_btree_node_nchildren_max(btree, sib)) {
+                       if (nilfs_btree_node_get_nchildren(sib) <
+                           nilfs_btree_node_nchildren_max(sib, btree)) {
                                path[level].bp_sib_bh = bh;
                                path[level].bp_op = nilfs_btree_carry_right;
                                stats->bs_nblocks++;
@@ -1059,7 +1012,7 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
                path[level].bp_newreq.bpr_ptr =
                        path[level - 1].bp_newreq.bpr_ptr + 1;
                ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
-                                                  &path[level].bp_newreq);
+                                                  &path[level].bp_newreq, dat);
                if (ret < 0)
                        goto err_out_child_node;
                ret = nilfs_btree_get_new_block(btree,
@@ -1081,8 +1034,8 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
 
        /* root */
        node = nilfs_btree_get_root(btree);
-       if (nilfs_btree_node_get_nchildren(btree, node) <
-           nilfs_btree_node_nchildren_max(btree, node)) {
+       if (nilfs_btree_node_get_nchildren(node) <
+           nilfs_btree_node_nchildren_max(node, btree)) {
                path[level].bp_op = nilfs_btree_do_insert;
                stats->bs_nblocks++;
                goto out;
@@ -1091,7 +1044,7 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
        /* grow */
        path[level].bp_newreq.bpr_ptr = path[level - 1].bp_newreq.bpr_ptr + 1;
        ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
-                                          &path[level].bp_newreq);
+                                          &path[level].bp_newreq, dat);
        if (ret < 0)
                goto err_out_child_node;
        ret = nilfs_btree_get_new_block(btree, path[level].bp_newreq.bpr_ptr,
@@ -1119,16 +1072,18 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
 
        /* error */
  err_out_curr_node:
-       nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq);
+       nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq,
+                                  dat);
  err_out_child_node:
        for (level--; level > NILFS_BTREE_LEVEL_DATA; level--) {
                nilfs_btnode_delete(path[level].bp_sib_bh);
                nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap,
-                                          &path[level].bp_newreq);
+                                          &path[level].bp_newreq, dat);
 
        }
 
-       nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq);
+       nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq,
+                                  dat);
  err_out_data:
        *levelp = level;
        stats->bs_nblocks = 0;
@@ -1139,16 +1094,19 @@ static void nilfs_btree_commit_insert(struct nilfs_btree *btree,
                                      struct nilfs_btree_path *path,
                                      int maxlevel, __u64 key, __u64 ptr)
 {
+       struct inode *dat = NULL;
        int level;
 
        set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr));
        ptr = path[NILFS_BTREE_LEVEL_DATA].bp_newreq.bpr_ptr;
-       if (NILFS_BMAP_USE_VBN(&btree->bt_bmap))
+       if (NILFS_BMAP_USE_VBN(&btree->bt_bmap)) {
                nilfs_btree_set_target_v(btree, key, ptr);
+               dat = nilfs_bmap_get_dat(&btree->bt_bmap);
+       }
 
        for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) {
                nilfs_bmap_commit_alloc_ptr(&btree->bt_bmap,
-                                           &path[level - 1].bp_newreq);
+                                           &path[level - 1].bp_newreq, dat);
                path[level].bp_op(btree, path, level, &key, &ptr);
        }
 
@@ -1164,10 +1122,10 @@ static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
        int level, ret;
 
        btree = (struct nilfs_btree *)bmap;
-       path = nilfs_btree_alloc_path(btree);
+       path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(btree, path);
+       nilfs_btree_init_path(path);
 
        ret = nilfs_btree_do_lookup(btree, path, key, NULL,
                                    NILFS_BTREE_LEVEL_NODE_MIN);
@@ -1184,8 +1142,8 @@ static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
        nilfs_bmap_add_blocks(bmap, stats.bs_nblocks);
 
  out:
-       nilfs_btree_clear_path(btree, path);
-       nilfs_btree_free_path(btree, path);
+       nilfs_btree_release_path(path);
+       nilfs_btree_free_path(path);
        return ret;
 }
 
@@ -1197,7 +1155,7 @@ static void nilfs_btree_do_delete(struct nilfs_btree *btree,
 
        if (level < nilfs_btree_height(btree) - 1) {
                lock_buffer(path[level].bp_bh);
-               node = nilfs_btree_get_nonroot_node(btree, path, level);
+               node = nilfs_btree_get_nonroot_node(path, level);
                nilfs_btree_node_delete(btree, node, keyp, ptrp,
                                        path[level].bp_index);
                if (!buffer_dirty(path[level].bp_bh))
@@ -1205,7 +1163,7 @@ static void nilfs_btree_do_delete(struct nilfs_btree *btree,
                unlock_buffer(path[level].bp_bh);
                if (path[level].bp_index == 0)
                        nilfs_btree_promote_key(btree, path, level + 1,
-                               nilfs_btree_node_get_key(btree, node, 0));
+                               nilfs_btree_node_get_key(node, 0));
        } else {
                node = nilfs_btree_get_root(btree);
                nilfs_btree_node_delete(btree, node, keyp, ptrp,
@@ -1225,10 +1183,10 @@ static void nilfs_btree_borrow_left(struct nilfs_btree *btree,
        lock_buffer(path[level].bp_bh);
        lock_buffer(path[level].bp_sib_bh);
 
-       node = nilfs_btree_get_nonroot_node(btree, path, level);
-       left = nilfs_btree_get_sib_node(btree, path, level);
-       nchildren = nilfs_btree_node_get_nchildren(btree, node);
-       lnchildren = nilfs_btree_node_get_nchildren(btree, left);
+       node = nilfs_btree_get_nonroot_node(path, level);
+       left = nilfs_btree_get_sib_node(path, level);
+       nchildren = nilfs_btree_node_get_nchildren(node);
+       lnchildren = nilfs_btree_node_get_nchildren(left);
 
        n = (nchildren + lnchildren) / 2 - nchildren;
 
@@ -1243,7 +1201,7 @@ static void nilfs_btree_borrow_left(struct nilfs_btree *btree,
        unlock_buffer(path[level].bp_sib_bh);
 
        nilfs_btree_promote_key(btree, path, level + 1,
-                               nilfs_btree_node_get_key(btree, node, 0));
+                               nilfs_btree_node_get_key(node, 0));
 
        brelse(path[level].bp_sib_bh);
        path[level].bp_sib_bh = NULL;
@@ -1262,10 +1220,10 @@ static void nilfs_btree_borrow_right(struct nilfs_btree *btree,
        lock_buffer(path[level].bp_bh);
        lock_buffer(path[level].bp_sib_bh);
 
-       node = nilfs_btree_get_nonroot_node(btree, path, level);
-       right = nilfs_btree_get_sib_node(btree, path, level);
-       nchildren = nilfs_btree_node_get_nchildren(btree, node);
-       rnchildren = nilfs_btree_node_get_nchildren(btree, right);
+       node = nilfs_btree_get_nonroot_node(path, level);
+       right = nilfs_btree_get_sib_node(path, level);
+       nchildren = nilfs_btree_node_get_nchildren(node);
+       rnchildren = nilfs_btree_node_get_nchildren(right);
 
        n = (nchildren + rnchildren) / 2 - nchildren;
 
@@ -1281,7 +1239,7 @@ static void nilfs_btree_borrow_right(struct nilfs_btree *btree,
 
        path[level + 1].bp_index++;
        nilfs_btree_promote_key(btree, path, level + 1,
-                               nilfs_btree_node_get_key(btree, right, 0));
+                               nilfs_btree_node_get_key(right, 0));
        path[level + 1].bp_index--;
 
        brelse(path[level].bp_sib_bh);
@@ -1300,10 +1258,10 @@ static void nilfs_btree_concat_left(struct nilfs_btree *btree,
        lock_buffer(path[level].bp_bh);
        lock_buffer(path[level].bp_sib_bh);
 
-       node = nilfs_btree_get_nonroot_node(btree, path, level);
-       left = nilfs_btree_get_sib_node(btree, path, level);
+       node = nilfs_btree_get_nonroot_node(path, level);
+       left = nilfs_btree_get_sib_node(path, level);
 
-       n = nilfs_btree_node_get_nchildren(btree, node);
+       n = nilfs_btree_node_get_nchildren(node);
 
        nilfs_btree_node_move_left(btree, left, node, n);
 
@@ -1316,7 +1274,7 @@ static void nilfs_btree_concat_left(struct nilfs_btree *btree,
        nilfs_btnode_delete(path[level].bp_bh);
        path[level].bp_bh = path[level].bp_sib_bh;
        path[level].bp_sib_bh = NULL;
-       path[level].bp_index += nilfs_btree_node_get_nchildren(btree, left);
+       path[level].bp_index += nilfs_btree_node_get_nchildren(left);
 }
 
 static void nilfs_btree_concat_right(struct nilfs_btree *btree,
@@ -1331,10 +1289,10 @@ static void nilfs_btree_concat_right(struct nilfs_btree *btree,
        lock_buffer(path[level].bp_bh);
        lock_buffer(path[level].bp_sib_bh);
 
-       node = nilfs_btree_get_nonroot_node(btree, path, level);
-       right = nilfs_btree_get_sib_node(btree, path, level);
+       node = nilfs_btree_get_nonroot_node(path, level);
+       right = nilfs_btree_get_sib_node(path, level);
 
-       n = nilfs_btree_node_get_nchildren(btree, right);
+       n = nilfs_btree_node_get_nchildren(right);
 
        nilfs_btree_node_move_left(btree, node, right, n);
 
@@ -1360,11 +1318,11 @@ static void nilfs_btree_shrink(struct nilfs_btree *btree,
 
        lock_buffer(path[level].bp_bh);
        root = nilfs_btree_get_root(btree);
-       child = nilfs_btree_get_nonroot_node(btree, path, level);
+       child = nilfs_btree_get_nonroot_node(path, level);
 
        nilfs_btree_node_delete(btree, root, NULL, NULL, 0);
-       nilfs_btree_node_set_level(btree, root, level);
-       n = nilfs_btree_node_get_nchildren(btree, child);
+       nilfs_btree_node_set_level(root, level);
+       n = nilfs_btree_node_get_nchildren(child);
        nilfs_btree_node_move_left(btree, root, child, n);
        unlock_buffer(path[level].bp_bh);
 
@@ -1376,7 +1334,8 @@ static void nilfs_btree_shrink(struct nilfs_btree *btree,
 static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
                                      struct nilfs_btree_path *path,
                                      int *levelp,
-                                     struct nilfs_bmap_stats *stats)
+                                     struct nilfs_bmap_stats *stats,
+                                     struct inode *dat)
 {
        struct buffer_head *bh;
        struct nilfs_btree_node *node, *parent, *sib;
@@ -1388,17 +1347,17 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
        for (level = NILFS_BTREE_LEVEL_NODE_MIN;
             level < nilfs_btree_height(btree) - 1;
             level++) {
-               node = nilfs_btree_get_nonroot_node(btree, path, level);
+               node = nilfs_btree_get_nonroot_node(path, level);
                path[level].bp_oldreq.bpr_ptr =
                        nilfs_btree_node_get_ptr(btree, node,
                                                 path[level].bp_index);
                ret = nilfs_bmap_prepare_end_ptr(&btree->bt_bmap,
-                                                &path[level].bp_oldreq);
+                                                &path[level].bp_oldreq, dat);
                if (ret < 0)
                        goto err_out_child_node;
 
-               if (nilfs_btree_node_get_nchildren(btree, node) >
-                   nilfs_btree_node_nchildren_min(btree, node)) {
+               if (nilfs_btree_node_get_nchildren(node) >
+                   nilfs_btree_node_nchildren_min(node, btree)) {
                        path[level].bp_op = nilfs_btree_do_delete;
                        stats->bs_nblocks++;
                        goto out;
@@ -1415,8 +1374,8 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
                        if (ret < 0)
                                goto err_out_curr_node;
                        sib = (struct nilfs_btree_node *)bh->b_data;
-                       if (nilfs_btree_node_get_nchildren(btree, sib) >
-                           nilfs_btree_node_nchildren_min(btree, sib)) {
+                       if (nilfs_btree_node_get_nchildren(sib) >
+                           nilfs_btree_node_nchildren_min(sib, btree)) {
                                path[level].bp_sib_bh = bh;
                                path[level].bp_op = nilfs_btree_borrow_left;
                                stats->bs_nblocks++;
@@ -1428,7 +1387,7 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
                                /* continue; */
                        }
                } else if (pindex <
-                          nilfs_btree_node_get_nchildren(btree, parent) - 1) {
+                          nilfs_btree_node_get_nchildren(parent) - 1) {
                        /* right sibling */
                        sibptr = nilfs_btree_node_get_ptr(btree, parent,
                                                          pindex + 1);
@@ -1436,8 +1395,8 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
                        if (ret < 0)
                                goto err_out_curr_node;
                        sib = (struct nilfs_btree_node *)bh->b_data;
-                       if (nilfs_btree_node_get_nchildren(btree, sib) >
-                           nilfs_btree_node_nchildren_min(btree, sib)) {
+                       if (nilfs_btree_node_get_nchildren(sib) >
+                           nilfs_btree_node_nchildren_min(sib, btree)) {
                                path[level].bp_sib_bh = bh;
                                path[level].bp_op = nilfs_btree_borrow_right;
                                stats->bs_nblocks++;
@@ -1452,7 +1411,7 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
                        /* no siblings */
                        /* the only child of the root node */
                        WARN_ON(level != nilfs_btree_height(btree) - 2);
-                       if (nilfs_btree_node_get_nchildren(btree, node) - 1 <=
+                       if (nilfs_btree_node_get_nchildren(node) - 1 <=
                            NILFS_BTREE_ROOT_NCHILDREN_MAX) {
                                path[level].bp_op = nilfs_btree_shrink;
                                stats->bs_nblocks += 2;
@@ -1471,7 +1430,7 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
                nilfs_btree_node_get_ptr(btree, node, path[level].bp_index);
 
        ret = nilfs_bmap_prepare_end_ptr(&btree->bt_bmap,
-                                        &path[level].bp_oldreq);
+                                        &path[level].bp_oldreq, dat);
        if (ret < 0)
                goto err_out_child_node;
 
@@ -1486,12 +1445,12 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
 
        /* error */
  err_out_curr_node:
-       nilfs_bmap_abort_end_ptr(&btree->bt_bmap, &path[level].bp_oldreq);
+       nilfs_bmap_abort_end_ptr(&btree->bt_bmap, &path[level].bp_oldreq, dat);
  err_out_child_node:
        for (level--; level >= NILFS_BTREE_LEVEL_NODE_MIN; level--) {
                brelse(path[level].bp_sib_bh);
                nilfs_bmap_abort_end_ptr(&btree->bt_bmap,
-                                        &path[level].bp_oldreq);
+                                        &path[level].bp_oldreq, dat);
        }
        *levelp = level;
        stats->bs_nblocks = 0;
@@ -1500,13 +1459,13 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
 
 static void nilfs_btree_commit_delete(struct nilfs_btree *btree,
                                      struct nilfs_btree_path *path,
-                                     int maxlevel)
+                                     int maxlevel, struct inode *dat)
 {
        int level;
 
        for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) {
                nilfs_bmap_commit_end_ptr(&btree->bt_bmap,
-                                         &path[level].bp_oldreq);
+                                         &path[level].bp_oldreq, dat);
                path[level].bp_op(btree, path, level, NULL, NULL);
        }
 
@@ -1520,27 +1479,32 @@ static int nilfs_btree_delete(struct nilfs_bmap *bmap, __u64 key)
        struct nilfs_btree *btree;
        struct nilfs_btree_path *path;
        struct nilfs_bmap_stats stats;
+       struct inode *dat;
        int level, ret;
 
        btree = (struct nilfs_btree *)bmap;
-       path = nilfs_btree_alloc_path(btree);
+       path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(btree, path);
+       nilfs_btree_init_path(path);
        ret = nilfs_btree_do_lookup(btree, path, key, NULL,
                                    NILFS_BTREE_LEVEL_NODE_MIN);
        if (ret < 0)
                goto out;
 
-       ret = nilfs_btree_prepare_delete(btree, path, &level, &stats);
+
+       dat = NILFS_BMAP_USE_VBN(&btree->bt_bmap) ?
+               nilfs_bmap_get_dat(&btree->bt_bmap) : NULL;
+
+       ret = nilfs_btree_prepare_delete(btree, path, &level, &stats, dat);
        if (ret < 0)
                goto out;
-       nilfs_btree_commit_delete(btree, path, level);
+       nilfs_btree_commit_delete(btree, path, level, dat);
        nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks);
 
 out:
-       nilfs_btree_clear_path(btree, path);
-       nilfs_btree_free_path(btree, path);
+       nilfs_btree_release_path(path);
+       nilfs_btree_free_path(path);
        return ret;
 }
 
@@ -1551,15 +1515,15 @@ static int nilfs_btree_last_key(const struct nilfs_bmap *bmap, __u64 *keyp)
        int ret;
 
        btree = (struct nilfs_btree *)bmap;
-       path = nilfs_btree_alloc_path(btree);
+       path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(btree, path);
+       nilfs_btree_init_path(path);
 
        ret = nilfs_btree_do_lookup_last(btree, path, keyp, NULL);
 
-       nilfs_btree_clear_path(btree, path);
-       nilfs_btree_free_path(btree, path);
+       nilfs_btree_release_path(path);
+       nilfs_btree_free_path(path);
 
        return ret;
 }
@@ -1581,7 +1545,7 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key)
                node = root;
                break;
        case 3:
-               nchildren = nilfs_btree_node_get_nchildren(btree, root);
+               nchildren = nilfs_btree_node_get_nchildren(root);
                if (nchildren > 1)
                        return 0;
                ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1);
@@ -1594,10 +1558,10 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key)
                return 0;
        }
 
-       nchildren = nilfs_btree_node_get_nchildren(btree, node);
-       maxkey = nilfs_btree_node_get_key(btree, node, nchildren - 1);
+       nchildren = nilfs_btree_node_get_nchildren(node);
+       maxkey = nilfs_btree_node_get_key(node, nchildren - 1);
        nextmaxkey = (nchildren > 1) ?
-               nilfs_btree_node_get_key(btree, node, nchildren - 2) : 0;
+               nilfs_btree_node_get_key(node, nchildren - 2) : 0;
        if (bh != NULL)
                brelse(bh);
 
@@ -1623,7 +1587,7 @@ static int nilfs_btree_gather_data(struct nilfs_bmap *bmap,
                node = root;
                break;
        case 3:
-               nchildren = nilfs_btree_node_get_nchildren(btree, root);
+               nchildren = nilfs_btree_node_get_nchildren(root);
                WARN_ON(nchildren > 1);
                ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1);
                ret = nilfs_btree_get_block(btree, ptr, &bh);
@@ -1636,11 +1600,11 @@ static int nilfs_btree_gather_data(struct nilfs_bmap *bmap,
                return -EINVAL;
        }
 
-       nchildren = nilfs_btree_node_get_nchildren(btree, node);
+       nchildren = nilfs_btree_node_get_nchildren(node);
        if (nchildren < nitems)
                nitems = nchildren;
-       dkeys = nilfs_btree_node_dkeys(btree, node);
-       dptrs = nilfs_btree_node_dptrs(btree, node);
+       dkeys = nilfs_btree_node_dkeys(node);
+       dptrs = nilfs_btree_node_dptrs(node, btree);
        for (i = 0; i < nitems; i++) {
                keys[i] = nilfs_bmap_dkey_to_key(dkeys[i]);
                ptrs[i] = nilfs_bmap_dptr_to_ptr(dptrs[i]);
@@ -1660,18 +1624,20 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
                                       struct nilfs_bmap_stats *stats)
 {
        struct buffer_head *bh;
-       struct nilfs_btree *btree;
+       struct nilfs_btree *btree = (struct nilfs_btree *)bmap;
+       struct inode *dat = NULL;
        int ret;
 
-       btree = (struct nilfs_btree *)bmap;
        stats->bs_nblocks = 0;
 
        /* for data */
        /* cannot find near ptr */
-       if (NILFS_BMAP_USE_VBN(bmap))
+       if (NILFS_BMAP_USE_VBN(bmap)) {
                dreq->bpr_ptr = nilfs_btree_find_target_v(btree, NULL, key);
+               dat = nilfs_bmap_get_dat(bmap);
+       }
 
-       ret = nilfs_bmap_prepare_alloc_ptr(bmap, dreq);
+       ret = nilfs_bmap_prepare_alloc_ptr(bmap, dreq, dat);
        if (ret < 0)
                return ret;
 
@@ -1679,7 +1645,7 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
        stats->bs_nblocks++;
        if (nreq != NULL) {
                nreq->bpr_ptr = dreq->bpr_ptr + 1;
-               ret = nilfs_bmap_prepare_alloc_ptr(bmap, nreq);
+               ret = nilfs_bmap_prepare_alloc_ptr(bmap, nreq, dat);
                if (ret < 0)
                        goto err_out_dreq;
 
@@ -1696,9 +1662,9 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
 
        /* error */
  err_out_nreq:
-       nilfs_bmap_abort_alloc_ptr(bmap, nreq);
+       nilfs_bmap_abort_alloc_ptr(bmap, nreq, dat);
  err_out_dreq:
-       nilfs_bmap_abort_alloc_ptr(bmap, dreq);
+       nilfs_bmap_abort_alloc_ptr(bmap, dreq, dat);
        stats->bs_nblocks = 0;
        return ret;
 
@@ -1713,8 +1679,9 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
                                      union nilfs_bmap_ptr_req *nreq,
                                      struct buffer_head *bh)
 {
-       struct nilfs_btree *btree;
+       struct nilfs_btree *btree = (struct nilfs_btree *)bmap;
        struct nilfs_btree_node *node;
+       struct inode *dat;
        __u64 tmpptr;
 
        /* free resources */
@@ -1725,11 +1692,11 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
        set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr));
 
        /* convert and insert */
-       btree = (struct nilfs_btree *)bmap;
+       dat = NILFS_BMAP_USE_VBN(bmap) ? nilfs_bmap_get_dat(bmap) : NULL;
        nilfs_btree_init(bmap);
        if (nreq != NULL) {
-               nilfs_bmap_commit_alloc_ptr(bmap, dreq);
-               nilfs_bmap_commit_alloc_ptr(bmap, nreq);
+               nilfs_bmap_commit_alloc_ptr(bmap, dreq, dat);
+               nilfs_bmap_commit_alloc_ptr(bmap, nreq, dat);
 
                /* create child node at level 1 */
                lock_buffer(bh);
@@ -1751,7 +1718,7 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
                nilfs_btree_node_init(btree, node, NILFS_BTREE_NODE_ROOT,
                                      2, 1, &keys[0], &tmpptr);
        } else {
-               nilfs_bmap_commit_alloc_ptr(bmap, dreq);
+               nilfs_bmap_commit_alloc_ptr(bmap, dreq, dat);
 
                /* create root node at level 1 */
                node = nilfs_btree_get_root(btree);
@@ -1822,7 +1789,7 @@ static int nilfs_btree_propagate_p(struct nilfs_btree *btree,
 
 static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
                                        struct nilfs_btree_path *path,
-                                       int level)
+                                       int level, struct inode *dat)
 {
        struct nilfs_btree_node *parent;
        int ret;
@@ -1832,9 +1799,8 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
                nilfs_btree_node_get_ptr(btree, parent,
                                         path[level + 1].bp_index);
        path[level].bp_newreq.bpr_ptr = path[level].bp_oldreq.bpr_ptr + 1;
-       ret = nilfs_bmap_prepare_update_v(&btree->bt_bmap,
-                                         &path[level].bp_oldreq,
-                                         &path[level].bp_newreq);
+       ret = nilfs_dat_prepare_update(dat, &path[level].bp_oldreq.bpr_req,
+                                      &path[level].bp_newreq.bpr_req);
        if (ret < 0)
                return ret;
 
@@ -1846,9 +1812,9 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
                        &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
                        &path[level].bp_ctxt);
                if (ret < 0) {
-                       nilfs_bmap_abort_update_v(&btree->bt_bmap,
-                                                 &path[level].bp_oldreq,
-                                                 &path[level].bp_newreq);
+                       nilfs_dat_abort_update(dat,
+                                              &path[level].bp_oldreq.bpr_req,
+                                              &path[level].bp_newreq.bpr_req);
                        return ret;
                }
        }
@@ -1858,13 +1824,13 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
 
 static void nilfs_btree_commit_update_v(struct nilfs_btree *btree,
                                        struct nilfs_btree_path *path,
-                                       int level)
+                                       int level, struct inode *dat)
 {
        struct nilfs_btree_node *parent;
 
-       nilfs_bmap_commit_update_v(&btree->bt_bmap,
-                                  &path[level].bp_oldreq,
-                                  &path[level].bp_newreq);
+       nilfs_dat_commit_update(dat, &path[level].bp_oldreq.bpr_req,
+                               &path[level].bp_newreq.bpr_req,
+                               btree->bt_bmap.b_ptr_type == NILFS_BMAP_PTR_VS);
 
        if (buffer_nilfs_node(path[level].bp_bh)) {
                nilfs_btnode_commit_change_key(
@@ -1881,11 +1847,10 @@ static void nilfs_btree_commit_update_v(struct nilfs_btree *btree,
 
 static void nilfs_btree_abort_update_v(struct nilfs_btree *btree,
                                       struct nilfs_btree_path *path,
-                                      int level)
+                                      int level, struct inode *dat)
 {
-       nilfs_bmap_abort_update_v(&btree->bt_bmap,
-                                 &path[level].bp_oldreq,
-                                 &path[level].bp_newreq);
+       nilfs_dat_abort_update(dat, &path[level].bp_oldreq.bpr_req,
+                              &path[level].bp_newreq.bpr_req);
        if (buffer_nilfs_node(path[level].bp_bh))
                nilfs_btnode_abort_change_key(
                        &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
@@ -1894,14 +1859,14 @@ static void nilfs_btree_abort_update_v(struct nilfs_btree *btree,
 
 static int nilfs_btree_prepare_propagate_v(struct nilfs_btree *btree,
                                           struct nilfs_btree_path *path,
-                                          int minlevel,
-                                          int *maxlevelp)
+                                          int minlevel, int *maxlevelp,
+                                          struct inode *dat)
 {
        int level, ret;
 
        level = minlevel;
        if (!buffer_nilfs_volatile(path[level].bp_bh)) {
-               ret = nilfs_btree_prepare_update_v(btree, path, level);
+               ret = nilfs_btree_prepare_update_v(btree, path, level, dat);
                if (ret < 0)
                        return ret;
        }
@@ -1909,7 +1874,7 @@ static int nilfs_btree_prepare_propagate_v(struct nilfs_btree *btree,
               !buffer_dirty(path[level].bp_bh)) {
 
                WARN_ON(buffer_nilfs_volatile(path[level].bp_bh));
-               ret = nilfs_btree_prepare_update_v(btree, path, level);
+               ret = nilfs_btree_prepare_update_v(btree, path, level, dat);
                if (ret < 0)
                        goto out;
        }
@@ -1921,39 +1886,40 @@ static int nilfs_btree_prepare_propagate_v(struct nilfs_btree *btree,
        /* error */
  out:
        while (--level > minlevel)
-               nilfs_btree_abort_update_v(btree, path, level);
+               nilfs_btree_abort_update_v(btree, path, level, dat);
        if (!buffer_nilfs_volatile(path[level].bp_bh))
-               nilfs_btree_abort_update_v(btree, path, level);
+               nilfs_btree_abort_update_v(btree, path, level, dat);
        return ret;
 }
 
 static void nilfs_btree_commit_propagate_v(struct nilfs_btree *btree,
                                           struct nilfs_btree_path *path,
-                                          int minlevel,
-                                          int maxlevel,
-                                          struct buffer_head *bh)
+                                          int minlevel, int maxlevel,
+                                          struct buffer_head *bh,
+                                          struct inode *dat)
 {
        int level;
 
        if (!buffer_nilfs_volatile(path[minlevel].bp_bh))
-               nilfs_btree_commit_update_v(btree, path, minlevel);
+               nilfs_btree_commit_update_v(btree, path, minlevel, dat);
 
        for (level = minlevel + 1; level <= maxlevel; level++)
-               nilfs_btree_commit_update_v(btree, path, level);
+               nilfs_btree_commit_update_v(btree, path, level, dat);
 }
 
 static int nilfs_btree_propagate_v(struct nilfs_btree *btree,
                                   struct nilfs_btree_path *path,
-                                  int level,
-                                  struct buffer_head *bh)
+                                  int level, struct buffer_head *bh)
 {
        int maxlevel, ret;
        struct nilfs_btree_node *parent;
+       struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap);
        __u64 ptr;
 
        get_bh(bh);
        path[level].bp_bh = bh;
-       ret = nilfs_btree_prepare_propagate_v(btree, path, level, &maxlevel);
+       ret = nilfs_btree_prepare_propagate_v(btree, path, level, &maxlevel,
+                                             dat);
        if (ret < 0)
                goto out;
 
@@ -1961,12 +1927,12 @@ static int nilfs_btree_propagate_v(struct nilfs_btree *btree,
                parent = nilfs_btree_get_node(btree, path, level + 1);
                ptr = nilfs_btree_node_get_ptr(btree, parent,
                                               path[level + 1].bp_index);
-               ret = nilfs_bmap_mark_dirty(&btree->bt_bmap, ptr);
+               ret = nilfs_dat_mark_dirty(dat, ptr);
                if (ret < 0)
                        goto out;
        }
 
-       nilfs_btree_commit_propagate_v(btree, path, level, maxlevel, bh);
+       nilfs_btree_commit_propagate_v(btree, path, level, maxlevel, bh, dat);
 
  out:
        brelse(path[level].bp_bh);
@@ -1986,15 +1952,15 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
        WARN_ON(!buffer_dirty(bh));
 
        btree = (struct nilfs_btree *)bmap;
-       path = nilfs_btree_alloc_path(btree);
+       path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(btree, path);
+       nilfs_btree_init_path(path);
 
        if (buffer_nilfs_node(bh)) {
                node = (struct nilfs_btree_node *)bh->b_data;
-               key = nilfs_btree_node_get_key(btree, node, 0);
-               level = nilfs_btree_node_get_level(btree, node);
+               key = nilfs_btree_node_get_key(node, 0);
+               level = nilfs_btree_node_get_level(node);
        } else {
                key = nilfs_bmap_data_get_key(bmap, bh);
                level = NILFS_BTREE_LEVEL_DATA;
@@ -2013,8 +1979,8 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
                nilfs_btree_propagate_p(btree, path, level, bh);
 
  out:
-       nilfs_btree_clear_path(btree, path);
-       nilfs_btree_free_path(btree, path);
+       nilfs_btree_release_path(path);
+       nilfs_btree_free_path(path);
 
        return ret;
 }
@@ -2022,7 +1988,7 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
 static int nilfs_btree_propagate_gc(const struct nilfs_bmap *bmap,
                                    struct buffer_head *bh)
 {
-       return nilfs_bmap_mark_dirty(bmap, bh->b_blocknr);
+       return nilfs_dat_mark_dirty(nilfs_bmap_get_dat(bmap), bh->b_blocknr);
 }
 
 static void nilfs_btree_add_dirty_buffer(struct nilfs_btree *btree,
@@ -2037,12 +2003,12 @@ static void nilfs_btree_add_dirty_buffer(struct nilfs_btree *btree,
 
        get_bh(bh);
        node = (struct nilfs_btree_node *)bh->b_data;
-       key = nilfs_btree_node_get_key(btree, node, 0);
-       level = nilfs_btree_node_get_level(btree, node);
+       key = nilfs_btree_node_get_key(node, 0);
+       level = nilfs_btree_node_get_level(node);
        list_for_each(head, &lists[level]) {
                cbh = list_entry(head, struct buffer_head, b_assoc_buffers);
                cnode = (struct nilfs_btree_node *)cbh->b_data;
-               ckey = nilfs_btree_node_get_key(btree, cnode, 0);
+               ckey = nilfs_btree_node_get_key(cnode, 0);
                if (key < ckey)
                        break;
        }
@@ -2120,8 +2086,7 @@ static int nilfs_btree_assign_p(struct nilfs_btree *btree,
        nilfs_btree_node_set_ptr(btree, parent,
                                 path[level + 1].bp_index, blocknr);
 
-       key = nilfs_btree_node_get_key(btree, parent,
-                                      path[level + 1].bp_index);
+       key = nilfs_btree_node_get_key(parent, path[level + 1].bp_index);
        /* on-disk format */
        binfo->bi_dat.bi_blkoff = nilfs_bmap_key_to_dkey(key);
        binfo->bi_dat.bi_level = level;
@@ -2137,6 +2102,7 @@ static int nilfs_btree_assign_v(struct nilfs_btree *btree,
                                union nilfs_binfo *binfo)
 {
        struct nilfs_btree_node *parent;
+       struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap);
        __u64 key;
        __u64 ptr;
        union nilfs_bmap_ptr_req req;
@@ -2146,12 +2112,12 @@ static int nilfs_btree_assign_v(struct nilfs_btree *btree,
        ptr = nilfs_btree_node_get_ptr(btree, parent,
                                       path[level + 1].bp_index);
        req.bpr_ptr = ptr;
-       ret = nilfs_bmap_start_v(&btree->bt_bmap, &req, blocknr);
-       if (unlikely(ret < 0))
+       ret = nilfs_dat_prepare_start(dat, &req.bpr_req);
+       if (ret < 0)
                return ret;
+       nilfs_dat_commit_start(dat, &req.bpr_req, blocknr);
 
-       key = nilfs_btree_node_get_key(btree, parent,
-                                      path[level + 1].bp_index);
+       key = nilfs_btree_node_get_key(parent, path[level + 1].bp_index);
        /* on-disk format */
        binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr);
        binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
@@ -2171,15 +2137,15 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap,
        int level, ret;
 
        btree = (struct nilfs_btree *)bmap;
-       path = nilfs_btree_alloc_path(btree);
+       path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(btree, path);
+       nilfs_btree_init_path(path);
 
        if (buffer_nilfs_node(*bh)) {
                node = (struct nilfs_btree_node *)(*bh)->b_data;
-               key = nilfs_btree_node_get_key(btree, node, 0);
-               level = nilfs_btree_node_get_level(btree, node);
+               key = nilfs_btree_node_get_key(node, 0);
+               level = nilfs_btree_node_get_level(node);
        } else {
                key = nilfs_bmap_data_get_key(bmap, *bh);
                level = NILFS_BTREE_LEVEL_DATA;
@@ -2196,8 +2162,8 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap,
                nilfs_btree_assign_p(btree, path, level, bh, blocknr, binfo);
 
  out:
-       nilfs_btree_clear_path(btree, path);
-       nilfs_btree_free_path(btree, path);
+       nilfs_btree_release_path(path);
+       nilfs_btree_free_path(path);
 
        return ret;
 }
@@ -2207,19 +2173,18 @@ static int nilfs_btree_assign_gc(struct nilfs_bmap *bmap,
                                 sector_t blocknr,
                                 union nilfs_binfo *binfo)
 {
-       struct nilfs_btree *btree;
        struct nilfs_btree_node *node;
        __u64 key;
        int ret;
 
-       btree = (struct nilfs_btree *)bmap;
-       ret = nilfs_bmap_move_v(bmap, (*bh)->b_blocknr, blocknr);
+       ret = nilfs_dat_move(nilfs_bmap_get_dat(bmap), (*bh)->b_blocknr,
+                            blocknr);
        if (ret < 0)
                return ret;
 
        if (buffer_nilfs_node(*bh)) {
                node = (struct nilfs_btree_node *)(*bh)->b_data;
-               key = nilfs_btree_node_get_key(btree, node, 0);
+               key = nilfs_btree_node_get_key(node, 0);
        } else
                key = nilfs_bmap_data_get_key(bmap, *bh);
 
@@ -2239,10 +2204,10 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
        int ret;
 
        btree = (struct nilfs_btree *)bmap;
-       path = nilfs_btree_alloc_path(btree);
+       path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(btree, path);
+       nilfs_btree_init_path(path);
 
        ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level + 1);
        if (ret < 0) {
@@ -2262,8 +2227,8 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
                nilfs_bmap_set_dirty(&btree->bt_bmap);
 
  out:
-       nilfs_btree_clear_path(btree, path);
-       nilfs_btree_free_path(btree, path);
+       nilfs_btree_release_path(path);
+       nilfs_btree_free_path(path);
        return ret;
 }
 
index aec942cf79e34cc35764d270e645fd3f24a29229..1c6cfb59128d6b522139cd26274efe76ca054415 100644 (file)
@@ -815,8 +815,10 @@ int nilfs_cpfile_is_snapshot(struct inode *cpfile, __u64 cno)
        void *kaddr;
        int ret;
 
-       if (cno == 0)
-               return -ENOENT; /* checkpoint number 0 is invalid */
+       /* CP number is invalid if it's zero or larger than the
+       largest exist one.*/
+       if (cno == 0 || cno >= nilfs_mdt_cno(cpfile))
+               return -ENOENT;
        down_read(&NILFS_MDT(cpfile)->mi_sem);
 
        ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &bh);
@@ -824,7 +826,10 @@ int nilfs_cpfile_is_snapshot(struct inode *cpfile, __u64 cno)
                goto out;
        kaddr = kmap_atomic(bh->b_page, KM_USER0);
        cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr);
-       ret = nilfs_checkpoint_snapshot(cp);
+       if (nilfs_checkpoint_invalid(cp))
+               ret = -ENOENT;
+       else
+               ret = nilfs_checkpoint_snapshot(cp);
        kunmap_atomic(kaddr, KM_USER0);
        brelse(bh);
 
index 788a45950197c3299b03e1985e31b0b349053efa..debea896e70111a276a92ef3910ba1e96388b587 100644 (file)
@@ -27,8 +27,6 @@
 #include <linux/buffer_head.h>
 #include <linux/nilfs2_fs.h>
 
-#define NILFS_CPFILE_GFP       NILFS_MDT_GFP
-
 
 int nilfs_cpfile_get_checkpoint(struct inode *, __u64, int,
                                struct nilfs_checkpoint **,
index 8927ca27e6f79cbd82db5028d5dfd002baa99bb0..1ff8e15bd36b52dad460dd1f28e7797916b87165 100644 (file)
@@ -109,12 +109,6 @@ void nilfs_dat_commit_free(struct inode *dat, struct nilfs_palloc_req *req)
        nilfs_palloc_commit_free_entry(dat, req);
 }
 
-void nilfs_dat_abort_free(struct inode *dat, struct nilfs_palloc_req *req)
-{
-       nilfs_dat_abort_entry(dat, req);
-       nilfs_palloc_abort_free_entry(dat, req);
-}
-
 int nilfs_dat_prepare_start(struct inode *dat, struct nilfs_palloc_req *req)
 {
        int ret;
@@ -140,11 +134,6 @@ void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req,
        nilfs_dat_commit_entry(dat, req);
 }
 
-void nilfs_dat_abort_start(struct inode *dat, struct nilfs_palloc_req *req)
-{
-       nilfs_dat_abort_entry(dat, req);
-}
-
 int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req)
 {
        struct nilfs_dat_entry *entry;
@@ -222,6 +211,37 @@ void nilfs_dat_abort_end(struct inode *dat, struct nilfs_palloc_req *req)
        nilfs_dat_abort_entry(dat, req);
 }
 
+int nilfs_dat_prepare_update(struct inode *dat,
+                            struct nilfs_palloc_req *oldreq,
+                            struct nilfs_palloc_req *newreq)
+{
+       int ret;
+
+       ret = nilfs_dat_prepare_end(dat, oldreq);
+       if (!ret) {
+               ret = nilfs_dat_prepare_alloc(dat, newreq);
+               if (ret < 0)
+                       nilfs_dat_abort_end(dat, oldreq);
+       }
+       return ret;
+}
+
+void nilfs_dat_commit_update(struct inode *dat,
+                            struct nilfs_palloc_req *oldreq,
+                            struct nilfs_palloc_req *newreq, int dead)
+{
+       nilfs_dat_commit_end(dat, oldreq, dead);
+       nilfs_dat_commit_alloc(dat, newreq);
+}
+
+void nilfs_dat_abort_update(struct inode *dat,
+                           struct nilfs_palloc_req *oldreq,
+                           struct nilfs_palloc_req *newreq)
+{
+       nilfs_dat_abort_end(dat, oldreq);
+       nilfs_dat_abort_alloc(dat, newreq);
+}
+
 /**
  * nilfs_dat_mark_dirty -
  * @dat: DAT file inode
index d328b81eead403311d599f2f8a45694be3044e0a..406070d3ff4922b97dc62e36c28f47b47d671d74 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/buffer_head.h>
 #include <linux/fs.h>
 
-#define NILFS_DAT_GFP  NILFS_MDT_GFP
 
 struct nilfs_palloc_req;
 
@@ -39,10 +38,15 @@ void nilfs_dat_abort_alloc(struct inode *, struct nilfs_palloc_req *);
 int nilfs_dat_prepare_start(struct inode *, struct nilfs_palloc_req *);
 void nilfs_dat_commit_start(struct inode *, struct nilfs_palloc_req *,
                            sector_t);
-void nilfs_dat_abort_start(struct inode *, struct nilfs_palloc_req *);
 int nilfs_dat_prepare_end(struct inode *, struct nilfs_palloc_req *);
 void nilfs_dat_commit_end(struct inode *, struct nilfs_palloc_req *, int);
 void nilfs_dat_abort_end(struct inode *, struct nilfs_palloc_req *);
+int nilfs_dat_prepare_update(struct inode *, struct nilfs_palloc_req *,
+                            struct nilfs_palloc_req *);
+void nilfs_dat_commit_update(struct inode *, struct nilfs_palloc_req *,
+                            struct nilfs_palloc_req *, int);
+void nilfs_dat_abort_update(struct inode *, struct nilfs_palloc_req *,
+                           struct nilfs_palloc_req *);
 
 int nilfs_dat_mark_dirty(struct inode *, __u64);
 int nilfs_dat_freev(struct inode *, __u64 *, size_t);
index 342d9765df8df2bab8ca8a57869f77bc57f739e5..d369ac7182772b359bc148bd5dc7d7a30d3285d9 100644 (file)
@@ -125,106 +125,64 @@ static void nilfs_direct_set_target_v(struct nilfs_direct *direct,
        direct->d_bmap.b_last_allocated_ptr = ptr;
 }
 
-static int nilfs_direct_prepare_insert(struct nilfs_direct *direct,
-                                      __u64 key,
-                                      union nilfs_bmap_ptr_req *req,
-                                      struct nilfs_bmap_stats *stats)
-{
-       int ret;
-
-       if (NILFS_BMAP_USE_VBN(&direct->d_bmap))
-               req->bpr_ptr = nilfs_direct_find_target_v(direct, key);
-       ret = nilfs_bmap_prepare_alloc_ptr(&direct->d_bmap, req);
-       if (ret < 0)
-               return ret;
-
-       stats->bs_nblocks = 1;
-       return 0;
-}
-
-static void nilfs_direct_commit_insert(struct nilfs_direct *direct,
-                                      union nilfs_bmap_ptr_req *req,
-                                      __u64 key, __u64 ptr)
-{
-       struct buffer_head *bh;
-
-       /* ptr must be a pointer to a buffer head. */
-       bh = (struct buffer_head *)((unsigned long)ptr);
-       set_buffer_nilfs_volatile(bh);
-
-       nilfs_bmap_commit_alloc_ptr(&direct->d_bmap, req);
-       nilfs_direct_set_ptr(direct, key, req->bpr_ptr);
-
-       if (!nilfs_bmap_dirty(&direct->d_bmap))
-               nilfs_bmap_set_dirty(&direct->d_bmap);
-
-       if (NILFS_BMAP_USE_VBN(&direct->d_bmap))
-               nilfs_direct_set_target_v(direct, key, req->bpr_ptr);
-}
-
 static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
 {
-       struct nilfs_direct *direct;
+       struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
        union nilfs_bmap_ptr_req req;
-       struct nilfs_bmap_stats stats;
+       struct inode *dat = NULL;
+       struct buffer_head *bh;
        int ret;
 
-       direct = (struct nilfs_direct *)bmap;
        if (key > NILFS_DIRECT_KEY_MAX)
                return -ENOENT;
        if (nilfs_direct_get_ptr(direct, key) != NILFS_BMAP_INVALID_PTR)
                return -EEXIST;
 
-       ret = nilfs_direct_prepare_insert(direct, key, &req, &stats);
-       if (ret < 0)
-               return ret;
-       nilfs_direct_commit_insert(direct, &req, key, ptr);
-       nilfs_bmap_add_blocks(bmap, stats.bs_nblocks);
+       if (NILFS_BMAP_USE_VBN(bmap)) {
+               req.bpr_ptr = nilfs_direct_find_target_v(direct, key);
+               dat = nilfs_bmap_get_dat(bmap);
+       }
+       ret = nilfs_bmap_prepare_alloc_ptr(bmap, &req, dat);
+       if (!ret) {
+               /* ptr must be a pointer to a buffer head. */
+               bh = (struct buffer_head *)((unsigned long)ptr);
+               set_buffer_nilfs_volatile(bh);
 
-       return 0;
-}
+               nilfs_bmap_commit_alloc_ptr(bmap, &req, dat);
+               nilfs_direct_set_ptr(direct, key, req.bpr_ptr);
 
-static int nilfs_direct_prepare_delete(struct nilfs_direct *direct,
-                                      union nilfs_bmap_ptr_req *req,
-                                      __u64 key,
-                                      struct nilfs_bmap_stats *stats)
-{
-       int ret;
+               if (!nilfs_bmap_dirty(bmap))
+                       nilfs_bmap_set_dirty(bmap);
 
-       req->bpr_ptr = nilfs_direct_get_ptr(direct, key);
-       ret = nilfs_bmap_prepare_end_ptr(&direct->d_bmap, req);
-       if (!ret)
-               stats->bs_nblocks = 1;
-       return ret;
-}
+               if (NILFS_BMAP_USE_VBN(bmap))
+                       nilfs_direct_set_target_v(direct, key, req.bpr_ptr);
 
-static void nilfs_direct_commit_delete(struct nilfs_direct *direct,
-                                      union nilfs_bmap_ptr_req *req,
-                                      __u64 key)
-{
-       nilfs_bmap_commit_end_ptr(&direct->d_bmap, req);
-       nilfs_direct_set_ptr(direct, key, NILFS_BMAP_INVALID_PTR);
+               nilfs_bmap_add_blocks(bmap, 1);
+       }
+       return ret;
 }
 
 static int nilfs_direct_delete(struct nilfs_bmap *bmap, __u64 key)
 {
-       struct nilfs_direct *direct;
+       struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
        union nilfs_bmap_ptr_req req;
-       struct nilfs_bmap_stats stats;
+       struct inode *dat;
        int ret;
 
-       direct = (struct nilfs_direct *)bmap;
-       if ((key > NILFS_DIRECT_KEY_MAX) ||
+       if (key > NILFS_DIRECT_KEY_MAX ||
            nilfs_direct_get_ptr(direct, key) == NILFS_BMAP_INVALID_PTR)
                return -ENOENT;
 
-       ret = nilfs_direct_prepare_delete(direct, &req, key, &stats);
-       if (ret < 0)
-               return ret;
-       nilfs_direct_commit_delete(direct, &req, key);
-       nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks);
+       dat = NILFS_BMAP_USE_VBN(bmap) ? nilfs_bmap_get_dat(bmap) : NULL;
+       req.bpr_ptr = nilfs_direct_get_ptr(direct, key);
 
-       return 0;
+       ret = nilfs_bmap_prepare_end_ptr(bmap, &req, dat);
+       if (!ret) {
+               nilfs_bmap_commit_end_ptr(bmap, &req, dat);
+               nilfs_direct_set_ptr(direct, key, NILFS_BMAP_INVALID_PTR);
+               nilfs_bmap_sub_blocks(bmap, 1);
+       }
+       return ret;
 }
 
 static int nilfs_direct_last_key(const struct nilfs_bmap *bmap, __u64 *keyp)
@@ -310,59 +268,56 @@ int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap,
        return 0;
 }
 
-static int nilfs_direct_propagate_v(struct nilfs_direct *direct,
-                                   struct buffer_head *bh)
+static int nilfs_direct_propagate(const struct nilfs_bmap *bmap,
+                                 struct buffer_head *bh)
 {
-       union nilfs_bmap_ptr_req oldreq, newreq;
+       struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
+       struct nilfs_palloc_req oldreq, newreq;
+       struct inode *dat;
        __u64 key;
        __u64 ptr;
        int ret;
 
-       key = nilfs_bmap_data_get_key(&direct->d_bmap, bh);
+       if (!NILFS_BMAP_USE_VBN(bmap))
+               return 0;
+
+       dat = nilfs_bmap_get_dat(bmap);
+       key = nilfs_bmap_data_get_key(bmap, bh);
        ptr = nilfs_direct_get_ptr(direct, key);
        if (!buffer_nilfs_volatile(bh)) {
-               oldreq.bpr_ptr = ptr;
-               newreq.bpr_ptr = ptr;
-               ret = nilfs_bmap_prepare_update_v(&direct->d_bmap, &oldreq,
-                                                 &newreq);
+               oldreq.pr_entry_nr = ptr;
+               newreq.pr_entry_nr = ptr;
+               ret = nilfs_dat_prepare_update(dat, &oldreq, &newreq);
                if (ret < 0)
                        return ret;
-               nilfs_bmap_commit_update_v(&direct->d_bmap, &oldreq, &newreq);
+               nilfs_dat_commit_update(dat, &oldreq, &newreq,
+                                       bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
                set_buffer_nilfs_volatile(bh);
-               nilfs_direct_set_ptr(direct, key, newreq.bpr_ptr);
+               nilfs_direct_set_ptr(direct, key, newreq.pr_entry_nr);
        } else
-               ret = nilfs_bmap_mark_dirty(&direct->d_bmap, ptr);
+               ret = nilfs_dat_mark_dirty(dat, ptr);
 
        return ret;
 }
 
-static int nilfs_direct_propagate(const struct nilfs_bmap *bmap,
-                                 struct buffer_head *bh)
-{
-       struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
-
-       return NILFS_BMAP_USE_VBN(bmap) ?
-               nilfs_direct_propagate_v(direct, bh) : 0;
-}
-
 static int nilfs_direct_assign_v(struct nilfs_direct *direct,
                                 __u64 key, __u64 ptr,
                                 struct buffer_head **bh,
                                 sector_t blocknr,
                                 union nilfs_binfo *binfo)
 {
+       struct inode *dat = nilfs_bmap_get_dat(&direct->d_bmap);
        union nilfs_bmap_ptr_req req;
        int ret;
 
        req.bpr_ptr = ptr;
-       ret = nilfs_bmap_start_v(&direct->d_bmap, &req, blocknr);
-       if (unlikely(ret < 0))
-               return ret;
-
-       binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr);
-       binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
-
-       return 0;
+       ret = nilfs_dat_prepare_start(dat, &req.bpr_req);
+       if (!ret) {
+               nilfs_dat_commit_start(dat, &req.bpr_req, blocknr);
+               binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr);
+               binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
+       }
+       return ret;
 }
 
 static int nilfs_direct_assign_p(struct nilfs_direct *direct,
index 5d30a35679b511ed50511c7e04105fec4adf4866..ecc3ba76db475155f887f258d45cd0daf3b01341 100644 (file)
@@ -31,7 +31,6 @@
 #include "mdt.h"
 #include "alloc.h"
 
-#define NILFS_IFILE_GFP  NILFS_MDT_GFP
 
 static inline struct nilfs_inode *
 nilfs_ifile_map_inode(struct inode *ifile, ino_t ino, struct buffer_head *ibh)
index fe9d8f2a13f8785bf366f0a5884261af8ccfd782..807e584b163d8db488cec503570712090b2493c9 100644 (file)
@@ -430,7 +430,8 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino,
 
        raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, bh);
 
-       if (nilfs_read_inode_common(inode, raw_inode))
+       err = nilfs_read_inode_common(inode, raw_inode);
+       if (err)
                goto failed_unmap;
 
        if (S_ISREG(inode->i_mode)) {
index 6ea5f872e2de041cb5ba028f2b6f2ff731ed90e4..6572ea4bc4df70498dc62b29b93968d0396c7775 100644 (file)
@@ -442,12 +442,6 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
        const char *msg;
        int ret;
 
-       ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], kbufs[0]);
-       if (ret < 0) {
-               msg = "cannot read source blocks";
-               goto failed;
-       }
-
        ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], kbufs[1]);
        if (ret < 0) {
                /*
@@ -548,7 +542,25 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
                }
        }
 
-       ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
+       /*
+        * nilfs_ioctl_move_blocks() will call nilfs_gc_iget(),
+        * which will operates an inode list without blocking.
+        * To protect the list from concurrent operations,
+        * nilfs_ioctl_move_blocks should be atomic operation.
+        */
+       if (test_and_set_bit(THE_NILFS_GC_RUNNING, &nilfs->ns_flags)) {
+               ret = -EBUSY;
+               goto out_free;
+       }
+
+       ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], kbufs[0]);
+       if (ret < 0)
+               printk(KERN_ERR "NILFS: GC failed during preparation: "
+                       "cannot read source blocks: err=%d\n", ret);
+       else
+               ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
+
+       clear_nilfs_gc_running(nilfs);
 
  out_free:
        while (--n >= 0)
index 2dfd47714ae5b7329448b107cebd1614989e6e89..156bf6091a96da8bdd14e16474d78e9ba4093bf3 100644 (file)
@@ -103,15 +103,12 @@ static int nilfs_mdt_create_block(struct inode *inode, unsigned long block,
                goto failed_unlock;
 
        err = -EEXIST;
-       if (buffer_uptodate(bh) || buffer_mapped(bh))
+       if (buffer_uptodate(bh))
                goto failed_bh;
-#if 0
-       /* The uptodate flag is not protected by the page lock, but
-          the mapped flag is.  Thus, we don't have to wait the buffer. */
+
        wait_on_buffer(bh);
        if (buffer_uptodate(bh))
                goto failed_bh;
-#endif
 
        bh->b_bdev = nilfs->ns_bdev;
        err = nilfs_mdt_insert_new_block(inode, block, bh, init_block);
@@ -139,7 +136,7 @@ nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff,
                       int mode, struct buffer_head **out_bh)
 {
        struct buffer_head *bh;
-       unsigned long blknum = 0;
+       __u64 blknum = 0;
        int ret = -ENOMEM;
 
        bh = nilfs_grab_buffer(inode, inode->i_mapping, blkoff, 0);
@@ -162,17 +159,15 @@ nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff,
                unlock_buffer(bh);
                goto out;
        }
-       if (!buffer_mapped(bh)) { /* unused buffer */
-               ret = nilfs_bmap_lookup(NILFS_I(inode)->i_bmap, blkoff,
-                                       &blknum);
-               if (unlikely(ret)) {
-                       unlock_buffer(bh);
-                       goto failed_bh;
-               }
-               bh->b_bdev = NILFS_MDT(inode)->mi_nilfs->ns_bdev;
-               bh->b_blocknr = blknum;
-               set_buffer_mapped(bh);
+
+       ret = nilfs_bmap_lookup(NILFS_I(inode)->i_bmap, blkoff, &blknum);
+       if (unlikely(ret)) {
+               unlock_buffer(bh);
+               goto failed_bh;
        }
+       bh->b_bdev = NILFS_MDT(inode)->mi_nilfs->ns_bdev;
+       bh->b_blocknr = (sector_t)blknum;
+       set_buffer_mapped(bh);
 
        bh->b_end_io = end_buffer_read_sync;
        get_bh(bh);
@@ -402,6 +397,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
        struct inode *inode = container_of(page->mapping,
                                           struct inode, i_data);
        struct super_block *sb = inode->i_sb;
+       struct the_nilfs *nilfs = NILFS_MDT(inode)->mi_nilfs;
        struct nilfs_sb_info *writer = NULL;
        int err = 0;
 
@@ -411,9 +407,10 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
        if (page->mapping->assoc_mapping)
                return 0; /* Do not request flush for shadow page cache */
        if (!sb) {
-               writer = nilfs_get_writer(NILFS_MDT(inode)->mi_nilfs);
+               down_read(&nilfs->ns_writer_sem);
+               writer = nilfs->ns_writer;
                if (!writer) {
-                       nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs);
+                       up_read(&nilfs->ns_writer_sem);
                        return -EROFS;
                }
                sb = writer->s_super;
@@ -425,7 +422,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
                nilfs_flush_segment(sb, inode->i_ino);
 
        if (writer)
-               nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs);
+               up_read(&nilfs->ns_writer_sem);
        return err;
 }
 
@@ -516,9 +513,10 @@ 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, gfp_t gfp_mask)
+                           ino_t ino)
 {
-       struct inode *inode = nilfs_mdt_new_common(nilfs, sb, ino, gfp_mask);
+       struct inode *inode = nilfs_mdt_new_common(nilfs, sb, ino,
+                                                  NILFS_MDT_GFP);
 
        if (!inode)
                return NULL;
index df683e0bca6a6418c45e207cd8967e126c366f7f..431599733c9b20e9479407590991f805633f36c6 100644 (file)
@@ -74,8 +74,7 @@ int nilfs_mdt_forget_block(struct inode *, unsigned long);
 int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long);
 int nilfs_mdt_fetch_dirty(struct inode *);
 
-struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t,
-                           gfp_t);
+struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t);
 struct inode *nilfs_mdt_new_common(struct the_nilfs *, struct super_block *,
                                   ino_t, gfp_t);
 void nilfs_mdt_destroy(struct inode *);
index d80cc71be7499cd62be748324eec1be57ecfe43a..6dc83591d1182164c5fdaf4b27e92d20b794d4a6 100644 (file)
@@ -552,7 +552,8 @@ static int recover_dsync_blocks(struct nilfs_sb_info *sbi,
                printk(KERN_WARNING
                       "NILFS warning: error recovering data block "
                       "(err=%d, ino=%lu, block-offset=%llu)\n",
-                      err, rb->ino, (unsigned long long)rb->blkoff);
+                      err, (unsigned long)rb->ino,
+                      (unsigned long long)rb->blkoff);
                if (!err2)
                        err2 = err;
  next:
index 9e3fe17bb96bcb86ec786a4469d659b9554ae399..e6d9e37fa241784c62400c0d4493185de97dd654 100644 (file)
@@ -316,10 +316,10 @@ static struct bio *nilfs_alloc_seg_bio(struct super_block *sb, sector_t start,
 {
        struct bio *bio;
 
-       bio = bio_alloc(GFP_NOWAIT, nr_vecs);
+       bio = bio_alloc(GFP_NOIO, nr_vecs);
        if (bio == NULL) {
                while (!bio && (nr_vecs >>= 1))
-                       bio = bio_alloc(GFP_NOWAIT, nr_vecs);
+                       bio = bio_alloc(GFP_NOIO, nr_vecs);
        }
        if (likely(bio)) {
                bio->bi_bdev = sb->s_bdev;
index 51ff3d0a4ee256445f8ddbe9e85d7ff2ae2a7798..683df89dbae5a3366ac459e660776bcccc69bc47 100644 (file)
@@ -2501,7 +2501,8 @@ static int nilfs_segctor_construct(struct nilfs_sc_info *sci,
                if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) &&
                    nilfs_discontinued(nilfs)) {
                        down_write(&nilfs->ns_sem);
-                       req->sb_err = nilfs_commit_super(sbi, 0);
+                       req->sb_err = nilfs_commit_super(sbi,
+                                       nilfs_altsb_need_update(nilfs));
                        up_write(&nilfs->ns_sem);
                }
        }
@@ -2689,6 +2690,7 @@ static int nilfs_segctor_thread(void *arg)
        } else {
                DEFINE_WAIT(wait);
                int should_sleep = 1;
+               struct the_nilfs *nilfs;
 
                prepare_to_wait(&sci->sc_wait_daemon, &wait,
                                TASK_INTERRUPTIBLE);
@@ -2709,6 +2711,9 @@ static int nilfs_segctor_thread(void *arg)
                finish_wait(&sci->sc_wait_daemon, &wait);
                timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) &&
                           time_after_eq(jiffies, sci->sc_timer->expires));
+               nilfs = sci->sc_sbi->s_nilfs;
+               if (sci->sc_super->s_dirt && nilfs_sb_need_update(nilfs))
+                       set_nilfs_discontinued(nilfs);
        }
        goto loop;
 
index a2c4d76c3366968e3d0a44a37278b9a9dcd90de0..0e99e5c0bd0f564fd4281bfb537fad4e3ee59c58 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/nilfs2_fs.h>
 #include "mdt.h"
 
-#define NILFS_SUFILE_GFP       NILFS_MDT_GFP
 
 static inline unsigned long nilfs_sufile_get_nsegments(struct inode *sufile)
 {
index 151964f0de4c1e475f0c89222928d82e5ac45684..55f3d6b60732abd1693e72cb3b5a43941e9d80be 100644 (file)
@@ -50,6 +50,8 @@
 #include <linux/writeback.h>
 #include <linux/kobject.h>
 #include <linux/exportfs.h>
+#include <linux/seq_file.h>
+#include <linux/mount.h>
 #include "nilfs.h"
 #include "mdt.h"
 #include "alloc.h"
@@ -65,7 +67,6 @@ MODULE_DESCRIPTION("A New Implementation of the Log-structured Filesystem "
                   "(NILFS)");
 MODULE_LICENSE("GPL");
 
-static void nilfs_write_super(struct super_block *sb);
 static int nilfs_remount(struct super_block *sb, int *flags, char *data);
 
 /**
@@ -311,9 +312,6 @@ static void nilfs_put_super(struct super_block *sb)
 
        lock_kernel();
 
-       if (sb->s_dirt)
-               nilfs_write_super(sb);
-
        nilfs_detach_segment_constructor(sbi);
 
        if (!(sb->s_flags & MS_RDONLY)) {
@@ -336,63 +334,21 @@ static void nilfs_put_super(struct super_block *sb)
        unlock_kernel();
 }
 
-/**
- * nilfs_write_super - write super block(s) of NILFS
- * @sb: super_block
- *
- * nilfs_write_super() gets a fs-dependent lock, writes super block(s), and
- * clears s_dirt.  This function is called in the section protected by
- * lock_super().
- *
- * The s_dirt flag is managed by each filesystem and we protect it by ns_sem
- * of the struct the_nilfs.  Lock order must be as follows:
- *
- *   1. lock_super()
- *   2.    down_write(&nilfs->ns_sem)
- *
- * Inside NILFS, locking ns_sem is enough to protect s_dirt and the buffer
- * of the super block (nilfs->ns_sbp[]).
- *
- * In most cases, VFS functions call lock_super() before calling these
- * methods.  So we must be careful not to bring on deadlocks when using
- * lock_super();  see generic_shutdown_super(), write_super(), and so on.
- *
- * Note that order of lock_kernel() and lock_super() depends on contexts
- * of VFS.  We should also note that lock_kernel() can be used in its
- * protective section and only the outermost one has an effect.
- */
-static void nilfs_write_super(struct super_block *sb)
+static int nilfs_sync_fs(struct super_block *sb, int wait)
 {
        struct nilfs_sb_info *sbi = NILFS_SB(sb);
        struct the_nilfs *nilfs = sbi->s_nilfs;
-
-       down_write(&nilfs->ns_sem);
-       if (!(sb->s_flags & MS_RDONLY)) {
-               struct nilfs_super_block **sbp = nilfs->ns_sbp;
-               u64 t = get_seconds();
-               int dupsb;
-
-               if (!nilfs_discontinued(nilfs) && t >= nilfs->ns_sbwtime[0] &&
-                   t < nilfs->ns_sbwtime[0] + NILFS_SB_FREQ) {
-                       up_write(&nilfs->ns_sem);
-                       return;
-               }
-               dupsb = sbp[1] && t > nilfs->ns_sbwtime[1] + NILFS_ALTSB_FREQ;
-               nilfs_commit_super(sbi, dupsb);
-       }
-       sb->s_dirt = 0;
-       up_write(&nilfs->ns_sem);
-}
-
-static int nilfs_sync_fs(struct super_block *sb, int wait)
-{
        int err = 0;
 
-       nilfs_write_super(sb);
-
        /* This function is called when super block should be written back */
        if (wait)
                err = nilfs_construct_segment(sb);
+
+       down_write(&nilfs->ns_sem);
+       if (sb->s_dirt)
+               nilfs_commit_super(sbi, 1);
+       up_write(&nilfs->ns_sem);
+
        return err;
 }
 
@@ -407,8 +363,7 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno)
        list_add(&sbi->s_list, &nilfs->ns_supers);
        up_write(&nilfs->ns_super_sem);
 
-       sbi->s_ifile = nilfs_mdt_new(
-               nilfs, sbi->s_super, NILFS_IFILE_INO, NILFS_IFILE_GFP);
+       sbi->s_ifile = nilfs_mdt_new(nilfs, sbi->s_super, NILFS_IFILE_INO);
        if (!sbi->s_ifile)
                return -ENOMEM;
 
@@ -529,6 +484,26 @@ static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf)
        return 0;
 }
 
+static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+       struct super_block *sb = vfs->mnt_sb;
+       struct nilfs_sb_info *sbi = NILFS_SB(sb);
+
+       if (!nilfs_test_opt(sbi, BARRIER))
+               seq_printf(seq, ",barrier=off");
+       if (nilfs_test_opt(sbi, SNAPSHOT))
+               seq_printf(seq, ",cp=%llu",
+                          (unsigned long long int)sbi->s_snapshot_cno);
+       if (nilfs_test_opt(sbi, ERRORS_RO))
+               seq_printf(seq, ",errors=remount-ro");
+       if (nilfs_test_opt(sbi, ERRORS_PANIC))
+               seq_printf(seq, ",errors=panic");
+       if (nilfs_test_opt(sbi, STRICT_ORDER))
+               seq_printf(seq, ",order=strict");
+
+       return 0;
+}
+
 static struct super_operations nilfs_sops = {
        .alloc_inode    = nilfs_alloc_inode,
        .destroy_inode  = nilfs_destroy_inode,
@@ -538,7 +513,7 @@ static struct super_operations nilfs_sops = {
        /* .drop_inode    = nilfs_drop_inode, */
        .delete_inode   = nilfs_delete_inode,
        .put_super      = nilfs_put_super,
-       .write_super    = nilfs_write_super,
+       /* .write_super    = nilfs_write_super, */
        .sync_fs        = nilfs_sync_fs,
        /* .write_super_lockfs */
        /* .unlockfs */
@@ -546,7 +521,7 @@ static struct super_operations nilfs_sops = {
        .remount_fs     = nilfs_remount,
        .clear_inode    = nilfs_clear_inode,
        /* .umount_begin */
-       /* .show_options */
+       .show_options = nilfs_show_options
 };
 
 static struct inode *
@@ -816,10 +791,15 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
 
        if (sb->s_flags & MS_RDONLY) {
                if (nilfs_test_opt(sbi, SNAPSHOT)) {
+                       down_read(&nilfs->ns_segctor_sem);
                        err = nilfs_cpfile_is_snapshot(nilfs->ns_cpfile,
                                                       sbi->s_snapshot_cno);
-                       if (err < 0)
+                       up_read(&nilfs->ns_segctor_sem);
+                       if (err < 0) {
+                               if (err == -ENOENT)
+                                       err = -EINVAL;
                                goto failed_sbi;
+                       }
                        if (!err) {
                                printk(KERN_ERR
                                       "NILFS: The specified checkpoint is "
@@ -1127,10 +1107,6 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
         */
        sd.sbi = nilfs_find_sbinfo(nilfs, !(flags & MS_RDONLY), sd.cno);
 
-       if (!sd.cno)
-               /* trying to get the latest checkpoint.  */
-               sd.cno = nilfs_last_cno(nilfs);
-
        /*
         * Get super block instance holding the nilfs_sb_info struct.
         * A new instance is allocated if no existing mount is present or
index 8b8889825716a9df7b7f71cff2102d89ee547eec..d4168e269c5d66a4fe85915f24f70f2e35c7aa3c 100644 (file)
@@ -68,12 +68,11 @@ static struct the_nilfs *alloc_nilfs(struct block_device *bdev)
 
        nilfs->ns_bdev = bdev;
        atomic_set(&nilfs->ns_count, 1);
-       atomic_set(&nilfs->ns_writer_refcount, -1);
        atomic_set(&nilfs->ns_ndirtyblks, 0);
        init_rwsem(&nilfs->ns_sem);
        init_rwsem(&nilfs->ns_super_sem);
        mutex_init(&nilfs->ns_mount_mutex);
-       mutex_init(&nilfs->ns_writer_mutex);
+       init_rwsem(&nilfs->ns_writer_sem);
        INIT_LIST_HEAD(&nilfs->ns_list);
        INIT_LIST_HEAD(&nilfs->ns_supers);
        spin_lock_init(&nilfs->ns_last_segment_lock);
@@ -188,23 +187,19 @@ static int nilfs_load_super_root(struct the_nilfs *nilfs,
        inode_size = nilfs->ns_inode_size;
 
        err = -ENOMEM;
-       nilfs->ns_dat = nilfs_mdt_new(
-               nilfs, NULL, NILFS_DAT_INO, NILFS_DAT_GFP);
+       nilfs->ns_dat = nilfs_mdt_new(nilfs, NULL, NILFS_DAT_INO);
        if (unlikely(!nilfs->ns_dat))
                goto failed;
 
-       nilfs->ns_gc_dat = nilfs_mdt_new(
-               nilfs, NULL, NILFS_DAT_INO, NILFS_DAT_GFP);
+       nilfs->ns_gc_dat = nilfs_mdt_new(nilfs, NULL, NILFS_DAT_INO);
        if (unlikely(!nilfs->ns_gc_dat))
                goto failed_dat;
 
-       nilfs->ns_cpfile = nilfs_mdt_new(
-               nilfs, NULL, NILFS_CPFILE_INO, NILFS_CPFILE_GFP);
+       nilfs->ns_cpfile = nilfs_mdt_new(nilfs, NULL, NILFS_CPFILE_INO);
        if (unlikely(!nilfs->ns_cpfile))
                goto failed_gc_dat;
 
-       nilfs->ns_sufile = nilfs_mdt_new(
-               nilfs, NULL, NILFS_SUFILE_INO, NILFS_SUFILE_GFP);
+       nilfs->ns_sufile = nilfs_mdt_new(nilfs, NULL, NILFS_SUFILE_INO);
        if (unlikely(!nilfs->ns_sufile))
                goto failed_cpfile;
 
index 1b9caafb866270a78c0d7e61cf4fb741f2a71a84..20abd55881e0adc7903682c4fb15a3a057230a97 100644 (file)
@@ -37,6 +37,7 @@ enum {
        THE_NILFS_LOADED,       /* Roll-back/roll-forward has done and
                                   the latest checkpoint was loaded */
        THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */
+       THE_NILFS_GC_RUNNING,   /* gc process is running */
 };
 
 /**
@@ -50,8 +51,7 @@ enum {
  * @ns_sem: semaphore for shared states
  * @ns_super_sem: semaphore for global operations across super block instances
  * @ns_mount_mutex: mutex protecting mount process of nilfs
- * @ns_writer_mutex: mutex protecting ns_writer attach/detach
- * @ns_writer_refcount: number of referrers on ns_writer
+ * @ns_writer_sem: semaphore protecting ns_writer attach/detach
  * @ns_current: back pointer to current mount
  * @ns_sbh: buffer heads of on-disk super blocks
  * @ns_sbp: pointers to super block data
@@ -100,8 +100,7 @@ struct the_nilfs {
        struct rw_semaphore     ns_sem;
        struct rw_semaphore     ns_super_sem;
        struct mutex            ns_mount_mutex;
-       struct mutex            ns_writer_mutex;
-       atomic_t                ns_writer_refcount;
+       struct rw_semaphore     ns_writer_sem;
 
        /*
         * components protected by ns_super_sem
@@ -197,11 +196,26 @@ static inline int nilfs_##name(struct the_nilfs *nilfs)                   \
 THE_NILFS_FNS(INIT, init)
 THE_NILFS_FNS(LOADED, loaded)
 THE_NILFS_FNS(DISCONTINUED, discontinued)
+THE_NILFS_FNS(GC_RUNNING, gc_running)
 
 /* Minimum interval of periodical update of superblocks (in seconds) */
 #define NILFS_SB_FREQ          10
 #define NILFS_ALTSB_FREQ       60  /* spare superblock */
 
+static inline int nilfs_sb_need_update(struct the_nilfs *nilfs)
+{
+       u64 t = get_seconds();
+       return t < nilfs->ns_sbwtime[0] ||
+                t > nilfs->ns_sbwtime[0] + NILFS_SB_FREQ;
+}
+
+static inline int nilfs_altsb_need_update(struct the_nilfs *nilfs)
+{
+       u64 t = get_seconds();
+       struct nilfs_super_block **sbp = nilfs->ns_sbp;
+       return sbp[1] && t > nilfs->ns_sbwtime[1] + NILFS_ALTSB_FREQ;
+}
+
 void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64);
 struct the_nilfs *find_or_create_nilfs(struct block_device *);
 void put_nilfs(struct the_nilfs *);
@@ -221,34 +235,21 @@ static inline void get_nilfs(struct the_nilfs *nilfs)
        atomic_inc(&nilfs->ns_count);
 }
 
-static inline struct nilfs_sb_info *nilfs_get_writer(struct the_nilfs *nilfs)
-{
-       if (atomic_inc_and_test(&nilfs->ns_writer_refcount))
-               mutex_lock(&nilfs->ns_writer_mutex);
-       return nilfs->ns_writer;
-}
-
-static inline void nilfs_put_writer(struct the_nilfs *nilfs)
-{
-       if (atomic_add_negative(-1, &nilfs->ns_writer_refcount))
-               mutex_unlock(&nilfs->ns_writer_mutex);
-}
-
 static inline void
 nilfs_attach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
 {
-       mutex_lock(&nilfs->ns_writer_mutex);
+       down_write(&nilfs->ns_writer_sem);
        nilfs->ns_writer = sbi;
-       mutex_unlock(&nilfs->ns_writer_mutex);
+       up_write(&nilfs->ns_writer_sem);
 }
 
 static inline void
 nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
 {
-       mutex_lock(&nilfs->ns_writer_mutex);
+       down_write(&nilfs->ns_writer_sem);
        if (sbi == nilfs->ns_writer)
                nilfs->ns_writer = NULL;
-       mutex_unlock(&nilfs->ns_writer_mutex);
+       up_write(&nilfs->ns_writer_sem);
 }
 
 static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi)