aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorSuresh Jayaraman <sjayaraman@suse.de>2010-07-05 08:43:25 -0400
committerSteve French <sfrench@us.ibm.com>2010-08-02 08:40:37 -0400
commit56698236e1294848c63d4768673865ae5a9c69e0 (patch)
treece6d43104a236595763759fe68c26ca3089abdd1 /fs/cifs
parent9dc06558c223bbc08290917ac44c25963bc09e43 (diff)
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>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/file.c17
-rw-r--r--fs/cifs/fscache.c73
-rw-r--r--fs/cifs/fscache.h40
3 files changed, 129 insertions, 1 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index ff726c86b290..fa04a00d126d 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1977,6 +1977,15 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1977 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1977 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1978 pTcon = cifs_sb->tcon; 1978 pTcon = cifs_sb->tcon;
1979 1979
1980 /*
1981 * Reads as many pages as possible from fscache. Returns -ENOBUFS
1982 * immediately if the cookie is negative
1983 */
1984 rc = cifs_readpages_from_fscache(mapping->host, mapping, page_list,
1985 &num_pages);
1986 if (rc == 0)
1987 goto read_complete;
1988
1980 cFYI(DBG2, "rpages: num pages %d", num_pages); 1989 cFYI(DBG2, "rpages: num pages %d", num_pages);
1981 for (i = 0; i < num_pages; ) { 1990 for (i = 0; i < num_pages; ) {
1982 unsigned contig_pages; 1991 unsigned contig_pages;
@@ -2087,6 +2096,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
2087 smb_read_data = NULL; 2096 smb_read_data = NULL;
2088 } 2097 }
2089 2098
2099read_complete:
2090 FreeXid(xid); 2100 FreeXid(xid);
2091 return rc; 2101 return rc;
2092} 2102}
@@ -2097,6 +2107,11 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
2097 char *read_data; 2107 char *read_data;
2098 int rc; 2108 int rc;
2099 2109
2110 /* Is the page cached? */
2111 rc = cifs_readpage_from_fscache(file->f_path.dentry->d_inode, page);
2112 if (rc == 0)
2113 goto read_complete;
2114
2100 page_cache_get(page); 2115 page_cache_get(page);
2101 read_data = kmap(page); 2116 read_data = kmap(page);
2102 /* for reads over a certain size could initiate async read ahead */ 2117 /* 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,
2125io_error: 2140io_error:
2126 kunmap(page); 2141 kunmap(page);
2127 page_cache_release(page); 2142 page_cache_release(page);
2143
2144read_complete:
2128 return rc; 2145 return rc;
2129} 2146}
2130 2147
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
index 3b1636704c85..9f3f5c4be161 100644
--- a/fs/cifs/fscache.c
+++ b/fs/cifs/fscache.c
@@ -140,6 +140,79 @@ int cifs_fscache_release_page(struct page *page, gfp_t gfp)
140 return 1; 140 return 1;
141} 141}
142 142
143static void cifs_readpage_from_fscache_complete(struct page *page, void *ctx,
144 int error)
145{
146 cFYI(1, "CFS: readpage_from_fscache_complete (0x%p/%d)",
147 page, error);
148 if (!error)
149 SetPageUptodate(page);
150 unlock_page(page);
151}
152
153/*
154 * Retrieve a page from FS-Cache
155 */
156int __cifs_readpage_from_fscache(struct inode *inode, struct page *page)
157{
158 int ret;
159
160 cFYI(1, "CIFS: readpage_from_fscache(fsc:%p, p:%p, i:0x%p",
161 CIFS_I(inode)->fscache, page, inode);
162 ret = fscache_read_or_alloc_page(CIFS_I(inode)->fscache, page,
163 cifs_readpage_from_fscache_complete,
164 NULL,
165 GFP_KERNEL);
166 switch (ret) {
167
168 case 0: /* page found in fscache, read submitted */
169 cFYI(1, "CIFS: readpage_from_fscache: submitted");
170 return ret;
171 case -ENOBUFS: /* page won't be cached */
172 case -ENODATA: /* page not in cache */
173 cFYI(1, "CIFS: readpage_from_fscache %d", ret);
174 return 1;
175
176 default:
177 cERROR(1, "unknown error ret = %d", ret);
178 }
179 return ret;
180}
181
182/*
183 * Retrieve a set of pages from FS-Cache
184 */
185int __cifs_readpages_from_fscache(struct inode *inode,
186 struct address_space *mapping,
187 struct list_head *pages,
188 unsigned *nr_pages)
189{
190 int ret;
191
192 cFYI(1, "CIFS: __cifs_readpages_from_fscache (0x%p/%u/0x%p)",
193 CIFS_I(inode)->fscache, *nr_pages, inode);
194 ret = fscache_read_or_alloc_pages(CIFS_I(inode)->fscache, mapping,
195 pages, nr_pages,
196 cifs_readpage_from_fscache_complete,
197 NULL,
198 mapping_gfp_mask(mapping));
199 switch (ret) {
200 case 0: /* read submitted to the cache for all pages */
201 cFYI(1, "CIFS: readpages_from_fscache: submitted");
202 return ret;
203
204 case -ENOBUFS: /* some pages are not cached and can't be */
205 case -ENODATA: /* some pages are not cached */
206 cFYI(1, "CIFS: readpages_from_fscache: no page");
207 return 1;
208
209 default:
210 cFYI(1, "unknown error ret = %d", ret);
211 }
212
213 return ret;
214}
215
143void __cifs_readpage_to_fscache(struct inode *inode, struct page *page) 216void __cifs_readpage_to_fscache(struct inode *inode, struct page *page)
144{ 217{
145 int ret; 218 int ret;
diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h
index 1a00d70bca97..79164c66797e 100644
--- a/fs/cifs/fscache.h
+++ b/fs/cifs/fscache.h
@@ -32,7 +32,6 @@ extern const struct fscache_cookie_def cifs_fscache_server_index_def;
32extern const struct fscache_cookie_def cifs_fscache_super_index_def; 32extern const struct fscache_cookie_def cifs_fscache_super_index_def;
33extern const struct fscache_cookie_def cifs_fscache_inode_object_def; 33extern const struct fscache_cookie_def cifs_fscache_inode_object_def;
34 34
35
36extern int cifs_fscache_register(void); 35extern int cifs_fscache_register(void);
37extern void cifs_fscache_unregister(void); 36extern void cifs_fscache_unregister(void);
38 37
@@ -50,6 +49,11 @@ extern void cifs_fscache_reset_inode_cookie(struct inode *);
50 49
51extern void __cifs_fscache_invalidate_page(struct page *, struct inode *); 50extern void __cifs_fscache_invalidate_page(struct page *, struct inode *);
52extern int cifs_fscache_release_page(struct page *page, gfp_t gfp); 51extern int cifs_fscache_release_page(struct page *page, gfp_t gfp);
52extern int __cifs_readpage_from_fscache(struct inode *, struct page *);
53extern int __cifs_readpages_from_fscache(struct inode *,
54 struct address_space *,
55 struct list_head *,
56 unsigned *);
53 57
54extern void __cifs_readpage_to_fscache(struct inode *, struct page *); 58extern void __cifs_readpage_to_fscache(struct inode *, struct page *);
55 59
@@ -60,6 +64,26 @@ static inline void cifs_fscache_invalidate_page(struct page *page,
60 __cifs_fscache_invalidate_page(page, inode); 64 __cifs_fscache_invalidate_page(page, inode);
61} 65}
62 66
67static inline int cifs_readpage_from_fscache(struct inode *inode,
68 struct page *page)
69{
70 if (CIFS_I(inode)->fscache)
71 return __cifs_readpage_from_fscache(inode, page);
72
73 return -ENOBUFS;
74}
75
76static inline int cifs_readpages_from_fscache(struct inode *inode,
77 struct address_space *mapping,
78 struct list_head *pages,
79 unsigned *nr_pages)
80{
81 if (CIFS_I(inode)->fscache)
82 return __cifs_readpages_from_fscache(inode, mapping, pages,
83 nr_pages);
84 return -ENOBUFS;
85}
86
63static inline void cifs_readpage_to_fscache(struct inode *inode, 87static inline void cifs_readpage_to_fscache(struct inode *inode,
64 struct page *page) 88 struct page *page)
65{ 89{
@@ -90,6 +114,20 @@ static inline void cifs_fscache_release_page(struct page *page, gfp_t gfp)
90 114
91static inline int cifs_fscache_invalidate_page(struct page *page, 115static inline int cifs_fscache_invalidate_page(struct page *page,
92 struct inode *) {} 116 struct inode *) {}
117static inline int
118cifs_readpage_from_fscache(struct inode *inode, struct page *page)
119{
120 return -ENOBUFS;
121}
122
123static inline int cifs_readpages_from_fscache(struct inode *inode,
124 struct address_space *mapping,
125 struct list_head *pages,
126 unsigned *nr_pages)
127{
128 return -ENOBUFS;
129}
130
93static inline void cifs_readpage_to_fscache(struct inode *inode, 131static inline void cifs_readpage_to_fscache(struct inode *inode,
94 struct page *page) {} 132 struct page *page) {}
95 133