ceph: define struct for dir entry in readdir reply
authorYan, Zheng <zyan@redhat.com>
Thu, 28 Apr 2016 01:37:39 +0000 (09:37 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 25 May 2016 23:15:34 +0000 (01:15 +0200)
This avoids defining multiple arrays for entries in readdir reply

Signed-off-by: Yan, Zheng <zyan@redhat.com>
fs/ceph/dir.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h

index 31a2cdf39210342e0a5085af62fb6ab63f1e48ac..68530acea2c8688c1ac8f2cc4995c03ae510f14a 100644 (file)
@@ -416,9 +416,9 @@ more:
                        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 @@ more:
 
        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;
                }
index 51ce5ce59f040088fdb3a94e60c0813bb9080704..40d081d7028ed716b0c11c0d43f2e5298fa7dfd1 100644 (file)
@@ -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 @@ retry_lookup:
                        }
                }
 
-               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 @@ retry_lookup:
                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) {
index 047f723bdbe62a31da6dc1b2cfa94e2a40b0a446..6220d3caf7aba0c9f8ece32710bc0713c9852ae3 100644 (file)
@@ -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 @@ out_bad:
 
 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;
index ee69a537dba53bc7770ac92997263d1a1ec190ad..0b84f9c0afa30ab4610603677033899ef4135d23 100644 (file)
@@ -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 */