Skip to content

Commit

Permalink
userns: Convert struct dquot dq_id to be a struct kqid
Browse files Browse the repository at this point in the history
Change struct dquot dq_id to a struct kqid and remove the now
unecessary dq_type.

Make minimal changes to dquot, quota_tree, quota_v1, quota_v2, ext3,
ext4, and ocfs2 to deal with the change in quota structures and
signatures.  The ocfs2 changes are larger than most because of the
extensive tracing throughout the ocfs2 quota code that prints out
dq_id.

quota_tree.c:get_index is modified to take a struct kqid instead of a
qid_t because all of it's callers pass in dquot->dq_id and it allows
me to introduce only a single conversion.

The rest of the changes are either just replacing dq_type with dq_id.type,
adding conversions to deal with the change in type and occassionally
adding qid_eq to allow quota id comparisons in a user namespace safe way.

Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: Theodore Tso <tytso@mit.edu>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
  • Loading branch information
Eric W. Biederman committed Sep 18, 2012
1 parent aca645a commit 4c376dc
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 82 deletions.
2 changes: 1 addition & 1 deletion fs/ext3/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -2814,7 +2814,7 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf)

static inline struct inode *dquot_to_inode(struct dquot *dquot)
{
return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
return sb_dqopt(dquot->dq_sb)->files[dquot->dq_id.type];
}

static int ext3_write_dquot(struct dquot *dquot)
Expand Down
2 changes: 1 addition & 1 deletion fs/ext4/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -4796,7 +4796,7 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)

static inline struct inode *dquot_to_inode(struct dquot *dquot)
{
return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
return sb_dqopt(dquot->dq_sb)->files[dquot->dq_id.type];
}

static int ext4_write_dquot(struct dquot *dquot)
Expand Down
43 changes: 26 additions & 17 deletions fs/ocfs2/quota_global.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static void ocfs2_global_mem2diskdqb(void *dp, struct dquot *dquot)
struct ocfs2_global_disk_dqblk *d = dp;
struct mem_dqblk *m = &dquot->dq_dqb;

d->dqb_id = cpu_to_le32(dquot->dq_id);
d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id));
d->dqb_use_count = cpu_to_le32(OCFS2_DQUOT(dquot)->dq_use_count);
d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit);
d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit);
Expand All @@ -112,11 +112,14 @@ static int ocfs2_global_is_id(void *dp, struct dquot *dquot)
{
struct ocfs2_global_disk_dqblk *d = dp;
struct ocfs2_mem_dqinfo *oinfo =
sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv;

if (qtree_entry_unused(&oinfo->dqi_gi, dp))
return 0;
return le32_to_cpu(d->dqb_id) == dquot->dq_id;

return qid_eq(make_kqid(&init_user_ns, dquot->dq_id.type,
le32_to_cpu(d->dqb_id)),
dquot->dq_id);
}

struct qtree_fmt_operations ocfs2_global_ops = {
Expand Down Expand Up @@ -475,7 +478,7 @@ int __ocfs2_sync_dquot(struct dquot *dquot, int freeing)
{
int err, err2;
struct super_block *sb = dquot->dq_sb;
int type = dquot->dq_type;
int type = dquot->dq_id.type;
struct ocfs2_mem_dqinfo *info = sb_dqinfo(sb, type)->dqi_priv;
struct ocfs2_global_disk_dqblk dqblk;
s64 spacechange, inodechange;
Expand Down Expand Up @@ -504,7 +507,8 @@ int __ocfs2_sync_dquot(struct dquot *dquot, int freeing)
olditime = dquot->dq_dqb.dqb_itime;
oldbtime = dquot->dq_dqb.dqb_btime;
ocfs2_global_disk2memdqb(dquot, &dqblk);
trace_ocfs2_sync_dquot(dquot->dq_id, dquot->dq_dqb.dqb_curspace,
trace_ocfs2_sync_dquot(from_kqid(&init_user_ns, dquot->dq_id),
dquot->dq_dqb.dqb_curspace,
(long long)spacechange,
dquot->dq_dqb.dqb_curinodes,
(long long)inodechange);
Expand Down Expand Up @@ -555,8 +559,8 @@ int __ocfs2_sync_dquot(struct dquot *dquot, int freeing)
err = ocfs2_qinfo_lock(info, freeing);
if (err < 0) {
mlog(ML_ERROR, "Failed to lock quota info, losing quota write"
" (type=%d, id=%u)\n", dquot->dq_type,
(unsigned)dquot->dq_id);
" (type=%d, id=%u)\n", dquot->dq_id.type,
(unsigned)from_kqid(&init_user_ns, dquot->dq_id));
goto out;
}
if (freeing)
Expand Down Expand Up @@ -591,9 +595,10 @@ static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type)
struct ocfs2_super *osb = OCFS2_SB(sb);
int status = 0;

trace_ocfs2_sync_dquot_helper(dquot->dq_id, dquot->dq_type,
trace_ocfs2_sync_dquot_helper(from_kqid(&init_user_ns, dquot->dq_id),
dquot->dq_id.type,
type, sb->s_id);
if (type != dquot->dq_type)
if (type != dquot->dq_id.type)
goto out;
status = ocfs2_lock_global_qf(oinfo, 1);
if (status < 0)
Expand Down Expand Up @@ -643,7 +648,8 @@ static int ocfs2_write_dquot(struct dquot *dquot)
struct ocfs2_super *osb = OCFS2_SB(dquot->dq_sb);
int status = 0;

trace_ocfs2_write_dquot(dquot->dq_id, dquot->dq_type);
trace_ocfs2_write_dquot(from_kqid(&init_user_ns, dquot->dq_id),
dquot->dq_id.type);

handle = ocfs2_start_trans(osb, OCFS2_QWRITE_CREDITS);
if (IS_ERR(handle)) {
Expand Down Expand Up @@ -677,11 +683,12 @@ static int ocfs2_release_dquot(struct dquot *dquot)
{
handle_t *handle;
struct ocfs2_mem_dqinfo *oinfo =
sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv;
struct ocfs2_super *osb = OCFS2_SB(dquot->dq_sb);
int status = 0;

trace_ocfs2_release_dquot(dquot->dq_id, dquot->dq_type);
trace_ocfs2_release_dquot(from_kqid(&init_user_ns, dquot->dq_id),
dquot->dq_id.type);

mutex_lock(&dquot->dq_lock);
/* Check whether we are not racing with some other dqget() */
Expand All @@ -691,7 +698,7 @@ static int ocfs2_release_dquot(struct dquot *dquot)
if (status < 0)
goto out;
handle = ocfs2_start_trans(osb,
ocfs2_calc_qdel_credits(dquot->dq_sb, dquot->dq_type));
ocfs2_calc_qdel_credits(dquot->dq_sb, dquot->dq_id.type));
if (IS_ERR(handle)) {
status = PTR_ERR(handle);
mlog_errno(status);
Expand Down Expand Up @@ -733,13 +740,14 @@ static int ocfs2_acquire_dquot(struct dquot *dquot)
int ex = 0;
struct super_block *sb = dquot->dq_sb;
struct ocfs2_super *osb = OCFS2_SB(sb);
int type = dquot->dq_type;
int type = dquot->dq_id.type;
struct ocfs2_mem_dqinfo *info = sb_dqinfo(sb, type)->dqi_priv;
struct inode *gqinode = info->dqi_gqinode;
int need_alloc = ocfs2_global_qinit_alloc(sb, type);
handle_t *handle;

trace_ocfs2_acquire_dquot(dquot->dq_id, type);
trace_ocfs2_acquire_dquot(from_kqid(&init_user_ns, dquot->dq_id),
type);
mutex_lock(&dquot->dq_lock);
/*
* We need an exclusive lock, because we're going to update use count
Expand Down Expand Up @@ -821,12 +829,13 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot)
int sync = 0;
int status;
struct super_block *sb = dquot->dq_sb;
int type = dquot->dq_type;
int type = dquot->dq_id.type;
struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
handle_t *handle;
struct ocfs2_super *osb = OCFS2_SB(sb);

trace_ocfs2_mark_dquot_dirty(dquot->dq_id, type);
trace_ocfs2_mark_dquot_dirty(from_kqid(&init_user_ns, dquot->dq_id),
type);

/* In case user set some limits, sync dquot immediately to global
* quota file so that information propagates quicker */
Expand Down
11 changes: 6 additions & 5 deletions fs/ocfs2/quota_local.c
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,8 @@ static void olq_set_dquot(struct buffer_head *bh, void *private)
dqblk = (struct ocfs2_local_disk_dqblk *)(bh->b_data
+ ol_dqblk_block_offset(sb, od->dq_local_off));

dqblk->dqb_id = cpu_to_le64(od->dq_dquot.dq_id);
dqblk->dqb_id = cpu_to_le64(from_kqid(&init_user_ns,
od->dq_dquot.dq_id));
spin_lock(&dq_data_lock);
dqblk->dqb_spacemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curspace -
od->dq_origspace);
Expand All @@ -893,7 +894,7 @@ static void olq_set_dquot(struct buffer_head *bh, void *private)
trace_olq_set_dquot(
(unsigned long long)le64_to_cpu(dqblk->dqb_spacemod),
(unsigned long long)le64_to_cpu(dqblk->dqb_inodemod),
od->dq_dquot.dq_id);
from_kqid(&init_user_ns, od->dq_dquot.dq_id));
}

/* Write dquot to local quota file */
Expand All @@ -902,7 +903,7 @@ int ocfs2_local_write_dquot(struct dquot *dquot)
struct super_block *sb = dquot->dq_sb;
struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
struct buffer_head *bh;
struct inode *lqinode = sb_dqopt(sb)->files[dquot->dq_type];
struct inode *lqinode = sb_dqopt(sb)->files[dquot->dq_id.type];
int status;

status = ocfs2_read_quota_phys_block(lqinode, od->dq_local_phys_blk,
Expand Down Expand Up @@ -1223,7 +1224,7 @@ static void olq_alloc_dquot(struct buffer_head *bh, void *private)
int ocfs2_create_local_dquot(struct dquot *dquot)
{
struct super_block *sb = dquot->dq_sb;
int type = dquot->dq_type;
int type = dquot->dq_id.type;
struct inode *lqinode = sb_dqopt(sb)->files[type];
struct ocfs2_quota_chunk *chunk;
struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
Expand Down Expand Up @@ -1277,7 +1278,7 @@ int ocfs2_create_local_dquot(struct dquot *dquot)
int ocfs2_local_release_dquot(handle_t *handle, struct dquot *dquot)
{
int status;
int type = dquot->dq_type;
int type = dquot->dq_id.type;
struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
struct super_block *sb = dquot->dq_sb;
struct ocfs2_local_disk_chunk *dchunk;
Expand Down
Loading

0 comments on commit 4c376dc

Please sign in to comment.