|
@@ -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;
|