* [Cluster-devel] [PATCH] GFS2: Improve statfs and quota usability
@ 2010-01-20 15:34 Benjamin Marzinski
2010-01-20 16:45 ` Benjamin Marzinski
0 siblings, 1 reply; 4+ messages in thread
From: Benjamin Marzinski @ 2010-01-20 15:34 UTC (permalink / raw)
To: cluster-devel.redhat.com
Since gfs2 writes the rindex file a block at a time, and releases the exclusive
lock after each block, it is possible that another process will grab the lock
in the middle of the write. Since rindex entries are not an even divisor of
blocks, that other process may see partial entries. On grows, this is fine.
The process can simply ignore the the partial entires. Previously, the code
withdrew when it saw partial entries. Now is simply prints an info message
letting the user know that it found a partial entry.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
fs/gfs2/rgrp.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
Index: gfs2-2.6-nmw/fs/gfs2/rgrp.c
===================================================================
--- gfs2-2.6-nmw.orig/fs/gfs2/rgrp.c
+++ gfs2-2.6-nmw/fs/gfs2/rgrp.c
@@ -591,10 +591,8 @@ static int gfs2_ri_update(struct gfs2_in
u64 rgrp_count = ip->i_disksize;
int error;
- if (do_div(rgrp_count, sizeof(struct gfs2_rindex))) {
- gfs2_consist_inode(ip);
- return -EIO;
- }
+ if (do_div(rgrp_count, sizeof(struct gfs2_rindex)))
+ fs_info(sdp, "incomplete resource index. Is the filesystem being grown?\n");
clear_rgrpdi(sdp);
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Cluster-devel] [PATCH] GFS2: Improve statfs and quota usability
@ 2009-10-13 14:49 Benjamin Marzinski
2009-10-13 15:38 ` Steven Whitehouse
0 siblings, 1 reply; 4+ messages in thread
From: Benjamin Marzinski @ 2009-10-13 14:49 UTC (permalink / raw)
To: cluster-devel.redhat.com
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 is both a mount option
and a tunable. It 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 <bmarzins@redhat.com>
---
fs/gfs2/incore.h | 5 ++++
fs/gfs2/ops_fstype.c | 15 ++++++++++---
fs/gfs2/quota.c | 21 ++++++++++++++++---
fs/gfs2/quota.h | 2 +
fs/gfs2/super.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++
fs/gfs2/sys.c | 33 +++++++++++++++++-------------
6 files changed, 112 insertions(+), 20 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 {
@@ -451,6 +454,7 @@ struct gfs2_tune {
unsigned int gt_complain_secs;
unsigned int gt_statfs_quantum;
unsigned int gt_statfs_slow;
+ unsigned int gt_statfs_percent;
};
enum {
@@ -558,6 +562,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,16 @@ 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;
+ }
+ sdp->sd_tune.gt_statfs_percent = sdp->sd_args.ar_statfs_percent;
error = init_names(sdp, silent);
if (error)
@@ -1308,6 +1315,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 = gfs2_tune_get(sdp, gt_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,12 @@ 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;
+ args.ar_statfs_percent = gt->gt_statfs_percent;
spin_unlock(>->gt_spin);
error = gfs2_mount_args(&args, data);
if (error)
@@ -1100,6 +1145,17 @@ 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_statfs_quantum = args.ar_statfs_quantum;
+ 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;
+ }
+ gt->gt_statfs_percent = args.ar_statfs_percent;
spin_unlock(>->gt_spin);
gfs2_online_uevent(sdp);
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);
Index: gfs2-2.6-nmw/fs/gfs2/sys.c
===================================================================
--- gfs2-2.6-nmw.orig/fs/gfs2/sys.c
+++ gfs2-2.6-nmw/fs/gfs2/sys.c
@@ -437,7 +437,7 @@ static ssize_t quota_scale_store(struct
}
static ssize_t tune_set(struct gfs2_sbd *sdp, unsigned int *field,
- int check_zero, const char *buf, size_t len)
+ int check_zero, int max, const char *buf, size_t len)
{
struct gfs2_tune *gt = &sdp->sd_tune;
unsigned int x;
@@ -450,6 +450,9 @@ static ssize_t tune_set(struct gfs2_sbd
if (check_zero && !x)
return -EINVAL;
+ if (max && x > max)
+ return -EINVAL;
+
spin_lock(>->gt_spin);
*field = x;
spin_unlock(>->gt_spin);
@@ -466,24 +469,25 @@ static ssize_t name##_show(struct gfs2_s
} \
TUNE_ATTR_3(name, name##_show, store)
-#define TUNE_ATTR(name, check_zero) \
+#define TUNE_ATTR(name, chk_zero, max) \
static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\
{ \
- return tune_set(sdp, &sdp->sd_tune.gt_##name, check_zero, buf, len); \
+ return tune_set(sdp, &sdp->sd_tune.gt_##name, chk_zero, max, buf, len);\
} \
TUNE_ATTR_2(name, name##_store)
-TUNE_ATTR(incore_log_blocks, 0);
-TUNE_ATTR(log_flush_secs, 0);
-TUNE_ATTR(quota_warn_period, 0);
-TUNE_ATTR(quota_quantum, 0);
-TUNE_ATTR(max_readahead, 0);
-TUNE_ATTR(complain_secs, 0);
-TUNE_ATTR(statfs_slow, 0);
-TUNE_ATTR(new_files_jdata, 0);
-TUNE_ATTR(quota_simul_sync, 1);
-TUNE_ATTR(stall_secs, 1);
-TUNE_ATTR(statfs_quantum, 1);
+TUNE_ATTR(incore_log_blocks, 0, 0);
+TUNE_ATTR(log_flush_secs, 0, 0);
+TUNE_ATTR(quota_warn_period, 0, 0);
+TUNE_ATTR(quota_quantum, 0, 0);
+TUNE_ATTR(max_readahead, 0, 0);
+TUNE_ATTR(complain_secs, 0, 0);
+TUNE_ATTR(statfs_slow, 0, 0);
+TUNE_ATTR(new_files_jdata, 0, 0);
+TUNE_ATTR(quota_simul_sync, 1, 0);
+TUNE_ATTR(stall_secs, 1, 0);
+TUNE_ATTR(statfs_quantum, 1, 0);
+TUNE_ATTR(statfs_percent, 0, 100);
TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);
static struct attribute *tune_attrs[] = {
@@ -497,6 +501,7 @@ static struct attribute *tune_attrs[] =
&tune_attr_quota_simul_sync.attr,
&tune_attr_stall_secs.attr,
&tune_attr_statfs_quantum.attr,
+ &tune_attr_statfs_percent.attr,
&tune_attr_quota_scale.attr,
&tune_attr_new_files_jdata.attr,
NULL,
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Cluster-devel] [PATCH] GFS2: Improve statfs and quota usability
2009-10-13 14:49 Benjamin Marzinski
@ 2009-10-13 15:38 ` Steven Whitehouse
0 siblings, 0 replies; 4+ messages in thread
From: Steven Whitehouse @ 2009-10-13 15:38 UTC (permalink / raw)
To: cluster-devel.redhat.com
Hi,
On Tue, 2009-10-13 at 09:49 -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 is both a mount option
> and a tunable. It 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 <bmarzins@redhat.com>
> ---
> fs/gfs2/incore.h | 5 ++++
> fs/gfs2/ops_fstype.c | 15 ++++++++++---
> fs/gfs2/quota.c | 21 ++++++++++++++++---
> fs/gfs2/quota.h | 2 +
> fs/gfs2/super.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++
> fs/gfs2/sys.c | 33 +++++++++++++++++-------------
> 6 files changed, 112 insertions(+), 20 deletions(-)
>
Can you drop out the bit adding the new sysfs file? The plan is to
reduce those in favour of using mount options as much as possible. Other
than that, it looks good to me.
When we update the docs we should add something to ensure that people
realise that setting the options via the mount command line is the
preferred method,
Steve.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-01-20 16:45 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-20 15:34 [Cluster-devel] [PATCH] GFS2: Improve statfs and quota usability Benjamin Marzinski
2010-01-20 16:45 ` Benjamin Marzinski
-- strict thread matches above, loose matches on Subject: below --
2009-10-13 14:49 Benjamin Marzinski
2009-10-13 15:38 ` Steven Whitehouse
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).