|
@@ -267,7 +267,7 @@ hashfn(const struct super_block *sb, unsigned int id, int type)
|
|
|
static inline void insert_dquot_hash(struct dquot *dquot)
|
|
|
{
|
|
|
struct hlist_head *head;
|
|
|
- head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type);
|
|
|
+ head = dquot_hash + hashfn(dquot->dq_sb, from_kqid(&init_user_ns, dquot->dq_id), dquot->dq_id.type);
|
|
|
hlist_add_head(&dquot->dq_hash, head);
|
|
|
}
|
|
|
|
|
@@ -279,13 +279,13 @@ static inline void remove_dquot_hash(struct dquot *dquot)
|
|
|
static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb,
|
|
|
unsigned int id, int type)
|
|
|
{
|
|
|
+ struct kqid qid = make_kqid(&init_user_ns, type, id);
|
|
|
struct hlist_node *node;
|
|
|
struct dquot *dquot;
|
|
|
|
|
|
hlist_for_each (node, dquot_hash+hashent) {
|
|
|
dquot = hlist_entry(node, struct dquot, dq_hash);
|
|
|
- if (dquot->dq_sb == sb && dquot->dq_id == id &&
|
|
|
- dquot->dq_type == type)
|
|
|
+ if (dquot->dq_sb == sb && qid_eq(dquot->dq_id, qid))
|
|
|
return dquot;
|
|
|
}
|
|
|
return NULL;
|
|
@@ -351,7 +351,7 @@ int dquot_mark_dquot_dirty(struct dquot *dquot)
|
|
|
spin_lock(&dq_list_lock);
|
|
|
if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags)) {
|
|
|
list_add(&dquot->dq_dirty, &sb_dqopt(dquot->dq_sb)->
|
|
|
- info[dquot->dq_type].dqi_dirty_list);
|
|
|
+ info[dquot->dq_id.type].dqi_dirty_list);
|
|
|
ret = 0;
|
|
|
}
|
|
|
spin_unlock(&dq_list_lock);
|
|
@@ -410,17 +410,17 @@ int dquot_acquire(struct dquot *dquot)
|
|
|
mutex_lock(&dquot->dq_lock);
|
|
|
mutex_lock(&dqopt->dqio_mutex);
|
|
|
if (!test_bit(DQ_READ_B, &dquot->dq_flags))
|
|
|
- ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot);
|
|
|
+ ret = dqopt->ops[dquot->dq_id.type]->read_dqblk(dquot);
|
|
|
if (ret < 0)
|
|
|
goto out_iolock;
|
|
|
set_bit(DQ_READ_B, &dquot->dq_flags);
|
|
|
/* Instantiate dquot if needed */
|
|
|
if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) {
|
|
|
- ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
|
|
|
+ ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot);
|
|
|
/* Write the info if needed */
|
|
|
- if (info_dirty(&dqopt->info[dquot->dq_type])) {
|
|
|
- ret2 = dqopt->ops[dquot->dq_type]->write_file_info(
|
|
|
- dquot->dq_sb, dquot->dq_type);
|
|
|
+ if (info_dirty(&dqopt->info[dquot->dq_id.type])) {
|
|
|
+ ret2 = dqopt->ops[dquot->dq_id.type]->write_file_info(
|
|
|
+ dquot->dq_sb, dquot->dq_id.type);
|
|
|
}
|
|
|
if (ret < 0)
|
|
|
goto out_iolock;
|
|
@@ -455,7 +455,7 @@ int dquot_commit(struct dquot *dquot)
|
|
|
/* Inactive dquot can be only if there was error during read/init
|
|
|
* => we have better not writing it */
|
|
|
if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
|
|
|
- ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
|
|
|
+ ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot);
|
|
|
else
|
|
|
ret = -EIO;
|
|
|
out_sem:
|
|
@@ -477,12 +477,12 @@ int dquot_release(struct dquot *dquot)
|
|
|
if (atomic_read(&dquot->dq_count) > 1)
|
|
|
goto out_dqlock;
|
|
|
mutex_lock(&dqopt->dqio_mutex);
|
|
|
- if (dqopt->ops[dquot->dq_type]->release_dqblk) {
|
|
|
- ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot);
|
|
|
+ if (dqopt->ops[dquot->dq_id.type]->release_dqblk) {
|
|
|
+ ret = dqopt->ops[dquot->dq_id.type]->release_dqblk(dquot);
|
|
|
/* Write the info */
|
|
|
- if (info_dirty(&dqopt->info[dquot->dq_type])) {
|
|
|
- ret2 = dqopt->ops[dquot->dq_type]->write_file_info(
|
|
|
- dquot->dq_sb, dquot->dq_type);
|
|
|
+ if (info_dirty(&dqopt->info[dquot->dq_id.type])) {
|
|
|
+ ret2 = dqopt->ops[dquot->dq_id.type]->write_file_info(
|
|
|
+ dquot->dq_sb, dquot->dq_id.type);
|
|
|
}
|
|
|
if (ret >= 0)
|
|
|
ret = ret2;
|
|
@@ -521,7 +521,7 @@ restart:
|
|
|
list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) {
|
|
|
if (dquot->dq_sb != sb)
|
|
|
continue;
|
|
|
- if (dquot->dq_type != type)
|
|
|
+ if (dquot->dq_id.type != type)
|
|
|
continue;
|
|
|
/* Wait for dquot users */
|
|
|
if (atomic_read(&dquot->dq_count)) {
|
|
@@ -741,7 +741,8 @@ void dqput(struct dquot *dquot)
|
|
|
#ifdef CONFIG_QUOTA_DEBUG
|
|
|
if (!atomic_read(&dquot->dq_count)) {
|
|
|
quota_error(dquot->dq_sb, "trying to free free dquot of %s %d",
|
|
|
- quotatypes[dquot->dq_type], dquot->dq_id);
|
|
|
+ quotatypes[dquot->dq_id.type],
|
|
|
+ from_kqid(&init_user_ns, dquot->dq_id));
|
|
|
BUG();
|
|
|
}
|
|
|
#endif
|
|
@@ -752,7 +753,7 @@ we_slept:
|
|
|
/* We have more than one user... nothing to do */
|
|
|
atomic_dec(&dquot->dq_count);
|
|
|
/* Releasing dquot during quotaoff phase? */
|
|
|
- if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_type) &&
|
|
|
+ if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_id.type) &&
|
|
|
atomic_read(&dquot->dq_count) == 1)
|
|
|
wake_up(&dquot->dq_wait_unused);
|
|
|
spin_unlock(&dq_list_lock);
|
|
@@ -815,7 +816,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type)
|
|
|
INIT_LIST_HEAD(&dquot->dq_dirty);
|
|
|
init_waitqueue_head(&dquot->dq_wait_unused);
|
|
|
dquot->dq_sb = sb;
|
|
|
- dquot->dq_type = type;
|
|
|
+ dquot->dq_id.type = type;
|
|
|
atomic_set(&dquot->dq_count, 1);
|
|
|
|
|
|
return dquot;
|
|
@@ -859,7 +860,7 @@ we_slept:
|
|
|
}
|
|
|
dquot = empty;
|
|
|
empty = NULL;
|
|
|
- dquot->dq_id = id;
|
|
|
+ dquot->dq_id = qid;
|
|
|
/* all dquots go on the inuse_list */
|
|
|
put_inuse(dquot);
|
|
|
/* hash it first so it can be found */
|
|
@@ -1219,8 +1220,8 @@ static void prepare_warning(struct dquot_warn *warn, struct dquot *dquot,
|
|
|
return;
|
|
|
warn->w_type = warntype;
|
|
|
warn->w_sb = dquot->dq_sb;
|
|
|
- warn->w_dq_id = dquot->dq_id;
|
|
|
- warn->w_dq_type = dquot->dq_type;
|
|
|
+ warn->w_dq_id = from_kqid(&init_user_ns, dquot->dq_id);
|
|
|
+ warn->w_dq_type = dquot->dq_id.type;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1245,7 +1246,7 @@ static void flush_warnings(struct dquot_warn *warn)
|
|
|
|
|
|
static int ignore_hardlimit(struct dquot *dquot)
|
|
|
{
|
|
|
- struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
|
|
|
+ struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type];
|
|
|
|
|
|
return capable(CAP_SYS_RESOURCE) &&
|
|
|
(info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
|
|
@@ -1258,7 +1259,7 @@ static int check_idq(struct dquot *dquot, qsize_t inodes,
|
|
|
{
|
|
|
qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes;
|
|
|
|
|
|
- if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) ||
|
|
|
+ if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_id.type) ||
|
|
|
test_bit(DQ_FAKE_B, &dquot->dq_flags))
|
|
|
return 0;
|
|
|
|
|
@@ -1283,7 +1284,7 @@ static int check_idq(struct dquot *dquot, qsize_t inodes,
|
|
|
dquot->dq_dqb.dqb_itime == 0) {
|
|
|
prepare_warning(warn, dquot, QUOTA_NL_ISOFTWARN);
|
|
|
dquot->dq_dqb.dqb_itime = get_seconds() +
|
|
|
- sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
|
|
|
+ sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type].dqi_igrace;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -1296,7 +1297,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc,
|
|
|
qsize_t tspace;
|
|
|
struct super_block *sb = dquot->dq_sb;
|
|
|
|
|
|
- if (!sb_has_quota_limits_enabled(sb, dquot->dq_type) ||
|
|
|
+ if (!sb_has_quota_limits_enabled(sb, dquot->dq_id.type) ||
|
|
|
test_bit(DQ_FAKE_B, &dquot->dq_flags))
|
|
|
return 0;
|
|
|
|
|
@@ -1327,7 +1328,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc,
|
|
|
if (!prealloc) {
|
|
|
prepare_warning(warn, dquot, QUOTA_NL_BSOFTWARN);
|
|
|
dquot->dq_dqb.dqb_btime = get_seconds() +
|
|
|
- sb_dqopt(sb)->info[dquot->dq_type].dqi_bgrace;
|
|
|
+ sb_dqopt(sb)->info[dquot->dq_id.type].dqi_bgrace;
|
|
|
}
|
|
|
else
|
|
|
/*
|
|
@@ -1346,7 +1347,7 @@ static int info_idq_free(struct dquot *dquot, qsize_t inodes)
|
|
|
|
|
|
if (test_bit(DQ_FAKE_B, &dquot->dq_flags) ||
|
|
|
dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit ||
|
|
|
- !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type))
|
|
|
+ !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_id.type))
|
|
|
return QUOTA_NL_NOWARN;
|
|
|
|
|
|
newinodes = dquot->dq_dqb.dqb_curinodes - inodes;
|
|
@@ -2362,9 +2363,9 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
|
|
|
|
|
|
memset(di, 0, sizeof(*di));
|
|
|
di->d_version = FS_DQUOT_VERSION;
|
|
|
- di->d_flags = dquot->dq_type == USRQUOTA ?
|
|
|
+ di->d_flags = dquot->dq_id.type == USRQUOTA ?
|
|
|
FS_USER_QUOTA : FS_GROUP_QUOTA;
|
|
|
- di->d_id = dquot->dq_id;
|
|
|
+ di->d_id = from_kqid_munged(current_user_ns(), dquot->dq_id);
|
|
|
|
|
|
spin_lock(&dq_data_lock);
|
|
|
di->d_blk_hardlimit = stoqb(dm->dqb_bhardlimit);
|
|
@@ -2403,7 +2404,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
|
|
|
{
|
|
|
struct mem_dqblk *dm = &dquot->dq_dqb;
|
|
|
int check_blim = 0, check_ilim = 0;
|
|
|
- struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
|
|
|
+ struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type];
|
|
|
|
|
|
if (di->d_fieldmask & ~VFS_FS_DQ_MASK)
|
|
|
return -EINVAL;
|