ceph: use getattr request to fetch inline data
Add a new parameter 'locked_page' to ceph_do_getattr(). If inline data in getattr reply will be copied to the page. Signed-off-by: Yan, Zheng <zyan@redhat.com>
This commit is contained in:
Родитель
31c542a199
Коммит
01deead041
|
@ -659,7 +659,7 @@ void ceph_fill_file_time(struct inode *inode, int issued,
|
|||
* Populate an inode based on info from mds. May be called on new or
|
||||
* existing inodes.
|
||||
*/
|
||||
static int fill_inode(struct inode *inode,
|
||||
static int fill_inode(struct inode *inode, struct page *locked_page,
|
||||
struct ceph_mds_reply_info_in *iinfo,
|
||||
struct ceph_mds_reply_dirfrag *dirinfo,
|
||||
struct ceph_mds_session *session,
|
||||
|
@ -883,14 +883,15 @@ static int fill_inode(struct inode *inode,
|
|||
int cache_caps = CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO;
|
||||
ci->i_inline_version = iinfo->inline_version;
|
||||
if (ci->i_inline_version != CEPH_INLINE_NONE &&
|
||||
(le32_to_cpu(info->cap.caps) & cache_caps))
|
||||
(locked_page ||
|
||||
(le32_to_cpu(info->cap.caps) & cache_caps)))
|
||||
fill_inline = true;
|
||||
}
|
||||
|
||||
spin_unlock(&ci->i_ceph_lock);
|
||||
|
||||
if (fill_inline)
|
||||
ceph_fill_inline_data(inode, NULL,
|
||||
ceph_fill_inline_data(inode, locked_page,
|
||||
iinfo->inline_data, iinfo->inline_len);
|
||||
|
||||
if (wake)
|
||||
|
@ -1080,7 +1081,8 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
|
|||
struct inode *dir = req->r_locked_dir;
|
||||
|
||||
if (dir) {
|
||||
err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag,
|
||||
err = fill_inode(dir, NULL,
|
||||
&rinfo->diri, rinfo->dirfrag,
|
||||
session, req->r_request_started, -1,
|
||||
&req->r_caps_reservation);
|
||||
if (err < 0)
|
||||
|
@ -1150,7 +1152,7 @@ retry_lookup:
|
|||
}
|
||||
req->r_target_inode = in;
|
||||
|
||||
err = fill_inode(in, &rinfo->targeti, NULL,
|
||||
err = fill_inode(in, req->r_locked_page, &rinfo->targeti, NULL,
|
||||
session, req->r_request_started,
|
||||
(!req->r_aborted && rinfo->head->result == 0) ?
|
||||
req->r_fmode : -1,
|
||||
|
@ -1321,7 +1323,7 @@ static int readdir_prepopulate_inodes_only(struct ceph_mds_request *req,
|
|||
dout("new_inode badness got %d\n", err);
|
||||
continue;
|
||||
}
|
||||
rc = fill_inode(in, &rinfo->dir_in[i], NULL, session,
|
||||
rc = fill_inode(in, NULL, &rinfo->dir_in[i], NULL, session,
|
||||
req->r_request_started, -1,
|
||||
&req->r_caps_reservation);
|
||||
if (rc < 0) {
|
||||
|
@ -1437,7 +1439,7 @@ retry_lookup:
|
|||
}
|
||||
}
|
||||
|
||||
if (fill_inode(in, &rinfo->dir_in[i], NULL, session,
|
||||
if (fill_inode(in, NULL, &rinfo->dir_in[i], NULL, session,
|
||||
req->r_request_started, -1,
|
||||
&req->r_caps_reservation) < 0) {
|
||||
pr_err("fill_inode badness on %p\n", in);
|
||||
|
@ -1920,7 +1922,8 @@ out_put:
|
|||
* Verify that we have a lease on the given mask. If not,
|
||||
* do a getattr against an mds.
|
||||
*/
|
||||
int ceph_do_getattr(struct inode *inode, int mask, bool force)
|
||||
int __ceph_do_getattr(struct inode *inode, struct page *locked_page,
|
||||
int mask, bool force)
|
||||
{
|
||||
struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb);
|
||||
struct ceph_mds_client *mdsc = fsc->mdsc;
|
||||
|
@ -1932,7 +1935,8 @@ int ceph_do_getattr(struct inode *inode, int mask, bool force)
|
|||
return 0;
|
||||
}
|
||||
|
||||
dout("do_getattr inode %p mask %s mode 0%o\n", inode, ceph_cap_string(mask), inode->i_mode);
|
||||
dout("do_getattr inode %p mask %s mode 0%o\n",
|
||||
inode, ceph_cap_string(mask), inode->i_mode);
|
||||
if (!force && ceph_caps_issued_mask(ceph_inode(inode), mask, 1))
|
||||
return 0;
|
||||
|
||||
|
@ -1943,7 +1947,19 @@ int ceph_do_getattr(struct inode *inode, int mask, bool force)
|
|||
ihold(inode);
|
||||
req->r_num_caps = 1;
|
||||
req->r_args.getattr.mask = cpu_to_le32(mask);
|
||||
req->r_locked_page = locked_page;
|
||||
err = ceph_mdsc_do_request(mdsc, NULL, req);
|
||||
if (locked_page && err == 0) {
|
||||
u64 inline_version = req->r_reply_info.targeti.inline_version;
|
||||
if (inline_version == 0) {
|
||||
/* the reply is supposed to contain inline data */
|
||||
err = -EINVAL;
|
||||
} else if (inline_version == CEPH_INLINE_NONE) {
|
||||
err = -ENODATA;
|
||||
} else {
|
||||
err = req->r_reply_info.targeti.inline_len;
|
||||
}
|
||||
}
|
||||
ceph_mdsc_put_request(req);
|
||||
dout("do_getattr result=%d\n", err);
|
||||
return err;
|
||||
|
|
|
@ -223,6 +223,7 @@ struct ceph_mds_request {
|
|||
int r_request_release_offset;
|
||||
struct ceph_msg *r_reply;
|
||||
struct ceph_mds_reply_info_parsed r_reply_info;
|
||||
struct page *r_locked_page;
|
||||
int r_err;
|
||||
bool r_aborted;
|
||||
|
||||
|
|
|
@ -744,7 +744,12 @@ extern void ceph_queue_vmtruncate(struct inode *inode);
|
|||
extern void ceph_queue_invalidate(struct inode *inode);
|
||||
extern void ceph_queue_writeback(struct inode *inode);
|
||||
|
||||
extern int ceph_do_getattr(struct inode *inode, int mask, bool force);
|
||||
extern int __ceph_do_getattr(struct inode *inode, struct page *locked_page,
|
||||
int mask, bool force);
|
||||
static inline int ceph_do_getattr(struct inode *inode, int mask, bool force)
|
||||
{
|
||||
return __ceph_do_getattr(inode, NULL, mask, force);
|
||||
}
|
||||
extern int ceph_permission(struct inode *inode, int mask);
|
||||
extern int ceph_setattr(struct dentry *dentry, struct iattr *attr);
|
||||
extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
||||
|
|
|
@ -617,6 +617,8 @@ int ceph_flags_to_mode(int flags);
|
|||
CEPH_CAP_LINK_SHARED | \
|
||||
CEPH_CAP_FILE_SHARED | \
|
||||
CEPH_CAP_XATTR_SHARED)
|
||||
#define CEPH_STAT_CAP_INLINE_DATA (CEPH_CAP_FILE_SHARED | \
|
||||
CEPH_CAP_FILE_RD)
|
||||
|
||||
#define CEPH_CAP_ANY_SHARED (CEPH_CAP_AUTH_SHARED | \
|
||||
CEPH_CAP_LINK_SHARED | \
|
||||
|
|
Загрузка…
Ссылка в новой задаче