forked from luck/tmp_suning_uos_patched
ceph: define struct for dir entry in readdir reply
This avoids defining multiple arrays for entries in readdir reply Signed-off-by: Yan, Zheng <zyan@redhat.com>
This commit is contained in:
parent
a78600e7c4
commit
2a5beea3f1
|
@ -416,9 +416,9 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
|
|||
fi->last_name = NULL;
|
||||
fi->next_offset = 2;
|
||||
} else {
|
||||
err = note_last_dentry(fi,
|
||||
rinfo->dir_dname[rinfo->dir_nr-1],
|
||||
rinfo->dir_dname_len[rinfo->dir_nr-1],
|
||||
struct ceph_mds_reply_dir_entry *rde =
|
||||
rinfo->dir_entries + (rinfo->dir_nr-1);
|
||||
err = note_last_dentry(fi, rde->name, rde->name_len,
|
||||
fi->next_offset + rinfo->dir_nr);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -431,24 +431,21 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
|
|||
|
||||
ctx->pos = ceph_make_fpos(frag, off);
|
||||
while (off >= fi->offset && off - fi->offset < rinfo->dir_nr) {
|
||||
struct ceph_mds_reply_inode *in =
|
||||
rinfo->dir_in[off - fi->offset].in;
|
||||
struct ceph_mds_reply_dir_entry *rde =
|
||||
rinfo->dir_entries + (off - fi->offset);
|
||||
struct ceph_vino vino;
|
||||
ino_t ino;
|
||||
|
||||
dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n",
|
||||
off, off - fi->offset, rinfo->dir_nr, ctx->pos,
|
||||
rinfo->dir_dname_len[off - fi->offset],
|
||||
rinfo->dir_dname[off - fi->offset], in);
|
||||
BUG_ON(!in);
|
||||
ftype = le32_to_cpu(in->mode) >> 12;
|
||||
vino.ino = le64_to_cpu(in->ino);
|
||||
vino.snap = le64_to_cpu(in->snapid);
|
||||
rde->name_len, rde->name, &rde->inode.in);
|
||||
BUG_ON(!rde->inode.in);
|
||||
ftype = le32_to_cpu(rde->inode.in->mode) >> 12;
|
||||
vino.ino = le64_to_cpu(rde->inode.in->ino);
|
||||
vino.snap = le64_to_cpu(rde->inode.in->snapid);
|
||||
ino = ceph_vino_to_ino(vino);
|
||||
if (!dir_emit(ctx,
|
||||
rinfo->dir_dname[off - fi->offset],
|
||||
rinfo->dir_dname_len[off - fi->offset],
|
||||
ceph_translate_ino(inode->i_sb, ino), ftype)) {
|
||||
if (!dir_emit(ctx, rde->name, rde->name_len,
|
||||
ceph_translate_ino(inode->i_sb, ino), ftype)) {
|
||||
dout("filldir stopping us...\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1308,12 +1308,13 @@ static int readdir_prepopulate_inodes_only(struct ceph_mds_request *req,
|
|||
int i, err = 0;
|
||||
|
||||
for (i = 0; i < rinfo->dir_nr; i++) {
|
||||
struct ceph_mds_reply_dir_entry *rde = rinfo->dir_entries + i;
|
||||
struct ceph_vino vino;
|
||||
struct inode *in;
|
||||
int rc;
|
||||
|
||||
vino.ino = le64_to_cpu(rinfo->dir_in[i].in->ino);
|
||||
vino.snap = le64_to_cpu(rinfo->dir_in[i].in->snapid);
|
||||
vino.ino = le64_to_cpu(rde->inode.in->ino);
|
||||
vino.snap = le64_to_cpu(rde->inode.in->snapid);
|
||||
|
||||
in = ceph_get_inode(req->r_dentry->d_sb, vino);
|
||||
if (IS_ERR(in)) {
|
||||
|
@ -1321,7 +1322,7 @@ static int readdir_prepopulate_inodes_only(struct ceph_mds_request *req,
|
|||
dout("new_inode badness got %d\n", err);
|
||||
continue;
|
||||
}
|
||||
rc = fill_inode(in, NULL, &rinfo->dir_in[i], NULL, session,
|
||||
rc = fill_inode(in, NULL, &rde->inode, NULL, session,
|
||||
req->r_request_started, -1,
|
||||
&req->r_caps_reservation);
|
||||
if (rc < 0) {
|
||||
|
@ -1433,14 +1434,15 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
|
|||
|
||||
/* FIXME: release caps/leases if error occurs */
|
||||
for (i = 0; i < rinfo->dir_nr; i++) {
|
||||
struct ceph_mds_reply_dir_entry *rde = rinfo->dir_entries + i;
|
||||
struct ceph_vino vino;
|
||||
|
||||
dname.name = rinfo->dir_dname[i];
|
||||
dname.len = rinfo->dir_dname_len[i];
|
||||
dname.name = rde->name;
|
||||
dname.len = rde->name_len;
|
||||
dname.hash = full_name_hash(dname.name, dname.len);
|
||||
|
||||
vino.ino = le64_to_cpu(rinfo->dir_in[i].in->ino);
|
||||
vino.snap = le64_to_cpu(rinfo->dir_in[i].in->snapid);
|
||||
vino.ino = le64_to_cpu(rde->inode.in->ino);
|
||||
vino.snap = le64_to_cpu(rde->inode.in->snapid);
|
||||
|
||||
retry_lookup:
|
||||
dn = d_lookup(parent, &dname);
|
||||
|
@ -1486,7 +1488,7 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
|
|||
}
|
||||
}
|
||||
|
||||
ret = fill_inode(in, NULL, &rinfo->dir_in[i], NULL, session,
|
||||
ret = fill_inode(in, NULL, &rde->inode, NULL, session,
|
||||
req->r_request_started, -1,
|
||||
&req->r_caps_reservation);
|
||||
if (ret < 0) {
|
||||
|
@ -1522,8 +1524,7 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
|
|||
di = dn->d_fsdata;
|
||||
di->offset = ceph_make_fpos(frag, i + req->r_readdir_offset);
|
||||
|
||||
update_dentry_lease(dn, rinfo->dir_dlease[i],
|
||||
req->r_session,
|
||||
update_dentry_lease(dn, rde->lease, req->r_session,
|
||||
req->r_request_started);
|
||||
|
||||
if (err == 0 && skipped == 0 && cache_ctl.index >= 0) {
|
||||
|
|
|
@ -186,12 +186,9 @@ static int parse_reply_info_dir(void **p, void *end,
|
|||
if (num == 0)
|
||||
goto done;
|
||||
|
||||
BUG_ON(!info->dir_in);
|
||||
info->dir_dname = (void *)(info->dir_in + num);
|
||||
info->dir_dname_len = (void *)(info->dir_dname + num);
|
||||
info->dir_dlease = (void *)(info->dir_dname_len + num);
|
||||
if ((unsigned long)(info->dir_dlease + num) >
|
||||
(unsigned long)info->dir_in + info->dir_buf_size) {
|
||||
BUG_ON(!info->dir_entries);
|
||||
if ((unsigned long)(info->dir_entries + num) >
|
||||
(unsigned long)info->dir_entries + info->dir_buf_size) {
|
||||
pr_err("dir contents are larger than expected\n");
|
||||
WARN_ON(1);
|
||||
goto bad;
|
||||
|
@ -199,19 +196,19 @@ static int parse_reply_info_dir(void **p, void *end,
|
|||
|
||||
info->dir_nr = num;
|
||||
while (num) {
|
||||
struct ceph_mds_reply_dir_entry *rde = info->dir_entries + i;
|
||||
/* dentry */
|
||||
ceph_decode_need(p, end, sizeof(u32)*2, bad);
|
||||
info->dir_dname_len[i] = ceph_decode_32(p);
|
||||
ceph_decode_need(p, end, info->dir_dname_len[i], bad);
|
||||
info->dir_dname[i] = *p;
|
||||
*p += info->dir_dname_len[i];
|
||||
dout("parsed dir dname '%.*s'\n", info->dir_dname_len[i],
|
||||
info->dir_dname[i]);
|
||||
info->dir_dlease[i] = *p;
|
||||
rde->name_len = ceph_decode_32(p);
|
||||
ceph_decode_need(p, end, rde->name_len, bad);
|
||||
rde->name = *p;
|
||||
*p += rde->name_len;
|
||||
dout("parsed dir dname '%.*s'\n", rde->name_len, rde->name);
|
||||
rde->lease = *p;
|
||||
*p += sizeof(struct ceph_mds_reply_lease);
|
||||
|
||||
/* inode */
|
||||
err = parse_reply_info_in(p, end, &info->dir_in[i], features);
|
||||
err = parse_reply_info_in(p, end, &rde->inode, features);
|
||||
if (err < 0)
|
||||
goto out_bad;
|
||||
i++;
|
||||
|
@ -345,9 +342,9 @@ static int parse_reply_info(struct ceph_msg *msg,
|
|||
|
||||
static void destroy_reply_info(struct ceph_mds_reply_info_parsed *info)
|
||||
{
|
||||
if (!info->dir_in)
|
||||
if (!info->dir_entries)
|
||||
return;
|
||||
free_pages((unsigned long)info->dir_in, get_order(info->dir_buf_size));
|
||||
free_pages((unsigned long)info->dir_entries, get_order(info->dir_buf_size));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1656,8 +1653,7 @@ int ceph_alloc_readdir_reply_buffer(struct ceph_mds_request *req,
|
|||
struct ceph_inode_info *ci = ceph_inode(dir);
|
||||
struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
|
||||
struct ceph_mount_options *opt = req->r_mdsc->fsc->mount_options;
|
||||
size_t size = sizeof(*rinfo->dir_in) + sizeof(*rinfo->dir_dname_len) +
|
||||
sizeof(*rinfo->dir_dname) + sizeof(*rinfo->dir_dlease);
|
||||
size_t size = sizeof(struct ceph_mds_reply_dir_entry);
|
||||
int order, num_entries;
|
||||
|
||||
spin_lock(&ci->i_ceph_lock);
|
||||
|
@ -1668,14 +1664,14 @@ int ceph_alloc_readdir_reply_buffer(struct ceph_mds_request *req,
|
|||
|
||||
order = get_order(size * num_entries);
|
||||
while (order >= 0) {
|
||||
rinfo->dir_in = (void*)__get_free_pages(GFP_KERNEL |
|
||||
__GFP_NOWARN,
|
||||
order);
|
||||
if (rinfo->dir_in)
|
||||
rinfo->dir_entries = (void*)__get_free_pages(GFP_KERNEL |
|
||||
__GFP_NOWARN,
|
||||
order);
|
||||
if (rinfo->dir_entries)
|
||||
break;
|
||||
order--;
|
||||
}
|
||||
if (!rinfo->dir_in)
|
||||
if (!rinfo->dir_entries)
|
||||
return -ENOMEM;
|
||||
|
||||
num_entries = (PAGE_SIZE << order) / size;
|
||||
|
|
|
@ -47,6 +47,13 @@ struct ceph_mds_reply_info_in {
|
|||
u32 pool_ns_len;
|
||||
};
|
||||
|
||||
struct ceph_mds_reply_dir_entry {
|
||||
char *name;
|
||||
u32 name_len;
|
||||
struct ceph_mds_reply_lease *lease;
|
||||
struct ceph_mds_reply_info_in inode;
|
||||
};
|
||||
|
||||
/*
|
||||
* parsed info about an mds reply, including information about
|
||||
* either: 1) the target inode and/or its parent directory and dentry,
|
||||
|
@ -73,11 +80,8 @@ struct ceph_mds_reply_info_parsed {
|
|||
struct ceph_mds_reply_dirfrag *dir_dir;
|
||||
size_t dir_buf_size;
|
||||
int dir_nr;
|
||||
char **dir_dname;
|
||||
u32 *dir_dname_len;
|
||||
struct ceph_mds_reply_lease **dir_dlease;
|
||||
struct ceph_mds_reply_info_in *dir_in;
|
||||
u8 dir_complete, dir_end;
|
||||
struct ceph_mds_reply_dir_entry *dir_entries;
|
||||
};
|
||||
|
||||
/* for create results */
|
||||
|
|
Loading…
Reference in New Issue
Block a user