summaryrefslogtreecommitdiff
path: root/fs/afs/file.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-03-17 22:16:44 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2017-03-17 22:16:44 +0300
commit57fd0b77d659d5733434d3ce37cf606273abb1e8 (patch)
tree7a83ba8baa2c31dcfa908f3b73eb577464f8ad29 /fs/afs/file.c
parentc79d5ff0e249824674e70e89142f55b52f261722 (diff)
parentc5051c7bc777dffa5661569dec5997f432b9a34a (diff)
downloadlinux-57fd0b77d659d5733434d3ce37cf606273abb1e8.tar.xz
Merge tag 'afs-20170316' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull AFS fixes from David Howells: "Fixes to the AFS filesystem in the kernel. They fix a variety of bugs. These include some issues fixed for consistency with other AFS implementations: - handle AFS mode bits better - use the client mtime rather than the server mtime in the protocol - handle the server returning more or less data than was requested in a FetchData call - distinguish mountpoints from symlinks based on the mode bits rather than preemptively reading every symlink to find out what it actually represents One other notable change for the user is that files are now flushed on close analogously with other network filesystems" * tag 'afs-20170316' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: (28 commits) afs: Don't wait for page writeback with the page lock held afs: ->writepage() shouldn't call clear_page_dirty_for_io() afs: Fix abort on signal while waiting for call completion afs: Fix an off-by-one error in afs_send_pages() afs: Fix afs_kill_pages() afs: Fix page leak in afs_write_begin() afs: Don't set PG_error on local EINTR or ENOMEM when filling a page afs: Populate and use client modification time afs: Better abort and net error handling afs: Invalid op ID should abort with RXGEN_OPCODE afs: Fix the maths in afs_fs_store_data() afs: Use a bvec rather than a kvec in afs_send_pages() afs: Make struct afs_read::remain 64-bit afs: Fix AFS read bug afs: Prevent callback expiry timer overflow afs: Migrate vlocation fields to 64-bit afs: security: Replace rcu_assign_pointer() with RCU_INIT_POINTER() afs: inode: Replace rcu_assign_pointer() with RCU_INIT_POINTER() afs: Distinguish mountpoints from symlinks by file mode alone afs: Flush outstanding writes when an fd is closed ...
Diffstat (limited to 'fs/afs/file.c')
-rw-r--r--fs/afs/file.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/fs/afs/file.c b/fs/afs/file.c
index ba7b71fba34b..0d5b8508869b 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -30,6 +30,7 @@ static int afs_readpages(struct file *filp, struct address_space *mapping,
const struct file_operations afs_file_operations = {
.open = afs_open,
+ .flush = afs_flush,
.release = afs_release,
.llseek = generic_file_llseek,
.read_iter = generic_file_read_iter,
@@ -184,10 +185,13 @@ int afs_page_filler(void *data, struct page *page)
if (!req)
goto enomem;
+ /* We request a full page. If the page is a partial one at the
+ * end of the file, the server will return a short read and the
+ * unmarshalling code will clear the unfilled space.
+ */
atomic_set(&req->usage, 1);
req->pos = (loff_t)page->index << PAGE_SHIFT;
- req->len = min_t(size_t, i_size_read(inode) - req->pos,
- PAGE_SIZE);
+ req->len = PAGE_SIZE;
req->nr_pages = 1;
req->pages[0] = page;
get_page(page);
@@ -208,7 +212,13 @@ int afs_page_filler(void *data, struct page *page)
fscache_uncache_page(vnode->cache, page);
#endif
BUG_ON(PageFsCache(page));
- goto error;
+
+ if (ret == -EINTR ||
+ ret == -ENOMEM ||
+ ret == -ERESTARTSYS ||
+ ret == -EAGAIN)
+ goto error;
+ goto io_error;
}
SetPageUptodate(page);
@@ -227,10 +237,12 @@ int afs_page_filler(void *data, struct page *page)
_leave(" = 0");
return 0;
+io_error:
+ SetPageError(page);
+ goto error;
enomem:
ret = -ENOMEM;
error:
- SetPageError(page);
unlock_page(page);
_leave(" = %d", ret);
return ret;