mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 21:51:40 +00:00
bcachefs: Initialize sb_quota with default 1 week timer
For compliance with other quota implementations, we should be initializing quota information with a default 1 week timelimit: this fixes fstests generic/235. Also, this adds to_text() functions for some quota structs - useful debugging aids. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
de107dc800
commit
f866870f5d
@ -95,6 +95,113 @@ void bch2_quota_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
#include <linux/fs.h>
|
||||
#include <linux/quota.h>
|
||||
|
||||
static void qc_info_to_text(struct printbuf *out, struct qc_info *i)
|
||||
{
|
||||
printbuf_tabstops_reset(out);
|
||||
printbuf_tabstop_push(out, 20);
|
||||
|
||||
prt_str(out, "i_fieldmask");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%x", i->i_fieldmask);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "i_flags");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", i->i_flags);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "i_spc_timelimit");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", i->i_spc_timelimit);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "i_ino_timelimit");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", i->i_ino_timelimit);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "i_rt_spc_timelimit");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", i->i_rt_spc_timelimit);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "i_spc_warnlimit");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", i->i_spc_warnlimit);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "i_ino_warnlimit");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", i->i_ino_warnlimit);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "i_rt_spc_warnlimit");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", i->i_rt_spc_warnlimit);
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
static void qc_dqblk_to_text(struct printbuf *out, struct qc_dqblk *q)
|
||||
{
|
||||
printbuf_tabstops_reset(out);
|
||||
printbuf_tabstop_push(out, 20);
|
||||
|
||||
prt_str(out, "d_fieldmask");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%x", q->d_fieldmask);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "d_spc_hardlimit");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", q->d_spc_hardlimit);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "d_spc_softlimit");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", q->d_spc_softlimit);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "d_ino_hardlimit");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", q->d_ino_hardlimit);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "d_ino_softlimit");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", q->d_ino_softlimit);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "d_space");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", q->d_space);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "d_ino_count");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", q->d_ino_count);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "d_ino_timer");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", q->d_ino_timer);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "d_spc_timer");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", q->d_spc_timer);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "d_ino_warns");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%i", q->d_ino_warns);
|
||||
prt_newline(out);
|
||||
|
||||
prt_str(out, "d_spc_warns");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%i", q->d_spc_warns);
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
static inline unsigned __next_qtype(unsigned i, unsigned qtypes)
|
||||
{
|
||||
qtypes >>= i;
|
||||
@ -413,6 +520,26 @@ void bch2_fs_quota_init(struct bch_fs *c)
|
||||
mutex_init(&c->quotas[i].lock);
|
||||
}
|
||||
|
||||
static struct bch_sb_field_quota *bch2_sb_get_or_create_quota(struct bch_sb_handle *sb)
|
||||
{
|
||||
struct bch_sb_field_quota *sb_quota = bch2_sb_get_quota(sb->sb);
|
||||
|
||||
if (sb_quota)
|
||||
return sb_quota;
|
||||
|
||||
sb_quota = bch2_sb_resize_quota(sb, sizeof(*sb_quota) / sizeof(u64));
|
||||
if (sb_quota) {
|
||||
unsigned qtype, qc;
|
||||
|
||||
for (qtype = 0; qtype < QTYP_NR; qtype++)
|
||||
for (qc = 0; qc < Q_COUNTERS; qc++)
|
||||
sb_quota->q[qtype].c[qc].timelimit =
|
||||
cpu_to_le32(7 * 24 * 60 * 60);
|
||||
}
|
||||
|
||||
return sb_quota;
|
||||
}
|
||||
|
||||
static void bch2_sb_quota_read(struct bch_fs *c)
|
||||
{
|
||||
struct bch_sb_field_quota *sb_quota;
|
||||
@ -471,12 +598,19 @@ advance:
|
||||
|
||||
int bch2_fs_quota_read(struct bch_fs *c)
|
||||
{
|
||||
struct bch_sb_field_quota *sb_quota;
|
||||
struct btree_trans trans;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&c->sb_lock);
|
||||
sb_quota = bch2_sb_get_or_create_quota(&c->disk_sb);
|
||||
if (!sb_quota) {
|
||||
mutex_unlock(&c->sb_lock);
|
||||
return -BCH_ERR_ENOSPC_sb_quota;
|
||||
}
|
||||
|
||||
bch2_sb_quota_read(c);
|
||||
mutex_unlock(&c->sb_lock);
|
||||
|
||||
@ -500,6 +634,8 @@ int bch2_fs_quota_read(struct bch_fs *c)
|
||||
static int bch2_quota_enable(struct super_block *sb, unsigned uflags)
|
||||
{
|
||||
struct bch_fs *c = sb->s_fs_info;
|
||||
struct bch_sb_field_quota *sb_quota;
|
||||
int ret = 0;
|
||||
|
||||
if (sb->s_flags & SB_RDONLY)
|
||||
return -EROFS;
|
||||
@ -519,6 +655,12 @@ static int bch2_quota_enable(struct super_block *sb, unsigned uflags)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&c->sb_lock);
|
||||
sb_quota = bch2_sb_get_or_create_quota(&c->disk_sb);
|
||||
if (!sb_quota) {
|
||||
ret = -BCH_ERR_ENOSPC_sb_quota;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (uflags & FS_QUOTA_UDQ_ENFD)
|
||||
SET_BCH_SB_USRQUOTA(c->disk_sb.sb, true);
|
||||
|
||||
@ -529,9 +671,10 @@ static int bch2_quota_enable(struct super_block *sb, unsigned uflags)
|
||||
SET_BCH_SB_PRJQUOTA(c->disk_sb.sb, true);
|
||||
|
||||
bch2_write_super(c);
|
||||
unlock:
|
||||
mutex_unlock(&c->sb_lock);
|
||||
|
||||
return 0;
|
||||
return bch2_err_class(ret);
|
||||
}
|
||||
|
||||
static int bch2_quota_disable(struct super_block *sb, unsigned uflags)
|
||||
@ -643,6 +786,15 @@ static int bch2_quota_set_info(struct super_block *sb, int type,
|
||||
struct bch_fs *c = sb->s_fs_info;
|
||||
struct bch_sb_field_quota *sb_quota;
|
||||
struct bch_memquota_type *q;
|
||||
int ret = 0;
|
||||
|
||||
if (0) {
|
||||
struct printbuf buf = PRINTBUF;
|
||||
|
||||
qc_info_to_text(&buf, info);
|
||||
pr_info("setting:\n%s", buf.buf);
|
||||
printbuf_exit(&buf);
|
||||
}
|
||||
|
||||
if (sb->s_flags & SB_RDONLY)
|
||||
return -EROFS;
|
||||
@ -660,12 +812,10 @@ static int bch2_quota_set_info(struct super_block *sb, int type,
|
||||
q = &c->quotas[type];
|
||||
|
||||
mutex_lock(&c->sb_lock);
|
||||
sb_quota = bch2_sb_get_quota(c->disk_sb.sb);
|
||||
sb_quota = bch2_sb_get_or_create_quota(&c->disk_sb);
|
||||
if (!sb_quota) {
|
||||
sb_quota = bch2_sb_resize_quota(&c->disk_sb,
|
||||
sizeof(*sb_quota) / sizeof(u64));
|
||||
if (!sb_quota)
|
||||
return -BCH_ERR_ENOSPC_sb_quota;
|
||||
ret = -BCH_ERR_ENOSPC_sb_quota;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (info->i_fieldmask & QC_SPC_TIMER)
|
||||
@ -687,9 +837,10 @@ static int bch2_quota_set_info(struct super_block *sb, int type,
|
||||
bch2_sb_quota_read(c);
|
||||
|
||||
bch2_write_super(c);
|
||||
unlock:
|
||||
mutex_unlock(&c->sb_lock);
|
||||
|
||||
return 0;
|
||||
return bch2_err_class(ret);
|
||||
}
|
||||
|
||||
/* Get/set individual quotas: */
|
||||
@ -794,6 +945,14 @@ static int bch2_set_quota(struct super_block *sb, struct kqid qid,
|
||||
struct bkey_i_quota new_quota;
|
||||
int ret;
|
||||
|
||||
if (0) {
|
||||
struct printbuf buf = PRINTBUF;
|
||||
|
||||
qc_dqblk_to_text(&buf, qdq);
|
||||
pr_info("setting:\n%s", buf.buf);
|
||||
printbuf_exit(&buf);
|
||||
}
|
||||
|
||||
if (sb->s_flags & SB_RDONLY)
|
||||
return -EROFS;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user