]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: move readdir cache prepopulation inside reply handler, out of caller process...
authorSage Weil <sage@newdream.net>
Mon, 31 Mar 2008 14:10:20 +0000 (07:10 -0700)
committerSage Weil <sage@newdream.net>
Mon, 31 Mar 2008 14:10:20 +0000 (07:10 -0700)
src/TODO
src/kernel/dir.c
src/kernel/inode.c
src/kernel/mds_client.c
src/kernel/super.h

index f8c08c2b6581de3fe5e8c6421a6004a5e7440abb..e6745fd67d23609f148a1049261c37d8b69d91d4 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -27,12 +27,9 @@ userspace client
 - reference count lease validations on path lookup?
 
 kernel client
-- make sure create() is setting mode properly.. untar shouldn't need to chmod!
 - use list_for_each_safe for caps removal?
   - revisit cap removal locking, make sure it's okay....
-- fix dentry locking on lease addition
 - trim expired leases so we don't indefinitely hold dcache refs...
-- move readdir result prepopulation inside reply handler (not in caller context!)
 - carry wrbuffer/rdcache caps until data is flushed
   - this should make the utimes bit kick in
 - make sure link/unlink results reflected by inode/dentry cache  (let fill_trace do it?  invalidate?  do actual update?)
index 11b1fe53d4effa6db217f937f3eabb0eacc769b1..f92990e392c40a5ef6642b4636d6c49286520377 100644 (file)
@@ -94,77 +94,6 @@ static unsigned fpos_off(loff_t p)
        return p & 0xffffffff;
 }
 
-
-static int prepopulate_dir(struct dentry *parent,
-                          struct ceph_mds_reply_info *rinfo,
-                          struct ceph_mds_session *session, 
-                          unsigned long from_time)
-{
-       struct qstr dname;
-       struct dentry *dn;
-       struct inode *in;
-       int i;
-
-       for (i = 0; i < rinfo->dir_nr; i++) {
-               /* dentry */
-               dname.name = rinfo->dir_dname[i];
-               dname.len = rinfo->dir_dname_len[i];
-               dname.hash = full_name_hash(dname.name, dname.len);
-
-               dn = d_lookup(parent, &dname);
-               dout(30, "calling d_lookup on parent=%p name=%.*s"
-                    " returned %p\n", parent, dname.len, dname.name, dn);
-
-               if (!dn) {
-                       dn = d_alloc(parent, &dname);
-                       if (dn == NULL) {
-                               dout(30, "d_alloc badness\n");
-                               return -1;
-                       }
-                       ceph_init_dentry(dn);
-               }
-               ceph_update_dentry_lease(dn, rinfo->dir_dlease[i], 
-                                        session, from_time);
-
-               /* inode */
-               if (dn->d_inode == NULL) {
-                       in = new_inode(parent->d_sb);
-                       if (in == NULL) {
-                               dout(30, "new_inode badness\n");
-                               d_delete(dn);
-                               return -1;
-                       }
-               } else {
-                       in = dn->d_inode;
-               }
-
-               if (ceph_ino(in) !=
-                   le64_to_cpu(rinfo->dir_in[i].in->ino)) {
-                       if (ceph_fill_inode(in, rinfo->dir_in[i].in) < 0) {
-                               dout(30, "ceph_fill_inode badness\n");
-                               iput(in);
-                               d_delete(dn);
-                               return -1;
-                       }
-                       d_instantiate(dn, in);
-                       if (d_unhashed(dn))
-                               d_rehash(dn);
-                       dout(10, "dir_readdir added dentry %p ino %llx %d/%d\n",
-                            dn, ceph_ino(in), i, rinfo->dir_nr);
-               } else {
-                       if (ceph_fill_inode(in, rinfo->dir_in[i].in) < 0) {
-                               dout(30, "ceph_fill_inode badness\n");
-                               return -1;
-                       }
-               }
-               ceph_update_inode_lease(in, rinfo->dir_ilease[i], session,
-                                       from_time);
-
-               dput(dn);
-       }
-       return 0;
-}
-
 static int ceph_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
 {
        struct ceph_file_info *fi = filp->private_data;
@@ -204,11 +133,6 @@ nextfrag:
                dout(10, "dir_readdir got and parsed readdir result=%d"
                     " on frag %u\n", err, frag);
                fi->last_readdir = req;
-
-               /* pre-populate dentry cache */
-               prepopulate_dir(filp->f_dentry, &req->r_reply_info, 
-                               req->r_session,
-                               req->r_from_time);
        }
 
        /* include . and .. with first fragment */
index 8860a286b84c1dcd385bf1a217e0d6c76342952a..b3f7fd0dda0eb4ee077b285ef9f8aa7b7bd03920 100644 (file)
@@ -337,7 +337,6 @@ void ceph_revoke_dentry_lease(struct dentry *dentry)
 
 
 
-
 int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, 
                    struct ceph_mds_session *session)
 {
@@ -479,6 +478,81 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
        return err;
 }
 
+/*
+ * prepopulate cache with readdir results
+ */
+int ceph_readdir_prepopulate(struct ceph_mds_request *req)
+{
+       struct dentry *parent = req->r_last_dentry;
+       struct ceph_mds_reply_info *rinfo = &req->r_reply_info;
+       struct qstr dname;
+       struct dentry *dn;
+       struct inode *in;
+       int i;
+
+       dout(10, "readdir_prepopulate %d items under dentry %p\n", 
+            rinfo->dir_nr, parent);
+       for (i = 0; i < rinfo->dir_nr; i++) {
+               /* dentry */
+               dname.name = rinfo->dir_dname[i];
+               dname.len = rinfo->dir_dname_len[i];
+               dname.hash = full_name_hash(dname.name, dname.len);
+
+               dn = d_lookup(parent, &dname);
+               dout(30, "calling d_lookup on parent=%p name=%.*s"
+                    " returned %p\n", parent, dname.len, dname.name, dn);
+
+               if (!dn) {
+                       dn = d_alloc(parent, &dname);
+                       if (dn == NULL) {
+                               dout(30, "d_alloc badness\n");
+                               return -1;
+                       }
+                       ceph_init_dentry(dn);
+               }
+               ceph_update_dentry_lease(dn, rinfo->dir_dlease[i], 
+                                        req->r_session, req->r_from_time);
+
+               /* inode */
+               if (dn->d_inode == NULL) {
+                       in = new_inode(parent->d_sb);
+                       if (in == NULL) {
+                               dout(30, "new_inode badness\n");
+                               d_delete(dn);
+                               return -1;
+                       }
+               } else {
+                       in = dn->d_inode;
+               }
+
+               if (ceph_ino(in) !=
+                   le64_to_cpu(rinfo->dir_in[i].in->ino)) {
+                       if (ceph_fill_inode(in, rinfo->dir_in[i].in) < 0) {
+                               dout(30, "ceph_fill_inode badness\n");
+                               iput(in);
+                               d_delete(dn);
+                               return -1;
+                       }
+                       d_instantiate(dn, in);
+                       if (d_unhashed(dn))
+                               d_rehash(dn);
+                       dout(10, "added dentry %p ino %llx %d/%d\n",
+                            dn, ceph_ino(in), i, rinfo->dir_nr);
+               } else {
+                       if (ceph_fill_inode(in, rinfo->dir_in[i].in) < 0) {
+                               dout(30, "ceph_fill_inode badness\n");
+                               return -1;
+                       }
+               }
+               ceph_update_inode_lease(in, rinfo->dir_ilease[i], 
+                                       req->r_session, req->r_from_time);
+
+               dput(dn);
+       }
+       dout(10, "readdir_prepopulate done\n");
+       return 0;
+}
+
 
 /*
  * capabilities
index 1ae6308ba890cce00a3f6a1316af9629d4148b43..50c0754839d68853a989b56b081f0e3820275778 100644 (file)
@@ -928,17 +928,23 @@ void ceph_mdsc_handle_reply(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
        err = ceph_fill_trace(mdsc->client->sb, req, req->r_session);
        if (err)
                goto done;
-       if (result == 0 && req->r_expects_cap) {
-               cap = le32_to_cpu(rinfo->head->file_caps);
-               capseq = le32_to_cpu(rinfo->head->file_caps_seq);
-               req->r_cap = ceph_add_cap(req->r_last_inode,
-                                         req->r_session,
-                                         cap, capseq);
-               if (IS_ERR(req->r_cap)) {
-                       err = PTR_ERR(req->r_cap);
-                       req->r_cap = 0;
-                       goto done;
+       if (result == 0) {
+               /* caps? */
+               if (req->r_expects_cap) {
+                       cap = le32_to_cpu(rinfo->head->file_caps);
+                       capseq = le32_to_cpu(rinfo->head->file_caps_seq);
+                       req->r_cap = ceph_add_cap(req->r_last_inode,
+                                                 req->r_session,
+                                                 cap, capseq);
+                       if (IS_ERR(req->r_cap)) {
+                               err = PTR_ERR(req->r_cap);
+                               req->r_cap = 0;
+                               goto done;
+                       }
                }
+
+               /* readdir result? */
+               ceph_readdir_prepopulate(req);
        }
 
 done:
index 893850273316e6b3619656065feb467c3a05ebfa..bc0499babd1b89352843a5b3f06d89733afc2dd8 100644 (file)
@@ -329,6 +329,10 @@ extern int ceph_get_inode(struct super_block *sb, u64 ino,
                          struct inode **pinode);
 extern int ceph_fill_inode(struct inode *inode,
                           struct ceph_mds_reply_inode *info);
+extern int ceph_fill_trace(struct super_block *sb, 
+                          struct ceph_mds_request *req,
+                          struct ceph_mds_session *session);
+extern int ceph_readdir_prepopulate(struct ceph_mds_request *req);
 
 extern void ceph_update_inode_lease(struct inode *inode, 
                                    struct ceph_mds_reply_lease *lease,
@@ -378,9 +382,6 @@ extern const struct file_operations ceph_dir_fops;
 extern struct dentry_operations ceph_dentry_ops;
 
 extern char *ceph_build_dentry_path(struct dentry *dentry, int *len);
-extern int ceph_fill_trace(struct super_block *sb, 
-                          struct ceph_mds_request *req,
-                          struct ceph_mds_session *session);
 extern int ceph_do_lookup(struct super_block *sb, struct dentry *dentry, int m);
 
 static inline void ceph_init_dentry(struct dentry *dentry) {