diff options
author | Yan, Zheng <zyan@redhat.com> | 2015-01-04 22:04:04 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2015-02-19 05:31:37 -0500 |
commit | 03f4fcb02884859b584c709652bb48f8125ceb45 (patch) | |
tree | a65b5f4bb6661d17b9a9bdacf7b1c27ddff33137 | |
parent | f646912d1044ace6c6c5b5785b2579177781873b (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.c | 15 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 10 | ||||
-rw-r--r-- | fs/ceph/mds_client.h | 1 | ||||
-rw-r--r-- | include/linux/ceph/ceph_fs.h | 1 |
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 | ||
276 | extern const char *ceph_session_op_name(int op); | 277 | extern const char *ceph_session_op_name(int op); |