diff options
author | Yan, Zheng <zyan@redhat.com> | 2014-11-14 08:56:29 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@redhat.com> | 2014-12-17 12:09:52 -0500 |
commit | 01deead041e03c9a6b4e1b2dd165dee4cced6112 (patch) | |
tree | 6c7a29c90eb8d69a730154a7f8c326fbcd3940f8 /fs | |
parent | 31c542a199d79f0f402c2f3e04229464510d47ec (diff) |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ceph/inode.c | 34 | ||||
-rw-r--r-- | fs/ceph/mds_client.h | 1 | ||||
-rw-r--r-- | fs/ceph/super.h | 7 |
3 files changed, 32 insertions, 10 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index feea6a8f88ae..0bdabd1bff8a 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -659,7 +659,7 @@ void ceph_fill_file_time(struct inode *inode, int issued, | |||
659 | * Populate an inode based on info from mds. May be called on new or | 659 | * Populate an inode based on info from mds. May be called on new or |
660 | * existing inodes. | 660 | * existing inodes. |
661 | */ | 661 | */ |
662 | static int fill_inode(struct inode *inode, | 662 | static int fill_inode(struct inode *inode, struct page *locked_page, |
663 | struct ceph_mds_reply_info_in *iinfo, | 663 | struct ceph_mds_reply_info_in *iinfo, |
664 | struct ceph_mds_reply_dirfrag *dirinfo, | 664 | struct ceph_mds_reply_dirfrag *dirinfo, |
665 | struct ceph_mds_session *session, | 665 | struct ceph_mds_session *session, |
@@ -883,14 +883,15 @@ static int fill_inode(struct inode *inode, | |||
883 | int cache_caps = CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO; | 883 | int cache_caps = CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO; |
884 | ci->i_inline_version = iinfo->inline_version; | 884 | ci->i_inline_version = iinfo->inline_version; |
885 | if (ci->i_inline_version != CEPH_INLINE_NONE && | 885 | if (ci->i_inline_version != CEPH_INLINE_NONE && |
886 | (le32_to_cpu(info->cap.caps) & cache_caps)) | 886 | (locked_page || |
887 | (le32_to_cpu(info->cap.caps) & cache_caps))) | ||
887 | fill_inline = true; | 888 | fill_inline = true; |
888 | } | 889 | } |
889 | 890 | ||
890 | spin_unlock(&ci->i_ceph_lock); | 891 | spin_unlock(&ci->i_ceph_lock); |
891 | 892 | ||
892 | if (fill_inline) | 893 | if (fill_inline) |
893 | ceph_fill_inline_data(inode, NULL, | 894 | ceph_fill_inline_data(inode, locked_page, |
894 | iinfo->inline_data, iinfo->inline_len); | 895 | iinfo->inline_data, iinfo->inline_len); |
895 | 896 | ||
896 | if (wake) | 897 | if (wake) |
@@ -1080,7 +1081,8 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
1080 | struct inode *dir = req->r_locked_dir; | 1081 | struct inode *dir = req->r_locked_dir; |
1081 | 1082 | ||
1082 | if (dir) { | 1083 | if (dir) { |
1083 | err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag, | 1084 | err = fill_inode(dir, NULL, |
1085 | &rinfo->diri, rinfo->dirfrag, | ||
1084 | session, req->r_request_started, -1, | 1086 | session, req->r_request_started, -1, |
1085 | &req->r_caps_reservation); | 1087 | &req->r_caps_reservation); |
1086 | if (err < 0) | 1088 | if (err < 0) |
@@ -1150,7 +1152,7 @@ retry_lookup: | |||
1150 | } | 1152 | } |
1151 | req->r_target_inode = in; | 1153 | req->r_target_inode = in; |
1152 | 1154 | ||
1153 | err = fill_inode(in, &rinfo->targeti, NULL, | 1155 | err = fill_inode(in, req->r_locked_page, &rinfo->targeti, NULL, |
1154 | session, req->r_request_started, | 1156 | session, req->r_request_started, |
1155 | (!req->r_aborted && rinfo->head->result == 0) ? | 1157 | (!req->r_aborted && rinfo->head->result == 0) ? |
1156 | req->r_fmode : -1, | 1158 | req->r_fmode : -1, |
@@ -1321,7 +1323,7 @@ static int readdir_prepopulate_inodes_only(struct ceph_mds_request *req, | |||
1321 | dout("new_inode badness got %d\n", err); | 1323 | dout("new_inode badness got %d\n", err); |
1322 | continue; | 1324 | continue; |
1323 | } | 1325 | } |
1324 | rc = fill_inode(in, &rinfo->dir_in[i], NULL, session, | 1326 | rc = fill_inode(in, NULL, &rinfo->dir_in[i], NULL, session, |
1325 | req->r_request_started, -1, | 1327 | req->r_request_started, -1, |
1326 | &req->r_caps_reservation); | 1328 | &req->r_caps_reservation); |
1327 | if (rc < 0) { | 1329 | if (rc < 0) { |
@@ -1437,7 +1439,7 @@ retry_lookup: | |||
1437 | } | 1439 | } |
1438 | } | 1440 | } |
1439 | 1441 | ||
1440 | if (fill_inode(in, &rinfo->dir_in[i], NULL, session, | 1442 | if (fill_inode(in, NULL, &rinfo->dir_in[i], NULL, session, |
1441 | req->r_request_started, -1, | 1443 | req->r_request_started, -1, |
1442 | &req->r_caps_reservation) < 0) { | 1444 | &req->r_caps_reservation) < 0) { |
1443 | pr_err("fill_inode badness on %p\n", in); | 1445 | pr_err("fill_inode badness on %p\n", in); |
@@ -1920,7 +1922,8 @@ out_put: | |||
1920 | * Verify that we have a lease on the given mask. If not, | 1922 | * Verify that we have a lease on the given mask. If not, |
1921 | * do a getattr against an mds. | 1923 | * do a getattr against an mds. |
1922 | */ | 1924 | */ |
1923 | int ceph_do_getattr(struct inode *inode, int mask, bool force) | 1925 | int __ceph_do_getattr(struct inode *inode, struct page *locked_page, |
1926 | int mask, bool force) | ||
1924 | { | 1927 | { |
1925 | struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb); | 1928 | struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb); |
1926 | struct ceph_mds_client *mdsc = fsc->mdsc; | 1929 | struct ceph_mds_client *mdsc = fsc->mdsc; |
@@ -1932,7 +1935,8 @@ int ceph_do_getattr(struct inode *inode, int mask, bool force) | |||
1932 | return 0; | 1935 | return 0; |
1933 | } | 1936 | } |
1934 | 1937 | ||
1935 | dout("do_getattr inode %p mask %s mode 0%o\n", inode, ceph_cap_string(mask), inode->i_mode); | 1938 | dout("do_getattr inode %p mask %s mode 0%o\n", |
1939 | inode, ceph_cap_string(mask), inode->i_mode); | ||
1936 | if (!force && ceph_caps_issued_mask(ceph_inode(inode), mask, 1)) | 1940 | if (!force && ceph_caps_issued_mask(ceph_inode(inode), mask, 1)) |
1937 | return 0; | 1941 | return 0; |
1938 | 1942 | ||
@@ -1943,7 +1947,19 @@ int ceph_do_getattr(struct inode *inode, int mask, bool force) | |||
1943 | ihold(inode); | 1947 | ihold(inode); |
1944 | req->r_num_caps = 1; | 1948 | req->r_num_caps = 1; |
1945 | req->r_args.getattr.mask = cpu_to_le32(mask); | 1949 | req->r_args.getattr.mask = cpu_to_le32(mask); |
1950 | req->r_locked_page = locked_page; | ||
1946 | err = ceph_mdsc_do_request(mdsc, NULL, req); | 1951 | err = ceph_mdsc_do_request(mdsc, NULL, req); |
1952 | if (locked_page && err == 0) { | ||
1953 | u64 inline_version = req->r_reply_info.targeti.inline_version; | ||
1954 | if (inline_version == 0) { | ||
1955 | /* the reply is supposed to contain inline data */ | ||
1956 | err = -EINVAL; | ||
1957 | } else if (inline_version == CEPH_INLINE_NONE) { | ||
1958 | err = -ENODATA; | ||
1959 | } else { | ||
1960 | err = req->r_reply_info.targeti.inline_len; | ||
1961 | } | ||
1962 | } | ||
1947 | ceph_mdsc_put_request(req); | 1963 | ceph_mdsc_put_request(req); |
1948 | dout("do_getattr result=%d\n", err); | 1964 | dout("do_getattr result=%d\n", err); |
1949 | return err; | 1965 | return err; |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 01f5e4cfd684..e2817d00f7d9 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -223,6 +223,7 @@ struct ceph_mds_request { | |||
223 | int r_request_release_offset; | 223 | int r_request_release_offset; |
224 | struct ceph_msg *r_reply; | 224 | struct ceph_msg *r_reply; |
225 | struct ceph_mds_reply_info_parsed r_reply_info; | 225 | struct ceph_mds_reply_info_parsed r_reply_info; |
226 | struct page *r_locked_page; | ||
226 | int r_err; | 227 | int r_err; |
227 | bool r_aborted; | 228 | bool r_aborted; |
228 | 229 | ||
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index b0de9162758b..6d56fae863ca 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -744,7 +744,12 @@ extern void ceph_queue_vmtruncate(struct inode *inode); | |||
744 | extern void ceph_queue_invalidate(struct inode *inode); | 744 | extern void ceph_queue_invalidate(struct inode *inode); |
745 | extern void ceph_queue_writeback(struct inode *inode); | 745 | extern void ceph_queue_writeback(struct inode *inode); |
746 | 746 | ||
747 | extern int ceph_do_getattr(struct inode *inode, int mask, bool force); | 747 | extern int __ceph_do_getattr(struct inode *inode, struct page *locked_page, |
748 | int mask, bool force); | ||
749 | static inline int ceph_do_getattr(struct inode *inode, int mask, bool force) | ||
750 | { | ||
751 | return __ceph_do_getattr(inode, NULL, mask, force); | ||
752 | } | ||
748 | extern int ceph_permission(struct inode *inode, int mask); | 753 | extern int ceph_permission(struct inode *inode, int mask); |
749 | extern int ceph_setattr(struct dentry *dentry, struct iattr *attr); | 754 | extern int ceph_setattr(struct dentry *dentry, struct iattr *attr); |
750 | extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, | 755 | extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, |