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 /fs/ceph | |
| 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>
Diffstat (limited to 'fs/ceph')
| -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 |
3 files changed, 26 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; |
