]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/nilfs2/sufile.c
nilfs2: simplify handling of active state of segments
[linux-2.6-omap-h63xx.git] / fs / nilfs2 / sufile.c
index b3674a8162a199ee5568212a814721435f0d6517..c774cf397e2fab6e43065b4ff18e58bcb4192040 100644 (file)
@@ -158,7 +158,6 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
                        if (!nilfs_segment_usage_clean(su))
                                continue;
                        /* found a clean segment */
-                       nilfs_segment_usage_set_active(su);
                        nilfs_segment_usage_set_dirty(su);
                        kunmap_atomic(kaddr, KM_USER0);
 
@@ -231,10 +230,11 @@ int nilfs_sufile_cancel_free(struct inode *sufile, __u64 segnum)
        kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
        su = nilfs_sufile_block_get_segment_usage(
                sufile, segnum, su_bh, kaddr);
-       if (!nilfs_segment_usage_clean(su)) {
-               printk(KERN_CRIT "%s: segment %llu must be clean\n",
+       if (unlikely(!nilfs_segment_usage_clean(su))) {
+               printk(KERN_WARNING "%s: segment %llu must be clean\n",
                       __func__, (unsigned long long)segnum);
-               BUG();
+               kunmap_atomic(kaddr, KM_USER0);
+               goto out_su_bh;
        }
        nilfs_segment_usage_set_dirty(su);
        kunmap_atomic(kaddr, KM_USER0);
@@ -249,11 +249,10 @@ int nilfs_sufile_cancel_free(struct inode *sufile, __u64 segnum)
        nilfs_mdt_mark_buffer_dirty(su_bh);
        nilfs_mdt_mark_dirty(sufile);
 
+ out_su_bh:
        brelse(su_bh);
-
  out_header:
        brelse(header_bh);
-
  out_sem:
        up_write(&NILFS_MDT(sufile)->mi_sem);
        return ret;
@@ -317,7 +316,7 @@ int nilfs_sufile_freev(struct inode *sufile, __u64 *segnum, size_t nsegs)
                kaddr = kmap_atomic(su_bh[i]->b_page, KM_USER0);
                su = nilfs_sufile_block_get_segment_usage(
                        sufile, segnum[i], su_bh[i], kaddr);
-               BUG_ON(nilfs_segment_usage_error(su));
+               WARN_ON(nilfs_segment_usage_error(su));
                nilfs_segment_usage_set_clean(su);
                kunmap_atomic(kaddr, KM_USER0);
                nilfs_mdt_mark_buffer_dirty(su_bh[i]);
@@ -385,8 +384,8 @@ int nilfs_sufile_get_segment_usage(struct inode *sufile, __u64 segnum,
        int ret;
 
        /* segnum is 0 origin */
-       BUG_ON(segnum >= nilfs_sufile_get_nsegments(sufile));
-
+       if (segnum >= nilfs_sufile_get_nsegments(sufile))
+               return -EINVAL;
        down_write(&NILFS_MDT(sufile)->mi_sem);
        ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 1, &bh);
        if (ret < 0)
@@ -446,6 +445,7 @@ int nilfs_sufile_get_stat(struct inode *sufile, struct nilfs_sustat *sustat)
 {
        struct buffer_head *header_bh;
        struct nilfs_sufile_header *header;
+       struct the_nilfs *nilfs = NILFS_MDT(sufile)->mi_nilfs;
        void *kaddr;
        int ret;
 
@@ -460,8 +460,11 @@ int nilfs_sufile_get_stat(struct inode *sufile, struct nilfs_sustat *sustat)
        sustat->ss_nsegs = nilfs_sufile_get_nsegments(sufile);
        sustat->ss_ncleansegs = le64_to_cpu(header->sh_ncleansegs);
        sustat->ss_ndirtysegs = le64_to_cpu(header->sh_ndirtysegs);
-       sustat->ss_ctime = NILFS_MDT(sufile)->mi_nilfs->ns_ctime;
-       sustat->ss_nongc_ctime = NILFS_MDT(sufile)->mi_nilfs->ns_nongc_ctime;
+       sustat->ss_ctime = nilfs->ns_ctime;
+       sustat->ss_nongc_ctime = nilfs->ns_nongc_ctime;
+       spin_lock(&nilfs->ns_last_segment_lock);
+       sustat->ss_prot_seq = nilfs->ns_prot_seq;
+       spin_unlock(&nilfs->ns_last_segment_lock);
        kunmap_atomic(kaddr, KM_USER0);
        brelse(header_bh);
 
@@ -511,6 +514,8 @@ int nilfs_sufile_get_ncleansegs(struct inode *sufile, unsigned long *nsegsp)
  * %-EIO - I/O error.
  *
  * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-EINVAL - Invalid segment usage number.
  */
 int nilfs_sufile_set_error(struct inode *sufile, __u64 segnum)
 {
@@ -520,8 +525,11 @@ int nilfs_sufile_set_error(struct inode *sufile, __u64 segnum)
        void *kaddr;
        int ret;
 
-       BUG_ON(segnum >= nilfs_sufile_get_nsegments(sufile));
-
+       if (unlikely(segnum >= nilfs_sufile_get_nsegments(sufile))) {
+               printk(KERN_WARNING "%s: invalid segment number: %llu\n",
+                      __func__, (unsigned long long)segnum);
+               return -EINVAL;
+       }
        down_write(&NILFS_MDT(sufile)->mi_sem);
 
        ret = nilfs_sufile_get_header_block(sufile, &header_bh);
@@ -582,6 +590,7 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum,
        struct buffer_head *su_bh;
        struct nilfs_segment_usage *su;
        size_t susz = NILFS_MDT(sufile)->mi_entry_size;
+       struct the_nilfs *nilfs = NILFS_MDT(sufile)->mi_nilfs;
        void *kaddr;
        unsigned long nsegs, segusages_per_block;
        ssize_t n;
@@ -614,7 +623,11 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum,
                for (j = 0; j < n; j++, su = (void *)su + susz) {
                        si[i + j].sui_lastmod = le64_to_cpu(su->su_lastmod);
                        si[i + j].sui_nblocks = le32_to_cpu(su->su_nblocks);
-                       si[i + j].sui_flags = le32_to_cpu(su->su_flags);
+                       si[i + j].sui_flags = le32_to_cpu(su->su_flags) &
+                               ~(1UL << NILFS_SEGMENT_USAGE_ACTIVE);
+                       if (nilfs_segment_is_active(nilfs, segnum + i + j))
+                               si[i + j].sui_flags |=
+                                       (1UL << NILFS_SEGMENT_USAGE_ACTIVE);
                }
                kunmap_atomic(kaddr, KM_USER0);
                brelse(su_bh);