]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/ceph/inode.c
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi...
[karo-tx-linux.git] / fs / ceph / inode.c
index d45895f4a04dd466de53e5a6b1dfbcb01608824c..851814d951cd57c42b64b113c1055c31c8640106 100644 (file)
@@ -1131,8 +1131,8 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                                            req->r_request_started);
                dout(" final dn %p\n", dn);
                i++;
-       } else if (req->r_op == CEPH_MDS_OP_LOOKUPSNAP ||
-                  req->r_op == CEPH_MDS_OP_MKSNAP) {
+       } else if ((req->r_op == CEPH_MDS_OP_LOOKUPSNAP ||
+                  req->r_op == CEPH_MDS_OP_MKSNAP) && !req->r_aborted) {
                struct dentry *dn = req->r_dentry;
 
                /* fill out a snapdir LOOKUPSNAP dentry */
@@ -1196,6 +1196,39 @@ done:
 /*
  * Prepopulate our cache with readdir results, leases, etc.
  */
+static int readdir_prepopulate_inodes_only(struct ceph_mds_request *req,
+                                          struct ceph_mds_session *session)
+{
+       struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
+       int i, err = 0;
+
+       for (i = 0; i < rinfo->dir_nr; 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);
+
+               in = ceph_get_inode(req->r_dentry->d_sb, vino);
+               if (IS_ERR(in)) {
+                       err = PTR_ERR(in);
+                       dout("new_inode badness got %d\n", err);
+                       continue;
+               }
+               rc = fill_inode(in, &rinfo->dir_in[i], NULL, session,
+                               req->r_request_started, -1,
+                               &req->r_caps_reservation);
+               if (rc < 0) {
+                       pr_err("fill_inode badness on %p got %d\n", in, rc);
+                       err = rc;
+                       continue;
+               }
+       }
+
+       return err;
+}
+
 int ceph_readdir_prepopulate(struct ceph_mds_request *req,
                             struct ceph_mds_session *session)
 {
@@ -1210,6 +1243,9 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
        u64 frag = le32_to_cpu(rhead->args.readdir.frag);
        struct ceph_dentry_info *di;
 
+       if (req->r_aborted)
+               return readdir_prepopulate_inodes_only(req, session);
+
        if (le32_to_cpu(rinfo->head->op) == CEPH_MDS_OP_LSSNAP) {
                snapdir = ceph_get_snapdir(parent->d_inode);
                parent = d_find_alias(snapdir);