]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: simplify fill_trace, mount
authorSage Weil <sage@newdream.net>
Wed, 25 Mar 2009 23:41:43 +0000 (16:41 -0700)
committerSage Weil <sage@newdream.net>
Thu, 26 Mar 2009 20:10:11 +0000 (13:10 -0700)
Don't set sb->s_root.

src/kernel/file.c
src/kernel/inode.c
src/kernel/mds_client.c
src/kernel/mds_client.h
src/kernel/super.c

index 49e9fdc3fc92331833e99691631d3cd8720f8f6e..1b3401160e018fb14ae242f82a41d448d9a1be73 100644 (file)
@@ -197,7 +197,8 @@ struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
        err = ceph_mdsc_do_request(mdsc, parent_inode, req);
        dentry = ceph_finish_lookup(req, dentry, err);
        if (!err)
-               err = ceph_init_file(dentry->d_inode, file, req->r_fmode);
+               err = ceph_init_file(req->r_dentry->d_inode, file,
+                                    req->r_fmode);
        ceph_mdsc_put_request(req);
        dout(5, "ceph_lookup_open result=%p\n", dentry);
        return dentry;
index 2e53081378f6cdd1f84e01f793480dd221396b80..f57bf9a9b29fffded2f8116831be5f908386cb0f 100644 (file)
@@ -775,17 +775,14 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                    struct ceph_mds_session *session)
 {
        struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
-       int err = 0;
-       struct qstr dname;
-       struct dentry *dn;
-       struct dentry *parent = NULL;
-       struct dentry *existing;
-       struct inode *in;
+       struct inode *in = NULL;
        struct ceph_mds_reply_inode *ininfo;
-       int d = 0;
        struct ceph_vino vino;
-       bool have_dir_cap, have_lease;
-       int update_parent;
+       int i = 0;
+       int err = 0;
+
+       dout(10, "fill_trace %p numi %d numd %d\n", req, rinfo->trace_numi,
+            rinfo->trace_numd);
 
 #if 0
        /*
@@ -815,62 +812,42 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                return 0;
        }
 
-       vino.ino = le64_to_cpu(rinfo->trace_in[0].in->ino);
-       vino.snap = le64_to_cpu(rinfo->trace_in[0].in->snapid);
-       in = ceph_get_inode(sb, vino);
-       if (IS_ERR(in))
-               return PTR_ERR(in);
-
-       err = fill_inode(in, &rinfo->trace_in[0],
-                        rinfo->trace_numd ?
-                        rinfo->trace_dir[0] : NULL,
-                        session, req->r_request_started,
-                        (rinfo->trace_numd == 0 &&
-                         le32_to_cpu(rinfo->head->result) == 0) ?
-                        req->r_fmode : -1);
-       if (err < 0)
-               return err;
-
-       if (likely(sb->s_root)) {
-               dn = d_find_alias(in);
-               if (IS_ERR(dn))
-                       return PTR_ERR(dn);
-               iput(in); /* dn still references in */
-       } else {
-               /* first reply (i.e. we just mounted) */
-               dn = d_alloc_root(in);
-               if (dn == NULL) {
-                       derr(0, "d_alloc_root ENOMEM badness on root dentry\n");
-                       return -ENOMEM;
-               }
-               sb->s_root = dget(dn);
-       }
-
-       if (rinfo->trace_numd) {
+       /*
+        * update a dentry?
+        */
+       if (req->r_locked_dir) {
                /*
-                 lookup
-                 mknod symlink mkdir link rename
-                 unlink
-               */
-               int d = 0;
-
-               BUG_ON(req->r_locked_dir != in);
-               BUG_ON(!req->r_dentry);
-               parent = dn;
-               dn = req->r_dentry;
-               BUG_ON(dn->d_parent != parent);
-               in = NULL;
-
-               update_parent = 0;
+                * lookup link rename   : null -> possibly existing inode
+                * mknod symlink mkdir  : null -> new inode
+                * unlink               : linked -> null
+                */
+               struct inode *dir = req->r_locked_dir;
+               struct dentry *dn = req->r_dentry;
+               bool have_dir_cap, have_lease;
+
+               BUG_ON(!dn);
+               BUG_ON(!rinfo->trace_numd);
+               BUG_ON(dn->d_parent->d_inode != dir);
+               BUG_ON(ceph_ino(dir) !=
+                      le64_to_cpu(rinfo->trace_in[0].in->ino));
+               BUG_ON(ceph_snap(dir) !=
+                      le64_to_cpu(rinfo->trace_in[0].in->snapid));
+
+               err = fill_inode(dir, &rinfo->trace_in[0],
+                                rinfo->trace_dir[0],
+                                session, req->r_request_started,
+                                -1);
+               if (err < 0)
+                       return err;
 
                /* do we have a lease on the whole dir? */
                have_dir_cap =
-                       (le32_to_cpu(rinfo->trace_in[d].in->cap.caps) &
+                       (le32_to_cpu(rinfo->trace_in[0].in->cap.caps) &
                         CEPH_CAP_FILE_RDCACHE);
 
                /* do we have a dn lease? */
                have_lease = have_dir_cap ||
-                       (le16_to_cpu(rinfo->trace_dlease[d]->mask) &
+                       (le16_to_cpu(rinfo->trace_dlease[0]->mask) &
                         CEPH_LOCK_DN);
 
                if (!have_lease)
@@ -897,7 +874,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                }
 
                /* null dentry? */
-               if (1 == rinfo->trace_numi) {
+               if (rinfo->trace_numi == 1) {
                        dout(10, "fill_trace null dentry\n");
                        if (dn->d_inode) {
                                dout(20, "d_delete %p\n", dn);
@@ -907,7 +884,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                                d_instantiate(dn, NULL);
                                if (have_lease && d_unhashed(dn))
                                        d_rehash(dn);
-                               update_dentry_lease(dn, rinfo->trace_dlease[d],
+                               update_dentry_lease(dn, rinfo->trace_dlease[0],
                                                    session,
                                                    req->r_request_started);
                        }
@@ -915,99 +892,69 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                }
 
                /* attach proper inode */
-               ininfo = rinfo->trace_in[d+1].in;
-               vino.ino = le64_to_cpu(ininfo->ino);
-               vino.snap = le64_to_cpu(ininfo->snapid);
                BUG_ON(dn->d_inode);
 
-               struct dentry *newdn;
+               ininfo = rinfo->trace_in[1].in;
+               vino.ino = le64_to_cpu(ininfo->ino);
+               vino.snap = le64_to_cpu(ininfo->snapid);
                in = ceph_get_inode(dn->d_sb, vino);
                if (IS_ERR(in)) {
                        derr(30, "get_inode badness\n");
                        err = PTR_ERR(in);
                        d_delete(dn);
-                       dn = NULL;
                        goto done;
                }
-               newdn = splice_dentry(dn, in, &have_lease);
-
-               if (IS_ERR(newdn))
-                       goto update_inode;
+               dn = splice_dentry(dn, in, &have_lease);
+               if (IS_ERR(dn)) {
+                       err = PTR_ERR(dn);
+                       goto done;
+               }
+               req->r_dentry = dn;  /* may have changed from the splice */
 
                if (have_lease)
-                       update_dentry_lease(dn, rinfo->trace_dlease[d],
-                                           session, req->r_request_started);
+                       update_dentry_lease(dn, rinfo->trace_dlease[0],
+                                           session,
+                                           req->r_request_started);
+               dout(10, " final dn %p\n", dn);
+               i++;
+       }
 
-               if (update_parent) {
-                       struct ceph_inode_info *ci = ceph_inode(parent->d_inode);
-                       dout(10, " updated parent, clearing %p complete\n", parent->d_inode);
-                       ci->i_ceph_flags &= ~(CEPH_I_READDIR | CEPH_I_COMPLETE);
+       /* update any additional inodes */
+       for (; i < rinfo->trace_numi; i++) {
+               int is_target = i == rinfo->trace_numd;
+
+               vino.ino = le64_to_cpu(rinfo->trace_in[i].in->ino);
+               vino.snap = le64_to_cpu(rinfo->trace_in[i].in->snapid);
+
+               if (in != NULL &&
+                   ceph_ino(in) == vino.ino && ceph_snap(in) == vino.snap) {
+                       igrab(in);
+               } else {
+                       in = ceph_get_inode(sb, vino);
+                       if (IS_ERR(in)) {
+                               err = PTR_ERR(in);
+                               break;
+                       }
                }
 
-               /* done with dn update */
-               BUG_ON(dn->d_inode != in);
-       update_inode:
                err = fill_inode(in,
-                                &rinfo->trace_in[d+1],
-                                rinfo->trace_numd <= d ?
-                                rinfo->trace_dir[d+1] : NULL,
+                                &rinfo->trace_in[i], NULL,
                                 session, req->r_request_started,
-                                (d == rinfo->trace_numd-1 &&
+                                (is_target &&
                                  le32_to_cpu(rinfo->head->result) == 0) ?
                                 req->r_fmode : -1);
                if (err < 0) {
                        derr(30, "fill_inode badness\n");
-                       d_delete(dn);
-                       dn = NULL;
-                       in = NULL;
                        break;
                }
-
-               dput(parent);
-               parent = NULL;
-
-               /* do we diverge into a snap dir at this point in the trace? */
-               if (d == rinfo->trace_numi - rinfo->trace_snapdirpos - 1) {
-                       struct inode *snapdir = ceph_get_snapdir(in);
-                       dput(dn);
-                       dn = d_find_alias(snapdir);
-                       if (!dn) {
-                               struct ceph_client *client =
-                                       ceph_sb_to_client(parent->d_sb);
-
-                               dname.name = client->mount_args.snapdir_name,
-                               dname.len = strlen(dname.name);
-                               dname.hash = full_name_hash(dname.name,
-                                                           dname.len);
-                               dn = d_alloc(parent, &dname);
-                               if (!dn) {
-                                       err = -ENOMEM;
-                                       iput(snapdir);
-                                       break;
-                               }
-                               d_add(dn, snapdir);
-                       }
-                       iput(snapdir);
-                       dout(10, " snapdir dentry is %p\n", dn);
-               }
-               continue;
-
-
-       out_dir_no_inode:
-               in = NULL;
-               break;
+               if (is_target)
+                       req->r_target_inode = in;
+               else
+                       iput(in);
        }
 
 done:
-       if (parent)
-               dput(parent);
-
-       dout(10, "fill_trace done err=%d, last dn %p in %p\n", err, dn, in);
-       if (req->r_last_inode)
-               iput(req->r_last_inode);
-       req->r_last_inode = in;
-       if (in)
-               igrab(in);
+       dout(10, "fill_trace done err=%d\n", err);
        return err;
 }
 
index 5d307f42cc4f932eb5c38f496c961fc42e2b9d02..3f543ddfc7964f220c2d84bb8efaf659e38bd3c4 100644 (file)
@@ -397,8 +397,8 @@ void ceph_mdsc_put_request(struct ceph_mds_request *req)
                        ceph_msg_put(req->r_reply);
                        destroy_reply_info(&req->r_reply_info);
                }
-               if (req->r_last_inode)
-                       iput(req->r_last_inode);
+               if (req->r_target_inode)
+                       iput(req->r_target_inode);
                if (req->r_dentry)
                        dput(req->r_dentry);
                if (req->r_old_dentry)
@@ -1074,10 +1074,11 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc,
        rhead->oldest_client_tid = cpu_to_le64(__get_oldest_tid(mdsc));
        rhead->num_fwd = cpu_to_le32(req->r_num_fwd);
 
+       dout(20, " r_locked_dir = %p\n", req->r_locked_dir);
        rhead->num_dentries_wanted = req->r_locked_dir ? 1:0;
 
-       if (req->r_last_inode)
-               rhead->ino = cpu_to_le64(ceph_ino(req->r_last_inode));
+       if (req->r_target_inode)
+               rhead->ino = cpu_to_le64(ceph_ino(req->r_target_inode));
        else
                rhead->ino = 0;
        return 0;
index 5104b907de11efd1a3b79ea367f86d22ff4dc04a..14732c3a67c20899856c878ec3852ba8bd969edd 100644 (file)
@@ -182,7 +182,7 @@ struct ceph_mds_request {
        /* references to the trailing dentry and inode from parsing the
         * mds response.  also used to feed a VFS-provided dentry into
         * the reply handler */
-       struct inode     *r_last_inode;
+       struct inode     *r_target_inode;
        int               r_fmode;        /* file mode, if expecting cap */
        struct ceph_mds_session *r_session;
        struct ceph_mds_session *r_fwd_session;  /* forwarded from */
index eb1eb03a40242ec2fdd9634bf9cb65bd9a1e7ecc..216008cc9809289adc5e73ae20e6bbac9ed323fa 100644 (file)
@@ -771,11 +771,11 @@ static struct dentry *open_root_dentry(struct ceph_client *client,
        req->r_args.stat.mask = cpu_to_le32(CEPH_STAT_CAP_INODE);
        err = ceph_mdsc_do_request(mdsc, NULL, req);
        if (err == 0) {
-               root = req->r_dentry;
-               dget(root);
+               root = d_obtain_alias(req->r_target_inode);
                dout(30, "open_root_inode success, root dentry is %p\n", root);
-       } else
+       } else {
                root = ERR_PTR(err);
+       }
        ceph_mdsc_put_request(req);
        return root;
 }
@@ -788,12 +788,12 @@ static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt,
 {
        struct ceph_entity_addr *myaddr = NULL;
        struct ceph_msg *mount_msg;
-       struct dentry *root;
        int err;
        int request_interval = 5 * HZ;
        unsigned long timeout = client->mount_args.mount_timeout * HZ;
        unsigned long started = jiffies;  /* note the start time */
        int which;
+       struct dentry *root;
        unsigned char r;
 
        dout(10, "mount start\n");
@@ -1081,6 +1081,7 @@ static int ceph_get_sb(struct file_system_type *fs_type,
        err = ceph_mount(client, mnt, path);
        if (err < 0)
                goto out_splat;
+       dout(22, "hi mnt_root %p\n", mnt->mnt_root);
        dout(22, "root ino %llx.%llx\n", ceph_vinop(mnt->mnt_root->d_inode));
        return 0;