Commit 25933abd authored by Herb Shiu's avatar Herb Shiu Committed by Sage Weil

ceph: Handle file locks in replies from the MDS.

Previously the kernel client incorrectly assumed everything was a directory.
Signed-off-by: default avatarHerb Shiu <herb_shiu@tcloudcomputing.com>
Acked-by: default avatarGreg Farnum <gregf@hq.newdream.net>
Signed-off-by: default avatarSage Weil <sage@newdream.net>
parent 884ea892
...@@ -201,6 +201,38 @@ static int parse_reply_info_dir(void **p, void *end, ...@@ -201,6 +201,38 @@ static int parse_reply_info_dir(void **p, void *end,
return err; return err;
} }
/*
* parse fcntl F_GETLK results
*/
static int parse_reply_info_filelock(void **p, void *end,
struct ceph_mds_reply_info_parsed *info)
{
if (*p + sizeof(*info->filelock_reply) > end)
goto bad;
info->filelock_reply = *p;
*p += sizeof(*info->filelock_reply);
if (unlikely(*p != end))
goto bad;
return 0;
bad:
return -EIO;
}
/*
* parse extra results
*/
static int parse_reply_info_extra(void **p, void *end,
struct ceph_mds_reply_info_parsed *info)
{
if (info->head->op == CEPH_MDS_OP_GETFILELOCK)
return parse_reply_info_filelock(p, end, info);
else
return parse_reply_info_dir(p, end, info);
}
/* /*
* parse entire mds reply * parse entire mds reply
*/ */
...@@ -223,10 +255,10 @@ static int parse_reply_info(struct ceph_msg *msg, ...@@ -223,10 +255,10 @@ static int parse_reply_info(struct ceph_msg *msg,
goto out_bad; goto out_bad;
} }
/* dir content */ /* extra */
ceph_decode_32_safe(&p, end, len, bad); ceph_decode_32_safe(&p, end, len, bad);
if (len > 0) { if (len > 0) {
err = parse_reply_info_dir(&p, p+len, info); err = parse_reply_info_extra(&p, p+len, info);
if (err < 0) if (err < 0)
goto out_bad; goto out_bad;
} }
...@@ -2074,7 +2106,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) ...@@ -2074,7 +2106,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
mutex_lock(&session->s_mutex); mutex_lock(&session->s_mutex);
if (err < 0) { if (err < 0) {
pr_err("mdsc_handle_reply got corrupt reply mds%d\n", mds); pr_err("mdsc_handle_reply got corrupt reply mds%d(tid:%lld)\n", mds, tid);
ceph_msg_dump(msg); ceph_msg_dump(msg);
goto out_err; goto out_err;
} }
...@@ -2094,7 +2126,8 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) ...@@ -2094,7 +2126,8 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
mutex_lock(&req->r_fill_mutex); mutex_lock(&req->r_fill_mutex);
err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session); err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session);
if (err == 0) { if (err == 0) {
if (result == 0 && rinfo->dir_nr) if (result == 0 && req->r_op != CEPH_MDS_OP_GETFILELOCK &&
rinfo->dir_nr)
ceph_readdir_prepopulate(req, req->r_session); ceph_readdir_prepopulate(req, req->r_session);
ceph_unreserve_caps(mdsc, &req->r_caps_reservation); ceph_unreserve_caps(mdsc, &req->r_caps_reservation);
} }
......
...@@ -42,26 +42,37 @@ struct ceph_mds_reply_info_in { ...@@ -42,26 +42,37 @@ struct ceph_mds_reply_info_in {
}; };
/* /*
* parsed info about an mds reply, including information about the * parsed info about an mds reply, including information about
* target inode and/or its parent directory and dentry, and directory * either: 1) the target inode and/or its parent directory and dentry,
* contents (for readdir results). * and directory contents (for readdir results), or
* 2) the file range lock info (for fcntl F_GETLK results).
*/ */
struct ceph_mds_reply_info_parsed { struct ceph_mds_reply_info_parsed {
struct ceph_mds_reply_head *head; struct ceph_mds_reply_head *head;
/* trace */
struct ceph_mds_reply_info_in diri, targeti; struct ceph_mds_reply_info_in diri, targeti;
struct ceph_mds_reply_dirfrag *dirfrag; struct ceph_mds_reply_dirfrag *dirfrag;
char *dname; char *dname;
u32 dname_len; u32 dname_len;
struct ceph_mds_reply_lease *dlease; struct ceph_mds_reply_lease *dlease;
struct ceph_mds_reply_dirfrag *dir_dir; /* extra */
int dir_nr; union {
char **dir_dname; /* for fcntl F_GETLK results */
u32 *dir_dname_len; struct ceph_filelock *filelock_reply;
struct ceph_mds_reply_lease **dir_dlease;
struct ceph_mds_reply_info_in *dir_in; /* for readdir results */
u8 dir_complete, dir_end; struct {
struct ceph_mds_reply_dirfrag *dir_dir;
int dir_nr;
char **dir_dname;
u32 *dir_dname_len;
struct ceph_mds_reply_lease **dir_dlease;
struct ceph_mds_reply_info_in *dir_in;
u8 dir_complete, dir_end;
};
};
/* encoded blob describing snapshot contexts for certain /* encoded blob describing snapshot contexts for certain
operations (e.g., open) */ operations (e.g., open) */
......
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