aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r--fs/ceph/caps.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 0c1681806867..0dd0b81e64f7 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -858,6 +858,8 @@ static int __ceph_is_any_caps(struct ceph_inode_info *ci)
858} 858}
859 859
860/* 860/*
861 * Remove a cap. Take steps to deal with a racing iterate_session_caps.
862 *
861 * caller should hold i_lock. 863 * caller should hold i_lock.
862 * caller will not hold session s_mutex if called from destroy_inode. 864 * caller will not hold session s_mutex if called from destroy_inode.
863 */ 865 */
@@ -865,16 +867,12 @@ void __ceph_remove_cap(struct ceph_cap *cap)
865{ 867{
866 struct ceph_mds_session *session = cap->session; 868 struct ceph_mds_session *session = cap->session;
867 struct ceph_inode_info *ci = cap->ci; 869 struct ceph_inode_info *ci = cap->ci;
868 struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc; 870 struct ceph_mds_client *mdsc =
871 &ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc;
872 int removed = 0;
869 873
870 dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode); 874 dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode);
871 875
872 /* remove from inode list */
873 rb_erase(&cap->ci_node, &ci->i_caps);
874 cap->ci = NULL;
875 if (ci->i_auth_cap == cap)
876 ci->i_auth_cap = NULL;
877
878 /* remove from session list */ 876 /* remove from session list */
879 spin_lock(&session->s_cap_lock); 877 spin_lock(&session->s_cap_lock);
880 if (session->s_cap_iterator == cap) { 878 if (session->s_cap_iterator == cap) {
@@ -885,10 +883,18 @@ void __ceph_remove_cap(struct ceph_cap *cap)
885 list_del_init(&cap->session_caps); 883 list_del_init(&cap->session_caps);
886 session->s_nr_caps--; 884 session->s_nr_caps--;
887 cap->session = NULL; 885 cap->session = NULL;
886 removed = 1;
888 } 887 }
888 /* protect backpointer with s_cap_lock: see iterate_session_caps */
889 cap->ci = NULL;
889 spin_unlock(&session->s_cap_lock); 890 spin_unlock(&session->s_cap_lock);
890 891
891 if (cap->session == NULL) 892 /* remove from inode list */
893 rb_erase(&cap->ci_node, &ci->i_caps);
894 if (ci->i_auth_cap == cap)
895 ci->i_auth_cap = NULL;
896
897 if (removed)
892 ceph_put_cap(cap); 898 ceph_put_cap(cap);
893 899
894 if (!__ceph_is_any_caps(ci) && ci->i_snap_realm) { 900 if (!__ceph_is_any_caps(ci) && ci->i_snap_realm) {
@@ -932,9 +938,9 @@ static int send_cap_msg(struct ceph_mds_session *session,
932 seq, issue_seq, mseq, follows, size, max_size, 938 seq, issue_seq, mseq, follows, size, max_size,
933 xattr_version, xattrs_buf ? (int)xattrs_buf->vec.iov_len : 0); 939 xattr_version, xattrs_buf ? (int)xattrs_buf->vec.iov_len : 0);
934 940
935 msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, sizeof(*fc), 0, 0, NULL); 941 msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, sizeof(*fc), GFP_NOFS);
936 if (IS_ERR(msg)) 942 if (!msg)
937 return PTR_ERR(msg); 943 return -ENOMEM;
938 944
939 msg->hdr.tid = cpu_to_le64(flush_tid); 945 msg->hdr.tid = cpu_to_le64(flush_tid);
940 946
@@ -1293,7 +1299,8 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci)
1293 */ 1299 */
1294void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) 1300void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
1295{ 1301{
1296 struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc; 1302 struct ceph_mds_client *mdsc =
1303 &ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc;
1297 struct inode *inode = &ci->vfs_inode; 1304 struct inode *inode = &ci->vfs_inode;
1298 int was = ci->i_dirty_caps; 1305 int was = ci->i_dirty_caps;
1299 int dirty = 0; 1306 int dirty = 0;
@@ -1331,7 +1338,7 @@ void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
1331static int __mark_caps_flushing(struct inode *inode, 1338static int __mark_caps_flushing(struct inode *inode,
1332 struct ceph_mds_session *session) 1339 struct ceph_mds_session *session)
1333{ 1340{
1334 struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc; 1341 struct ceph_mds_client *mdsc = &ceph_sb_to_client(inode->i_sb)->mdsc;
1335 struct ceph_inode_info *ci = ceph_inode(inode); 1342 struct ceph_inode_info *ci = ceph_inode(inode);
1336 int flushing; 1343 int flushing;
1337 1344
@@ -1658,7 +1665,7 @@ ack:
1658static int try_flush_caps(struct inode *inode, struct ceph_mds_session *session, 1665static int try_flush_caps(struct inode *inode, struct ceph_mds_session *session,
1659 unsigned *flush_tid) 1666 unsigned *flush_tid)
1660{ 1667{
1661 struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc; 1668 struct ceph_mds_client *mdsc = &ceph_sb_to_client(inode->i_sb)->mdsc;
1662 struct ceph_inode_info *ci = ceph_inode(inode); 1669 struct ceph_inode_info *ci = ceph_inode(inode);
1663 int unlock_session = session ? 0 : 1; 1670 int unlock_session = session ? 0 : 1;
1664 int flushing = 0; 1671 int flushing = 0;
@@ -1711,10 +1718,9 @@ out_unlocked:
1711static int caps_are_flushed(struct inode *inode, unsigned tid) 1718static int caps_are_flushed(struct inode *inode, unsigned tid)
1712{ 1719{
1713 struct ceph_inode_info *ci = ceph_inode(inode); 1720 struct ceph_inode_info *ci = ceph_inode(inode);
1714 int dirty, i, ret = 1; 1721 int i, ret = 1;
1715 1722
1716 spin_lock(&inode->i_lock); 1723 spin_lock(&inode->i_lock);
1717 dirty = __ceph_caps_dirty(ci);
1718 for (i = 0; i < CEPH_CAP_BITS; i++) 1724 for (i = 0; i < CEPH_CAP_BITS; i++)
1719 if ((ci->i_flushing_caps & (1 << i)) && 1725 if ((ci->i_flushing_caps & (1 << i)) &&
1720 ci->i_cap_flush_tid[i] <= tid) { 1726 ci->i_cap_flush_tid[i] <= tid) {
@@ -1824,7 +1830,8 @@ int ceph_write_inode(struct inode *inode, struct writeback_control *wbc)
1824 err = wait_event_interruptible(ci->i_cap_wq, 1830 err = wait_event_interruptible(ci->i_cap_wq,
1825 caps_are_flushed(inode, flush_tid)); 1831 caps_are_flushed(inode, flush_tid));
1826 } else { 1832 } else {
1827 struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc; 1833 struct ceph_mds_client *mdsc =
1834 &ceph_sb_to_client(inode->i_sb)->mdsc;
1828 1835
1829 spin_lock(&inode->i_lock); 1836 spin_lock(&inode->i_lock);
1830 if (__ceph_caps_dirty(ci)) 1837 if (__ceph_caps_dirty(ci))
@@ -2406,7 +2413,7 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid,
2406 __releases(inode->i_lock) 2413 __releases(inode->i_lock)
2407{ 2414{
2408 struct ceph_inode_info *ci = ceph_inode(inode); 2415 struct ceph_inode_info *ci = ceph_inode(inode);
2409 struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc; 2416 struct ceph_mds_client *mdsc = &ceph_sb_to_client(inode->i_sb)->mdsc;
2410 unsigned seq = le32_to_cpu(m->seq); 2417 unsigned seq = le32_to_cpu(m->seq);
2411 int dirty = le32_to_cpu(m->dirty); 2418 int dirty = le32_to_cpu(m->dirty);
2412 int cleaned = 0; 2419 int cleaned = 0;