Skip to content

Commit

Permalink
ceph: add inline data to pagecache
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
ukernel authored and idryomov committed Dec 17, 2014
1 parent fb01d1f commit 31c542a
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 1 deletion.
43 changes: 43 additions & 0 deletions fs/ceph/addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,49 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
return ret;
}

void ceph_fill_inline_data(struct inode *inode, struct page *locked_page,
char *data, size_t len)
{
struct address_space *mapping = inode->i_mapping;
struct page *page;

if (locked_page) {
page = locked_page;
} else {
if (i_size_read(inode) == 0)
return;
page = find_or_create_page(mapping, 0,
mapping_gfp_mask(mapping) & ~__GFP_FS);
if (!page)
return;
if (PageUptodate(page)) {
unlock_page(page);
page_cache_release(page);
return;
}
}

dout("fill_inline_data %p %llx.%llx len %lu locked_page %p\n",
inode, ceph_vinop(inode), len, locked_page);

if (len > 0) {
void *kaddr = kmap_atomic(page);
memcpy(kaddr, data, len);
kunmap_atomic(kaddr);
}

if (page != locked_page) {
if (len < PAGE_CACHE_SIZE)
zero_user_segment(page, len, PAGE_CACHE_SIZE);
else
flush_dcache_page(page);

SetPageUptodate(page);
unlock_page(page);
page_cache_release(page);
}
}

static struct vm_operations_struct ceph_vmops = {
.fault = ceph_filemap_fault,
.page_mkwrite = ceph_page_mkwrite,
Expand Down
11 changes: 11 additions & 0 deletions fs/ceph/caps.c
Original file line number Diff line number Diff line change
Expand Up @@ -2405,6 +2405,7 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
bool queue_invalidate = false;
bool queue_revalidate = false;
bool deleted_inode = false;
bool fill_inline = false;

dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n",
inode, cap, mds, seq, ceph_cap_string(newcaps));
Expand Down Expand Up @@ -2578,6 +2579,13 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
}
BUG_ON(cap->issued & ~cap->implemented);

if (inline_version > 0 && inline_version >= ci->i_inline_version) {
ci->i_inline_version = inline_version;
if (ci->i_inline_version != CEPH_INLINE_NONE &&
(newcaps & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)))
fill_inline = true;
}

spin_unlock(&ci->i_ceph_lock);

if (le32_to_cpu(grant->op) == CEPH_CAP_OP_IMPORT) {
Expand All @@ -2591,6 +2599,9 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
wake = true;
}

if (fill_inline)
ceph_fill_inline_data(inode, NULL, inline_data, inline_len);

if (queue_trunc) {
ceph_queue_vmtruncate(inode);
ceph_queue_revalidate(inode);
Expand Down
16 changes: 16 additions & 0 deletions fs/ceph/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
spin_lock_init(&ci->i_ceph_lock);

ci->i_version = 0;
ci->i_inline_version = 0;
ci->i_time_warp_seq = 0;
ci->i_ceph_flags = 0;
ci->i_ordered_count = 0;
Expand Down Expand Up @@ -676,6 +677,7 @@ static int fill_inode(struct inode *inode,
bool wake = false;
bool queue_trunc = false;
bool new_version = false;
bool fill_inline = false;

dout("fill_inode %p ino %llx.%llx v %llu had %llu\n",
inode, ceph_vinop(inode), le64_to_cpu(info->version),
Expand Down Expand Up @@ -875,8 +877,22 @@ static int fill_inode(struct inode *inode,
ceph_vinop(inode));
__ceph_get_fmode(ci, cap_fmode);
}

if (iinfo->inline_version > 0 &&
iinfo->inline_version >= ci->i_inline_version) {
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))
fill_inline = true;
}

spin_unlock(&ci->i_ceph_lock);

if (fill_inline)
ceph_fill_inline_data(inode, NULL,
iinfo->inline_data, iinfo->inline_len);

if (wake)
wake_up_all(&ci->i_cap_wq);

Expand Down
5 changes: 4 additions & 1 deletion fs/ceph/super.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ struct ceph_inode_info {
spinlock_t i_ceph_lock;

u64 i_version;
u64 i_inline_version;
u32 i_time_warp_seq;

unsigned i_ceph_flags;
Expand Down Expand Up @@ -858,7 +859,7 @@ extern int ceph_encode_dentry_release(void **p, struct dentry *dn,
int mds, int drop, int unless);

extern int ceph_get_caps(struct ceph_inode_info *ci, int need, int want,
int *got, loff_t endoff);
loff_t endoff, int *got, struct page **pinned_page);

/* for counting open files by mode */
static inline void __ceph_get_fmode(struct ceph_inode_info *ci, int mode)
Expand All @@ -880,6 +881,8 @@ extern int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
struct file *file, unsigned flags, umode_t mode,
int *opened);
extern int ceph_release(struct inode *inode, struct file *filp);
extern void ceph_fill_inline_data(struct inode *inode, struct page *locked_page,
char *data, size_t len);

/* dir.c */
extern const struct file_operations ceph_dir_fops;
Expand Down
10 changes: 10 additions & 0 deletions fs/ceph/super.h.rej
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
--- fs/ceph/super.h
+++ fs/ceph/super.h
@@ -254,6 +255,7 @@
spinlock_t i_ceph_lock;

u64 i_version;
+ u64 i_inline_version;
u32 i_time_warp_seq;

unsigned i_ceph_flags;
1 change: 1 addition & 0 deletions include/linux/ceph/ceph_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@ struct ceph_filelock {

int ceph_flags_to_mode(int flags);

#define CEPH_INLINE_NONE ((__u64)-1)

/* capability bits */
#define CEPH_CAP_PIN 1 /* no specific capabilities beyond the pin */
Expand Down

0 comments on commit 31c542a

Please sign in to comment.