nilfs2: get rid of GCDAT inode
[pandora-kernel.git] / fs / nilfs2 / the_nilfs.h
index f785a7b..a5178dc 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/types.h>
 #include <linux/buffer_head.h>
+#include <linux/rbtree.h>
 #include <linux/fs.h>
 #include <linux/blkdev.h>
 #include <linux/backing-dev.h>
@@ -45,22 +46,16 @@ enum {
 /**
  * struct the_nilfs - struct to supervise multiple nilfs mount points
  * @ns_flags: flags
- * @ns_count: reference count
- * @ns_list: list head for nilfs_list
  * @ns_bdev: block device
  * @ns_bdi: backing dev info
  * @ns_writer: back pointer to writable nilfs_sb_info
  * @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_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
  * @ns_sbwtime: previous write time of super block
  * @ns_sbwcount: write count of super block
  * @ns_sbsize: size of valid data in super block
- * @ns_supers: list of nilfs super block structs
  * @ns_seg_seq: segment sequence counter
  * @ns_segnum: index number of the latest full segment.
  * @ns_nextnum: index number of the full segment index to be used next
@@ -79,9 +74,9 @@ enum {
  * @ns_dat: DAT file inode
  * @ns_cpfile: checkpoint file inode
  * @ns_sufile: segusage file inode
- * @ns_gc_dat: shadow inode of the DAT file inode for GC
+ * @ns_cptree: rb-tree of all mounted checkpoints (nilfs_root)
+ * @ns_cptree_lock: lock protecting @ns_cptree
  * @ns_gc_inodes: dummy inodes to keep live blocks
- * @ns_gc_inodes_h: hash list to keep dummy inode holding live blocks
  * @ns_blocksize_bits: bit length of block size
  * @ns_blocksize: block size
  * @ns_nsegments: number of segments in filesystem
@@ -95,23 +90,13 @@ enum {
  */
 struct the_nilfs {
        unsigned long           ns_flags;
-       atomic_t                ns_count;
-       struct list_head        ns_list;
 
        struct block_device    *ns_bdev;
        struct backing_dev_info *ns_bdi;
        struct nilfs_sb_info   *ns_writer;
        struct rw_semaphore     ns_sem;
-       struct rw_semaphore     ns_super_sem;
-       struct mutex            ns_mount_mutex;
        struct rw_semaphore     ns_writer_sem;
 
-       /*
-        * components protected by ns_super_sem
-        */
-       struct nilfs_sb_info   *ns_current;
-       struct list_head        ns_supers;
-
        /*
         * used for
         * - loading the latest checkpoint exclusively.
@@ -163,11 +148,13 @@ struct the_nilfs {
        struct inode           *ns_dat;
        struct inode           *ns_cpfile;
        struct inode           *ns_sufile;
-       struct inode           *ns_gc_dat;
 
-       /* GC inode list and hash table head */
+       /* Checkpoint tree */
+       struct rb_root          ns_cptree;
+       spinlock_t              ns_cptree_lock;
+
+       /* GC inode list */
        struct list_head        ns_gc_inodes;
-       struct hlist_head      *ns_gc_inodes_h;
 
        /* Disk layout information (static) */
        unsigned int            ns_blocksize_bits;
@@ -182,9 +169,6 @@ struct the_nilfs {
        u32                     ns_crc_seed;
 };
 
-#define NILFS_GCINODE_HASH_BITS                8
-#define NILFS_GCINODE_HASH_SIZE                (1<<NILFS_GCINODE_HASH_BITS)
-
 #define THE_NILFS_FNS(bit, name)                                       \
 static inline void set_nilfs_##name(struct the_nilfs *nilfs)           \
 {                                                                      \
@@ -205,6 +189,32 @@ THE_NILFS_FNS(DISCONTINUED, discontinued)
 THE_NILFS_FNS(GC_RUNNING, gc_running)
 THE_NILFS_FNS(SB_DIRTY, sb_dirty)
 
+/**
+ * struct nilfs_root - nilfs root object
+ * @cno: checkpoint number
+ * @rb_node: red-black tree node
+ * @count: refcount of this structure
+ * @nilfs: nilfs object
+ * @ifile: inode file
+ * @root: root inode
+ * @inodes_count: number of inodes
+ * @blocks_count: number of blocks (Reserved)
+ */
+struct nilfs_root {
+       __u64 cno;
+       struct rb_node rb_node;
+
+       atomic_t count;
+       struct the_nilfs *nilfs;
+       struct inode *ifile;
+
+       atomic_t inodes_count;
+       atomic_t blocks_count;
+};
+
+/* Special checkpoint number */
+#define NILFS_CPTREE_CURRENT_CNO       0
+
 /* Minimum interval of periodical update of superblocks (in seconds) */
 #define NILFS_SB_FREQ          10
 
@@ -221,12 +231,16 @@ static inline int nilfs_sb_will_flip(struct the_nilfs *nilfs)
 }
 
 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 *);
+struct the_nilfs *alloc_nilfs(struct block_device *bdev);
+void destroy_nilfs(struct the_nilfs *nilfs);
 int init_nilfs(struct the_nilfs *, struct nilfs_sb_info *, char *);
 int load_nilfs(struct the_nilfs *, struct nilfs_sb_info *);
 int nilfs_discard_segments(struct the_nilfs *, __u64 *, size_t);
 int nilfs_count_free_blocks(struct the_nilfs *, sector_t *);
+struct nilfs_root *nilfs_lookup_root(struct the_nilfs *nilfs, __u64 cno);
+struct nilfs_root *nilfs_find_or_create_root(struct the_nilfs *nilfs,
+                                            __u64 cno);
+void nilfs_put_root(struct nilfs_root *root);
 struct nilfs_sb_info *nilfs_find_sbinfo(struct the_nilfs *, int, __u64);
 int nilfs_checkpoint_is_mounted(struct the_nilfs *, __u64, int);
 int nilfs_near_disk_full(struct the_nilfs *);
@@ -234,10 +248,9 @@ void nilfs_fall_back_super_block(struct the_nilfs *);
 void nilfs_swap_super_block(struct the_nilfs *);
 
 
-static inline void get_nilfs(struct the_nilfs *nilfs)
+static inline void nilfs_get_root(struct nilfs_root *root)
 {
-       /* Caller must have at least one reference of the_nilfs. */
-       atomic_inc(&nilfs->ns_count);
+       atomic_inc(&root->count);
 }
 
 static inline void
@@ -257,12 +270,6 @@ nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
        up_write(&nilfs->ns_writer_sem);
 }
 
-static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi)
-{
-       if (atomic_dec_and_test(&sbi->s_count))
-               kfree(sbi);
-}
-
 static inline int nilfs_valid_fs(struct the_nilfs *nilfs)
 {
        unsigned valid_fs;