mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-12-29 12:51:43 +01:00
257 lines
8.3 KiB
Text
257 lines
8.3 KiB
Text
|
From: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>
|
||
|
Subject: [RFC][PATCH 09/10] cifs: read pages from FS-Cache
|
||
|
Date: Tue, 22 Jun 2010 20:54:21 +0530
|
||
|
Lines: 219
|
||
|
Message-ID: <1277220261-3717-1-git-send-email-sjayaraman@suse.de>
|
||
|
References: <yes>
|
||
|
Cc: linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
|
||
|
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
|
||
|
To: Steve French <smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
|
||
|
X-From: linux-cifs-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Tue Jun 22 17:44:46 2010
|
||
|
Return-path: <linux-cifs-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
|
||
|
Envelope-to: glkc-linux-cifs-1dZseelyfdZg9hUCZPvPmw@public.gmane.org
|
||
|
Received: from vger.kernel.org ([209.132.180.67])
|
||
|
by lo.gmane.org with esmtp (Exim 4.69)
|
||
|
(envelope-from <linux-cifs-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>)
|
||
|
id 1OR5eX-0008O2-Q4
|
||
|
for glkc-linux-cifs-1dZseelyfdZg9hUCZPvPmw@public.gmane.org; Tue, 22 Jun 2010 17:44:46 +0200
|
||
|
Received: (majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org) by vger.kernel.org via listexpand
|
||
|
id S1752563Ab0FVPom (ORCPT <rfc822;glkc-linux-cifs@m.gmane.org>);
|
||
|
Tue, 22 Jun 2010 11:44:42 -0400
|
||
|
Received: from victor.provo.novell.com ([137.65.250.26]:42741 "EHLO
|
||
|
victor.provo.novell.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
|
||
|
with ESMTP id S1752542Ab0FVPok (ORCPT
|
||
|
<rfc822;groupwise-SJayaraman-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org:0:0>);
|
||
|
Tue, 22 Jun 2010 11:44:40 -0400
|
||
|
Received: from localhost (prv-ext-foundry1int.gns.novell.com [137.65.251.240])
|
||
|
by victor.provo.novell.com with ESMTP; Tue, 22 Jun 2010 09:24:22 -0600
|
||
|
X-Mailer: git-send-email 1.6.4.2
|
||
|
In-Reply-To: <yes>
|
||
|
Sender: linux-cifs-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
|
||
|
Precedence: bulk
|
||
|
List-ID: <linux-cifs.vger.kernel.org>
|
||
|
X-Mailing-List: linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
|
||
|
Archived-At: <http://permalink.gmane.org/gmane.linux.kernel/1001762>
|
||
|
|
||
|
Read pages from a FS-Cache data storage object into a CIFS inode.
|
||
|
|
||
|
Signed-off-by: Suresh Jayaraman <sjayaraman-l3A5Bk7waGM@public.gmane.org>
|
||
|
---
|
||
|
fs/cifs/file.c | 19 ++++++++++++++
|
||
|
fs/cifs/fscache.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
fs/cifs/fscache.h | 40 ++++++++++++++++++++++++++++-
|
||
|
3 files changed, 131 insertions(+), 1 deletions(-)
|
||
|
|
||
|
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
|
||
|
index 39c1ce0..42d2f25 100644
|
||
|
--- a/fs/cifs/file.c
|
||
|
+++ b/fs/cifs/file.c
|
||
|
@@ -1978,6 +1978,16 @@ 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);
|
||
|
+ cFYI(1, "CIFS: readpages_from_fscache returned %d\n", rc);
|
||
|
+ if (rc == 0)
|
||
|
+ goto read_complete;
|
||
|
+
|
||
|
cFYI(DBG2, "rpages: num pages %d", num_pages);
|
||
|
for (i = 0; i < num_pages; ) {
|
||
|
unsigned contig_pages;
|
||
|
@@ -2090,6 +2100,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
|
||
|
smb_read_data = NULL;
|
||
|
}
|
||
|
|
||
|
+read_complete:
|
||
|
FreeXid(xid);
|
||
|
return rc;
|
||
|
}
|
||
|
@@ -2100,6 +2111,12 @@ 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);
|
||
|
+ cFYI(1, "CIFS: cifs_readpage_from_fscache returned %d\n", rc);
|
||
|
+ 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 */
|
||
|
@@ -2128,6 +2145,8 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
|
||
|
io_error:
|
||
|
kunmap(page);
|
||
|
page_cache_release(page);
|
||
|
+
|
||
|
+read_complete:
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
|
||
|
index 13e47d5..6813737 100644
|
||
|
--- a/fs/cifs/fscache.c
|
||
|
+++ b/fs/cifs/fscache.c
|
||
|
@@ -145,6 +145,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)\n",
|
||
|
+ 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\n",
|
||
|
+ 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\n");
|
||
|
+ return ret;
|
||
|
+ case -ENOBUFS: /* page won't be cached */
|
||
|
+ case -ENODATA: /* page not in cache */
|
||
|
+ cFYI(1, "CIFS: readpage_from_fscache %d\n", ret);
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ default:
|
||
|
+ cFYI(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)\n",
|
||
|
+ 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\n");
|
||
|
+ 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\n");
|
||
|
+ 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;
|
||
|
diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h
|
||
|
index e34d8ab..03bd3fe 100644
|
||
|
--- a/fs/cifs/fscache.h
|
||
|
+++ b/fs/cifs/fscache.h
|
||
|
@@ -31,7 +31,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);
|
||
|
|
||
|
@@ -49,6 +48,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 *);
|
||
|
|
||
|
@@ -59,6 +63,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)
|
||
|
{
|
||
|
@@ -89,6 +113,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) {}
|
||
|
|
||
|
--
|
||
|
1.6.4.2
|
||
|
|
||
|
|
||
|
|