Merge branch 'linus' into cont_syslog
[safe/jmp/linux-2.6] / fs / nilfs2 / the_nilfs.h
index 1b9caaf..1ab9745 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/fs.h>
 #include <linux/blkdev.h>
 #include <linux/backing-dev.h>
+#include <linux/slab.h>
 #include "sb.h"
 
 /* the_nilfs struct */
@@ -37,6 +38,8 @@ 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 */
+       THE_NILFS_SB_DIRTY,     /* super block is dirty */
 };
 
 /**
@@ -50,8 +53,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 +102,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,16 +198,33 @@ 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)
+THE_NILFS_FNS(SB_DIRTY, sb_dirty)
 
 /* 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 *);
 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_sb_info *nilfs_find_sbinfo(struct the_nilfs *, int, __u64);
 int nilfs_checkpoint_is_mounted(struct the_nilfs *, __u64, int);
@@ -221,34 +239,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)
@@ -257,6 +262,16 @@ static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi)
                kfree(sbi);
 }
 
+static inline int nilfs_valid_fs(struct the_nilfs *nilfs)
+{
+       unsigned valid_fs;
+
+       down_read(&nilfs->ns_sem);
+       valid_fs = (nilfs->ns_mount_state & NILFS_VALID_FS);
+       up_read(&nilfs->ns_sem);
+       return valid_fs;
+}
+
 static inline void
 nilfs_get_segment_range(struct the_nilfs *nilfs, __u64 segnum,
                        sector_t *seg_start, sector_t *seg_end)