Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31c542a1 authored by Yan, Zheng's avatar Yan, Zheng Committed by Ilya Dryomov
Browse files

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: default avatarYan, Zheng <zyan@redhat.com>
parent fb01d1f8
Loading
Loading
Loading
Loading
+43 −0
Original line number Original line Diff line number Diff line
@@ -1318,6 +1318,49 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
	return ret;
	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 = {
static struct vm_operations_struct ceph_vmops = {
	.fault		= ceph_filemap_fault,
	.fault		= ceph_filemap_fault,
	.page_mkwrite	= ceph_page_mkwrite,
	.page_mkwrite	= ceph_page_mkwrite,
+11 −0
Original line number Original line Diff line number Diff line
@@ -2405,6 +2405,7 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
	bool queue_invalidate = false;
	bool queue_invalidate = false;
	bool queue_revalidate = false;
	bool queue_revalidate = false;
	bool deleted_inode = false;
	bool deleted_inode = false;
	bool fill_inline = false;


	dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n",
	dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n",
	     inode, cap, mds, seq, ceph_cap_string(newcaps));
	     inode, cap, mds, seq, ceph_cap_string(newcaps));
@@ -2578,6 +2579,13 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
	}
	}
	BUG_ON(cap->issued & ~cap->implemented);
	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);
	spin_unlock(&ci->i_ceph_lock);


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


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

	if (queue_trunc) {
	if (queue_trunc) {
		ceph_queue_vmtruncate(inode);
		ceph_queue_vmtruncate(inode);
		ceph_queue_revalidate(inode);
		ceph_queue_revalidate(inode);
+16 −0
Original line number Original line Diff line number Diff line
@@ -387,6 +387,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
	spin_lock_init(&ci->i_ceph_lock);
	spin_lock_init(&ci->i_ceph_lock);


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


	dout("fill_inode %p ino %llx.%llx v %llu had %llu\n",
	dout("fill_inode %p ino %llx.%llx v %llu had %llu\n",
	     inode, ceph_vinop(inode), le64_to_cpu(info->version),
	     inode, ceph_vinop(inode), le64_to_cpu(info->version),
@@ -875,8 +877,22 @@ static int fill_inode(struct inode *inode,
			   ceph_vinop(inode));
			   ceph_vinop(inode));
		__ceph_get_fmode(ci, cap_fmode);
		__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);
	spin_unlock(&ci->i_ceph_lock);


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

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


+4 −1
Original line number Original line Diff line number Diff line
@@ -253,6 +253,7 @@ struct ceph_inode_info {
	spinlock_t i_ceph_lock;
	spinlock_t i_ceph_lock;


	u64 i_version;
	u64 i_version;
	u64 i_inline_version;
	u32 i_time_warp_seq;
	u32 i_time_warp_seq;


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


extern int ceph_get_caps(struct ceph_inode_info *ci, int need, int want,
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 */
/* for counting open files by mode */
static inline void __ceph_get_fmode(struct ceph_inode_info *ci, int mode)
static inline void __ceph_get_fmode(struct ceph_inode_info *ci, int mode)
@@ -880,6 +881,8 @@ extern int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
			    struct file *file, unsigned flags, umode_t mode,
			    struct file *file, unsigned flags, umode_t mode,
			    int *opened);
			    int *opened);
extern int ceph_release(struct inode *inode, struct file *filp);
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 */
/* dir.c */
extern const struct file_operations ceph_dir_fops;
extern const struct file_operations ceph_dir_fops;

fs/ceph/super.h.rej

0 → 100644
+10 −0
Original line number Original line Diff line number Diff line
--- 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;
Loading