Hi, Now in the -nmw tree. Thanks,
Steve. On Tue, 2009-10-20 at 02:39 -0500, Benjamin Marzinski wrote: > GFS2 now has three new mount options, statfs_quantum, quota_quantum and > statfs_percent. statfs_quantum and quota_quantum simply allow you to > set the tunables of the same name. Setting setting statfs_quantum to 0 > will also turn on the statfs_slow tunable. statfs_percent accepts an > integer between 0 and 100. Numbers between 1 and 100 will cause GFS2 to > do any early sync when the local number of blocks free changes by at > least statfs_percent from the totoal number of blocks free. Setting > statfs_percent to 0 disables this. > > Signed-off-by: Benjamin Marzinski <bmarz...@redhat.com> > --- > fs/gfs2/incore.h | 4 ++ > fs/gfs2/ops_fstype.c | 14 ++++++++-- > fs/gfs2/quota.c | 21 +++++++++++++-- > fs/gfs2/quota.h | 2 + > fs/gfs2/super.c | 69 > ++++++++++++++++++++++++++++++++++++++++++++++++--- > 5 files changed, 100 insertions(+), 10 deletions(-) > > Index: gfs2-2.6-nmw/fs/gfs2/incore.h > =================================================================== > --- gfs2-2.6-nmw.orig/fs/gfs2/incore.h > +++ gfs2-2.6-nmw/fs/gfs2/incore.h > @@ -430,6 +430,9 @@ struct gfs2_args { > unsigned int ar_discard:1; /* discard requests */ > unsigned int ar_errors:2; /* errors=withdraw | panic */ > int ar_commit; /* Commit interval */ > + int ar_statfs_quantum; /* The fast statfs interval */ > + int ar_quota_quantum; /* The quota interval */ > + int ar_statfs_percent; /* The % change to force sync */ > }; > > struct gfs2_tune { > @@ -558,6 +561,7 @@ struct gfs2_sbd { > spinlock_t sd_statfs_spin; > struct gfs2_statfs_change_host sd_statfs_master; > struct gfs2_statfs_change_host sd_statfs_local; > + int sd_statfs_force_sync; > > /* Resource group stuff */ > > Index: gfs2-2.6-nmw/fs/gfs2/ops_fstype.c > =================================================================== > --- gfs2-2.6-nmw.orig/fs/gfs2/ops_fstype.c > +++ gfs2-2.6-nmw/fs/gfs2/ops_fstype.c > @@ -63,13 +63,10 @@ static void gfs2_tune_init(struct gfs2_t > gt->gt_quota_warn_period = 10; > gt->gt_quota_scale_num = 1; > gt->gt_quota_scale_den = 1; > - gt->gt_quota_quantum = 60; > gt->gt_new_files_jdata = 0; > gt->gt_max_readahead = 1 << 18; > gt->gt_stall_secs = 600; > gt->gt_complain_secs = 10; > - gt->gt_statfs_quantum = 30; > - gt->gt_statfs_slow = 0; > } > > static struct gfs2_sbd *init_sbd(struct super_block *sb) > @@ -1153,6 +1150,15 @@ static int fill_super(struct super_block > sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; > > sdp->sd_tune.gt_log_flush_secs = sdp->sd_args.ar_commit; > + sdp->sd_tune.gt_quota_quantum = sdp->sd_args.ar_quota_quantum; > + if (sdp->sd_args.ar_statfs_quantum) { > + sdp->sd_tune.gt_statfs_slow = 0; > + sdp->sd_tune.gt_statfs_quantum = sdp->sd_args.ar_statfs_quantum; > + } > + else { > + sdp->sd_tune.gt_statfs_slow = 1; > + sdp->sd_tune.gt_statfs_quantum = 30; > + } > > error = init_names(sdp, silent); > if (error) > @@ -1308,6 +1314,8 @@ static int gfs2_get_sb(struct file_syste > args.ar_quota = GFS2_QUOTA_DEFAULT; > args.ar_data = GFS2_DATA_DEFAULT; > args.ar_commit = 60; > + args.ar_statfs_quantum = 30; > + args.ar_quota_quantum = 60; > args.ar_errors = GFS2_ERRORS_DEFAULT; > > error = gfs2_mount_args(&args, data); > Index: gfs2-2.6-nmw/fs/gfs2/super.c > =================================================================== > --- gfs2-2.6-nmw.orig/fs/gfs2/super.c > +++ gfs2-2.6-nmw/fs/gfs2/super.c > @@ -70,6 +70,9 @@ enum { > Opt_commit, > Opt_err_withdraw, > Opt_err_panic, > + Opt_statfs_quantum, > + Opt_statfs_percent, > + Opt_quota_quantum, > Opt_error, > }; > > @@ -101,6 +104,9 @@ static const match_table_t tokens = { > {Opt_commit, "commit=%d"}, > {Opt_err_withdraw, "errors=withdraw"}, > {Opt_err_panic, "errors=panic"}, > + {Opt_statfs_quantum, "statfs_quantum=%d"}, > + {Opt_statfs_percent, "statfs_percent=%d"}, > + {Opt_quota_quantum, "quota_quantum=%d"}, > {Opt_error, NULL} > }; > > @@ -214,6 +220,28 @@ int gfs2_mount_args(struct gfs2_args *ar > return rv ? rv : -EINVAL; > } > break; > + case Opt_statfs_quantum: > + rv = match_int(&tmp[0], &args->ar_statfs_quantum); > + if (rv || args->ar_statfs_quantum < 0) { > + printk(KERN_WARNING "GFS2: statfs_quantum mount > option requires a non-negative numeric argument\n"); > + return rv ? rv : -EINVAL; > + } > + break; > + case Opt_quota_quantum: > + rv = match_int(&tmp[0], &args->ar_quota_quantum); > + if (rv || args->ar_quota_quantum <= 0) { > + printk(KERN_WARNING "GFS2: quota_quantum mount > option requires a positive numeric argument\n"); > + return rv ? rv : -EINVAL; > + } > + break; > + case Opt_statfs_percent: > + rv = match_int(&tmp[0], &args->ar_statfs_percent); > + if (rv || args->ar_statfs_percent < 0 || > + args->ar_statfs_percent > 100) { > + printk(KERN_WARNING "statfs_percent mount > option requires a numeric argument between 0 and 100\n"); > + return rv ? rv : -EINVAL; > + } > + break; > case Opt_err_withdraw: > args->ar_errors = GFS2_ERRORS_WITHDRAW; > break; > @@ -442,7 +470,9 @@ void gfs2_statfs_change(struct gfs2_sbd > { > struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); > struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; > + struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; > struct buffer_head *l_bh; > + int percent, sync_percent; > int error; > > error = gfs2_meta_inode_buffer(l_ip, &l_bh); > @@ -456,9 +486,17 @@ void gfs2_statfs_change(struct gfs2_sbd > l_sc->sc_free += free; > l_sc->sc_dinodes += dinodes; > gfs2_statfs_change_out(l_sc, l_bh->b_data + sizeof(struct gfs2_dinode)); > + if (m_sc->sc_free) > + percent = (100 * l_sc->sc_free) / m_sc->sc_free; > + else > + percent = 100; > spin_unlock(&sdp->sd_statfs_spin); > > brelse(l_bh); > + sync_percent = sdp->sd_args.ar_statfs_percent; > + if (sync_percent && (percent >= sync_percent || > + percent <= -sync_percent)) > + gfs2_wake_up_statfs(sdp); > } > > void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, > @@ -522,6 +560,7 @@ int gfs2_statfs_sync(struct super_block > goto out_bh2; > > update_statfs(sdp, m_bh, l_bh); > + sdp->sd_statfs_force_sync = 0; > > gfs2_trans_end(sdp); > > @@ -1062,6 +1101,11 @@ static int gfs2_remount_fs(struct super_ > > spin_lock(>->gt_spin); > args.ar_commit = gt->gt_log_flush_secs; > + args.ar_quota_quantum = gt->gt_quota_quantum; > + if (gt->gt_statfs_slow) > + args.ar_statfs_quantum = 0; > + else > + args.ar_statfs_quantum = gt->gt_statfs_quantum; > spin_unlock(>->gt_spin); > error = gfs2_mount_args(&args, data); > if (error) > @@ -1100,6 +1144,15 @@ static int gfs2_remount_fs(struct super_ > sb->s_flags &= ~MS_POSIXACL; > spin_lock(>->gt_spin); > gt->gt_log_flush_secs = args.ar_commit; > + gt->gt_quota_quantum = args.ar_quota_quantum; > + if (args.ar_statfs_quantum) { > + gt->gt_statfs_slow = 0; > + gt->gt_statfs_quantum = args.ar_statfs_quantum; > + } > + else { > + gt->gt_statfs_slow = 1; > + gt->gt_statfs_quantum = 30; > + } > spin_unlock(>->gt_spin); > > gfs2_online_uevent(sdp); > @@ -1180,7 +1233,7 @@ static int gfs2_show_options(struct seq_ > { > struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info; > struct gfs2_args *args = &sdp->sd_args; > - int lfsecs; > + int val; > > if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir)) > seq_printf(s, ",meta"); > @@ -1241,9 +1294,17 @@ static int gfs2_show_options(struct seq_ > } > if (args->ar_discard) > seq_printf(s, ",discard"); > - lfsecs = sdp->sd_tune.gt_log_flush_secs; > - if (lfsecs != 60) > - seq_printf(s, ",commit=%d", lfsecs); > + val = sdp->sd_tune.gt_log_flush_secs; > + if (val != 60) > + seq_printf(s, ",commit=%d", val); > + val = sdp->sd_tune.gt_statfs_quantum; > + if (val != 30) > + seq_printf(s, ",statfs_quantum=%d", val); > + val = sdp->sd_tune.gt_quota_quantum; > + if (val != 60) > + seq_printf(s, ",quota_quantum=%d", val); > + if (args->ar_statfs_percent) > + seq_printf(s, ",statfs_percent=%d", args->ar_statfs_percent); > if (args->ar_errors != GFS2_ERRORS_DEFAULT) { > const char *state; > > Index: gfs2-2.6-nmw/fs/gfs2/quota.c > =================================================================== > --- gfs2-2.6-nmw.orig/fs/gfs2/quota.c > +++ gfs2-2.6-nmw/fs/gfs2/quota.c > @@ -1336,6 +1336,14 @@ static void quotad_check_trunc_list(stru > } > } > > +void gfs2_wake_up_statfs(struct gfs2_sbd *sdp) { > + if (!sdp->sd_statfs_force_sync) { > + sdp->sd_statfs_force_sync = 1; > + wake_up(&sdp->sd_quota_wait); > + } > +} > + > + > /** > * gfs2_quotad - Write cached quota changes into the quota file > * @sdp: Pointer to GFS2 superblock > @@ -1355,8 +1363,15 @@ int gfs2_quotad(void *data) > while (!kthread_should_stop()) { > > /* Update the master statfs file */ > - quotad_check_timeo(sdp, "statfs", gfs2_statfs_sync, t, > - &statfs_timeo, &tune->gt_statfs_quantum); > + if (sdp->sd_statfs_force_sync) { > + int error = gfs2_statfs_sync(sdp->sd_vfs, 0); > + quotad_error(sdp, "statfs", error); > + statfs_timeo = gfs2_tune_get(sdp, gt_statfs_quantum) * > HZ; > + } > + else > + quotad_check_timeo(sdp, "statfs", gfs2_statfs_sync, t, > + &statfs_timeo, > + &tune->gt_statfs_quantum); > > /* Update quota file */ > quotad_check_timeo(sdp, "sync", gfs2_quota_sync, t, > @@ -1373,7 +1388,7 @@ int gfs2_quotad(void *data) > spin_lock(&sdp->sd_trunc_lock); > empty = list_empty(&sdp->sd_trunc_list); > spin_unlock(&sdp->sd_trunc_lock); > - if (empty) > + if (empty && !sdp->sd_statfs_force_sync) > t -= schedule_timeout(t); > else > t = 0; > Index: gfs2-2.6-nmw/fs/gfs2/quota.h > =================================================================== > --- gfs2-2.6-nmw.orig/fs/gfs2/quota.h > +++ gfs2-2.6-nmw/fs/gfs2/quota.h > @@ -32,6 +32,8 @@ extern int gfs2_quota_init(struct gfs2_s > extern void gfs2_quota_cleanup(struct gfs2_sbd *sdp); > extern int gfs2_quotad(void *data); > > +extern void gfs2_wake_up_statfs(struct gfs2_sbd *sdp); > + > static inline int gfs2_quota_lock_check(struct gfs2_inode *ip) > { > struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); >