Commit 31c542a199d79f0f402c2f3e04229464510d47ec
Committed by
Ilya Dryomov
1 parent
fb01d1f8b0
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
ceph: add inline data to pagecache
Request reply and cap message can contain inline data. add inline data to the page cache if there is Fc cap. Signed-off-by: Yan, Zheng <zyan@redhat.com>
Showing 6 changed files with 85 additions and 1 deletions Side-by-side Diff
fs/ceph/addr.c
... | ... | @@ -1318,6 +1318,49 @@ |
1318 | 1318 | return ret; |
1319 | 1319 | } |
1320 | 1320 | |
1321 | +void ceph_fill_inline_data(struct inode *inode, struct page *locked_page, | |
1322 | + char *data, size_t len) | |
1323 | +{ | |
1324 | + struct address_space *mapping = inode->i_mapping; | |
1325 | + struct page *page; | |
1326 | + | |
1327 | + if (locked_page) { | |
1328 | + page = locked_page; | |
1329 | + } else { | |
1330 | + if (i_size_read(inode) == 0) | |
1331 | + return; | |
1332 | + page = find_or_create_page(mapping, 0, | |
1333 | + mapping_gfp_mask(mapping) & ~__GFP_FS); | |
1334 | + if (!page) | |
1335 | + return; | |
1336 | + if (PageUptodate(page)) { | |
1337 | + unlock_page(page); | |
1338 | + page_cache_release(page); | |
1339 | + return; | |
1340 | + } | |
1341 | + } | |
1342 | + | |
1343 | + dout("fill_inline_data %p %llx.%llx len %lu locked_page %p\n", | |
1344 | + inode, ceph_vinop(inode), len, locked_page); | |
1345 | + | |
1346 | + if (len > 0) { | |
1347 | + void *kaddr = kmap_atomic(page); | |
1348 | + memcpy(kaddr, data, len); | |
1349 | + kunmap_atomic(kaddr); | |
1350 | + } | |
1351 | + | |
1352 | + if (page != locked_page) { | |
1353 | + if (len < PAGE_CACHE_SIZE) | |
1354 | + zero_user_segment(page, len, PAGE_CACHE_SIZE); | |
1355 | + else | |
1356 | + flush_dcache_page(page); | |
1357 | + | |
1358 | + SetPageUptodate(page); | |
1359 | + unlock_page(page); | |
1360 | + page_cache_release(page); | |
1361 | + } | |
1362 | +} | |
1363 | + | |
1321 | 1364 | static struct vm_operations_struct ceph_vmops = { |
1322 | 1365 | .fault = ceph_filemap_fault, |
1323 | 1366 | .page_mkwrite = ceph_page_mkwrite, |
fs/ceph/caps.c
... | ... | @@ -2405,6 +2405,7 @@ |
2405 | 2405 | bool queue_invalidate = false; |
2406 | 2406 | bool queue_revalidate = false; |
2407 | 2407 | bool deleted_inode = false; |
2408 | + bool fill_inline = false; | |
2408 | 2409 | |
2409 | 2410 | dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n", |
2410 | 2411 | inode, cap, mds, seq, ceph_cap_string(newcaps)); |
... | ... | @@ -2578,6 +2579,13 @@ |
2578 | 2579 | } |
2579 | 2580 | BUG_ON(cap->issued & ~cap->implemented); |
2580 | 2581 | |
2582 | + if (inline_version > 0 && inline_version >= ci->i_inline_version) { | |
2583 | + ci->i_inline_version = inline_version; | |
2584 | + if (ci->i_inline_version != CEPH_INLINE_NONE && | |
2585 | + (newcaps & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO))) | |
2586 | + fill_inline = true; | |
2587 | + } | |
2588 | + | |
2581 | 2589 | spin_unlock(&ci->i_ceph_lock); |
2582 | 2590 | |
2583 | 2591 | if (le32_to_cpu(grant->op) == CEPH_CAP_OP_IMPORT) { |
... | ... | @@ -2590,6 +2598,9 @@ |
2590 | 2598 | if (newcaps & ~issued) |
2591 | 2599 | wake = true; |
2592 | 2600 | } |
2601 | + | |
2602 | + if (fill_inline) | |
2603 | + ceph_fill_inline_data(inode, NULL, inline_data, inline_len); | |
2593 | 2604 | |
2594 | 2605 | if (queue_trunc) { |
2595 | 2606 | ceph_queue_vmtruncate(inode); |
fs/ceph/inode.c
... | ... | @@ -387,6 +387,7 @@ |
387 | 387 | spin_lock_init(&ci->i_ceph_lock); |
388 | 388 | |
389 | 389 | ci->i_version = 0; |
390 | + ci->i_inline_version = 0; | |
390 | 391 | ci->i_time_warp_seq = 0; |
391 | 392 | ci->i_ceph_flags = 0; |
392 | 393 | ci->i_ordered_count = 0; |
... | ... | @@ -676,6 +677,7 @@ |
676 | 677 | bool wake = false; |
677 | 678 | bool queue_trunc = false; |
678 | 679 | bool new_version = false; |
680 | + bool fill_inline = false; | |
679 | 681 | |
680 | 682 | dout("fill_inode %p ino %llx.%llx v %llu had %llu\n", |
681 | 683 | inode, ceph_vinop(inode), le64_to_cpu(info->version), |
682 | 684 | |
... | ... | @@ -875,7 +877,21 @@ |
875 | 877 | ceph_vinop(inode)); |
876 | 878 | __ceph_get_fmode(ci, cap_fmode); |
877 | 879 | } |
880 | + | |
881 | + if (iinfo->inline_version > 0 && | |
882 | + iinfo->inline_version >= ci->i_inline_version) { | |
883 | + int cache_caps = CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO; | |
884 | + ci->i_inline_version = iinfo->inline_version; | |
885 | + if (ci->i_inline_version != CEPH_INLINE_NONE && | |
886 | + (le32_to_cpu(info->cap.caps) & cache_caps)) | |
887 | + fill_inline = true; | |
888 | + } | |
889 | + | |
878 | 890 | spin_unlock(&ci->i_ceph_lock); |
891 | + | |
892 | + if (fill_inline) | |
893 | + ceph_fill_inline_data(inode, NULL, | |
894 | + iinfo->inline_data, iinfo->inline_len); | |
879 | 895 | |
880 | 896 | if (wake) |
881 | 897 | wake_up_all(&ci->i_cap_wq); |
fs/ceph/super.h
... | ... | @@ -253,6 +253,7 @@ |
253 | 253 | spinlock_t i_ceph_lock; |
254 | 254 | |
255 | 255 | u64 i_version; |
256 | + u64 i_inline_version; | |
256 | 257 | u32 i_time_warp_seq; |
257 | 258 | |
258 | 259 | unsigned i_ceph_flags; |
... | ... | @@ -858,7 +859,7 @@ |
858 | 859 | int mds, int drop, int unless); |
859 | 860 | |
860 | 861 | extern int ceph_get_caps(struct ceph_inode_info *ci, int need, int want, |
861 | - int *got, loff_t endoff); | |
862 | + loff_t endoff, int *got, struct page **pinned_page); | |
862 | 863 | |
863 | 864 | /* for counting open files by mode */ |
864 | 865 | static inline void __ceph_get_fmode(struct ceph_inode_info *ci, int mode) |
... | ... | @@ -880,6 +881,8 @@ |
880 | 881 | struct file *file, unsigned flags, umode_t mode, |
881 | 882 | int *opened); |
882 | 883 | extern int ceph_release(struct inode *inode, struct file *filp); |
884 | +extern void ceph_fill_inline_data(struct inode *inode, struct page *locked_page, | |
885 | + char *data, size_t len); | |
883 | 886 | |
884 | 887 | /* dir.c */ |
885 | 888 | extern const struct file_operations ceph_dir_fops; |
fs/ceph/super.h.rej
include/linux/ceph/ceph_fs.h
-
mentioned in commit 44e896
-
mentioned in commit 44e896
-
mentioned in commit 44e896
-
mentioned in commit 44e896
-
mentioned in commit 44e896
-
mentioned in commit 44e896
-
mentioned in commit 44e896
-
mentioned in commit 44e896
-
mentioned in commit 44e896
-
mentioned in commit 44e896
-
mentioned in commit 44e896
-
mentioned in commit 44e896
-
mentioned in commit 44e896