Merge branches 'rgrp-glock-sharing' and 'gfs2-revoke' from https://git.kernel.org...
[linux-2.6-microblaze.git] / fs / gfs2 / ops_fstype.c
index 61fce59..74c7d01 100644 (file)
@@ -136,8 +136,6 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
 
        init_rwsem(&sdp->sd_log_flush_lock);
        atomic_set(&sdp->sd_log_in_flight, 0);
-       atomic_set(&sdp->sd_reserving_log, 0);
-       init_waitqueue_head(&sdp->sd_reserving_log_wait);
        init_waitqueue_head(&sdp->sd_log_flush_wait);
        atomic_set(&sdp->sd_freeze_state, SFS_UNFROZEN);
        mutex_init(&sdp->sd_freeze_mutex);
@@ -171,7 +169,8 @@ static int gfs2_check_sb(struct gfs2_sbd *sdp, int silent)
                return -EINVAL;
        }
 
-       if (sb->sb_fs_format != GFS2_FORMAT_FS ||
+       if (sb->sb_fs_format < GFS2_FS_FORMAT_MIN ||
+           sb->sb_fs_format > GFS2_FS_FORMAT_MAX ||
            sb->sb_multihost_format != GFS2_FORMAT_MULTI) {
                fs_warn(sdp, "Unknown on-disk format, unable to mount\n");
                return -EINVAL;
@@ -179,7 +178,7 @@ static int gfs2_check_sb(struct gfs2_sbd *sdp, int silent)
 
        if (sb->sb_bsize < 512 || sb->sb_bsize > PAGE_SIZE ||
            (sb->sb_bsize & (sb->sb_bsize - 1))) {
-               pr_warn("Invalid superblock size\n");
+               pr_warn("Invalid block size\n");
                return -EINVAL;
        }
 
@@ -317,6 +316,13 @@ static int gfs2_read_sb(struct gfs2_sbd *sdp, int silent)
                                     sizeof(struct gfs2_meta_header))
                * GFS2_NBBY; /* not the rgrp bitmap, subsequent bitmaps only */
 
+       /*
+        * We always keep at least one block reserved for revokes in
+        * transactions.  This greatly simplifies allocating additional
+        * revoke blocks.
+        */
+       atomic_set(&sdp->sd_log_revokes_available, sdp->sd_ldptrs);
+
        /* Compute maximum reservation required to add a entry to a directory */
 
        hash_blocks = DIV_ROUND_UP(sizeof(u64) * BIT(GFS2_DIR_MAX_DEPTH),
@@ -488,6 +494,19 @@ static int init_sb(struct gfs2_sbd *sdp, int silent)
                goto out;
        }
 
+       switch(sdp->sd_sb.sb_fs_format) {
+       case GFS2_FS_FORMAT_MAX:
+               sb->s_xattr = gfs2_xattr_handlers_max;
+               break;
+
+       case GFS2_FS_FORMAT_MIN:
+               sb->s_xattr = gfs2_xattr_handlers_min;
+               break;
+
+       default:
+               BUG();
+       }
+
        /* Set up the buffer cache and SB for real */
        if (sdp->sd_sb.sb_bsize < bdev_logical_block_size(sb->s_bdev)) {
                ret = -EINVAL;
@@ -1032,13 +1051,14 @@ hostdata_error:
        }
 
        if (lm->lm_mount == NULL) {
-               fs_info(sdp, "Now mounting FS...\n");
+               fs_info(sdp, "Now mounting FS (format %u)...\n", sdp->sd_sb.sb_fs_format);
                complete_all(&sdp->sd_locking_init);
                return 0;
        }
        ret = lm->lm_mount(sdp, table);
        if (ret == 0)
-               fs_info(sdp, "Joined cluster. Now mounting FS...\n");
+               fs_info(sdp, "Joined cluster. Now mounting FS (format %u)...\n",
+                       sdp->sd_sb.sb_fs_format);
        complete_all(&sdp->sd_locking_init);
        return ret;
 }
@@ -1084,6 +1104,7 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
        int silent = fc->sb_flags & SB_SILENT;
        struct gfs2_sbd *sdp;
        struct gfs2_holder mount_gh;
+       struct gfs2_holder freeze_gh;
        int error;
 
        sdp = init_sbd(sb);
@@ -1107,7 +1128,6 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
        sb->s_op = &gfs2_super_ops;
        sb->s_d_op = &gfs2_dops;
        sb->s_export_op = &gfs2_export_ops;
-       sb->s_xattr = gfs2_xattr_handlers;
        sb->s_qcop = &gfs2_quotactl_ops;
        sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
        sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
@@ -1156,6 +1176,10 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
        if (error)
                goto fail_locking;
 
+       /* Turn rgrplvb on by default if fs format is recent enough */
+       if (!sdp->sd_args.ar_got_rgrplvb && sdp->sd_sb.sb_fs_format > 1801)
+               sdp->sd_args.ar_rgrplvb = 1;
+
        error = wait_on_journal(sdp);
        if (error)
                goto fail_sb;
@@ -1195,25 +1219,18 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
                goto fail_per_node;
        }
 
-       if (sb_rdonly(sb)) {
-               struct gfs2_holder freeze_gh;
+       error = gfs2_freeze_lock(sdp, &freeze_gh, 0);
+       if (error)
+               goto fail_per_node;
 
-               error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED,
-                                          LM_FLAG_NOEXP | GL_EXACT,
-                                          &freeze_gh);
-               if (error) {
-                       fs_err(sdp, "can't make FS RO: %d\n", error);
-                       goto fail_per_node;
-               }
-               gfs2_glock_dq_uninit(&freeze_gh);
-       } else {
+       if (!sb_rdonly(sb))
                error = gfs2_make_fs_rw(sdp);
-               if (error) {
-                       fs_err(sdp, "can't make FS RW: %d\n", error);
-                       goto fail_per_node;
-               }
-       }
 
+       gfs2_freeze_unlock(&freeze_gh);
+       if (error) {
+               fs_err(sdp, "can't make FS RW: %d\n", error);
+               goto fail_per_node;
+       }
        gfs2_glock_dq_uninit(&mount_gh);
        gfs2_online_uevent(sdp);
        return 0;
@@ -1456,6 +1473,7 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
                break;
        case Opt_rgrplvb:
                args->ar_rgrplvb = result.boolean;
+               args->ar_got_rgrplvb = 1;
                break;
        case Opt_loccookie:
                args->ar_loccookie = result.boolean;
@@ -1514,6 +1532,12 @@ static int gfs2_reconfigure(struct fs_context *fc)
                fc->sb_flags |= SB_RDONLY;
 
        if ((sb->s_flags ^ fc->sb_flags) & SB_RDONLY) {
+               struct gfs2_holder freeze_gh;
+
+               error = gfs2_freeze_lock(sdp, &freeze_gh, 0);
+               if (error)
+                       return -EINVAL;
+
                if (fc->sb_flags & SB_RDONLY) {
                        error = gfs2_make_fs_ro(sdp);
                        if (error)
@@ -1523,6 +1547,7 @@ static int gfs2_reconfigure(struct fs_context *fc)
                        if (error)
                                errorfc(fc, "unable to remount read-write");
                }
+               gfs2_freeze_unlock(&freeze_gh);
        }
        sdp->sd_args = *newargs;