nilfs2: move routine to set segment usage into sufile
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Wed, 18 Nov 2009 09:23:34 +0000 (18:23 +0900)
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Fri, 20 Nov 2009 01:05:51 +0000 (10:05 +0900)
This adds nilfs_sufile_set_segment_usage() function in sufile to
replace direct access to the sufile metadata in log writer code.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
fs/nilfs2/segment.c
fs/nilfs2/sufile.c
fs/nilfs2/sufile.h

index 3ae4a38..097f9c4 100644 (file)
@@ -1457,21 +1457,16 @@ static void nilfs_segctor_update_segusage(struct nilfs_sc_info *sci,
                                          struct inode *sufile)
 {
        struct nilfs_segment_buffer *segbuf;
-       struct buffer_head *bh_su;
-       struct nilfs_segment_usage *raw_su;
        unsigned long live_blocks;
        int ret;
 
        list_for_each_entry(segbuf, &sci->sc_segbufs, sb_list) {
-               ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum,
-                                                    &raw_su, &bh_su);
-               WARN_ON(ret); /* always succeed because bh_su is dirty */
                live_blocks = segbuf->sb_sum.nblocks +
                        (segbuf->sb_pseg_start - segbuf->sb_fseg_start);
-               raw_su->su_lastmod = cpu_to_le64(sci->sc_seg_ctime);
-               raw_su->su_nblocks = cpu_to_le32(live_blocks);
-               nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum,
-                                              bh_su);
+               ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
+                                                    live_blocks,
+                                                    sci->sc_seg_ctime);
+               WARN_ON(ret); /* always succeed because the segusage is dirty */
        }
 }
 
@@ -1479,25 +1474,18 @@ static void nilfs_segctor_cancel_segusage(struct nilfs_sc_info *sci,
                                          struct inode *sufile)
 {
        struct nilfs_segment_buffer *segbuf;
-       struct buffer_head *bh_su;
-       struct nilfs_segment_usage *raw_su;
        int ret;
 
        segbuf = NILFS_FIRST_SEGBUF(&sci->sc_segbufs);
-       ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum,
-                                            &raw_su, &bh_su);
-       WARN_ON(ret); /* always succeed because bh_su is dirty */
-       raw_su->su_nblocks = cpu_to_le32(segbuf->sb_pseg_start -
-                                        segbuf->sb_fseg_start);
-       nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum, bh_su);
+       ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
+                                            segbuf->sb_pseg_start -
+                                            segbuf->sb_fseg_start, 0);
+       WARN_ON(ret); /* always succeed because the segusage is dirty */
 
        list_for_each_entry_continue(segbuf, &sci->sc_segbufs, sb_list) {
-               ret = nilfs_sufile_get_segment_usage(sufile, segbuf->sb_segnum,
-                                                    &raw_su, &bh_su);
+               ret = nilfs_sufile_set_segment_usage(sufile, segbuf->sb_segnum,
+                                                    0, 0);
                WARN_ON(ret); /* always succeed */
-               raw_su->su_nblocks = 0;
-               nilfs_sufile_put_segment_usage(sufile, segbuf->sb_segnum,
-                                              bh_su);
        }
 }
 
index d560f88..3eed998 100644 (file)
@@ -521,6 +521,43 @@ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
 }
 
 /**
+ * nilfs_sufile_set_segment_usage - set usage of a segment
+ * @sufile: inode of segment usage file
+ * @segnum: segment number
+ * @nblocks: number of live blocks in the segment
+ * @modtime: modification time (option)
+ */
+int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
+                                  unsigned long nblocks, time_t modtime)
+{
+       struct buffer_head *bh;
+       struct nilfs_segment_usage *su;
+       void *kaddr;
+       int ret;
+
+       down_write(&NILFS_MDT(sufile)->mi_sem);
+       ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh);
+       if (ret < 0)
+               goto out_sem;
+
+       kaddr = kmap_atomic(bh->b_page, KM_USER0);
+       su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
+       WARN_ON(nilfs_segment_usage_error(su));
+       if (modtime)
+               su->su_lastmod = cpu_to_le64(modtime);
+       su->su_nblocks = cpu_to_le32(nblocks);
+       kunmap_atomic(kaddr, KM_USER0);
+
+       nilfs_mdt_mark_buffer_dirty(bh);
+       nilfs_mdt_mark_dirty(sufile);
+       brelse(bh);
+
+ out_sem:
+       up_write(&NILFS_MDT(sufile)->mi_sem);
+       return ret;
+}
+
+/**
  * nilfs_sufile_get_stat - get segment usage statistics
  * @sufile: inode of segment usage file
  * @stat: pointer to a structure of segment usage statistics
index 4146a65..e1186bf 100644 (file)
@@ -43,6 +43,8 @@ int nilfs_sufile_get_segment_usage(struct inode *, __u64,
 void nilfs_sufile_put_segment_usage(struct inode *, __u64,
                                    struct buffer_head *);
 int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum);
+int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
+                                  unsigned long nblocks, time_t modtime);
 int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
 ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned,
                                size_t);