Commit 03f4fcb0 authored by Yan, Zheng's avatar Yan, Zheng Committed by Ilya Dryomov

ceph: handle SESSION_FORCE_RO message

mark session as readonly and wake up all cap waiters.
Signed-off-by: default avatarYan, Zheng <zyan@redhat.com>
parent f646912d
...@@ -2143,6 +2143,21 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want, ...@@ -2143,6 +2143,21 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want,
ret = 1; ret = 1;
} }
} else { } else {
int session_readonly = false;
if ((need & CEPH_CAP_FILE_WR) && ci->i_auth_cap) {
struct ceph_mds_session *s = ci->i_auth_cap->session;
spin_lock(&s->s_cap_lock);
session_readonly = s->s_readonly;
spin_unlock(&s->s_cap_lock);
}
if (session_readonly) {
dout("get_cap_refs %p needed %s but mds%d readonly\n",
inode, ceph_cap_string(need), ci->i_auth_cap->mds);
*err = -EROFS;
ret = 1;
goto out_unlock;
}
dout("get_cap_refs %p have %s needed %s\n", inode, dout("get_cap_refs %p have %s needed %s\n", inode,
ceph_cap_string(have), ceph_cap_string(need)); ceph_cap_string(have), ceph_cap_string(need));
} }
......
...@@ -2580,6 +2580,14 @@ static void handle_session(struct ceph_mds_session *session, ...@@ -2580,6 +2580,14 @@ static void handle_session(struct ceph_mds_session *session,
send_flushmsg_ack(mdsc, session, seq); send_flushmsg_ack(mdsc, session, seq);
break; break;
case CEPH_SESSION_FORCE_RO:
dout("force_session_readonly %p\n", session);
spin_lock(&session->s_cap_lock);
session->s_readonly = true;
spin_unlock(&session->s_cap_lock);
wake_up_session_caps(session, 0);
break;
default: default:
pr_err("mdsc_handle_session bad op %d mds%d\n", op, mds); pr_err("mdsc_handle_session bad op %d mds%d\n", op, mds);
WARN_ON(1); WARN_ON(1);
...@@ -2791,6 +2799,8 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, ...@@ -2791,6 +2799,8 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
spin_unlock(&session->s_gen_ttl_lock); spin_unlock(&session->s_gen_ttl_lock);
spin_lock(&session->s_cap_lock); spin_lock(&session->s_cap_lock);
/* don't know if session is readonly */
session->s_readonly = 0;
/* /*
* notify __ceph_remove_cap() that we are composing cap reconnect. * notify __ceph_remove_cap() that we are composing cap reconnect.
* If a cap get released before being added to the cap reconnect, * If a cap get released before being added to the cap reconnect,
......
...@@ -137,6 +137,7 @@ struct ceph_mds_session { ...@@ -137,6 +137,7 @@ struct ceph_mds_session {
int s_nr_caps, s_trim_caps; int s_nr_caps, s_trim_caps;
int s_num_cap_releases; int s_num_cap_releases;
int s_cap_reconnect; int s_cap_reconnect;
int s_readonly;
struct list_head s_cap_releases; /* waiting cap_release messages */ struct list_head s_cap_releases; /* waiting cap_release messages */
struct list_head s_cap_releases_done; /* ready to send */ struct list_head s_cap_releases_done; /* ready to send */
struct ceph_cap *s_cap_iterator; struct ceph_cap *s_cap_iterator;
......
...@@ -271,6 +271,7 @@ enum { ...@@ -271,6 +271,7 @@ enum {
CEPH_SESSION_RECALL_STATE, CEPH_SESSION_RECALL_STATE,
CEPH_SESSION_FLUSHMSG, CEPH_SESSION_FLUSHMSG,
CEPH_SESSION_FLUSHMSG_ACK, CEPH_SESSION_FLUSHMSG_ACK,
CEPH_SESSION_FORCE_RO,
}; };
extern const char *ceph_session_op_name(int op); extern const char *ceph_session_op_name(int op);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment