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

Commit 56698236 authored by Suresh Jayaraman's avatar Suresh Jayaraman Committed by Steve French
Browse files

cifs: read pages from FS-Cache



Read pages from a FS-Cache data storage object into a CIFS inode.

Signed-off-by: default avatarSuresh Jayaraman <sjayaraman@suse.de>
Acked-by: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent 9dc06558
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -1977,6 +1977,15 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
	pTcon = cifs_sb->tcon;

	/*
	 * Reads as many pages as possible from fscache. Returns -ENOBUFS
	 * immediately if the cookie is negative
	 */
	rc = cifs_readpages_from_fscache(mapping->host, mapping, page_list,
					 &num_pages);
	if (rc == 0)
		goto read_complete;

	cFYI(DBG2, "rpages: num pages %d", num_pages);
	for (i = 0; i < num_pages; ) {
		unsigned contig_pages;
@@ -2087,6 +2096,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
		smb_read_data = NULL;
	}

read_complete:
	FreeXid(xid);
	return rc;
}
@@ -2097,6 +2107,11 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
	char *read_data;
	int rc;

	/* Is the page cached? */
	rc = cifs_readpage_from_fscache(file->f_path.dentry->d_inode, page);
	if (rc == 0)
		goto read_complete;

	page_cache_get(page);
	read_data = kmap(page);
	/* for reads over a certain size could initiate async read ahead */
@@ -2125,6 +2140,8 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
io_error:
	kunmap(page);
	page_cache_release(page);

read_complete:
	return rc;
}

+73 −0
Original line number Diff line number Diff line
@@ -140,6 +140,79 @@ int cifs_fscache_release_page(struct page *page, gfp_t gfp)
	return 1;
}

static void cifs_readpage_from_fscache_complete(struct page *page, void *ctx,
						int error)
{
	cFYI(1, "CFS: readpage_from_fscache_complete (0x%p/%d)",
			page, error);
	if (!error)
		SetPageUptodate(page);
	unlock_page(page);
}

/*
 * Retrieve a page from FS-Cache
 */
int __cifs_readpage_from_fscache(struct inode *inode, struct page *page)
{
	int ret;

	cFYI(1, "CIFS: readpage_from_fscache(fsc:%p, p:%p, i:0x%p",
			CIFS_I(inode)->fscache, page, inode);
	ret = fscache_read_or_alloc_page(CIFS_I(inode)->fscache, page,
					 cifs_readpage_from_fscache_complete,
					 NULL,
					 GFP_KERNEL);
	switch (ret) {

	case 0: /* page found in fscache, read submitted */
		cFYI(1, "CIFS: readpage_from_fscache: submitted");
		return ret;
	case -ENOBUFS:	/* page won't be cached */
	case -ENODATA:	/* page not in cache */
		cFYI(1, "CIFS: readpage_from_fscache %d", ret);
		return 1;

	default:
		cERROR(1, "unknown error ret = %d", ret);
	}
	return ret;
}

/*
 * Retrieve a set of pages from FS-Cache
 */
int __cifs_readpages_from_fscache(struct inode *inode,
				struct address_space *mapping,
				struct list_head *pages,
				unsigned *nr_pages)
{
	int ret;

	cFYI(1, "CIFS: __cifs_readpages_from_fscache (0x%p/%u/0x%p)",
			CIFS_I(inode)->fscache, *nr_pages, inode);
	ret = fscache_read_or_alloc_pages(CIFS_I(inode)->fscache, mapping,
					  pages, nr_pages,
					  cifs_readpage_from_fscache_complete,
					  NULL,
					  mapping_gfp_mask(mapping));
	switch (ret) {
	case 0:	/* read submitted to the cache for all pages */
		cFYI(1, "CIFS: readpages_from_fscache: submitted");
		return ret;

	case -ENOBUFS:	/* some pages are not cached and can't be */
	case -ENODATA:	/* some pages are not cached */
		cFYI(1, "CIFS: readpages_from_fscache: no page");
		return 1;

	default:
		cFYI(1, "unknown error ret = %d", ret);
	}

	return ret;
}

void __cifs_readpage_to_fscache(struct inode *inode, struct page *page)
{
	int ret;
+39 −1
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ extern const struct fscache_cookie_def cifs_fscache_server_index_def;
extern const struct fscache_cookie_def cifs_fscache_super_index_def;
extern const struct fscache_cookie_def cifs_fscache_inode_object_def;


extern int cifs_fscache_register(void);
extern void cifs_fscache_unregister(void);

@@ -50,6 +49,11 @@ extern void cifs_fscache_reset_inode_cookie(struct inode *);

extern void __cifs_fscache_invalidate_page(struct page *, struct inode *);
extern int cifs_fscache_release_page(struct page *page, gfp_t gfp);
extern int __cifs_readpage_from_fscache(struct inode *, struct page *);
extern int __cifs_readpages_from_fscache(struct inode *,
					 struct address_space *,
					 struct list_head *,
					 unsigned *);

extern void __cifs_readpage_to_fscache(struct inode *, struct page *);

@@ -60,6 +64,26 @@ static inline void cifs_fscache_invalidate_page(struct page *page,
		__cifs_fscache_invalidate_page(page, inode);
}

static inline int cifs_readpage_from_fscache(struct inode *inode,
					     struct page *page)
{
	if (CIFS_I(inode)->fscache)
		return __cifs_readpage_from_fscache(inode, page);

	return -ENOBUFS;
}

static inline int cifs_readpages_from_fscache(struct inode *inode,
					      struct address_space *mapping,
					      struct list_head *pages,
					      unsigned *nr_pages)
{
	if (CIFS_I(inode)->fscache)
		return __cifs_readpages_from_fscache(inode, mapping, pages,
						     nr_pages);
	return -ENOBUFS;
}

static inline void cifs_readpage_to_fscache(struct inode *inode,
					    struct page *page)
{
@@ -90,6 +114,20 @@ static inline void cifs_fscache_release_page(struct page *page, gfp_t gfp)

static inline int cifs_fscache_invalidate_page(struct page *page,
			struct inode *) {}
static inline int
cifs_readpage_from_fscache(struct inode *inode, struct page *page)
{
	return -ENOBUFS;
}

static inline int cifs_readpages_from_fscache(struct inode *inode,
					      struct address_space *mapping,
					      struct list_head *pages,
					      unsigned *nr_pages)
{
	return -ENOBUFS;
}

static inline void cifs_readpage_to_fscache(struct inode *inode,
			struct page *page) {}