]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 21 May 2010 14:47:00 +0000 (07:47 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 21 May 2010 14:47:00 +0000 (07:47 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2: (23 commits)
  nilfs2: disallow remount of snapshot from/to a regular mount
  nilfs2: use huge_encode_dev/huge_decode_dev
  nilfs2: update comment on deactivate_super at nilfs_get_sb
  nilfs2: replace MS_VERBOSE with MS_SILENT
  nilfs2: add missing initialization of s_mode
  nilfs2: fix misuse of open_bdev_exclusive/close_bdev_exclusive
  nilfs2: enlarge s_volume_name member in nilfs_super_block
  nilfs2: use checkpoint number instead of timestamp to select super block
  nilfs2: add missing endian conversion on super block magic number
  nilfs2: make nilfs_sc_*_ops static
  nilfs2: add kernel doc comments to persistent object allocator functions
  nilfs2: change sc_timer from a pointer to an embedded one in struct nilfs_sc_info
  nilfs2: remove nilfs_segctor_init() in segment.c
  nilfs2: insert checkpoint number in segment summary header
  nilfs2: add a print message after loading nilfs2
  nilfs2: cleanup multi kmem_cache_{create,destroy} code
  nilfs2: move out checksum routines to segment buffer code
  nilfs2: move pointer to super root block into logs
  nilfs2: change default of 'errors' mount option to 'remount-ro' mode
  nilfs2: Combine nilfs_btree_release_path() and nilfs_btree_free_path()
  ...

14 files changed:
Documentation/filesystems/nilfs2.txt
fs/nilfs2/alloc.c
fs/nilfs2/alloc.h
fs/nilfs2/btree.c
fs/nilfs2/btree.h
fs/nilfs2/inode.c
fs/nilfs2/recovery.c
fs/nilfs2/segbuf.c
fs/nilfs2/segbuf.h
fs/nilfs2/segment.c
fs/nilfs2/segment.h
fs/nilfs2/super.c
fs/nilfs2/the_nilfs.c
include/linux/nilfs2_fs.h

index cf6d0d85ca82308a171a4a70f66638caca7105d9..d3e7673995eb21ff3e75d35fdb60230b063849a6 100644 (file)
@@ -50,8 +50,8 @@ NILFS2 supports the following mount options:
 (*) == default
 
 nobarrier              Disables barriers.
-errors=continue(*)     Keep going on a filesystem error.
-errors=remount-ro      Remount the filesystem read-only on an error.
+errors=continue                Keep going on a filesystem error.
+errors=remount-ro(*)   Remount the filesystem read-only on an error.
 errors=panic           Panic and halt the machine if an error occurs.
 cp=n                   Specify the checkpoint-number of the snapshot to be
                        mounted.  Checkpoints and snapshots are listed by lscp
index 7cfb87e692da9b7594ee0666d3b912e6bc48a21d..d7fd696e595ccdcb67f42e7a1d9b9e21f6dec3dc 100644 (file)
 #include "alloc.h"
 
 
+/**
+ * nilfs_palloc_groups_per_desc_block - get the number of groups that a group
+ *                                     descriptor block can maintain
+ * @inode: inode of metadata file using this allocator
+ */
 static inline unsigned long
 nilfs_palloc_groups_per_desc_block(const struct inode *inode)
 {
@@ -38,12 +43,21 @@ nilfs_palloc_groups_per_desc_block(const struct inode *inode)
                sizeof(struct nilfs_palloc_group_desc);
 }
 
+/**
+ * nilfs_palloc_groups_count - get maximum number of groups
+ * @inode: inode of metadata file using this allocator
+ */
 static inline unsigned long
 nilfs_palloc_groups_count(const struct inode *inode)
 {
        return 1UL << (BITS_PER_LONG - (inode->i_blkbits + 3 /* log2(8) */));
 }
 
+/**
+ * nilfs_palloc_init_blockgroup - initialize private variables for allocator
+ * @inode: inode of metadata file using this allocator
+ * @entry_size: size of the persistent object
+ */
 int nilfs_palloc_init_blockgroup(struct inode *inode, unsigned entry_size)
 {
        struct nilfs_mdt_info *mi = NILFS_MDT(inode);
@@ -69,6 +83,12 @@ int nilfs_palloc_init_blockgroup(struct inode *inode, unsigned entry_size)
        return 0;
 }
 
+/**
+ * nilfs_palloc_group - get group number and offset from an entry number
+ * @inode: inode of metadata file using this allocator
+ * @nr: serial number of the entry (e.g. inode number)
+ * @offset: pointer to store offset number in the group
+ */
 static unsigned long nilfs_palloc_group(const struct inode *inode, __u64 nr,
                                        unsigned long *offset)
 {
@@ -78,6 +98,14 @@ static unsigned long nilfs_palloc_group(const struct inode *inode, __u64 nr,
        return group;
 }
 
+/**
+ * nilfs_palloc_desc_blkoff - get block offset of a group descriptor block
+ * @inode: inode of metadata file using this allocator
+ * @group: group number
+ *
+ * nilfs_palloc_desc_blkoff() returns block offset of the descriptor
+ * block which contains a descriptor of the specified group.
+ */
 static unsigned long
 nilfs_palloc_desc_blkoff(const struct inode *inode, unsigned long group)
 {
@@ -86,6 +114,14 @@ nilfs_palloc_desc_blkoff(const struct inode *inode, unsigned long group)
        return desc_block * NILFS_MDT(inode)->mi_blocks_per_desc_block;
 }
 
+/**
+ * nilfs_palloc_bitmap_blkoff - get block offset of a bitmap block
+ * @inode: inode of metadata file using this allocator
+ * @group: group number
+ *
+ * nilfs_palloc_bitmap_blkoff() returns block offset of the bitmap
+ * block used to allocate/deallocate entries in the specified group.
+ */
 static unsigned long
 nilfs_palloc_bitmap_blkoff(const struct inode *inode, unsigned long group)
 {
@@ -95,6 +131,12 @@ nilfs_palloc_bitmap_blkoff(const struct inode *inode, unsigned long group)
                desc_offset * NILFS_MDT(inode)->mi_blocks_per_group;
 }
 
+/**
+ * nilfs_palloc_group_desc_nfrees - get the number of free entries in a group
+ * @inode: inode of metadata file using this allocator
+ * @group: group number
+ * @desc: pointer to descriptor structure for the group
+ */
 static unsigned long
 nilfs_palloc_group_desc_nfrees(struct inode *inode, unsigned long group,
                               const struct nilfs_palloc_group_desc *desc)
@@ -107,6 +149,13 @@ nilfs_palloc_group_desc_nfrees(struct inode *inode, unsigned long group,
        return nfree;
 }
 
+/**
+ * nilfs_palloc_group_desc_add_entries - adjust count of free entries
+ * @inode: inode of metadata file using this allocator
+ * @group: group number
+ * @desc: pointer to descriptor structure for the group
+ * @n: delta to be added
+ */
 static void
 nilfs_palloc_group_desc_add_entries(struct inode *inode,
                                    unsigned long group,
@@ -118,6 +167,11 @@ nilfs_palloc_group_desc_add_entries(struct inode *inode,
        spin_unlock(nilfs_mdt_bgl_lock(inode, group));
 }
 
+/**
+ * nilfs_palloc_entry_blkoff - get block offset of an entry block
+ * @inode: inode of metadata file using this allocator
+ * @nr: serial number of the entry (e.g. inode number)
+ */
 static unsigned long
 nilfs_palloc_entry_blkoff(const struct inode *inode, __u64 nr)
 {
@@ -129,6 +183,12 @@ nilfs_palloc_entry_blkoff(const struct inode *inode, __u64 nr)
                group_offset / NILFS_MDT(inode)->mi_entries_per_block;
 }
 
+/**
+ * nilfs_palloc_desc_block_init - initialize buffer of a group descriptor block
+ * @inode: inode of metadata file
+ * @bh: buffer head of the buffer to be initialized
+ * @kaddr: kernel address mapped for the page including the buffer
+ */
 static void nilfs_palloc_desc_block_init(struct inode *inode,
                                         struct buffer_head *bh, void *kaddr)
 {
@@ -179,6 +239,13 @@ static int nilfs_palloc_get_block(struct inode *inode, unsigned long blkoff,
        return ret;
 }
 
+/**
+ * nilfs_palloc_get_desc_block - get buffer head of a group descriptor block
+ * @inode: inode of metadata file using this allocator
+ * @group: group number
+ * @create: create flag
+ * @bhp: pointer to store the resultant buffer head
+ */
 static int nilfs_palloc_get_desc_block(struct inode *inode,
                                       unsigned long group,
                                       int create, struct buffer_head **bhp)
@@ -191,6 +258,13 @@ static int nilfs_palloc_get_desc_block(struct inode *inode,
                                      bhp, &cache->prev_desc, &cache->lock);
 }
 
+/**
+ * nilfs_palloc_get_bitmap_block - get buffer head of a bitmap block
+ * @inode: inode of metadata file using this allocator
+ * @group: group number
+ * @create: create flag
+ * @bhp: pointer to store the resultant buffer head
+ */
 static int nilfs_palloc_get_bitmap_block(struct inode *inode,
                                         unsigned long group,
                                         int create, struct buffer_head **bhp)
@@ -203,6 +277,13 @@ static int nilfs_palloc_get_bitmap_block(struct inode *inode,
                                      &cache->prev_bitmap, &cache->lock);
 }
 
+/**
+ * nilfs_palloc_get_entry_block - get buffer head of an entry block
+ * @inode: inode of metadata file using this allocator
+ * @nr: serial number of the entry (e.g. inode number)
+ * @create: create flag
+ * @bhp: pointer to store the resultant buffer head
+ */
 int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr,
                                 int create, struct buffer_head **bhp)
 {
@@ -214,6 +295,13 @@ int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr,
                                      &cache->prev_entry, &cache->lock);
 }
 
+/**
+ * nilfs_palloc_block_get_group_desc - get kernel address of a group descriptor
+ * @inode: inode of metadata file using this allocator
+ * @group: group number
+ * @bh: buffer head of the buffer storing the group descriptor block
+ * @kaddr: kernel address mapped for the page including the buffer
+ */
 static struct nilfs_palloc_group_desc *
 nilfs_palloc_block_get_group_desc(const struct inode *inode,
                                  unsigned long group,
@@ -223,6 +311,13 @@ nilfs_palloc_block_get_group_desc(const struct inode *inode,
                group % nilfs_palloc_groups_per_desc_block(inode);
 }
 
+/**
+ * nilfs_palloc_block_get_entry - get kernel address of an entry
+ * @inode: inode of metadata file using this allocator
+ * @nr: serial number of the entry (e.g. inode number)
+ * @bh: buffer head of the buffer storing the entry block
+ * @kaddr: kernel address mapped for the page including the buffer
+ */
 void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr,
                                   const struct buffer_head *bh, void *kaddr)
 {
@@ -235,11 +330,19 @@ void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr,
                entry_offset * NILFS_MDT(inode)->mi_entry_size;
 }
 
+/**
+ * nilfs_palloc_find_available_slot - find available slot in a group
+ * @inode: inode of metadata file using this allocator
+ * @group: group number
+ * @target: offset number of an entry in the group (start point)
+ * @bitmap: bitmap of the group
+ * @bsize: size in bits
+ */
 static int nilfs_palloc_find_available_slot(struct inode *inode,
                                            unsigned long group,
                                            unsigned long target,
                                            unsigned char *bitmap,
-                                           int bsize)  /* size in bits */
+                                           int bsize)
 {
        int curr, pos, end, i;
 
@@ -277,6 +380,13 @@ static int nilfs_palloc_find_available_slot(struct inode *inode,
        return -ENOSPC;
 }
 
+/**
+ * nilfs_palloc_rest_groups_in_desc_block - get the remaining number of groups
+ *                                         in a group descriptor block
+ * @inode: inode of metadata file using this allocator
+ * @curr: current group number
+ * @max: maximum number of groups
+ */
 static unsigned long
 nilfs_palloc_rest_groups_in_desc_block(const struct inode *inode,
                                       unsigned long curr, unsigned long max)
@@ -287,6 +397,11 @@ nilfs_palloc_rest_groups_in_desc_block(const struct inode *inode,
                     max - curr + 1);
 }
 
+/**
+ * nilfs_palloc_prepare_alloc_entry - prepare to allocate a persistent object
+ * @inode: inode of metadata file using this allocator
+ * @req: nilfs_palloc_req structure exchanged for the allocation
+ */
 int nilfs_palloc_prepare_alloc_entry(struct inode *inode,
                                     struct nilfs_palloc_req *req)
 {
@@ -366,6 +481,11 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode,
        return ret;
 }
 
+/**
+ * nilfs_palloc_commit_alloc_entry - finish allocation of a persistent object
+ * @inode: inode of metadata file using this allocator
+ * @req: nilfs_palloc_req structure exchanged for the allocation
+ */
 void nilfs_palloc_commit_alloc_entry(struct inode *inode,
                                     struct nilfs_palloc_req *req)
 {
@@ -377,6 +497,11 @@ void nilfs_palloc_commit_alloc_entry(struct inode *inode,
        brelse(req->pr_desc_bh);
 }
 
+/**
+ * nilfs_palloc_commit_free_entry - finish deallocating a persistent object
+ * @inode: inode of metadata file using this allocator
+ * @req: nilfs_palloc_req structure exchanged for the removal
+ */
 void nilfs_palloc_commit_free_entry(struct inode *inode,
                                    struct nilfs_palloc_req *req)
 {
@@ -410,6 +535,11 @@ void nilfs_palloc_commit_free_entry(struct inode *inode,
        brelse(req->pr_desc_bh);
 }
 
+/**
+ * nilfs_palloc_abort_alloc_entry - cancel allocation of a persistent object
+ * @inode: inode of metadata file using this allocator
+ * @req: nilfs_palloc_req structure exchanged for the allocation
+ */
 void nilfs_palloc_abort_alloc_entry(struct inode *inode,
                                    struct nilfs_palloc_req *req)
 {
@@ -442,6 +572,11 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode,
        req->pr_desc_bh = NULL;
 }
 
+/**
+ * nilfs_palloc_prepare_free_entry - prepare to deallocate a persistent object
+ * @inode: inode of metadata file using this allocator
+ * @req: nilfs_palloc_req structure exchanged for the removal
+ */
 int nilfs_palloc_prepare_free_entry(struct inode *inode,
                                    struct nilfs_palloc_req *req)
 {
@@ -464,6 +599,11 @@ int nilfs_palloc_prepare_free_entry(struct inode *inode,
        return 0;
 }
 
+/**
+ * nilfs_palloc_abort_free_entry - cancel deallocating a persistent object
+ * @inode: inode of metadata file using this allocator
+ * @req: nilfs_palloc_req structure exchanged for the removal
+ */
 void nilfs_palloc_abort_free_entry(struct inode *inode,
                                   struct nilfs_palloc_req *req)
 {
@@ -475,6 +615,12 @@ void nilfs_palloc_abort_free_entry(struct inode *inode,
        req->pr_desc_bh = NULL;
 }
 
+/**
+ * nilfs_palloc_group_is_in - judge if an entry is in a group
+ * @inode: inode of metadata file using this allocator
+ * @group: group number
+ * @nr: serial number of the entry (e.g. inode number)
+ */
 static int
 nilfs_palloc_group_is_in(struct inode *inode, unsigned long group, __u64 nr)
 {
@@ -485,6 +631,12 @@ nilfs_palloc_group_is_in(struct inode *inode, unsigned long group, __u64 nr)
        return (nr >= first) && (nr <= last);
 }
 
+/**
+ * nilfs_palloc_freev - deallocate a set of persistent objects
+ * @inode: inode of metadata file using this allocator
+ * @entry_nrs: array of entry numbers to be deallocated
+ * @nitems: number of entries stored in @entry_nrs
+ */
 int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
 {
        struct buffer_head *desc_bh, *bitmap_bh;
index 5cccf874d6927897dbf9c74a02d3f93b5a8c7c22..9af34a7e6e13e1ba17e660a3b1f0fb767b484b89 100644 (file)
 #include <linux/buffer_head.h>
 #include <linux/fs.h>
 
+/**
+ * nilfs_palloc_entries_per_group - get the number of entries per group
+ * @inode: inode of metadata file using this allocator
+ *
+ * The number of entries per group is defined by the number of bits
+ * that a bitmap block can maintain.
+ */
 static inline unsigned long
 nilfs_palloc_entries_per_group(const struct inode *inode)
 {
index 76c38e3e19d20ec53d708fcd3d8453c502092150..b27a342c5af681efb28154f0109111a6843a7ab6 100644 (file)
 #include "alloc.h"
 #include "dat.h"
 
-/**
- * struct nilfs_btree_path - A path on which B-tree operations are executed
- * @bp_bh: buffer head of node block
- * @bp_sib_bh: buffer head of sibling node block
- * @bp_index: index of child node
- * @bp_oldreq: ptr end request for old ptr
- * @bp_newreq: ptr alloc request for new ptr
- * @bp_op: rebalance operation
- */
-struct nilfs_btree_path {
-       struct buffer_head *bp_bh;
-       struct buffer_head *bp_sib_bh;
-       int bp_index;
-       union nilfs_bmap_ptr_req bp_oldreq;
-       union nilfs_bmap_ptr_req bp_newreq;
-       struct nilfs_btnode_chkey_ctxt bp_ctxt;
-       void (*bp_op)(struct nilfs_btree *, struct nilfs_btree_path *,
-                     int, __u64 *, __u64 *);
-};
-
-/*
- * B-tree path operations
- */
-
-static struct kmem_cache *nilfs_btree_path_cache;
-
-int __init nilfs_btree_path_cache_init(void)
-{
-       nilfs_btree_path_cache =
-               kmem_cache_create("nilfs2_btree_path_cache",
-                                 sizeof(struct nilfs_btree_path) *
-                                 NILFS_BTREE_LEVEL_MAX, 0, 0, NULL);
-       return (nilfs_btree_path_cache != NULL) ? 0 : -ENOMEM;
-}
-
-void nilfs_btree_path_cache_destroy(void)
-{
-       kmem_cache_destroy(nilfs_btree_path_cache);
-}
-
-static inline struct nilfs_btree_path *nilfs_btree_alloc_path(void)
-{
-       return kmem_cache_alloc(nilfs_btree_path_cache, GFP_NOFS);
-}
-
-static inline void nilfs_btree_free_path(struct nilfs_btree_path *path)
+static struct nilfs_btree_path *nilfs_btree_alloc_path(void)
 {
-       kmem_cache_free(nilfs_btree_path_cache, path);
-}
+       struct nilfs_btree_path *path;
+       int level = NILFS_BTREE_LEVEL_DATA;
 
-static void nilfs_btree_init_path(struct nilfs_btree_path *path)
-{
-       int level;
+       path = kmem_cache_alloc(nilfs_btree_path_cache, GFP_NOFS);
+       if (path == NULL)
+               goto out;
 
-       for (level = NILFS_BTREE_LEVEL_DATA;
-            level < NILFS_BTREE_LEVEL_MAX;
-            level++) {
+       for (; level < NILFS_BTREE_LEVEL_MAX; level++) {
                path[level].bp_bh = NULL;
                path[level].bp_sib_bh = NULL;
                path[level].bp_index = 0;
@@ -95,15 +48,19 @@ static void nilfs_btree_init_path(struct nilfs_btree_path *path)
                path[level].bp_newreq.bpr_ptr = NILFS_BMAP_INVALID_PTR;
                path[level].bp_op = NULL;
        }
+
+out:
+       return path;
 }
 
-static void nilfs_btree_release_path(struct nilfs_btree_path *path)
+static void nilfs_btree_free_path(struct nilfs_btree_path *path)
 {
-       int level;
+       int level = NILFS_BTREE_LEVEL_DATA;
 
-       for (level = NILFS_BTREE_LEVEL_DATA; level < NILFS_BTREE_LEVEL_MAX;
-            level++)
+       for (; level < NILFS_BTREE_LEVEL_MAX; level++)
                brelse(path[level].bp_bh);
+
+       kmem_cache_free(nilfs_btree_path_cache, path);
 }
 
 /*
@@ -566,14 +523,12 @@ static int nilfs_btree_lookup(const struct nilfs_bmap *bmap,
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
 
        ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level);
 
        if (ptrp != NULL)
                *ptrp = ptr;
 
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
 
        return ret;
@@ -594,7 +549,7 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
+
        ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level);
        if (ret < 0)
                goto out;
@@ -655,7 +610,6 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
        *ptrp = ptr;
        ret = cnt;
  out:
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
        return ret;
 }
@@ -1123,7 +1077,6 @@ static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
 
        ret = nilfs_btree_do_lookup(btree, path, key, NULL,
                                    NILFS_BTREE_LEVEL_NODE_MIN);
@@ -1140,7 +1093,6 @@ static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
        nilfs_bmap_add_blocks(bmap, stats.bs_nblocks);
 
  out:
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
        return ret;
 }
@@ -1456,7 +1408,7 @@ static int nilfs_btree_delete(struct nilfs_bmap *bmap, __u64 key)
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
+
        ret = nilfs_btree_do_lookup(btree, path, key, NULL,
                                    NILFS_BTREE_LEVEL_NODE_MIN);
        if (ret < 0)
@@ -1473,7 +1425,6 @@ static int nilfs_btree_delete(struct nilfs_bmap *bmap, __u64 key)
        nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks);
 
 out:
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
        return ret;
 }
@@ -1488,11 +1439,9 @@ static int nilfs_btree_last_key(const struct nilfs_bmap *bmap, __u64 *keyp)
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
 
        ret = nilfs_btree_do_lookup_last(btree, path, keyp, NULL);
 
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
 
        return ret;
@@ -1923,7 +1872,6 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
 
        if (buffer_nilfs_node(bh)) {
                node = (struct nilfs_btree_node *)bh->b_data;
@@ -1947,7 +1895,6 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
                nilfs_btree_propagate_p(btree, path, level, bh);
 
  out:
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
 
        return ret;
@@ -2108,7 +2055,6 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap,
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
 
        if (buffer_nilfs_node(*bh)) {
                node = (struct nilfs_btree_node *)(*bh)->b_data;
@@ -2130,7 +2076,6 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap,
                nilfs_btree_assign_p(btree, path, level, bh, blocknr, binfo);
 
  out:
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
 
        return ret;
@@ -2175,7 +2120,6 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
        path = nilfs_btree_alloc_path();
        if (path == NULL)
                return -ENOMEM;
-       nilfs_btree_init_path(path);
 
        ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level + 1);
        if (ret < 0) {
@@ -2195,7 +2139,6 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
                nilfs_bmap_set_dirty(&btree->bt_bmap);
 
  out:
-       nilfs_btree_release_path(path);
        nilfs_btree_free_path(path);
        return ret;
 }
index 4b82d84ade750e6e9e7f1d525428b916d5931219..af638d59e3bf5ef07064e57173dcc2f82328724f 100644 (file)
@@ -30,9 +30,6 @@
 #include "btnode.h"
 #include "bmap.h"
 
-struct nilfs_btree;
-struct nilfs_btree_path;
-
 /**
  * struct nilfs_btree - B-tree structure
  * @bt_bmap: bmap base structure
@@ -41,6 +38,25 @@ struct nilfs_btree {
        struct nilfs_bmap bt_bmap;
 };
 
+/**
+ * struct nilfs_btree_path - A path on which B-tree operations are executed
+ * @bp_bh: buffer head of node block
+ * @bp_sib_bh: buffer head of sibling node block
+ * @bp_index: index of child node
+ * @bp_oldreq: ptr end request for old ptr
+ * @bp_newreq: ptr alloc request for new ptr
+ * @bp_op: rebalance operation
+ */
+struct nilfs_btree_path {
+       struct buffer_head *bp_bh;
+       struct buffer_head *bp_sib_bh;
+       int bp_index;
+       union nilfs_bmap_ptr_req bp_oldreq;
+       union nilfs_bmap_ptr_req bp_newreq;
+       struct nilfs_btnode_chkey_ctxt bp_ctxt;
+       void (*bp_op)(struct nilfs_btree *, struct nilfs_btree_path *,
+                     int, __u64 *, __u64 *);
+};
 
 #define NILFS_BTREE_ROOT_SIZE          NILFS_BMAP_SIZE
 #define NILFS_BTREE_ROOT_NCHILDREN_MAX                                 \
@@ -57,6 +73,7 @@ struct nilfs_btree {
 #define NILFS_BTREE_KEY_MIN    ((__u64)0)
 #define NILFS_BTREE_KEY_MAX    (~(__u64)0)
 
+extern struct kmem_cache *nilfs_btree_path_cache;
 
 int nilfs_btree_path_cache_init(void);
 void nilfs_btree_path_cache_destroy(void);
index 0957b58f909dc414348ea4b2529da54a468aabd4..5e226d4b41d386661b454bedb6bd22ef25837f6f 100644 (file)
@@ -451,7 +451,7 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino,
                inode->i_op = &nilfs_special_inode_operations;
                init_special_inode(
                        inode, inode->i_mode,
-                       new_decode_dev(le64_to_cpu(raw_inode->i_device_code)));
+                       huge_decode_dev(le64_to_cpu(raw_inode->i_device_code)));
        }
        nilfs_ifile_unmap_inode(sbi->s_ifile, ino, bh);
        brelse(bh);
@@ -511,7 +511,7 @@ void nilfs_write_inode_common(struct inode *inode,
                nilfs_bmap_write(ii->i_bmap, raw_inode);
        else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
                raw_inode->i_device_code =
-                       cpu_to_le64(new_encode_dev(inode->i_rdev));
+                       cpu_to_le64(huge_encode_dev(inode->i_rdev));
        /* When extending inode, nilfs->ns_inode_size should be checked
           for substitutions of appended fields */
 }
index ba43146f3c309308cfd8505382570906f971ee57..bae2a516b4ee0b6d72277d470747ae92cf40b4c5 100644 (file)
@@ -105,6 +105,8 @@ static void store_segsum_info(struct nilfs_segsum_info *ssi,
 
        ssi->nsumblk = DIV_ROUND_UP(ssi->sumbytes, blocksize);
        ssi->nfileblk = ssi->nblocks - ssi->nsumblk - !!NILFS_SEG_HAS_SR(ssi);
+
+       /* need to verify ->ss_bytes field if read ->ss_cno */
 }
 
 /**
index 17851f77f739d1942c8f0aad04d78fd82b8347e4..2e6a2723b8fa56e3c65e3a83af3aa346184ce510 100644 (file)
@@ -40,35 +40,10 @@ struct nilfs_write_info {
        sector_t                blocknr;
 };
 
-
 static int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
                              struct the_nilfs *nilfs);
 static int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf);
 
-
-static struct kmem_cache *nilfs_segbuf_cachep;
-
-static void nilfs_segbuf_init_once(void *obj)
-{
-       memset(obj, 0, sizeof(struct nilfs_segment_buffer));
-}
-
-int __init nilfs_init_segbuf_cache(void)
-{
-       nilfs_segbuf_cachep =
-               kmem_cache_create("nilfs2_segbuf_cache",
-                                 sizeof(struct nilfs_segment_buffer),
-                                 0, SLAB_RECLAIM_ACCOUNT,
-                                 nilfs_segbuf_init_once);
-
-       return (nilfs_segbuf_cachep == NULL) ? -ENOMEM : 0;
-}
-
-void nilfs_destroy_segbuf_cache(void)
-{
-       kmem_cache_destroy(nilfs_segbuf_cachep);
-}
-
 struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *sb)
 {
        struct nilfs_segment_buffer *segbuf;
@@ -81,6 +56,7 @@ struct nilfs_segment_buffer *nilfs_segbuf_new(struct super_block *sb)
        INIT_LIST_HEAD(&segbuf->sb_list);
        INIT_LIST_HEAD(&segbuf->sb_segsum_buffers);
        INIT_LIST_HEAD(&segbuf->sb_payload_buffers);
+       segbuf->sb_super_root = NULL;
 
        init_completion(&segbuf->sb_bio_event);
        atomic_set(&segbuf->sb_err, 0);
@@ -158,7 +134,7 @@ int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *segbuf,
 }
 
 int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned flags,
-                      time_t ctime)
+                      time_t ctime, __u64 cno)
 {
        int err;
 
@@ -171,6 +147,7 @@ int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned flags,
        segbuf->sb_sum.sumbytes = sizeof(struct nilfs_segment_summary);
        segbuf->sb_sum.nfinfo = segbuf->sb_sum.nfileblk = 0;
        segbuf->sb_sum.ctime = ctime;
+       segbuf->sb_sum.cno = cno;
        return 0;
 }
 
@@ -196,13 +173,14 @@ void nilfs_segbuf_fill_in_segsum(struct nilfs_segment_buffer *segbuf)
        raw_sum->ss_nfinfo   = cpu_to_le32(segbuf->sb_sum.nfinfo);
        raw_sum->ss_sumbytes = cpu_to_le32(segbuf->sb_sum.sumbytes);
        raw_sum->ss_pad      = 0;
+       raw_sum->ss_cno      = cpu_to_le64(segbuf->sb_sum.cno);
 }
 
 /*
  * CRC calculation routines
  */
-void nilfs_segbuf_fill_in_segsum_crc(struct nilfs_segment_buffer *segbuf,
-                                    u32 seed)
+static void
+nilfs_segbuf_fill_in_segsum_crc(struct nilfs_segment_buffer *segbuf, u32 seed)
 {
        struct buffer_head *bh;
        struct nilfs_segment_summary *raw_sum;
@@ -229,8 +207,8 @@ void nilfs_segbuf_fill_in_segsum_crc(struct nilfs_segment_buffer *segbuf,
        raw_sum->ss_sumsum = cpu_to_le32(crc);
 }
 
-void nilfs_segbuf_fill_in_data_crc(struct nilfs_segment_buffer *segbuf,
-                                  u32 seed)
+static void nilfs_segbuf_fill_in_data_crc(struct nilfs_segment_buffer *segbuf,
+                                         u32 seed)
 {
        struct buffer_head *bh;
        struct nilfs_segment_summary *raw_sum;
@@ -256,6 +234,20 @@ void nilfs_segbuf_fill_in_data_crc(struct nilfs_segment_buffer *segbuf,
        raw_sum->ss_datasum = cpu_to_le32(crc);
 }
 
+static void
+nilfs_segbuf_fill_in_super_root_crc(struct nilfs_segment_buffer *segbuf,
+                                   u32 seed)
+{
+       struct nilfs_super_root *raw_sr;
+       u32 crc;
+
+       raw_sr = (struct nilfs_super_root *)segbuf->sb_super_root->b_data;
+       crc = crc32_le(seed,
+                      (unsigned char *)raw_sr + sizeof(raw_sr->sr_sum),
+                      NILFS_SR_BYTES - sizeof(raw_sr->sr_sum));
+       raw_sr->sr_sum = cpu_to_le32(crc);
+}
+
 static void nilfs_release_buffers(struct list_head *list)
 {
        struct buffer_head *bh, *n;
@@ -282,6 +274,7 @@ static void nilfs_segbuf_clear(struct nilfs_segment_buffer *segbuf)
 {
        nilfs_release_buffers(&segbuf->sb_segsum_buffers);
        nilfs_release_buffers(&segbuf->sb_payload_buffers);
+       segbuf->sb_super_root = NULL;
 }
 
 /*
@@ -334,6 +327,23 @@ int nilfs_wait_on_logs(struct list_head *logs)
        return ret;
 }
 
+/**
+ * nilfs_add_checksums_on_logs - add checksums on the logs
+ * @logs: list of segment buffers storing target logs
+ * @seed: checksum seed value
+ */
+void nilfs_add_checksums_on_logs(struct list_head *logs, u32 seed)
+{
+       struct nilfs_segment_buffer *segbuf;
+
+       list_for_each_entry(segbuf, logs, sb_list) {
+               if (segbuf->sb_super_root)
+                       nilfs_segbuf_fill_in_super_root_crc(segbuf, seed);
+               nilfs_segbuf_fill_in_segsum_crc(segbuf, seed);
+               nilfs_segbuf_fill_in_data_crc(segbuf, seed);
+       }
+}
+
 /*
  * BIO operations
  */
index 94dfd3517bc0f5f8f96f0d4efc4588a0ff7dc775..fdf1c3b6d6739c6cc76bd451ee8230b573800acf 100644 (file)
@@ -37,6 +37,7 @@
  * @sumbytes: Byte count of segment summary
  * @nfileblk: Total number of file blocks
  * @seg_seq: Segment sequence number
+ * @cno: Checkpoint number
  * @ctime: Creation time
  * @next: Block number of the next full segment
  */
@@ -48,6 +49,7 @@ struct nilfs_segsum_info {
        unsigned long           sumbytes;
        unsigned long           nfileblk;
        u64                     seg_seq;
+       __u64                   cno;
        time_t                  ctime;
        sector_t                next;
 };
@@ -76,6 +78,7 @@ struct nilfs_segsum_info {
  * @sb_rest_blocks: Number of residual blocks in the current segment
  * @sb_segsum_buffers: List of buffers for segment summaries
  * @sb_payload_buffers: List of buffers for segment payload
+ * @sb_super_root: Pointer to buffer storing a super root block (if exists)
  * @sb_nbio: Number of flying bio requests
  * @sb_err: I/O error status
  * @sb_bio_event: Completion event of log writing
@@ -95,6 +98,7 @@ struct nilfs_segment_buffer {
        /* Buffers */
        struct list_head        sb_segsum_buffers;
        struct list_head        sb_payload_buffers; /* including super root */
+       struct buffer_head     *sb_super_root;
 
        /* io status */
        int                     sb_nbio;
@@ -121,6 +125,7 @@ struct nilfs_segment_buffer {
                    b_assoc_buffers))
 #define NILFS_SEGBUF_BH_IS_LAST(bh, head)  ((bh)->b_assoc_buffers.next == head)
 
+extern struct kmem_cache *nilfs_segbuf_cachep;
 
 int __init nilfs_init_segbuf_cache(void);
 void nilfs_destroy_segbuf_cache(void);
@@ -132,13 +137,11 @@ void nilfs_segbuf_map_cont(struct nilfs_segment_buffer *segbuf,
                           struct nilfs_segment_buffer *prev);
 void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *, __u64,
                                  struct the_nilfs *);
-int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned, time_t);
+int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned, time_t, __u64);
 int nilfs_segbuf_extend_segsum(struct nilfs_segment_buffer *);
 int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *,
                                struct buffer_head **);
 void nilfs_segbuf_fill_in_segsum(struct nilfs_segment_buffer *);
-void nilfs_segbuf_fill_in_segsum_crc(struct nilfs_segment_buffer *, u32);
-void nilfs_segbuf_fill_in_data_crc(struct nilfs_segment_buffer *, u32);
 
 static inline void
 nilfs_segbuf_add_segsum_buffer(struct nilfs_segment_buffer *segbuf,
@@ -171,6 +174,7 @@ void nilfs_truncate_logs(struct list_head *logs,
                         struct nilfs_segment_buffer *last);
 int nilfs_write_logs(struct list_head *logs, struct the_nilfs *nilfs);
 int nilfs_wait_on_logs(struct list_head *logs);
+void nilfs_add_checksums_on_logs(struct list_head *logs, u32 seed);
 
 static inline void nilfs_destroy_logs(struct list_head *logs)
 {
index 6a7dbd8451db73d40080156ff325c82183437f51..c9201649cc49f65e92a42cb3cd1fbe6c81e9184d 100644 (file)
@@ -116,42 +116,6 @@ static void nilfs_dispose_list(struct nilfs_sb_info *, struct list_head *,
 #define nilfs_cnt32_lt(a, b)  nilfs_cnt32_gt(b, a)
 #define nilfs_cnt32_le(a, b)  nilfs_cnt32_ge(b, a)
 
-/*
- * Transaction
- */
-static struct kmem_cache *nilfs_transaction_cachep;
-
-/**
- * nilfs_init_transaction_cache - create a cache for nilfs_transaction_info
- *
- * nilfs_init_transaction_cache() creates a slab cache for the struct
- * nilfs_transaction_info.
- *
- * Return Value: On success, it returns 0. On error, one of the following
- * negative error code is returned.
- *
- * %-ENOMEM - Insufficient memory available.
- */
-int nilfs_init_transaction_cache(void)
-{
-       nilfs_transaction_cachep =
-               kmem_cache_create("nilfs2_transaction_cache",
-                                 sizeof(struct nilfs_transaction_info),
-                                 0, SLAB_RECLAIM_ACCOUNT, NULL);
-       return (nilfs_transaction_cachep == NULL) ? -ENOMEM : 0;
-}
-
-/**
- * nilfs_destroy_transaction_cache - destroy the cache for transaction info
- *
- * nilfs_destroy_transaction_cache() frees the slab cache for the struct
- * nilfs_transaction_info.
- */
-void nilfs_destroy_transaction_cache(void)
-{
-       kmem_cache_destroy(nilfs_transaction_cachep);
-}
-
 static int nilfs_prepare_segment_lock(struct nilfs_transaction_info *ti)
 {
        struct nilfs_transaction_info *cur_ti = current->journal_info;
@@ -402,7 +366,8 @@ static int nilfs_segctor_reset_segment_buffer(struct nilfs_sc_info *sci)
 
        if (nilfs_doing_gc())
                flags = NILFS_SS_GC;
-       err = nilfs_segbuf_reset(segbuf, flags, sci->sc_seg_ctime);
+       err = nilfs_segbuf_reset(segbuf, flags, sci->sc_seg_ctime,
+                                sci->sc_sbi->s_nilfs->ns_cno);
        if (unlikely(err))
                return err;
 
@@ -435,7 +400,7 @@ static int nilfs_segctor_add_super_root(struct nilfs_sc_info *sci)
                        return err;
                segbuf = sci->sc_curseg;
        }
-       err = nilfs_segbuf_extend_payload(segbuf, &sci->sc_super_root);
+       err = nilfs_segbuf_extend_payload(segbuf, &segbuf->sb_super_root);
        if (likely(!err))
                segbuf->sb_sum.flags |= NILFS_SS_SR;
        return err;
@@ -599,7 +564,7 @@ static void nilfs_write_file_node_binfo(struct nilfs_sc_info *sci,
        *vblocknr = binfo->bi_v.bi_vblocknr;
 }
 
-struct nilfs_sc_operations nilfs_sc_file_ops = {
+static struct nilfs_sc_operations nilfs_sc_file_ops = {
        .collect_data = nilfs_collect_file_data,
        .collect_node = nilfs_collect_file_node,
        .collect_bmap = nilfs_collect_file_bmap,
@@ -649,7 +614,7 @@ static void nilfs_write_dat_node_binfo(struct nilfs_sc_info *sci,
        *binfo_dat = binfo->bi_dat;
 }
 
-struct nilfs_sc_operations nilfs_sc_dat_ops = {
+static struct nilfs_sc_operations nilfs_sc_dat_ops = {
        .collect_data = nilfs_collect_dat_data,
        .collect_node = nilfs_collect_file_node,
        .collect_bmap = nilfs_collect_dat_bmap,
@@ -657,7 +622,7 @@ struct nilfs_sc_operations nilfs_sc_dat_ops = {
        .write_node_binfo = nilfs_write_dat_node_binfo,
 };
 
-struct nilfs_sc_operations nilfs_sc_dsync_ops = {
+static struct nilfs_sc_operations nilfs_sc_dsync_ops = {
        .collect_data = nilfs_collect_file_data,
        .collect_node = NULL,
        .collect_bmap = NULL,
@@ -932,43 +897,16 @@ static void nilfs_segctor_fill_in_file_bmap(struct nilfs_sc_info *sci,
        }
 }
 
-/*
- * CRC calculation routines
- */
-static void nilfs_fill_in_super_root_crc(struct buffer_head *bh_sr, u32 seed)
-{
-       struct nilfs_super_root *raw_sr =
-               (struct nilfs_super_root *)bh_sr->b_data;
-       u32 crc;
-
-       crc = crc32_le(seed,
-                      (unsigned char *)raw_sr + sizeof(raw_sr->sr_sum),
-                      NILFS_SR_BYTES - sizeof(raw_sr->sr_sum));
-       raw_sr->sr_sum = cpu_to_le32(crc);
-}
-
-static void nilfs_segctor_fill_in_checksums(struct nilfs_sc_info *sci,
-                                           u32 seed)
-{
-       struct nilfs_segment_buffer *segbuf;
-
-       if (sci->sc_super_root)
-               nilfs_fill_in_super_root_crc(sci->sc_super_root, seed);
-
-       list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
-               nilfs_segbuf_fill_in_segsum_crc(segbuf, seed);
-               nilfs_segbuf_fill_in_data_crc(segbuf, seed);
-       }
-}
-
 static void nilfs_segctor_fill_in_super_root(struct nilfs_sc_info *sci,
                                             struct the_nilfs *nilfs)
 {
-       struct buffer_head *bh_sr = sci->sc_super_root;
-       struct nilfs_super_root *raw_sr =
-               (struct nilfs_super_root *)bh_sr->b_data;
+       struct buffer_head *bh_sr;
+       struct nilfs_super_root *raw_sr;
        unsigned isz = nilfs->ns_inode_size;
 
+       bh_sr = NILFS_LAST_SEGBUF(&sci->sc_segbufs)->sb_super_root;
+       raw_sr = (struct nilfs_super_root *)bh_sr->b_data;
+
        raw_sr->sr_bytes = cpu_to_le16(NILFS_SR_BYTES);
        raw_sr->sr_nongc_ctime
                = cpu_to_le64(nilfs_doing_gc() ?
@@ -1491,7 +1429,6 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
 
        /* Collection retry loop */
        for (;;) {
-               sci->sc_super_root = NULL;
                sci->sc_nblk_this_inc = 0;
                sci->sc_curseg = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
 
@@ -1568,7 +1505,7 @@ nilfs_segctor_update_payload_blocknr(struct nilfs_sc_info *sci,
        ssp.offset = sizeof(struct nilfs_segment_summary);
 
        list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) {
-               if (bh == sci->sc_super_root)
+               if (bh == segbuf->sb_super_root)
                        break;
                if (!finfo) {
                        finfo = nilfs_segctor_map_segsum_entry(
@@ -1729,7 +1666,7 @@ static int nilfs_segctor_prepare_write(struct nilfs_sc_info *sci,
 
                list_for_each_entry(bh, &segbuf->sb_payload_buffers,
                                    b_assoc_buffers) {
-                       if (bh == sci->sc_super_root) {
+                       if (bh == segbuf->sb_super_root) {
                                if (bh->b_page != bd_page) {
                                        lock_page(bd_page);
                                        clear_page_dirty_for_io(bd_page);
@@ -1848,7 +1785,7 @@ static void nilfs_clear_copied_buffers(struct list_head *list, int err)
 }
 
 static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page,
-                            struct buffer_head *bh_sr, int err)
+                            int err)
 {
        struct nilfs_segment_buffer *segbuf;
        struct page *bd_page = NULL, *fs_page = NULL;
@@ -1869,7 +1806,7 @@ static void nilfs_abort_logs(struct list_head *logs, struct page *failed_page,
 
                list_for_each_entry(bh, &segbuf->sb_payload_buffers,
                                    b_assoc_buffers) {
-                       if (bh == bh_sr) {
+                       if (bh == segbuf->sb_super_root) {
                                if (bh->b_page != bd_page) {
                                        end_page_writeback(bd_page);
                                        bd_page = bh->b_page;
@@ -1898,7 +1835,7 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
 
        list_splice_tail_init(&sci->sc_write_logs, &logs);
        ret = nilfs_wait_on_logs(&logs);
-       nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret ? : err);
+       nilfs_abort_logs(&logs, NULL, ret ? : err);
 
        list_splice_tail_init(&sci->sc_segbufs, &logs);
        nilfs_cancel_segusage(&logs, nilfs->ns_sufile);
@@ -1914,7 +1851,6 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci,
        }
 
        nilfs_destroy_logs(&logs);
-       sci->sc_super_root = NULL;
 }
 
 static void nilfs_set_next_segment(struct the_nilfs *nilfs,
@@ -1933,7 +1869,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
        struct nilfs_segment_buffer *segbuf;
        struct page *bd_page = NULL, *fs_page = NULL;
        struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs;
-       int update_sr = (sci->sc_super_root != NULL);
+       int update_sr = false;
 
        list_for_each_entry(segbuf, &sci->sc_write_logs, sb_list) {
                struct buffer_head *bh;
@@ -1964,11 +1900,12 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
                        set_buffer_uptodate(bh);
                        clear_buffer_dirty(bh);
                        clear_buffer_nilfs_volatile(bh);
-                       if (bh == sci->sc_super_root) {
+                       if (bh == segbuf->sb_super_root) {
                                if (bh->b_page != bd_page) {
                                        end_page_writeback(bd_page);
                                        bd_page = bh->b_page;
                                }
+                               update_sr = true;
                                break;
                        }
                        if (bh->b_page != fs_page) {
@@ -2115,7 +2052,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
        struct nilfs_sb_info *sbi = sci->sc_sbi;
        struct the_nilfs *nilfs = sbi->s_nilfs;
        struct page *failed_page;
-       int err, has_sr = 0;
+       int err;
 
        sci->sc_stage.scnt = NILFS_ST_INIT;
 
@@ -2143,8 +2080,6 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
                if (unlikely(err))
                        goto failed;
 
-               has_sr = (sci->sc_super_root != NULL);
-
                /* Avoid empty segment */
                if (sci->sc_stage.scnt == NILFS_ST_DONE &&
                    NILFS_SEG_EMPTY(&sci->sc_curseg->sb_sum)) {
@@ -2159,7 +2094,8 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
                if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
                        nilfs_segctor_fill_in_file_bmap(sci, sbi->s_ifile);
 
-               if (has_sr) {
+               if (mode == SC_LSEG_SR &&
+                   sci->sc_stage.scnt >= NILFS_ST_CPFILE) {
                        err = nilfs_segctor_fill_in_checkpoint(sci);
                        if (unlikely(err))
                                goto failed_to_write;
@@ -2171,11 +2107,12 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
                /* Write partial segments */
                err = nilfs_segctor_prepare_write(sci, &failed_page);
                if (err) {
-                       nilfs_abort_logs(&sci->sc_segbufs, failed_page,
-                                        sci->sc_super_root, err);
+                       nilfs_abort_logs(&sci->sc_segbufs, failed_page, err);
                        goto failed_to_write;
                }
-               nilfs_segctor_fill_in_checksums(sci, nilfs->ns_crc_seed);
+
+               nilfs_add_checksums_on_logs(&sci->sc_segbufs,
+                                           nilfs->ns_crc_seed);
 
                err = nilfs_segctor_write(sci, nilfs);
                if (unlikely(err))
@@ -2196,8 +2133,6 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
                }
        } while (sci->sc_stage.scnt != NILFS_ST_DONE);
 
-       sci->sc_super_root = NULL;
-
  out:
        nilfs_segctor_check_out_files(sci, sbi);
        return err;
@@ -2224,9 +2159,9 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
 static void nilfs_segctor_start_timer(struct nilfs_sc_info *sci)
 {
        spin_lock(&sci->sc_state_lock);
-       if (sci->sc_timer && !(sci->sc_state & NILFS_SEGCTOR_COMMIT)) {
-               sci->sc_timer->expires = jiffies + sci->sc_interval;
-               add_timer(sci->sc_timer);
+       if (!(sci->sc_state & NILFS_SEGCTOR_COMMIT)) {
+               sci->sc_timer.expires = jiffies + sci->sc_interval;
+               add_timer(&sci->sc_timer);
                sci->sc_state |= NILFS_SEGCTOR_COMMIT;
        }
        spin_unlock(&sci->sc_state_lock);
@@ -2431,9 +2366,7 @@ static void nilfs_segctor_accept(struct nilfs_sc_info *sci)
        spin_lock(&sci->sc_state_lock);
        sci->sc_seq_accepted = sci->sc_seq_request;
        spin_unlock(&sci->sc_state_lock);
-
-       if (sci->sc_timer)
-               del_timer_sync(sci->sc_timer);
+       del_timer_sync(&sci->sc_timer);
 }
 
 /**
@@ -2459,9 +2392,9 @@ static void nilfs_segctor_notify(struct nilfs_sc_info *sci, int mode, int err)
                        sci->sc_flush_request &= ~FLUSH_DAT_BIT;
 
                /* re-enable timer if checkpoint creation was not done */
-               if (sci->sc_timer && (sci->sc_state & NILFS_SEGCTOR_COMMIT) &&
-                   time_before(jiffies, sci->sc_timer->expires))
-                       add_timer(sci->sc_timer);
+               if ((sci->sc_state & NILFS_SEGCTOR_COMMIT) &&
+                   time_before(jiffies, sci->sc_timer.expires))
+                       add_timer(&sci->sc_timer);
        }
        spin_unlock(&sci->sc_state_lock);
 }
@@ -2640,13 +2573,10 @@ static int nilfs_segctor_thread(void *arg)
 {
        struct nilfs_sc_info *sci = (struct nilfs_sc_info *)arg;
        struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs;
-       struct timer_list timer;
        int timeout = 0;
 
-       init_timer(&timer);
-       timer.data = (unsigned long)current;
-       timer.function = nilfs_construction_timeout;
-       sci->sc_timer = &timer;
+       sci->sc_timer.data = (unsigned long)current;
+       sci->sc_timer.function = nilfs_construction_timeout;
 
        /* start sync. */
        sci->sc_task = current;
@@ -2695,7 +2625,7 @@ static int nilfs_segctor_thread(void *arg)
                        should_sleep = 0;
                else if (sci->sc_state & NILFS_SEGCTOR_COMMIT)
                        should_sleep = time_before(jiffies,
-                                                  sci->sc_timer->expires);
+                                       sci->sc_timer.expires);
 
                if (should_sleep) {
                        spin_unlock(&sci->sc_state_lock);
@@ -2704,7 +2634,7 @@ 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));
+                          time_after_eq(jiffies, sci->sc_timer.expires));
 
                if (nilfs_sb_dirty(nilfs) && nilfs_sb_need_update(nilfs))
                        set_nilfs_discontinued(nilfs);
@@ -2713,8 +2643,6 @@ static int nilfs_segctor_thread(void *arg)
 
  end_thread:
        spin_unlock(&sci->sc_state_lock);
-       del_timer_sync(sci->sc_timer);
-       sci->sc_timer = NULL;
 
        /* end sync. */
        sci->sc_task = NULL;
@@ -2750,13 +2678,6 @@ static void nilfs_segctor_kill_thread(struct nilfs_sc_info *sci)
        }
 }
 
-static int nilfs_segctor_init(struct nilfs_sc_info *sci)
-{
-       sci->sc_seq_done = sci->sc_seq_request;
-
-       return nilfs_segctor_start_thread(sci);
-}
-
 /*
  * Setup & clean-up functions
  */
@@ -2780,6 +2701,7 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi)
        INIT_LIST_HEAD(&sci->sc_write_logs);
        INIT_LIST_HEAD(&sci->sc_gc_inodes);
        INIT_LIST_HEAD(&sci->sc_copied_buffers);
+       init_timer(&sci->sc_timer);
 
        sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT;
        sci->sc_mjcp_freq = HZ * NILFS_SC_DEFAULT_SR_FREQ;
@@ -2846,6 +2768,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
 
        down_write(&sbi->s_nilfs->ns_segctor_sem);
 
+       del_timer_sync(&sci->sc_timer);
        kfree(sci);
 }
 
@@ -2880,7 +2803,7 @@ int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi)
                return -ENOMEM;
 
        nilfs_attach_writer(nilfs, sbi);
-       err = nilfs_segctor_init(NILFS_SC(sbi));
+       err = nilfs_segctor_start_thread(NILFS_SC(sbi));
        if (err) {
                nilfs_detach_writer(nilfs, sbi);
                kfree(sbi->s_sc_info);
index 82dfd6a686b9827327e0f6236990e1d5c61e5175..dca142361ccfcac8f038453ec689ee61a97012fa 100644 (file)
@@ -100,7 +100,6 @@ struct nilfs_segsum_pointer {
  * @sc_write_logs: List of segment buffers to hold logs under writing
  * @sc_segbuf_nblocks: Number of available blocks in segment buffers.
  * @sc_curseg: Current segment buffer
- * @sc_super_root: Pointer to the super root buffer
  * @sc_stage: Collection stage
  * @sc_finfo_ptr: pointer to the current finfo struct in the segment summary
  * @sc_binfo_ptr: pointer to the current binfo struct in the segment summary
@@ -148,7 +147,6 @@ struct nilfs_sc_info {
        struct list_head        sc_write_logs;
        unsigned long           sc_segbuf_nblocks;
        struct nilfs_segment_buffer *sc_curseg;
-       struct buffer_head     *sc_super_root;
 
        struct nilfs_cstage     sc_stage;
 
@@ -179,7 +177,7 @@ struct nilfs_sc_info {
        unsigned long           sc_lseg_stime;  /* in 1/HZ seconds */
        unsigned long           sc_watermark;
 
-       struct timer_list      *sc_timer;
+       struct timer_list       sc_timer;
        struct task_struct     *sc_task;
 };
 
@@ -219,6 +217,8 @@ enum {
  */
 #define NILFS_SC_DEFAULT_WATERMARK  3600
 
+/* super.c */
+extern struct kmem_cache *nilfs_transaction_cachep;
 
 /* segment.c */
 extern int nilfs_init_transaction_cache(void);
index 48145f505a6a8e7dbd33c8435b259a0e828a3f8c..03b34b738993fb39c006c1b3248e4f36488e4558 100644 (file)
@@ -67,6 +67,11 @@ MODULE_DESCRIPTION("A New Implementation of the Log-structured Filesystem "
                   "(NILFS)");
 MODULE_LICENSE("GPL");
 
+struct kmem_cache *nilfs_inode_cachep;
+struct kmem_cache *nilfs_transaction_cachep;
+struct kmem_cache *nilfs_segbuf_cachep;
+struct kmem_cache *nilfs_btree_path_cache;
+
 static int nilfs_remount(struct super_block *sb, int *flags, char *data);
 
 /**
@@ -129,7 +134,6 @@ void nilfs_warning(struct super_block *sb, const char *function,
        va_end(args);
 }
 
-static struct kmem_cache *nilfs_inode_cachep;
 
 struct inode *nilfs_alloc_inode_common(struct the_nilfs *nilfs)
 {
@@ -155,34 +159,6 @@ void nilfs_destroy_inode(struct inode *inode)
        kmem_cache_free(nilfs_inode_cachep, NILFS_I(inode));
 }
 
-static void init_once(void *obj)
-{
-       struct nilfs_inode_info *ii = obj;
-
-       INIT_LIST_HEAD(&ii->i_dirty);
-#ifdef CONFIG_NILFS_XATTR
-       init_rwsem(&ii->xattr_sem);
-#endif
-       nilfs_btnode_cache_init_once(&ii->i_btnode_cache);
-       ii->i_bmap = (struct nilfs_bmap *)&ii->i_bmap_union;
-       inode_init_once(&ii->vfs_inode);
-}
-
-static int nilfs_init_inode_cache(void)
-{
-       nilfs_inode_cachep = kmem_cache_create("nilfs2_inode_cache",
-                                              sizeof(struct nilfs_inode_info),
-                                              0, SLAB_RECLAIM_ACCOUNT,
-                                              init_once);
-
-       return (nilfs_inode_cachep == NULL) ? -ENOMEM : 0;
-}
-
-static inline void nilfs_destroy_inode_cache(void)
-{
-       kmem_cache_destroy(nilfs_inode_cachep);
-}
-
 static void nilfs_clear_inode(struct inode *inode)
 {
        struct nilfs_inode_info *ii = NILFS_I(inode);
@@ -266,8 +242,8 @@ int nilfs_commit_super(struct nilfs_sb_info *sbi, int dupsb)
        int err;
 
        /* nilfs->sem must be locked by the caller. */
-       if (sbp[0]->s_magic != NILFS_SUPER_MAGIC) {
-               if (sbp[1] && sbp[1]->s_magic == NILFS_SUPER_MAGIC)
+       if (sbp[0]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) {
+               if (sbp[1] && sbp[1]->s_magic == cpu_to_le16(NILFS_SUPER_MAGIC))
                        nilfs_swap_super_block(nilfs);
                else {
                        printk(KERN_CRIT "NILFS: superblock broke on dev %s\n",
@@ -470,10 +446,10 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
        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, ERRORS_CONT))
+               seq_printf(seq, ",errors=continue");
        if (nilfs_test_opt(sbi, STRICT_ORDER))
                seq_printf(seq, ",order=strict");
        if (nilfs_test_opt(sbi, NORECOVERY))
@@ -631,7 +607,7 @@ nilfs_set_default_options(struct nilfs_sb_info *sbi,
                          struct nilfs_super_block *sbp)
 {
        sbi->s_mount_opt =
-               NILFS_MOUNT_ERRORS_CONT | NILFS_MOUNT_BARRIER;
+               NILFS_MOUNT_ERRORS_RO | NILFS_MOUNT_BARRIER;
 }
 
 static int nilfs_setup_super(struct nilfs_sb_info *sbi)
@@ -778,9 +754,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
                                goto failed_sbi;
                        }
                        cno = sbi->s_snapshot_cno;
-               } else
-                       /* Read-only mount */
-                       sbi->s_snapshot_cno = cno;
+               }
        }
 
        err = nilfs_attach_checkpoint(sbi, cno);
@@ -849,7 +823,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
        struct the_nilfs *nilfs = sbi->s_nilfs;
        unsigned long old_sb_flags;
        struct nilfs_mount_options old_opts;
-       int err;
+       int was_snapshot, err;
 
        lock_kernel();
 
@@ -857,6 +831,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
        old_sb_flags = sb->s_flags;
        old_opts.mount_opt = sbi->s_mount_opt;
        old_opts.snapshot_cno = sbi->s_snapshot_cno;
+       was_snapshot = nilfs_test_opt(sbi, SNAPSHOT);
 
        if (!parse_options(data, sb)) {
                err = -EINVAL;
@@ -864,20 +839,32 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
        }
        sb->s_flags = (sb->s_flags & ~MS_POSIXACL);
 
-       if ((*flags & MS_RDONLY) &&
-           sbi->s_snapshot_cno != old_opts.snapshot_cno) {
-               printk(KERN_WARNING "NILFS (device %s): couldn't "
-                      "remount to a different snapshot.\n",
-                      sb->s_id);
-               err = -EINVAL;
-               goto restore_opts;
+       err = -EINVAL;
+       if (was_snapshot) {
+               if (!(*flags & MS_RDONLY)) {
+                       printk(KERN_ERR "NILFS (device %s): cannot remount "
+                              "snapshot read/write.\n",
+                              sb->s_id);
+                       goto restore_opts;
+               } else if (sbi->s_snapshot_cno != old_opts.snapshot_cno) {
+                       printk(KERN_ERR "NILFS (device %s): cannot "
+                              "remount to a different snapshot.\n",
+                              sb->s_id);
+                       goto restore_opts;
+               }
+       } else {
+               if (nilfs_test_opt(sbi, SNAPSHOT)) {
+                       printk(KERN_ERR "NILFS (device %s): cannot change "
+                              "a regular mount to a snapshot.\n",
+                              sb->s_id);
+                       goto restore_opts;
+               }
        }
 
        if (!nilfs_valid_fs(nilfs)) {
                printk(KERN_WARNING "NILFS (device %s): couldn't "
                       "remount because the filesystem is in an "
                       "incomplete recovery state.\n", sb->s_id);
-               err = -EINVAL;
                goto restore_opts;
        }
 
@@ -888,9 +875,6 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
                nilfs_detach_segment_constructor(sbi);
                sb->s_flags |= MS_RDONLY;
 
-               sbi->s_snapshot_cno = nilfs_last_cno(nilfs);
-               /* nilfs_set_opt(sbi, SNAPSHOT); */
-
                /*
                 * Remounting a valid RW partition RDONLY, so set
                 * the RDONLY flag and then mark the partition as valid again.
@@ -909,24 +893,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
                 * store the current valid flag.  (It may have been changed
                 * by fsck since we originally mounted the partition.)
                 */
-               if (nilfs->ns_current && nilfs->ns_current != sbi) {
-                       printk(KERN_WARNING "NILFS (device %s): couldn't "
-                              "remount because an RW-mount exists.\n",
-                              sb->s_id);
-                       err = -EBUSY;
-                       goto restore_opts;
-               }
-               if (sbi->s_snapshot_cno != nilfs_last_cno(nilfs)) {
-                       printk(KERN_WARNING "NILFS (device %s): couldn't "
-                              "remount because the current RO-mount is not "
-                              "the latest one.\n",
-                              sb->s_id);
-                       err = -EINVAL;
-                       goto restore_opts;
-               }
                sb->s_flags &= ~MS_RDONLY;
-               nilfs_clear_opt(sbi, SNAPSHOT);
-               sbi->s_snapshot_cno = 0;
 
                err = nilfs_attach_segment_constructor(sbi);
                if (err)
@@ -935,8 +902,6 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
                down_write(&nilfs->ns_sem);
                nilfs_setup_super(sbi);
                up_write(&nilfs->ns_sem);
-
-               nilfs->ns_current = sbi;
        }
  out:
        up_write(&nilfs->ns_super_sem);
@@ -1022,10 +987,14 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
 {
        struct nilfs_super_data sd;
        struct super_block *s;
+       fmode_t mode = FMODE_READ;
        struct the_nilfs *nilfs;
        int err, need_to_close = 1;
 
-       sd.bdev = open_bdev_exclusive(dev_name, flags, fs_type);
+       if (!(flags & MS_RDONLY))
+               mode |= FMODE_WRITE;
+
+       sd.bdev = open_bdev_exclusive(dev_name, mode, fs_type);
        if (IS_ERR(sd.bdev))
                return PTR_ERR(sd.bdev);
 
@@ -1092,10 +1061,12 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
 
                /* New superblock instance created */
                s->s_flags = flags;
+               s->s_mode = mode;
                strlcpy(s->s_id, bdevname(sd.bdev, b), sizeof(s->s_id));
                sb_set_blocksize(s, block_size(sd.bdev));
 
-               err = nilfs_fill_super(s, data, flags & MS_VERBOSE, nilfs);
+               err = nilfs_fill_super(s, data, flags & MS_SILENT ? 1 : 0,
+                                      nilfs);
                if (err)
                        goto cancel_new;
 
@@ -1106,7 +1077,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
        mutex_unlock(&nilfs->ns_mount_mutex);
        put_nilfs(nilfs);
        if (need_to_close)
-               close_bdev_exclusive(sd.bdev, flags);
+               close_bdev_exclusive(sd.bdev, mode);
        simple_set_mnt(mnt, s);
        return 0;
 
@@ -1114,7 +1085,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
        mutex_unlock(&nilfs->ns_mount_mutex);
        put_nilfs(nilfs);
  failed:
-       close_bdev_exclusive(sd.bdev, flags);
+       close_bdev_exclusive(sd.bdev, mode);
 
        return err;
 
@@ -1124,7 +1095,7 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
        put_nilfs(nilfs);
        deactivate_locked_super(s);
        /*
-        * deactivate_super() invokes close_bdev_exclusive().
+        * deactivate_locked_super() invokes close_bdev_exclusive().
         * We must finish all post-cleaning before this call;
         * put_nilfs() needs the block device.
         */
@@ -1139,54 +1110,93 @@ struct file_system_type nilfs_fs_type = {
        .fs_flags = FS_REQUIRES_DEV,
 };
 
-static int __init init_nilfs_fs(void)
+static void nilfs_inode_init_once(void *obj)
 {
-       int err;
-
-       err = nilfs_init_inode_cache();
-       if (err)
-               goto failed;
+       struct nilfs_inode_info *ii = obj;
 
-       err = nilfs_init_transaction_cache();
-       if (err)
-               goto failed_inode_cache;
+       INIT_LIST_HEAD(&ii->i_dirty);
+#ifdef CONFIG_NILFS_XATTR
+       init_rwsem(&ii->xattr_sem);
+#endif
+       nilfs_btnode_cache_init_once(&ii->i_btnode_cache);
+       ii->i_bmap = (struct nilfs_bmap *)&ii->i_bmap_union;
+       inode_init_once(&ii->vfs_inode);
+}
 
-       err = nilfs_init_segbuf_cache();
-       if (err)
-               goto failed_transaction_cache;
+static void nilfs_segbuf_init_once(void *obj)
+{
+       memset(obj, 0, sizeof(struct nilfs_segment_buffer));
+}
 
-       err = nilfs_btree_path_cache_init();
-       if (err)
-               goto failed_segbuf_cache;
+static void nilfs_destroy_cachep(void)
+{
+        if (nilfs_inode_cachep)
+               kmem_cache_destroy(nilfs_inode_cachep);
+        if (nilfs_transaction_cachep)
+               kmem_cache_destroy(nilfs_transaction_cachep);
+        if (nilfs_segbuf_cachep)
+               kmem_cache_destroy(nilfs_segbuf_cachep);
+        if (nilfs_btree_path_cache)
+               kmem_cache_destroy(nilfs_btree_path_cache);
+}
 
-       err = register_filesystem(&nilfs_fs_type);
-       if (err)
-               goto failed_btree_path_cache;
+static int __init nilfs_init_cachep(void)
+{
+       nilfs_inode_cachep = kmem_cache_create("nilfs2_inode_cache",
+                       sizeof(struct nilfs_inode_info), 0,
+                       SLAB_RECLAIM_ACCOUNT, nilfs_inode_init_once);
+       if (!nilfs_inode_cachep)
+               goto fail;
+
+       nilfs_transaction_cachep = kmem_cache_create("nilfs2_transaction_cache",
+                       sizeof(struct nilfs_transaction_info), 0,
+                       SLAB_RECLAIM_ACCOUNT, NULL);
+       if (!nilfs_transaction_cachep)
+               goto fail;
+
+       nilfs_segbuf_cachep = kmem_cache_create("nilfs2_segbuf_cache",
+                       sizeof(struct nilfs_segment_buffer), 0,
+                       SLAB_RECLAIM_ACCOUNT, nilfs_segbuf_init_once);
+       if (!nilfs_segbuf_cachep)
+               goto fail;
+
+       nilfs_btree_path_cache = kmem_cache_create("nilfs2_btree_path_cache",
+                       sizeof(struct nilfs_btree_path) * NILFS_BTREE_LEVEL_MAX,
+                       0, 0, NULL);
+       if (!nilfs_btree_path_cache)
+               goto fail;
 
        return 0;
 
- failed_btree_path_cache:
-       nilfs_btree_path_cache_destroy();
+fail:
+       nilfs_destroy_cachep();
+       return -ENOMEM;
+}
+
+static int __init init_nilfs_fs(void)
+{
+       int err;
 
- failed_segbuf_cache:
-       nilfs_destroy_segbuf_cache();
+       err = nilfs_init_cachep();
+       if (err)
+               goto fail;
 
- failed_transaction_cache:
-       nilfs_destroy_transaction_cache();
+       err = register_filesystem(&nilfs_fs_type);
+       if (err)
+               goto free_cachep;
 
- failed_inode_cache:
-       nilfs_destroy_inode_cache();
+       printk(KERN_INFO "NILFS version 2 loaded\n");
+       return 0;
 
- failed:
+free_cachep:
+       nilfs_destroy_cachep();
+fail:
        return err;
 }
 
 static void __exit exit_nilfs_fs(void)
 {
-       nilfs_destroy_segbuf_cache();
-       nilfs_destroy_transaction_cache();
-       nilfs_destroy_inode_cache();
-       nilfs_btree_path_cache_destroy();
+       nilfs_destroy_cachep();
        unregister_filesystem(&nilfs_fs_type);
 }
 
index 33871f7e4f013b2113547a4de2639685be007aae..a756168a21c21e00cdf096f2f1a99b5719e313f6 100644 (file)
@@ -486,11 +486,15 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs,
                printk(KERN_WARNING
                       "NILFS warning: unable to read secondary superblock\n");
 
+       /*
+        * Compare two super blocks and set 1 in swp if the secondary
+        * super block is valid and newer.  Otherwise, set 0 in swp.
+        */
        valid[0] = nilfs_valid_sb(sbp[0]);
        valid[1] = nilfs_valid_sb(sbp[1]);
-       swp = valid[1] &&
-               (!valid[0] ||
-                le64_to_cpu(sbp[1]->s_wtime) > le64_to_cpu(sbp[0]->s_wtime));
+       swp = valid[1] && (!valid[0] ||
+                          le64_to_cpu(sbp[1]->s_last_cno) >
+                          le64_to_cpu(sbp[0]->s_last_cno));
 
        if (valid[swp] && nilfs_sb2_bad_offset(sbp[swp], sb2off)) {
                brelse(sbh[1]);
index 640702e97457f58eaab573283906996071ea680e..8c2c6116e788994cf1f95aba1c771c92fe384a4d 100644 (file)
@@ -199,16 +199,15 @@ struct nilfs_super_block {
        __le32  s_creator_os;           /* OS */
        __le16  s_def_resuid;           /* Default uid for reserved blocks */
        __le16  s_def_resgid;           /* Default gid for reserved blocks */
-       __le32  s_first_ino;            /* First non-reserved inode */
+       __le32  s_first_ino;            /* First non-reserved inode */
 
-       __le16  s_inode_size;           /* Size of an inode */
+       __le16  s_inode_size;           /* Size of an inode */
        __le16  s_dat_entry_size;       /* Size of a dat entry */
        __le16  s_checkpoint_size;      /* Size of a checkpoint */
        __le16  s_segment_usage_size;   /* Size of a segment usage */
 
        __u8    s_uuid[16];             /* 128-bit uuid for volume */
-       char    s_volume_name[16];      /* volume name */
-       char    s_last_mounted[64];     /* directory where last mounted */
+       char    s_volume_name[80];      /* volume name */
 
        __le32  s_c_interval;           /* Commit interval of segment */
        __le32  s_c_block_max;          /* Threshold of data amount for
@@ -377,6 +376,7 @@ union nilfs_binfo {
  * @ss_nfinfo: number of finfo structures
  * @ss_sumbytes: total size of segment summary in bytes
  * @ss_pad: padding
+ * @ss_cno: checkpoint number
  */
 struct nilfs_segment_summary {
        __le32 ss_datasum;
@@ -391,6 +391,7 @@ struct nilfs_segment_summary {
        __le32 ss_nfinfo;
        __le32 ss_sumbytes;
        __le32 ss_pad;
+       __le64 ss_cno;
        /* array of finfo structures */
 };
 
@@ -437,10 +438,10 @@ struct nilfs_palloc_group_desc {
 
 /**
  * struct nilfs_dat_entry - disk address translation entry
- * @dt_blocknr: block number
- * @dt_start: start checkpoint number
- * @dt_end: end checkpoint number
- * @dt_rsv: reserved for future use
+ * @de_blocknr: block number
+ * @de_start: start checkpoint number
+ * @de_end: end checkpoint number
+ * @de_rsv: reserved for future use
  */
 struct nilfs_dat_entry {
        __le64 de_blocknr;