summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Layton <jlayton@kernel.org>2019-04-02 08:04:30 -0400
committerIlya Dryomov <idryomov@gmail.com>2020-03-30 12:42:40 +0200
commitf85122afeb230b4ad0b90ac40aba0fe6532baeea (patch)
tree18f4111a409899f7b05b795912fea24d0e6c9eac
parent3db0a2fc5668c6dc60218e0f55d2443bcd726aa0 (diff)
downloadlwn-f85122afeb230b4ad0b90ac40aba0fe6532baeea.tar.gz
lwn-f85122afeb230b4ad0b90ac40aba0fe6532baeea.zip
ceph: add refcounting for Fx caps
In future patches we'll be taking and relying on Fx caps. Add proper refcounting for them. Signed-off-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r--fs/ceph/caps.c7
-rw-r--r--fs/ceph/inode.c1
-rw-r--r--fs/ceph/super.h2
3 files changed, 9 insertions, 1 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 28ae0c134700..1a17f19fd8ad 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -965,6 +965,8 @@ int __ceph_caps_used(struct ceph_inode_info *ci)
used |= CEPH_CAP_FILE_WR;
if (ci->i_wb_ref || ci->i_wrbuffer_ref)
used |= CEPH_CAP_FILE_BUFFER;
+ if (ci->i_fx_ref)
+ used |= CEPH_CAP_FILE_EXCL;
return used;
}
@@ -2500,6 +2502,8 @@ static void __take_cap_refs(struct ceph_inode_info *ci, int got,
ci->i_rd_ref++;
if (got & CEPH_CAP_FILE_CACHE)
ci->i_rdcache_ref++;
+ if (got & CEPH_CAP_FILE_EXCL)
+ ci->i_fx_ref++;
if (got & CEPH_CAP_FILE_WR) {
if (ci->i_wr_ref == 0 && !ci->i_head_snapc) {
BUG_ON(!snap_rwsem_locked);
@@ -2911,6 +2915,9 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
if (had & CEPH_CAP_FILE_CACHE)
if (--ci->i_rdcache_ref == 0)
last++;
+ if (had & CEPH_CAP_FILE_EXCL)
+ if (--ci->i_fx_ref == 0)
+ last++;
if (had & CEPH_CAP_FILE_BUFFER) {
if (--ci->i_wb_ref == 0) {
last++;
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index d01710a16a4a..094b8fc37787 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -496,6 +496,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
ci->i_rdcache_ref = 0;
ci->i_wr_ref = 0;
ci->i_wb_ref = 0;
+ ci->i_fx_ref = 0;
ci->i_wrbuffer_ref = 0;
ci->i_wrbuffer_ref_head = 0;
atomic_set(&ci->i_filelock_ref, 0);
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 037cdfb2ad4f..2eee34b9ac71 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -375,7 +375,7 @@ struct ceph_inode_info {
/* held references to caps */
int i_pin_ref;
- int i_rd_ref, i_rdcache_ref, i_wr_ref, i_wb_ref;
+ int i_rd_ref, i_rdcache_ref, i_wr_ref, i_wb_ref, i_fx_ref;
int i_wrbuffer_ref, i_wrbuffer_ref_head;
atomic_t i_filelock_ref;
atomic_t i_shared_gen; /* increment each time we get FILE_SHARED */