ceph: pass filp to ceph_get_caps()
[linux-2.6-microblaze.git] / fs / ceph / file.c
index 685a03c..fb007b7 100644 (file)
@@ -201,6 +201,7 @@ out:
 static int ceph_init_file_info(struct inode *inode, struct file *file,
                                        int fmode, bool isdir)
 {
+       struct ceph_inode_info *ci = ceph_inode(inode);
        struct ceph_file_info *fi;
 
        dout("%s %p %p 0%o (%s)\n", __func__, inode, file,
@@ -211,7 +212,7 @@ static int ceph_init_file_info(struct inode *inode, struct file *file,
                struct ceph_dir_file_info *dfi =
                        kmem_cache_zalloc(ceph_dir_file_cachep, GFP_KERNEL);
                if (!dfi) {
-                       ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
+                       ceph_put_fmode(ci, fmode); /* clean up */
                        return -ENOMEM;
                }
 
@@ -222,7 +223,7 @@ static int ceph_init_file_info(struct inode *inode, struct file *file,
        } else {
                fi = kmem_cache_zalloc(ceph_file_cachep, GFP_KERNEL);
                if (!fi) {
-                       ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
+                       ceph_put_fmode(ci, fmode); /* clean up */
                        return -ENOMEM;
                }
 
@@ -232,6 +233,7 @@ static int ceph_init_file_info(struct inode *inode, struct file *file,
        fi->fmode = fmode;
        spin_lock_init(&fi->rw_contexts_lock);
        INIT_LIST_HEAD(&fi->rw_contexts);
+       fi->meta_err = errseq_sample(&ci->i_meta_err);
 
        return 0;
 }
@@ -1260,7 +1262,8 @@ again:
                want = CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO;
        else
                want = CEPH_CAP_FILE_CACHE;
-       ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, want, -1, &got, &pinned_page);
+       ret = ceph_get_caps(filp, CEPH_CAP_FILE_RD, want, -1,
+                           &got, &pinned_page);
        if (ret < 0)
                return ret;
 
@@ -1457,7 +1460,7 @@ retry_snap:
        else
                want = CEPH_CAP_FILE_BUFFER;
        got = 0;
-       err = ceph_get_caps(ci, CEPH_CAP_FILE_WR, want, pos + count,
+       err = ceph_get_caps(file, CEPH_CAP_FILE_WR, want, pos + count,
                            &got, NULL);
        if (err < 0)
                goto out;
@@ -1781,7 +1784,7 @@ static long ceph_fallocate(struct file *file, int mode,
        else
                want = CEPH_CAP_FILE_BUFFER;
 
-       ret = ceph_get_caps(ci, CEPH_CAP_FILE_WR, want, endoff, &got, NULL);
+       ret = ceph_get_caps(file, CEPH_CAP_FILE_WR, want, endoff, &got, NULL);
        if (ret < 0)
                goto unlock;
 
@@ -1810,16 +1813,15 @@ unlock:
  * src_ci.  Two attempts are made to obtain both caps, and an error is return if
  * this fails; zero is returned on success.
  */
-static int get_rd_wr_caps(struct ceph_inode_info *src_ci,
-                         loff_t src_endoff, int *src_got,
-                         struct ceph_inode_info *dst_ci,
+static int get_rd_wr_caps(struct file *src_filp, int *src_got,
+                         struct file *dst_filp,
                          loff_t dst_endoff, int *dst_got)
 {
        int ret = 0;
        bool retrying = false;
 
 retry_caps:
-       ret = ceph_get_caps(dst_ci, CEPH_CAP_FILE_WR, CEPH_CAP_FILE_BUFFER,
+       ret = ceph_get_caps(dst_filp, CEPH_CAP_FILE_WR, CEPH_CAP_FILE_BUFFER,
                            dst_endoff, dst_got, NULL);
        if (ret < 0)
                return ret;
@@ -1829,24 +1831,24 @@ retry_caps:
         * we would risk a deadlock by using ceph_get_caps.  Thus, we'll do some
         * retry dance instead to try to get both capabilities.
         */
-       ret = ceph_try_get_caps(src_ci, CEPH_CAP_FILE_RD, CEPH_CAP_FILE_SHARED,
+       ret = ceph_try_get_caps(file_inode(src_filp),
+                               CEPH_CAP_FILE_RD, CEPH_CAP_FILE_SHARED,
                                false, src_got);
        if (ret <= 0) {
                /* Start by dropping dst_ci caps and getting src_ci caps */
-               ceph_put_cap_refs(dst_ci, *dst_got);
+               ceph_put_cap_refs(ceph_inode(file_inode(dst_filp)), *dst_got);
                if (retrying) {
                        if (!ret)
                                /* ceph_try_get_caps masks EAGAIN */
                                ret = -EAGAIN;
                        return ret;
                }
-               ret = ceph_get_caps(src_ci, CEPH_CAP_FILE_RD,
-                                   CEPH_CAP_FILE_SHARED, src_endoff,
-                                   src_got, NULL);
+               ret = ceph_get_caps(src_filp, CEPH_CAP_FILE_RD,
+                                   CEPH_CAP_FILE_SHARED, -1, src_got, NULL);
                if (ret < 0)
                        return ret;
                /*... drop src_ci caps too, and retry */
-               ceph_put_cap_refs(src_ci, *src_got);
+               ceph_put_cap_refs(ceph_inode(file_inode(src_filp)), *src_got);
                retrying = true;
                goto retry_caps;
        }
@@ -1913,8 +1915,6 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
        int src_got = 0, dst_got = 0, err, dirty;
        bool do_final_copy = false;
 
-       if (src_inode == dst_inode)
-               return -EINVAL;
        if (src_inode->i_sb != dst_inode->i_sb)
                return -EXDEV;
        if (ceph_snap(dst_inode) != CEPH_NOSNAP)
@@ -1960,8 +1960,8 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
         * clients may have dirty data in their caches.  And OSDs know nothing
         * about caps, so they can't safely do the remote object copies.
         */
-       err = get_rd_wr_caps(src_ci, (src_off + len), &src_got,
-                            dst_ci, (dst_off + len), &dst_got);
+       err = get_rd_wr_caps(src_file, &src_got,
+                            dst_file, (dst_off + len), &dst_got);
        if (err < 0) {
                dout("get_rd_wr_caps returned %d\n", err);
                ret = -EOPNOTSUPP;
@@ -2018,9 +2018,8 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
                        goto out;
                }
                len -= ret;
-               err = get_rd_wr_caps(src_ci, (src_off + len),
-                                    &src_got, dst_ci,
-                                    (dst_off + len), &dst_got);
+               err = get_rd_wr_caps(src_file, &src_got,
+                                    dst_file, (dst_off + len), &dst_got);
                if (err < 0)
                        goto out;
                err = is_file_size_ok(src_inode, dst_inode,