aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ceph/caps.c4
-rw-r--r--fs/ceph/inode.c3
-rw-r--r--fs/ceph/quota.c24
-rw-r--r--fs/ceph/snap.c2
-rw-r--r--fs/ceph/super.h1
5 files changed, 19 insertions, 15 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 25141b6683e9..23dbfae16156 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -703,9 +703,11 @@ void ceph_add_cap(struct inode *inode,
703 } 703 }
704 704
705 spin_lock(&realm->inodes_with_caps_lock); 705 spin_lock(&realm->inodes_with_caps_lock);
706 ci->i_snap_realm = realm;
707 list_add(&ci->i_snap_realm_item, 706 list_add(&ci->i_snap_realm_item,
708 &realm->inodes_with_caps); 707 &realm->inodes_with_caps);
708 ci->i_snap_realm = realm;
709 if (realm->ino == ci->i_vino.ino)
710 realm->inode = inode;
709 spin_unlock(&realm->inodes_with_caps_lock); 711 spin_unlock(&realm->inodes_with_caps_lock);
710 712
711 if (oldrealm) 713 if (oldrealm)
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 50ccae151ea0..8ea11b1a2e23 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -551,6 +551,9 @@ void ceph_destroy_inode(struct inode *inode)
551 dout(" dropping residual ref to snap realm %p\n", realm); 551 dout(" dropping residual ref to snap realm %p\n", realm);
552 spin_lock(&realm->inodes_with_caps_lock); 552 spin_lock(&realm->inodes_with_caps_lock);
553 list_del_init(&ci->i_snap_realm_item); 553 list_del_init(&ci->i_snap_realm_item);
554 ci->i_snap_realm = NULL;
555 if (realm->ino == ci->i_vino.ino)
556 realm->inode = NULL;
554 spin_unlock(&realm->inodes_with_caps_lock); 557 spin_unlock(&realm->inodes_with_caps_lock);
555 ceph_put_snap_realm(mdsc, realm); 558 ceph_put_snap_realm(mdsc, realm);
556 } 559 }
diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c
index 121819baeb58..c561a85ea8b1 100644
--- a/fs/ceph/quota.c
+++ b/fs/ceph/quota.c
@@ -83,7 +83,6 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc,
83{ 83{
84 struct ceph_inode_info *ci = NULL; 84 struct ceph_inode_info *ci = NULL;
85 struct ceph_snap_realm *realm, *next; 85 struct ceph_snap_realm *realm, *next;
86 struct ceph_vino vino;
87 struct inode *in; 86 struct inode *in;
88 bool has_quota; 87 bool has_quota;
89 88
@@ -97,13 +96,12 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc,
97 pr_err_ratelimited("get_quota_realm: ino (%llx.%llx) " 96 pr_err_ratelimited("get_quota_realm: ino (%llx.%llx) "
98 "null i_snap_realm\n", ceph_vinop(inode)); 97 "null i_snap_realm\n", ceph_vinop(inode));
99 while (realm) { 98 while (realm) {
100 vino.ino = realm->ino; 99 spin_lock(&realm->inodes_with_caps_lock);
101 vino.snap = CEPH_NOSNAP; 100 in = realm->inode ? igrab(realm->inode) : NULL;
102 in = ceph_find_inode(inode->i_sb, vino); 101 spin_unlock(&realm->inodes_with_caps_lock);
103 if (!in) { 102 if (!in)
104 pr_warn("Failed to find inode for %llu\n", vino.ino);
105 break; 103 break;
106 } 104
107 ci = ceph_inode(in); 105 ci = ceph_inode(in);
108 has_quota = ceph_has_quota(ci); 106 has_quota = ceph_has_quota(ci);
109 iput(in); 107 iput(in);
@@ -161,7 +159,6 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op,
161 struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc; 159 struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
162 struct ceph_inode_info *ci; 160 struct ceph_inode_info *ci;
163 struct ceph_snap_realm *realm, *next; 161 struct ceph_snap_realm *realm, *next;
164 struct ceph_vino vino;
165 struct inode *in; 162 struct inode *in;
166 u64 max, rvalue; 163 u64 max, rvalue;
167 bool exceeded = false; 164 bool exceeded = false;
@@ -177,13 +174,12 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op,
177 pr_err_ratelimited("check_quota_exceeded: ino (%llx.%llx) " 174 pr_err_ratelimited("check_quota_exceeded: ino (%llx.%llx) "
178 "null i_snap_realm\n", ceph_vinop(inode)); 175 "null i_snap_realm\n", ceph_vinop(inode));
179 while (realm) { 176 while (realm) {
180 vino.ino = realm->ino; 177 spin_lock(&realm->inodes_with_caps_lock);
181 vino.snap = CEPH_NOSNAP; 178 in = realm->inode ? igrab(realm->inode) : NULL;
182 in = ceph_find_inode(inode->i_sb, vino); 179 spin_unlock(&realm->inodes_with_caps_lock);
183 if (!in) { 180 if (!in)
184 pr_warn("Failed to find inode for %llu\n", vino.ino);
185 break; 181 break;
186 } 182
187 ci = ceph_inode(in); 183 ci = ceph_inode(in);
188 spin_lock(&ci->i_ceph_lock); 184 spin_lock(&ci->i_ceph_lock);
189 if (op == QUOTA_CHECK_MAX_FILES_OP) { 185 if (op == QUOTA_CHECK_MAX_FILES_OP) {
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
index 07cf95e6413d..041c27ea8de1 100644
--- a/fs/ceph/snap.c
+++ b/fs/ceph/snap.c
@@ -931,6 +931,8 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc,
931 list_add(&ci->i_snap_realm_item, 931 list_add(&ci->i_snap_realm_item,
932 &realm->inodes_with_caps); 932 &realm->inodes_with_caps);
933 ci->i_snap_realm = realm; 933 ci->i_snap_realm = realm;
934 if (realm->ino == ci->i_vino.ino)
935 realm->inode = inode;
934 spin_unlock(&realm->inodes_with_caps_lock); 936 spin_unlock(&realm->inodes_with_caps_lock);
935 937
936 spin_unlock(&ci->i_ceph_lock); 938 spin_unlock(&ci->i_ceph_lock);
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index e4ff485d24c7..8217abf46182 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -755,6 +755,7 @@ struct ceph_readdir_cache_control {
755 */ 755 */
756struct ceph_snap_realm { 756struct ceph_snap_realm {
757 u64 ino; 757 u64 ino;
758 struct inode *inode;
758 atomic_t nref; 759 atomic_t nref;
759 struct rb_node node; 760 struct rb_node node;
760 761