cifs: read pages from FS-Cache
Read pages from a FS-Cache data storage object into a CIFS inode. Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de> Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
committed by
Steve French
parent
9dc06558c2
commit
56698236e1
@@ -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);
|
cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
|
||||||
pTcon = cifs_sb->tcon;
|
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);
|
cFYI(DBG2, "rpages: num pages %d", num_pages);
|
||||||
for (i = 0; i < num_pages; ) {
|
for (i = 0; i < num_pages; ) {
|
||||||
unsigned contig_pages;
|
unsigned contig_pages;
|
||||||
@@ -2087,6 +2096,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
|
|||||||
smb_read_data = NULL;
|
smb_read_data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
read_complete:
|
||||||
FreeXid(xid);
|
FreeXid(xid);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -2097,6 +2107,11 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
|
|||||||
char *read_data;
|
char *read_data;
|
||||||
int rc;
|
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);
|
page_cache_get(page);
|
||||||
read_data = kmap(page);
|
read_data = kmap(page);
|
||||||
/* for reads over a certain size could initiate async read ahead */
|
/* 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:
|
io_error:
|
||||||
kunmap(page);
|
kunmap(page);
|
||||||
page_cache_release(page);
|
page_cache_release(page);
|
||||||
|
|
||||||
|
read_complete:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -140,6 +140,79 @@ int cifs_fscache_release_page(struct page *page, gfp_t gfp)
|
|||||||
return 1;
|
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)
|
void __cifs_readpage_to_fscache(struct inode *inode, struct page *page)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@@ -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_super_index_def;
|
||||||
extern const struct fscache_cookie_def cifs_fscache_inode_object_def;
|
extern const struct fscache_cookie_def cifs_fscache_inode_object_def;
|
||||||
|
|
||||||
|
|
||||||
extern int cifs_fscache_register(void);
|
extern int cifs_fscache_register(void);
|
||||||
extern void cifs_fscache_unregister(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 void __cifs_fscache_invalidate_page(struct page *, struct inode *);
|
||||||
extern int cifs_fscache_release_page(struct page *page, gfp_t gfp);
|
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 *);
|
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);
|
__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,
|
static inline void cifs_readpage_to_fscache(struct inode *inode,
|
||||||
struct page *page)
|
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,
|
static inline int cifs_fscache_invalidate_page(struct page *page,
|
||||||
struct inode *) {}
|
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,
|
static inline void cifs_readpage_to_fscache(struct inode *inode,
|
||||||
struct page *page) {}
|
struct page *page) {}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user