* [Cluster-devel] Mostly quotas
@ 2009-09-16 15:03 Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 01/10] GFS2: Alter arguments of gfs2_quota/statfs_sync Steven Whitehouse
0 siblings, 1 reply; 11+ messages in thread
From: Steven Whitehouse @ 2009-09-16 15:03 UTC (permalink / raw)
To: cluster-devel.redhat.com
Here is my current patch queue. I plan to push these into the
-nmw git tree shortly. Patch 5 is the only non-quota patch in this
set. The edited highlights:
- Allows querying of the current state of quotas (on/off/account)
- Allows syncing of quotas via the new API
- Allows querying of user/group quotas via the new API
- Preserves the existing API
- Cleans up the quota code
- Fixes up error reporting for the quota sync operation
TODO:
- Setting of quotas via the XFS API
- Possible further ehnancements:
- Split the on/off/account settings so that they can be set for users and
group independently
- Count the number of quota warn & hardlimit violations
- Report quota events via netlink (bz #337691)
- More testing
Steve.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Cluster-devel] [PATCH 01/10] GFS2: Alter arguments of gfs2_quota/statfs_sync
2009-09-16 15:03 [Cluster-devel] Mostly quotas Steven Whitehouse
@ 2009-09-16 15:03 ` Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 02/10] GFS2: Hook gfs2_quota_sync into VFS via gfs2_quotactl_ops Steven Whitehouse
0 siblings, 1 reply; 11+ messages in thread
From: Steven Whitehouse @ 2009-09-16 15:03 UTC (permalink / raw)
To: cluster-devel.redhat.com
These two functions are altered so that gfs2_quota_sync may
in future be called directly from the VFS. The GFS2 superblock
changes to a VFS super block and there is an addition of an int
argument which is currently ignored.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
---
fs/gfs2/quota.c | 7 ++++---
fs/gfs2/quota.h | 2 +-
fs/gfs2/super.c | 7 ++++---
fs/gfs2/super.h | 2 +-
fs/gfs2/sys.c | 4 ++--
5 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 2e9b932..ed9e197 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -1069,8 +1069,9 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
}
}
-int gfs2_quota_sync(struct gfs2_sbd *sdp)
+int gfs2_quota_sync(struct super_block *sb, int type)
{
+ struct gfs2_sbd *sdp = sb->s_fs_info;
struct gfs2_quota_data **qda;
unsigned int max_qd = gfs2_tune_get(sdp, gt_quota_simul_sync);
unsigned int num_qd;
@@ -1298,12 +1299,12 @@ static void quotad_error(struct gfs2_sbd *sdp, const char *msg, int error)
}
static void quotad_check_timeo(struct gfs2_sbd *sdp, const char *msg,
- int (*fxn)(struct gfs2_sbd *sdp),
+ int (*fxn)(struct super_block *sb, int type),
unsigned long t, unsigned long *timeo,
unsigned int *new_timeo)
{
if (t >= *timeo) {
- int error = fxn(sdp);
+ int error = fxn(sdp->sd_vfs, 0);
quotad_error(sdp, msg, error);
*timeo = gfs2_tune_get_i(&sdp->sd_tune, new_timeo) * HZ;
} else {
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h
index 0fa5fa6..437afa7 100644
--- a/fs/gfs2/quota.h
+++ b/fs/gfs2/quota.h
@@ -25,7 +25,7 @@ extern int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid);
extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
u32 uid, u32 gid);
-extern int gfs2_quota_sync(struct gfs2_sbd *sdp);
+extern int gfs2_quota_sync(struct super_block *sb, int type);
extern int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id);
extern int gfs2_quota_init(struct gfs2_sbd *sdp);
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 0ec3ec6..481ec9c 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -484,8 +484,9 @@ void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode));
}
-int gfs2_statfs_sync(struct gfs2_sbd *sdp)
+int gfs2_statfs_sync(struct super_block *sb, int type)
{
+ struct gfs2_sbd *sdp = sb->s_fs_info;
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
@@ -712,8 +713,8 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
int error;
flush_workqueue(gfs2_delete_workqueue);
- gfs2_quota_sync(sdp);
- gfs2_statfs_sync(sdp);
+ gfs2_quota_sync(sdp->sd_vfs, 0);
+ gfs2_statfs_sync(sdp->sd_vfs, 0);
error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE,
&t_gh);
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h
index 235db36..3b31f49 100644
--- a/fs/gfs2/super.h
+++ b/fs/gfs2/super.h
@@ -44,7 +44,7 @@ extern void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc,
const void *buf);
extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
struct buffer_head *l_bh);
-extern int gfs2_statfs_sync(struct gfs2_sbd *sdp);
+extern int gfs2_statfs_sync(struct super_block *sb, int type);
extern int gfs2_freeze_fs(struct gfs2_sbd *sdp);
extern void gfs2_unfreeze_fs(struct gfs2_sbd *sdp);
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index 4463297..be1b8ac 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -158,7 +158,7 @@ static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, const char *buf,
if (simple_strtol(buf, NULL, 0) != 1)
return -EINVAL;
- gfs2_statfs_sync(sdp);
+ gfs2_statfs_sync(sdp->sd_vfs, 0);
return len;
}
@@ -171,7 +171,7 @@ static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf,
if (simple_strtol(buf, NULL, 0) != 1)
return -EINVAL;
- gfs2_quota_sync(sdp);
+ gfs2_quota_sync(sdp->sd_vfs, 0);
return len;
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Cluster-devel] [PATCH 02/10] GFS2: Hook gfs2_quota_sync into VFS via gfs2_quotactl_ops
2009-09-16 15:03 ` [Cluster-devel] [PATCH 01/10] GFS2: Alter arguments of gfs2_quota/statfs_sync Steven Whitehouse
@ 2009-09-16 15:03 ` Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 03/10] GFS2: Remove obsolete code in quota.c Steven Whitehouse
0 siblings, 1 reply; 11+ messages in thread
From: Steven Whitehouse @ 2009-09-16 15:03 UTC (permalink / raw)
To: cluster-devel.redhat.com
The plan is to add further operations to the gfs2_quotactl_ops
in future patches. The sync operation is easy, so we start with
that one.
We plan to use the XFS quota control functions because they more
closely match the GFS2 ones.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
---
fs/gfs2/Kconfig | 2 ++
fs/gfs2/ops_fstype.c | 3 +++
fs/gfs2/quota.c | 4 ++++
fs/gfs2/quota.h | 1 +
4 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig
index 5971359..4dcddf8 100644
--- a/fs/gfs2/Kconfig
+++ b/fs/gfs2/Kconfig
@@ -8,6 +8,8 @@ config GFS2_FS
select FS_POSIX_ACL
select CRC32
select SLOW_WORK
+ select QUOTA
+ select QUOTACTL
help
A cluster filesystem.
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 52fb6c0..5c8f8cc 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -18,6 +18,7 @@
#include <linux/mount.h>
#include <linux/gfs2_ondisk.h>
#include <linux/slow-work.h>
+#include <linux/quotaops.h>
#include "gfs2.h"
#include "incore.h"
@@ -1148,6 +1149,8 @@ static int fill_super(struct super_block *sb, void *data, int silent)
sb->s_op = &gfs2_super_ops;
sb->s_export_op = &gfs2_export_ops;
sb->s_xattr = gfs2_xattr_handlers;
+ sb->s_qcop = &gfs2_quotactl_ops;
+ sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
sb->s_time_gran = 1;
sb->s_maxbytes = MAX_LFS_FILESIZE;
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index ed9e197..73a43ce 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -1378,3 +1378,7 @@ int gfs2_quotad(void *data)
return 0;
}
+const struct quotactl_ops gfs2_quotactl_ops = {
+ .quota_sync = gfs2_quota_sync,
+};
+
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h
index 437afa7..025d15b 100644
--- a/fs/gfs2/quota.h
+++ b/fs/gfs2/quota.h
@@ -50,5 +50,6 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip)
}
extern int gfs2_shrink_qd_memory(int nr, gfp_t gfp_mask);
+extern const struct quotactl_ops gfs2_quotactl_ops;
#endif /* __QUOTA_DOT_H__ */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Cluster-devel] [PATCH 03/10] GFS2: Remove obsolete code in quota.c
2009-09-16 15:03 ` [Cluster-devel] [PATCH 02/10] GFS2: Hook gfs2_quota_sync into VFS via gfs2_quotactl_ops Steven Whitehouse
@ 2009-09-16 15:03 ` Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 04/10] GFS2: Add get_xstate quota function Steven Whitehouse
0 siblings, 1 reply; 11+ messages in thread
From: Steven Whitehouse @ 2009-09-16 15:03 UTC (permalink / raw)
To: cluster-devel.redhat.com
There is no point in testing for GLF_DEMOTE here, we might as
well always release the glock at that point.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
---
fs/gfs2/glock.h | 9 ---------
fs/gfs2/quota.c | 13 +++++--------
2 files changed, 5 insertions(+), 17 deletions(-)
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index c609894..13f0bd2 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -180,15 +180,6 @@ static inline int gfs2_glock_is_held_shrd(struct gfs2_glock *gl)
return gl->gl_state == LM_ST_SHARED;
}
-static inline int gfs2_glock_is_blocking(struct gfs2_glock *gl)
-{
- int ret;
- spin_lock(&gl->gl_spin);
- ret = test_bit(GLF_DEMOTE, &gl->gl_flags);
- spin_unlock(&gl->gl_spin);
- return ret;
-}
-
int gfs2_glock_get(struct gfs2_sbd *sdp,
u64 number, const struct gfs2_glock_operations *glops,
int create, struct gfs2_glock **glp);
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 73a43ce..6aaa6c5 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -843,9 +843,8 @@ restart:
if (force_refresh || qd->qd_qb.qb_magic != cpu_to_be32(GFS2_MAGIC)) {
loff_t pos;
gfs2_glock_dq_uninit(q_gh);
- error = gfs2_glock_nq_init(qd->qd_gl,
- LM_ST_EXCLUSIVE, GL_NOCACHE,
- q_gh);
+ error = gfs2_glock_nq_init(qd->qd_gl, LM_ST_EXCLUSIVE,
+ GL_NOCACHE, q_gh);
if (error)
return error;
@@ -871,11 +870,9 @@ restart:
qlvb->qb_value = cpu_to_be64(q.qu_value);
qd->qd_qb = *qlvb;
- if (gfs2_glock_is_blocking(qd->qd_gl)) {
- gfs2_glock_dq_uninit(q_gh);
- force_refresh = 0;
- goto restart;
- }
+ gfs2_glock_dq_uninit(q_gh);
+ force_refresh = 0;
+ goto restart;
}
return 0;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Cluster-devel] [PATCH 04/10] GFS2: Add get_xstate quota function
2009-09-16 15:03 ` [Cluster-devel] [PATCH 03/10] GFS2: Remove obsolete code in quota.c Steven Whitehouse
@ 2009-09-16 15:03 ` Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 05/10] GFS2: Remove sysfs "done" files Steven Whitehouse
0 siblings, 1 reply; 11+ messages in thread
From: Steven Whitehouse @ 2009-09-16 15:03 UTC (permalink / raw)
To: cluster-devel.redhat.com
This allows querying of the quota state via the XFS quota
API.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
---
fs/gfs2/quota.c | 23 +++++++++++++++++++++++
1 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 6aaa6c5..e7114be 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -47,6 +47,7 @@
#include <linux/gfs2_ondisk.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
+#include <linux/dqblk_xfs.h>
#include "gfs2.h"
#include "incore.h"
@@ -1375,7 +1376,29 @@ int gfs2_quotad(void *data)
return 0;
}
+static int gfs2_quota_get_xstate(struct super_block *sb,
+ struct fs_quota_stat *fqs)
+{
+ struct gfs2_sbd *sdp = sb->s_fs_info;
+
+ memset(fqs, 0, sizeof(struct fs_quota_stat));
+ fqs->qs_version = FS_QSTAT_VERSION;
+ if (sdp->sd_args.ar_quota == GFS2_QUOTA_ON)
+ fqs->qs_flags = (XFS_QUOTA_UDQ_ENFD | XFS_QUOTA_GDQ_ENFD);
+ else if (sdp->sd_args.ar_quota == GFS2_QUOTA_ACCOUNT)
+ fqs->qs_flags = (XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_GDQ_ACCT);
+ if (sdp->sd_quota_inode) {
+ fqs->qs_uquota.qfs_ino = GFS2_I(sdp->sd_quota_inode)->i_no_addr;
+ fqs->qs_uquota.qfs_nblks = sdp->sd_quota_inode->i_blocks;
+ }
+ fqs->qs_uquota.qfs_nextents = 1; /* unsupported */
+ fqs->qs_gquota = fqs->qs_uquota; /* its the same inode in both cases */
+ fqs->qs_incoredqs = atomic_read(&qd_lru_count);
+ return 0;
+}
+
const struct quotactl_ops gfs2_quotactl_ops = {
.quota_sync = gfs2_quota_sync,
+ .get_xstate = gfs2_quota_get_xstate,
};
--
1.6.2.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Cluster-devel] [PATCH 05/10] GFS2: Remove sysfs "done" files
2009-09-16 15:03 ` [Cluster-devel] [PATCH 04/10] GFS2: Add get_xstate quota function Steven Whitehouse
@ 2009-09-16 15:03 ` Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 06/10] GFS2: Add proper error reporting to quota sync via sysfs Steven Whitehouse
0 siblings, 1 reply; 11+ messages in thread
From: Steven Whitehouse @ 2009-09-16 15:03 UTC (permalink / raw)
To: cluster-devel.redhat.com
All recent userspace programs for GFS2 only require the uevents
and they don't read the (potentially racy) "done" files. This
patch removes the "done" files which are no longer used.
This also means that is it now potentially possible for a single
node to recover more than one journal at once. That won't happen
until such time as gfs_controld makes multiple requests though,
but all the kernel support is currently in place.
This also has the effect of slightly shrinking the GFS2 super
block (in core).
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
---
fs/gfs2/incore.h | 4 ----
fs/gfs2/ops_fstype.c | 3 +--
fs/gfs2/recovery.c | 4 +---
fs/gfs2/sys.c | 24 ------------------------
4 files changed, 2 insertions(+), 33 deletions(-)
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 6edb423..a564ac5 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -498,14 +498,10 @@ struct gfs2_sb_host {
struct lm_lockstruct {
unsigned int ls_jid;
unsigned int ls_first;
- unsigned int ls_first_done;
unsigned int ls_nodir;
const struct lm_lockops *ls_ops;
unsigned long ls_flags;
dlm_lockspace_t *ls_dlm;
-
- int ls_recover_jid_done;
- int ls_recover_jid_status;
};
struct gfs2_sbd {
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 5c8f8cc..a3e188d 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -626,8 +626,7 @@ static void gfs2_others_may_mount(struct gfs2_sbd *sdp)
{
char *message = "FIRSTMOUNT=Done";
char *envp[] = { message, NULL };
- struct lm_lockstruct *ls = &sdp->sd_lockstruct;
- ls->ls_first_done = 1;
+
kobject_uevent_env(&sdp->sd_kobj, KOBJ_CHANGE, envp);
}
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c
index 59d2695..2aeb02d 100644
--- a/fs/gfs2/recovery.c
+++ b/fs/gfs2/recovery.c
@@ -431,9 +431,7 @@ static void gfs2_recovery_done(struct gfs2_sbd *sdp, unsigned int jid,
char env_jid[20];
char env_status[20];
char *envp[] = { env_jid, env_status, NULL };
- struct lm_lockstruct *ls = &sdp->sd_lockstruct;
- ls->ls_recover_jid_done = jid;
- ls->ls_recover_jid_status = message;
+
sprintf(env_jid, "JID=%d", jid);
sprintf(env_status, "RECOVERY=%s",
message == LM_RD_SUCCESS ? "Done" : "Failed");
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index be1b8ac..b9e68e6 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -326,12 +326,6 @@ static ssize_t lkfirst_show(struct gfs2_sbd *sdp, char *buf)
return sprintf(buf, "%d\n", ls->ls_first);
}
-static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf)
-{
- struct lm_lockstruct *ls = &sdp->sd_lockstruct;
- return sprintf(buf, "%d\n", ls->ls_first_done);
-}
-
static ssize_t recover_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
{
unsigned jid;
@@ -361,18 +355,6 @@ out:
return rv ? rv : len;
}
-static ssize_t recover_done_show(struct gfs2_sbd *sdp, char *buf)
-{
- struct lm_lockstruct *ls = &sdp->sd_lockstruct;
- return sprintf(buf, "%d\n", ls->ls_recover_jid_done);
-}
-
-static ssize_t recover_status_show(struct gfs2_sbd *sdp, char *buf)
-{
- struct lm_lockstruct *ls = &sdp->sd_lockstruct;
- return sprintf(buf, "%d\n", ls->ls_recover_jid_status);
-}
-
static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf)
{
return sprintf(buf, "%u\n", sdp->sd_lockstruct.ls_jid);
@@ -386,10 +368,7 @@ GDLM_ATTR(block, 0644, block_show, block_store);
GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store);
GDLM_ATTR(jid, 0444, jid_show, NULL);
GDLM_ATTR(first, 0444, lkfirst_show, NULL);
-GDLM_ATTR(first_done, 0444, first_done_show, NULL);
GDLM_ATTR(recover, 0600, NULL, recover_store);
-GDLM_ATTR(recover_done, 0444, recover_done_show, NULL);
-GDLM_ATTR(recover_status, 0444, recover_status_show, NULL);
static struct attribute *lock_module_attrs[] = {
&gdlm_attr_proto_name.attr,
@@ -397,10 +376,7 @@ static struct attribute *lock_module_attrs[] = {
&gdlm_attr_withdraw.attr,
&gdlm_attr_jid.attr,
&gdlm_attr_first.attr,
- &gdlm_attr_first_done.attr,
&gdlm_attr_recover.attr,
- &gdlm_attr_recover_done.attr,
- &gdlm_attr_recover_status.attr,
NULL,
};
--
1.6.2.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Cluster-devel] [PATCH 06/10] GFS2: Add proper error reporting to quota sync via sysfs
2009-09-16 15:03 ` [Cluster-devel] [PATCH 05/10] GFS2: Remove sysfs "done" files Steven Whitehouse
@ 2009-09-16 15:03 ` Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 07/10] GFS2: Remove constant argument from qdsb_get() Steven Whitehouse
0 siblings, 1 reply; 11+ messages in thread
From: Steven Whitehouse @ 2009-09-16 15:03 UTC (permalink / raw)
To: cluster-devel.redhat.com
For some reason, the errors were not making it to userspace.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
---
fs/gfs2/sys.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index b9e68e6..35ef542 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -178,6 +178,7 @@ static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf,
static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf,
size_t len)
{
+ int error;
u32 id;
if (!capable(CAP_SYS_ADMIN))
@@ -185,13 +186,14 @@ static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf,
id = simple_strtoul(buf, NULL, 0);
- gfs2_quota_refresh(sdp, 1, id);
- return len;
+ error = gfs2_quota_refresh(sdp, 1, id);
+ return error ? error : len;
}
static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
size_t len)
{
+ int error;
u32 id;
if (!capable(CAP_SYS_ADMIN))
@@ -199,8 +201,8 @@ static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
id = simple_strtoul(buf, NULL, 0);
- gfs2_quota_refresh(sdp, 0, id);
- return len;
+ error = gfs2_quota_refresh(sdp, 0, id);
+ return error ? error : len;
}
static ssize_t demote_rq_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
--
1.6.2.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Cluster-devel] [PATCH 07/10] GFS2: Remove constant argument from qdsb_get()
2009-09-16 15:03 ` [Cluster-devel] [PATCH 06/10] GFS2: Add proper error reporting to quota sync via sysfs Steven Whitehouse
@ 2009-09-16 15:03 ` Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 08/10] GFS2: Remove constant argument from qd_get() Steven Whitehouse
0 siblings, 1 reply; 11+ messages in thread
From: Steven Whitehouse @ 2009-09-16 15:03 UTC (permalink / raw)
To: cluster-devel.redhat.com
The "create" argument to qdsb_get() was only ever set to true,
so this patch removes that argument.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
---
fs/gfs2/quota.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index e7114be..f790f5a 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -462,12 +462,12 @@ static void qd_unlock(struct gfs2_quota_data *qd)
qd_put(qd);
}
-static int qdsb_get(struct gfs2_sbd *sdp, int user, u32 id, int create,
+static int qdsb_get(struct gfs2_sbd *sdp, int user, u32 id,
struct gfs2_quota_data **qdp)
{
int error;
- error = qd_get(sdp, user, id, create, qdp);
+ error = qd_get(sdp, user, id, CREATE, qdp);
if (error)
return error;
@@ -509,20 +509,20 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
return 0;
- error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, CREATE, qd);
+ error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, qd);
if (error)
goto out;
al->al_qd_num++;
qd++;
- error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, CREATE, qd);
+ error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, qd);
if (error)
goto out;
al->al_qd_num++;
qd++;
if (uid != NO_QUOTA_CHANGE && uid != ip->i_inode.i_uid) {
- error = qdsb_get(sdp, QUOTA_USER, uid, CREATE, qd);
+ error = qdsb_get(sdp, QUOTA_USER, uid, qd);
if (error)
goto out;
al->al_qd_num++;
@@ -530,7 +530,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
}
if (gid != NO_QUOTA_CHANGE && gid != ip->i_inode.i_gid) {
- error = qdsb_get(sdp, QUOTA_GROUP, gid, CREATE, qd);
+ error = qdsb_get(sdp, QUOTA_GROUP, gid, qd);
if (error)
goto out;
al->al_qd_num++;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Cluster-devel] [PATCH 08/10] GFS2: Remove constant argument from qd_get()
2009-09-16 15:03 ` [Cluster-devel] [PATCH 07/10] GFS2: Remove constant argument from qdsb_get() Steven Whitehouse
@ 2009-09-16 15:03 ` Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 09/10] GFS2: Clean up gfs2_adjust_quota() and do_glock() Steven Whitehouse
0 siblings, 1 reply; 11+ messages in thread
From: Steven Whitehouse @ 2009-09-16 15:03 UTC (permalink / raw)
To: cluster-devel.redhat.com
This function was only ever called with the "create"
argument set to true, so we can remove it.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
---
fs/gfs2/quota.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index f790f5a..db124af 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -165,7 +165,7 @@ fail:
return error;
}
-static int qd_get(struct gfs2_sbd *sdp, int user, u32 id, int create,
+static int qd_get(struct gfs2_sbd *sdp, int user, u32 id,
struct gfs2_quota_data **qdp)
{
struct gfs2_quota_data *qd = NULL, *new_qd = NULL;
@@ -203,7 +203,7 @@ static int qd_get(struct gfs2_sbd *sdp, int user, u32 id, int create,
spin_unlock(&qd_lru_lock);
- if (qd || !create) {
+ if (qd) {
if (new_qd) {
gfs2_glock_put(new_qd->qd_gl);
kmem_cache_free(gfs2_quotad_cachep, new_qd);
@@ -467,7 +467,7 @@ static int qdsb_get(struct gfs2_sbd *sdp, int user, u32 id,
{
int error;
- error = qd_get(sdp, user, id, CREATE, qdp);
+ error = qd_get(sdp, user, id, qdp);
if (error)
return error;
@@ -1117,7 +1117,7 @@ int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id)
struct gfs2_holder q_gh;
int error;
- error = qd_get(sdp, user, id, CREATE, &qd);
+ error = qd_get(sdp, user, id, &qd);
if (error)
return error;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Cluster-devel] [PATCH 09/10] GFS2: Clean up gfs2_adjust_quota() and do_glock()
2009-09-16 15:03 ` [Cluster-devel] [PATCH 08/10] GFS2: Remove constant argument from qd_get() Steven Whitehouse
@ 2009-09-16 15:03 ` Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 10/10] GFS2: Add get_xquota support Steven Whitehouse
0 siblings, 1 reply; 11+ messages in thread
From: Steven Whitehouse @ 2009-09-16 15:03 UTC (permalink / raw)
To: cluster-devel.redhat.com
Both of these functions contained confusing and in one case
duplicate code. This patch adds a new check in do_glock()
so that we report -ENOENT if we are asked to sync a quota
entry which doesn't exist. Due to the previous patch this is
now reported correctly to userspace.
Also there are a few new comments, and I hope that the code
is easier to understand now.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
---
fs/gfs2/quota.c | 82 +++++++++++++++++-------------------------------------
1 files changed, 26 insertions(+), 56 deletions(-)
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index db124af..33e369f 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -15,7 +15,7 @@
* fuzziness in the current usage value of IDs that are being used on different
* nodes in the cluster simultaneously. So, it is possible for a user on
* multiple nodes to overrun their quota, but that overrun is controlable.
- * Since quota tags are part of transactions, there is no need to a quota check
+ * Since quota tags are part of transactions, there is no need for a quota check
* program to be run on node crashes or anything like that.
*
* There are couple of knobs that let the administrator manage the quota
@@ -66,13 +66,6 @@
#define QUOTA_USER 1
#define QUOTA_GROUP 0
-struct gfs2_quota_host {
- u64 qu_limit;
- u64 qu_warn;
- s64 qu_value;
- u32 qu_ll_next;
-};
-
struct gfs2_quota_change_host {
u64 qc_change;
u32 qc_flags; /* GFS2_QCF_... */
@@ -618,33 +611,19 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change)
mutex_unlock(&sdp->sd_quota_mutex);
}
-static void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf)
-{
- const struct gfs2_quota *str = buf;
-
- qu->qu_limit = be64_to_cpu(str->qu_limit);
- qu->qu_warn = be64_to_cpu(str->qu_warn);
- qu->qu_value = be64_to_cpu(str->qu_value);
- qu->qu_ll_next = be32_to_cpu(str->qu_ll_next);
-}
-
-static void gfs2_quota_out(const struct gfs2_quota_host *qu, void *buf)
-{
- struct gfs2_quota *str = buf;
-
- str->qu_limit = cpu_to_be64(qu->qu_limit);
- str->qu_warn = cpu_to_be64(qu->qu_warn);
- str->qu_value = cpu_to_be64(qu->qu_value);
- str->qu_ll_next = cpu_to_be32(qu->qu_ll_next);
- memset(&str->qu_reserved, 0, sizeof(str->qu_reserved));
-}
-
/**
- * gfs2_adjust_quota
+ * gfs2_adjust_quota - adjust record of current block usage
+ * @ip: The quota inode
+ * @loc: Offset of the entry in the quota file
+ * @change: The amount of change to record
+ * @qd: The quota data
*
* This function was mostly borrowed from gfs2_block_truncate_page which was
* in turn mostly borrowed from ext3
+ *
+ * Returns: 0 or -ve on error
*/
+
static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
s64 change, struct gfs2_quota_data *qd)
{
@@ -656,8 +635,7 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
struct buffer_head *bh;
struct page *page;
void *kaddr;
- char *ptr;
- struct gfs2_quota_host qp;
+ struct gfs2_quota *qp;
s64 value;
int err = -EIO;
@@ -701,18 +679,13 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
gfs2_trans_add_bh(ip->i_gl, bh, 0);
kaddr = kmap_atomic(page, KM_USER0);
- ptr = kaddr + offset;
- gfs2_quota_in(&qp, ptr);
- qp.qu_value += change;
- value = qp.qu_value;
- gfs2_quota_out(&qp, ptr);
+ qp = kaddr + offset;
+ value = (s64)be64_to_cpu(qp->qu_value) + change;
+ qp->qu_value = cpu_to_be64(value);
+ qd->qd_qb.qb_value = qp->qu_value;
flush_dcache_page(page);
kunmap_atomic(kaddr, KM_USER0);
err = 0;
- qd->qd_qb.qb_magic = cpu_to_be32(GFS2_MAGIC);
- qd->qd_qb.qb_value = cpu_to_be64(value);
- ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_magic = cpu_to_be32(GFS2_MAGIC);
- ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_value = cpu_to_be64(value);
unlock:
unlock_page(page);
page_cache_release(page);
@@ -741,8 +714,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
sort(qda, num_qd, sizeof(struct gfs2_quota_data *), sort_qd, NULL);
for (qx = 0; qx < num_qd; qx++) {
- error = gfs2_glock_nq_init(qda[qx]->qd_gl,
- LM_ST_EXCLUSIVE,
+ error = gfs2_glock_nq_init(qda[qx]->qd_gl, LM_ST_EXCLUSIVE,
GL_NOCACHE, &ghs[qx]);
if (error)
goto out;
@@ -797,8 +769,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
qd = qda[x];
offset = qd2offset(qd);
error = gfs2_adjust_quota(ip, offset, qd->qd_change_sync,
- (struct gfs2_quota_data *)
- qd);
+ (struct gfs2_quota_data *)qd);
if (error)
goto out_end_trans;
@@ -829,8 +800,7 @@ static int do_glock(struct gfs2_quota_data *qd, int force_refresh,
struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
struct gfs2_holder i_gh;
- struct gfs2_quota_host q;
- char buf[sizeof(struct gfs2_quota)];
+ struct gfs2_quota q;
int error;
struct gfs2_quota_lvb *qlvb;
@@ -853,22 +823,23 @@ restart:
if (error)
goto fail;
- memset(buf, 0, sizeof(struct gfs2_quota));
+ memset(&q, 0, sizeof(struct gfs2_quota));
pos = qd2offset(qd);
- error = gfs2_internal_read(ip, NULL, buf, &pos,
- sizeof(struct gfs2_quota));
+ error = gfs2_internal_read(ip, NULL, (char *)&q, &pos, sizeof(q));
if (error < 0)
goto fail_gunlock;
-
+ if ((error < sizeof(q)) && force_refresh) {
+ error = -ENOENT;
+ goto fail_gunlock;
+ }
gfs2_glock_dq_uninit(&i_gh);
- gfs2_quota_in(&q, buf);
qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb;
qlvb->qb_magic = cpu_to_be32(GFS2_MAGIC);
qlvb->__pad = 0;
- qlvb->qb_limit = cpu_to_be64(q.qu_limit);
- qlvb->qb_warn = cpu_to_be64(q.qu_warn);
- qlvb->qb_value = cpu_to_be64(q.qu_value);
+ qlvb->qb_limit = q.qu_limit;
+ qlvb->qb_warn = q.qu_warn;
+ qlvb->qb_value = q.qu_value;
qd->qd_qb = *qlvb;
gfs2_glock_dq_uninit(q_gh);
@@ -1126,7 +1097,6 @@ int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id)
gfs2_glock_dq_uninit(&q_gh);
qd_put(qd);
-
return error;
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Cluster-devel] [PATCH 10/10] GFS2: Add get_xquota support
2009-09-16 15:03 ` [Cluster-devel] [PATCH 09/10] GFS2: Clean up gfs2_adjust_quota() and do_glock() Steven Whitehouse
@ 2009-09-16 15:03 ` Steven Whitehouse
0 siblings, 0 replies; 11+ messages in thread
From: Steven Whitehouse @ 2009-09-16 15:03 UTC (permalink / raw)
To: cluster-devel.redhat.com
This adds support for viewing the current GFS2 quota settings
via the XFS quota API. The setting of quotas will be addressed
in a later patch. Fields which are not supported here are left
set to zero.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
---
fs/gfs2/quota.c | 43 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 43 insertions(+), 0 deletions(-)
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 33e369f..d451480 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -1367,8 +1367,51 @@ static int gfs2_quota_get_xstate(struct super_block *sb,
return 0;
}
+static int gfs2_xquota_get(struct super_block *sb, int type, qid_t id,
+ struct fs_disk_quota *fdq)
+{
+ struct gfs2_sbd *sdp = sb->s_fs_info;
+ struct gfs2_quota_lvb *qlvb;
+ struct gfs2_quota_data *qd;
+ struct gfs2_holder q_gh;
+ int error;
+
+ memset(fdq, 0, sizeof(struct fs_disk_quota));
+
+ if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
+ return -ESRCH; /* Crazy XFS error code */
+
+ if (type == USRQUOTA)
+ type = QUOTA_USER;
+ else if (type == GRPQUOTA)
+ type = QUOTA_GROUP;
+ else
+ return -EINVAL;
+
+ error = qd_get(sdp, type, id, &qd);
+ if (error)
+ return error;
+ error = do_glock(qd, FORCE, &q_gh);
+ if (error)
+ goto out;
+
+ qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb;
+ fdq->d_version = FS_DQUOT_VERSION;
+ fdq->d_flags = (type == QUOTA_USER) ? XFS_USER_QUOTA : XFS_GROUP_QUOTA;
+ fdq->d_id = id;
+ fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit);
+ fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn);
+ fdq->d_bcount = be64_to_cpu(qlvb->qb_value);
+
+ gfs2_glock_dq_uninit(&q_gh);
+out:
+ qd_put(qd);
+ return 0;
+}
+
const struct quotactl_ops gfs2_quotactl_ops = {
.quota_sync = gfs2_quota_sync,
.get_xstate = gfs2_quota_get_xstate,
+ .get_xquota = gfs2_xquota_get,
};
--
1.6.2.5
^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2009-09-16 15:03 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-16 15:03 [Cluster-devel] Mostly quotas Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 01/10] GFS2: Alter arguments of gfs2_quota/statfs_sync Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 02/10] GFS2: Hook gfs2_quota_sync into VFS via gfs2_quotactl_ops Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 03/10] GFS2: Remove obsolete code in quota.c Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 04/10] GFS2: Add get_xstate quota function Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 05/10] GFS2: Remove sysfs "done" files Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 06/10] GFS2: Add proper error reporting to quota sync via sysfs Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 07/10] GFS2: Remove constant argument from qdsb_get() Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 08/10] GFS2: Remove constant argument from qd_get() Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 09/10] GFS2: Clean up gfs2_adjust_quota() and do_glock() Steven Whitehouse
2009-09-16 15:03 ` [Cluster-devel] [PATCH 10/10] GFS2: Add get_xquota support 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).