ceph: consider inode's last read/write when calculating wanted caps
[sfrench/cifs-2.6.git] / fs / ceph / file.c
index a6c484123d98494c7ef208024a82177a838ec238..6239cff491e20c546d89169ebac255e7b26f3822 100644 (file)
@@ -213,7 +213,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(ci, fmode); /* clean up */
+                       ceph_put_fmode(ci, fmode, 1); /* clean up */
                        return -ENOMEM;
                }
 
@@ -224,7 +224,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(ci, fmode); /* clean up */
+                       ceph_put_fmode(ci, fmode, 1); /* clean up */
                        return -ENOMEM;
                }
 
@@ -263,7 +263,7 @@ static int ceph_init_file(struct inode *inode, struct file *file, int fmode)
        case S_IFLNK:
                dout("init_file %p %p 0%o (symlink)\n", inode, file,
                     inode->i_mode);
-               ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
+               ceph_put_fmode(ceph_inode(inode), fmode, 1); /* clean up */
                break;
 
        default:
@@ -273,7 +273,7 @@ static int ceph_init_file(struct inode *inode, struct file *file, int fmode)
                 * we need to drop the open ref now, since we don't
                 * have .release set to ceph_release.
                 */
-               ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
+               ceph_put_fmode(ceph_inode(inode), fmode, 1); /* clean up */
                BUG_ON(inode->i_fop->release == ceph_release);
 
                /* call the proper open fop */
@@ -285,14 +285,15 @@ static int ceph_init_file(struct inode *inode, struct file *file, int fmode)
 /*
  * try renew caps after session gets killed.
  */
-int ceph_renew_caps(struct inode *inode)
+int ceph_renew_caps(struct inode *inode, int fmode)
 {
-       struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
+       struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
        struct ceph_inode_info *ci = ceph_inode(inode);
        struct ceph_mds_request *req;
        int err, flags, wanted;
 
        spin_lock(&ci->i_ceph_lock);
+       __ceph_touch_fmode(ci, mdsc, fmode);
        wanted = __ceph_caps_file_wanted(ci);
        if (__ceph_is_any_real_caps(ci) &&
            (!(wanted & CEPH_CAP_ANY_WR) || ci->i_auth_cap)) {
@@ -405,6 +406,7 @@ int ceph_open(struct inode *inode, struct file *file)
        } else if (ceph_snap(inode) != CEPH_NOSNAP &&
                   (ci->i_snap_caps & wanted) == wanted) {
                __ceph_get_fmode(ci, fmode);
+               __ceph_touch_fmode(ci, mdsc, fmode);
                spin_unlock(&ci->i_ceph_lock);
                return ceph_init_file(inode, file, fmode);
        }
@@ -781,7 +783,7 @@ retry:
        }
 out_req:
        if (!req->r_err && req->r_target_inode)
-               ceph_put_fmode(ceph_inode(req->r_target_inode), req->r_fmode);
+               ceph_put_fmode(ceph_inode(req->r_target_inode), req->r_fmode, 1);
        ceph_mdsc_put_request(req);
 out_ctx:
        ceph_release_acl_sec_ctx(&as_ctx);
@@ -798,7 +800,7 @@ int ceph_release(struct inode *inode, struct file *file)
                dout("release inode %p dir file %p\n", inode, file);
                WARN_ON(!list_empty(&dfi->file_info.rw_contexts));
 
-               ceph_put_fmode(ci, dfi->file_info.fmode);
+               ceph_put_fmode(ci, dfi->file_info.fmode, 1);
 
                if (dfi->last_readdir)
                        ceph_mdsc_put_request(dfi->last_readdir);
@@ -810,7 +812,8 @@ int ceph_release(struct inode *inode, struct file *file)
                dout("release inode %p regular file %p\n", inode, file);
                WARN_ON(!list_empty(&fi->rw_contexts));
 
-               ceph_put_fmode(ci, fi->fmode);
+               ceph_put_fmode(ci, fi->fmode, 1);
+
                kmem_cache_free(ceph_file_cachep, fi);
        }