quota_v2: Implement get_next_id() for V2 quota format
Implement functions to get id of next existing quota structure in quota file for quota tree based formats and thus for V2 quota format. Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
Родитель
be6257b251
Коммит
0066373d9f
|
@ -22,10 +22,9 @@ MODULE_LICENSE("GPL");
|
|||
|
||||
#define __QUOTA_QT_PARANOIA
|
||||
|
||||
static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth)
|
||||
static int __get_index(struct qtree_mem_dqinfo *info, qid_t id, int depth)
|
||||
{
|
||||
unsigned int epb = info->dqi_usable_bs >> 2;
|
||||
qid_t id = from_kqid(&init_user_ns, qid);
|
||||
|
||||
depth = info->dqi_qtree_depth - depth - 1;
|
||||
while (depth--)
|
||||
|
@ -33,6 +32,13 @@ static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth)
|
|||
return id % epb;
|
||||
}
|
||||
|
||||
static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth)
|
||||
{
|
||||
qid_t id = from_kqid(&init_user_ns, qid);
|
||||
|
||||
return __get_index(info, id, depth);
|
||||
}
|
||||
|
||||
/* Number of entries in one blocks */
|
||||
static int qtree_dqstr_in_blk(struct qtree_mem_dqinfo *info)
|
||||
{
|
||||
|
@ -668,3 +674,60 @@ int qtree_release_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
|
|||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(qtree_release_dquot);
|
||||
|
||||
static int find_next_id(struct qtree_mem_dqinfo *info, qid_t *id,
|
||||
unsigned int blk, int depth)
|
||||
{
|
||||
char *buf = getdqbuf(info->dqi_usable_bs);
|
||||
__le32 *ref = (__le32 *)buf;
|
||||
ssize_t ret;
|
||||
unsigned int epb = info->dqi_usable_bs >> 2;
|
||||
unsigned int level_inc = 1;
|
||||
int i;
|
||||
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = depth; i < info->dqi_qtree_depth - 1; i++)
|
||||
level_inc *= epb;
|
||||
|
||||
ret = read_blk(info, blk, buf);
|
||||
if (ret < 0) {
|
||||
quota_error(info->dqi_sb,
|
||||
"Can't read quota tree block %u", blk);
|
||||
goto out_buf;
|
||||
}
|
||||
for (i = __get_index(info, *id, depth); i < epb; i++) {
|
||||
if (ref[i] == cpu_to_le32(0)) {
|
||||
*id += level_inc;
|
||||
continue;
|
||||
}
|
||||
if (depth == info->dqi_qtree_depth - 1) {
|
||||
ret = 0;
|
||||
goto out_buf;
|
||||
}
|
||||
ret = find_next_id(info, id, le32_to_cpu(ref[i]), depth + 1);
|
||||
if (ret != -ENOENT)
|
||||
break;
|
||||
}
|
||||
if (i == epb) {
|
||||
ret = -ENOENT;
|
||||
goto out_buf;
|
||||
}
|
||||
out_buf:
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qtree_get_next_id(struct qtree_mem_dqinfo *info, struct kqid *qid)
|
||||
{
|
||||
qid_t id = from_kqid(&init_user_ns, *qid);
|
||||
int ret;
|
||||
|
||||
ret = find_next_id(info, &id, QT_TREEOFF, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*qid = make_kqid(&init_user_ns, qid->type, id);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(qtree_get_next_id);
|
||||
|
|
|
@ -304,6 +304,11 @@ static int v2_free_file_info(struct super_block *sb, int type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int v2_get_next_id(struct super_block *sb, struct kqid *qid)
|
||||
{
|
||||
return qtree_get_next_id(sb_dqinfo(sb, qid->type)->dqi_priv, qid);
|
||||
}
|
||||
|
||||
static const struct quota_format_ops v2_format_ops = {
|
||||
.check_quota_file = v2_check_quota_file,
|
||||
.read_file_info = v2_read_file_info,
|
||||
|
@ -312,6 +317,7 @@ static const struct quota_format_ops v2_format_ops = {
|
|||
.read_dqblk = v2_read_dquot,
|
||||
.commit_dqblk = v2_write_dquot,
|
||||
.release_dqblk = v2_release_dquot,
|
||||
.get_next_id = v2_get_next_id,
|
||||
};
|
||||
|
||||
static struct quota_format_type v2r0_quota_format = {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#define QTREE_DEL_REWRITE 6
|
||||
|
||||
struct dquot;
|
||||
struct kqid;
|
||||
|
||||
/* Operations */
|
||||
struct qtree_fmt_operations {
|
||||
|
@ -52,5 +53,6 @@ static inline int qtree_depth(struct qtree_mem_dqinfo *info)
|
|||
entries *= epb;
|
||||
return i;
|
||||
}
|
||||
int qtree_get_next_id(struct qtree_mem_dqinfo *info, struct kqid *qid);
|
||||
|
||||
#endif /* _LINUX_DQBLK_QTREE_H */
|
||||
|
|
Загрузка…
Ссылка в новой задаче