aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2015-01-04 22:04:04 -0500
committerIlya Dryomov <idryomov@gmail.com>2015-02-19 05:31:37 -0500
commit03f4fcb02884859b584c709652bb48f8125ceb45 (patch)
treea65b5f4bb6661d17b9a9bdacf7b1c27ddff33137
parentf646912d1044ace6c6c5b5785b2579177781873b (diff)
ceph: handle SESSION_FORCE_RO message
mark session as readonly and wake up all cap waiters. Signed-off-by: Yan, Zheng <zyan@redhat.com>
-rw-r--r--fs/ceph/caps.c15
-rw-r--r--fs/ceph/mds_client.c10
-rw-r--r--fs/ceph/mds_client.h1
-rw-r--r--include/linux/ceph/ceph_fs.h1
4 files changed, 27 insertions, 0 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index b93c631c6c87..d0618e8412fd 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -2143,6 +2143,21 @@ again:
2143 ret = 1; 2143 ret = 1;
2144 } 2144 }
2145 } else { 2145 } else {
2146 int session_readonly = false;
2147 if ((need & CEPH_CAP_FILE_WR) && ci->i_auth_cap) {
2148 struct ceph_mds_session *s = ci->i_auth_cap->session;
2149 spin_lock(&s->s_cap_lock);
2150 session_readonly = s->s_readonly;
2151 spin_unlock(&s->s_cap_lock);
2152 }
2153 if (session_readonly) {
2154 dout("get_cap_refs %p needed %s but mds%d readonly\n",
2155 inode, ceph_cap_string(need), ci->i_auth_cap->mds);
2156 *err = -EROFS;
2157 ret = 1;
2158 goto out_unlock;
2159 }
2160
2146 dout("get_cap_refs %p have %s needed %s\n", inode, 2161 dout("get_cap_refs %p have %s needed %s\n", inode,
2147 ceph_cap_string(have), ceph_cap_string(need)); 2162 ceph_cap_string(have), ceph_cap_string(need));
2148 } 2163 }
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index d2171f4a6980..c6c33b411a2f 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2580,6 +2580,14 @@ static void handle_session(struct ceph_mds_session *session,
2580 send_flushmsg_ack(mdsc, session, seq); 2580 send_flushmsg_ack(mdsc, session, seq);
2581 break; 2581 break;
2582 2582
2583 case CEPH_SESSION_FORCE_RO:
2584 dout("force_session_readonly %p\n", session);
2585 spin_lock(&session->s_cap_lock);
2586 session->s_readonly = true;
2587 spin_unlock(&session->s_cap_lock);
2588 wake_up_session_caps(session, 0);
2589 break;
2590
2583 default: 2591 default:
2584 pr_err("mdsc_handle_session bad op %d mds%d\n", op, mds); 2592 pr_err("mdsc_handle_session bad op %d mds%d\n", op, mds);
2585 WARN_ON(1); 2593 WARN_ON(1);
@@ -2791,6 +2799,8 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
2791 spin_unlock(&session->s_gen_ttl_lock); 2799 spin_unlock(&session->s_gen_ttl_lock);
2792 2800
2793 spin_lock(&session->s_cap_lock); 2801 spin_lock(&session->s_cap_lock);
2802 /* don't know if session is readonly */
2803 session->s_readonly = 0;
2794 /* 2804 /*
2795 * notify __ceph_remove_cap() that we are composing cap reconnect. 2805 * notify __ceph_remove_cap() that we are composing cap reconnect.
2796 * If a cap get released before being added to the cap reconnect, 2806 * If a cap get released before being added to the cap reconnect,
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index e2817d00f7d9..a87b92f500bb 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -137,6 +137,7 @@ struct ceph_mds_session {
137 int s_nr_caps, s_trim_caps; 137 int s_nr_caps, s_trim_caps;
138 int s_num_cap_releases; 138 int s_num_cap_releases;
139 int s_cap_reconnect; 139 int s_cap_reconnect;
140 int s_readonly;
140 struct list_head s_cap_releases; /* waiting cap_release messages */ 141 struct list_head s_cap_releases; /* waiting cap_release messages */
141 struct list_head s_cap_releases_done; /* ready to send */ 142 struct list_head s_cap_releases_done; /* ready to send */
142 struct ceph_cap *s_cap_iterator; 143 struct ceph_cap *s_cap_iterator;
diff --git a/include/linux/ceph/ceph_fs.h b/include/linux/ceph/ceph_fs.h
index 69e2c9e2305b..31eb03d0c766 100644
--- a/include/linux/ceph/ceph_fs.h
+++ b/include/linux/ceph/ceph_fs.h
@@ -271,6 +271,7 @@ enum {
271 CEPH_SESSION_RECALL_STATE, 271 CEPH_SESSION_RECALL_STATE,
272 CEPH_SESSION_FLUSHMSG, 272 CEPH_SESSION_FLUSHMSG,
273 CEPH_SESSION_FLUSHMSG_ACK, 273 CEPH_SESSION_FLUSHMSG_ACK,
274 CEPH_SESSION_FORCE_RO,
274}; 275};
275 276
276extern const char *ceph_session_op_name(int op); 277extern const char *ceph_session_op_name(int op);