diff options
Diffstat (limited to 'fs/afs/file.c')
-rw-r--r-- | fs/afs/file.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/fs/afs/file.c b/fs/afs/file.c index 3eb3fc7b36be..3e25795e5a42 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c | |||
@@ -15,32 +15,43 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
17 | #include <linux/pagemap.h> | 17 | #include <linux/pagemap.h> |
18 | #include <linux/writeback.h> | ||
18 | #include "internal.h" | 19 | #include "internal.h" |
19 | 20 | ||
20 | static int afs_readpage(struct file *file, struct page *page); | 21 | static int afs_readpage(struct file *file, struct page *page); |
21 | static void afs_invalidatepage(struct page *page, unsigned long offset); | 22 | static void afs_invalidatepage(struct page *page, unsigned long offset); |
22 | static int afs_releasepage(struct page *page, gfp_t gfp_flags); | 23 | static int afs_releasepage(struct page *page, gfp_t gfp_flags); |
24 | static int afs_launder_page(struct page *page); | ||
23 | 25 | ||
24 | const struct file_operations afs_file_operations = { | 26 | const struct file_operations afs_file_operations = { |
25 | .open = afs_open, | 27 | .open = afs_open, |
26 | .release = afs_release, | 28 | .release = afs_release, |
27 | .llseek = generic_file_llseek, | 29 | .llseek = generic_file_llseek, |
28 | .read = do_sync_read, | 30 | .read = do_sync_read, |
31 | .write = do_sync_write, | ||
29 | .aio_read = generic_file_aio_read, | 32 | .aio_read = generic_file_aio_read, |
33 | .aio_write = afs_file_write, | ||
30 | .mmap = generic_file_readonly_mmap, | 34 | .mmap = generic_file_readonly_mmap, |
31 | .sendfile = generic_file_sendfile, | 35 | .sendfile = generic_file_sendfile, |
36 | .fsync = afs_fsync, | ||
32 | }; | 37 | }; |
33 | 38 | ||
34 | const struct inode_operations afs_file_inode_operations = { | 39 | const struct inode_operations afs_file_inode_operations = { |
35 | .getattr = afs_getattr, | 40 | .getattr = afs_getattr, |
41 | .setattr = afs_setattr, | ||
36 | .permission = afs_permission, | 42 | .permission = afs_permission, |
37 | }; | 43 | }; |
38 | 44 | ||
39 | const struct address_space_operations afs_fs_aops = { | 45 | const struct address_space_operations afs_fs_aops = { |
40 | .readpage = afs_readpage, | 46 | .readpage = afs_readpage, |
41 | .set_page_dirty = __set_page_dirty_nobuffers, | 47 | .set_page_dirty = afs_set_page_dirty, |
48 | .launder_page = afs_launder_page, | ||
42 | .releasepage = afs_releasepage, | 49 | .releasepage = afs_releasepage, |
43 | .invalidatepage = afs_invalidatepage, | 50 | .invalidatepage = afs_invalidatepage, |
51 | .prepare_write = afs_prepare_write, | ||
52 | .commit_write = afs_commit_write, | ||
53 | .writepage = afs_writepage, | ||
54 | .writepages = afs_writepages, | ||
44 | }; | 55 | }; |
45 | 56 | ||
46 | /* | 57 | /* |
@@ -230,11 +241,6 @@ static void afs_invalidatepage(struct page *page, unsigned long offset) | |||
230 | BUG_ON(!PageLocked(page)); | 241 | BUG_ON(!PageLocked(page)); |
231 | 242 | ||
232 | if (PagePrivate(page)) { | 243 | if (PagePrivate(page)) { |
233 | #ifdef AFS_CACHING_SUPPORT | ||
234 | struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); | ||
235 | cachefs_uncache_page(vnode->cache,page); | ||
236 | #endif | ||
237 | |||
238 | /* We release buffers only if the entire page is being | 244 | /* We release buffers only if the entire page is being |
239 | * invalidated. | 245 | * invalidated. |
240 | * The get_block cached value has been unconditionally | 246 | * The get_block cached value has been unconditionally |
@@ -255,19 +261,33 @@ static void afs_invalidatepage(struct page *page, unsigned long offset) | |||
255 | } | 261 | } |
256 | 262 | ||
257 | /* | 263 | /* |
264 | * write back a dirty page | ||
265 | */ | ||
266 | static int afs_launder_page(struct page *page) | ||
267 | { | ||
268 | _enter("{%lu}", page->index); | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | /* | ||
258 | * release a page and cleanup its private data | 274 | * release a page and cleanup its private data |
259 | */ | 275 | */ |
260 | static int afs_releasepage(struct page *page, gfp_t gfp_flags) | 276 | static int afs_releasepage(struct page *page, gfp_t gfp_flags) |
261 | { | 277 | { |
262 | struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); | 278 | struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); |
279 | struct afs_writeback *wb; | ||
263 | 280 | ||
264 | _enter("{{%x:%u}[%lu],%lx},%x", | 281 | _enter("{{%x:%u}[%lu],%lx},%x", |
265 | vnode->fid.vid, vnode->fid.vnode, page->index, page->flags, | 282 | vnode->fid.vid, vnode->fid.vnode, page->index, page->flags, |
266 | gfp_flags); | 283 | gfp_flags); |
267 | 284 | ||
268 | if (PagePrivate(page)) { | 285 | if (PagePrivate(page)) { |
286 | wb = (struct afs_writeback *) page_private(page); | ||
287 | ASSERT(wb != NULL); | ||
269 | set_page_private(page, 0); | 288 | set_page_private(page, 0); |
270 | ClearPagePrivate(page); | 289 | ClearPagePrivate(page); |
290 | afs_put_writeback(wb); | ||
271 | } | 291 | } |
272 | 292 | ||
273 | _leave(" = 0"); | 293 | _leave(" = 0"); |