ceph: Handle file locks in replies from the MDS.
Previously the kernel client incorrectly assumed everything was a directory. Signed-off-by: Herb Shiu <herb_shiu@tcloudcomputing.com> Acked-by: Greg Farnum <gregf@hq.newdream.net> Signed-off-by: Sage Weil <sage@newdream.net>
This commit is contained in:
parent
884ea89276
commit
25933abdd8
2 changed files with 58 additions and 14 deletions
|
@ -201,6 +201,38 @@ static int parse_reply_info_dir(void **p, void *end,
|
|||
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
|
||||
*/
|
||||
|
@ -223,10 +255,10 @@ static int parse_reply_info(struct ceph_msg *msg,
|
|||
goto out_bad;
|
||||
}
|
||||
|
||||
/* dir content */
|
||||
/* extra */
|
||||
ceph_decode_32_safe(&p, end, len, bad);
|
||||
if (len > 0) {
|
||||
err = parse_reply_info_dir(&p, p+len, info);
|
||||
err = parse_reply_info_extra(&p, p+len, info);
|
||||
if (err < 0)
|
||||
goto out_bad;
|
||||
}
|
||||
|
@ -2074,7 +2106,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
|
|||
|
||||
mutex_lock(&session->s_mutex);
|
||||
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);
|
||||
goto out_err;
|
||||
}
|
||||
|
@ -2094,7 +2126,8 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
|
|||
mutex_lock(&req->r_fill_mutex);
|
||||
err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session);
|
||||
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_unreserve_caps(mdsc, &req->r_caps_reservation);
|
||||
}
|
||||
|
|
|
@ -42,26 +42,37 @@ struct ceph_mds_reply_info_in {
|
|||
};
|
||||
|
||||
/*
|
||||
* parsed info about an mds reply, including information about the
|
||||
* target inode and/or its parent directory and dentry, and directory
|
||||
* contents (for readdir results).
|
||||
* parsed info about an mds reply, including information about
|
||||
* either: 1) the target inode and/or its parent directory and dentry,
|
||||
* 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_head *head;
|
||||
|
||||
/* trace */
|
||||
struct ceph_mds_reply_info_in diri, targeti;
|
||||
struct ceph_mds_reply_dirfrag *dirfrag;
|
||||
char *dname;
|
||||
u32 dname_len;
|
||||
struct ceph_mds_reply_lease *dlease;
|
||||
|
||||
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;
|
||||
/* extra */
|
||||
union {
|
||||
/* for fcntl F_GETLK results */
|
||||
struct ceph_filelock *filelock_reply;
|
||||
|
||||
/* for readdir results */
|
||||
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
|
||||
operations (e.g., open) */
|
||||
|
|
Loading…
Reference in a new issue