aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/file.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-03-17 15:16:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-03-17 15:16:44 -0400
commit57fd0b77d659d5733434d3ce37cf606273abb1e8 (patch)
tree7a83ba8baa2c31dcfa908f3b73eb577464f8ad29 /fs/afs/file.c
parentc79d5ff0e249824674e70e89142f55b52f261722 (diff)
parentc5051c7bc777dffa5661569dec5997f432b9a34a (diff)
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,
30 30
31const struct file_operations afs_file_operations = { 31const struct file_operations afs_file_operations = {
32 .open = afs_open, 32 .open = afs_open,
33 .flush = afs_flush,
33 .release = afs_release, 34 .release = afs_release,
34 .llseek = generic_file_llseek, 35 .llseek = generic_file_llseek,
35 .read_iter = generic_file_read_iter, 36 .read_iter = generic_file_read_iter,
@@ -184,10 +185,13 @@ int afs_page_filler(void *data, struct page *page)
184 if (!req) 185 if (!req)
185 goto enomem; 186 goto enomem;
186 187
188 /* We request a full page. If the page is a partial one at the
189 * end of the file, the server will return a short read and the
190 * unmarshalling code will clear the unfilled space.
191 */
187 atomic_set(&req->usage, 1); 192 atomic_set(&req->usage, 1);
188 req->pos = (loff_t)page->index << PAGE_SHIFT; 193 req->pos = (loff_t)page->index << PAGE_SHIFT;
189 req->len = min_t(size_t, i_size_read(inode) - req->pos, 194 req->len = PAGE_SIZE;
190 PAGE_SIZE);
191 req->nr_pages = 1; 195 req->nr_pages = 1;
192 req->pages[0] = page; 196 req->pages[0] = page;
193 get_page(page); 197 get_page(page);
@@ -208,7 +212,13 @@ int afs_page_filler(void *data, struct page *page)
208 fscache_uncache_page(vnode->cache, page); 212 fscache_uncache_page(vnode->cache, page);
209#endif 213#endif
210 BUG_ON(PageFsCache(page)); 214 BUG_ON(PageFsCache(page));
211 goto error; 215
216 if (ret == -EINTR ||
217 ret == -ENOMEM ||
218 ret == -ERESTARTSYS ||
219 ret == -EAGAIN)
220 goto error;
221 goto io_error;
212 } 222 }
213 223
214 SetPageUptodate(page); 224 SetPageUptodate(page);
@@ -227,10 +237,12 @@ int afs_page_filler(void *data, struct page *page)
227 _leave(" = 0"); 237 _leave(" = 0");
228 return 0; 238 return 0;
229 239
240io_error:
241 SetPageError(page);
242 goto error;
230enomem: 243enomem:
231 ret = -ENOMEM; 244 ret = -ENOMEM;
232error: 245error:
233 SetPageError(page);
234 unlock_page(page); 246 unlock_page(page);
235 _leave(" = %d", ret); 247 _leave(" = %d", ret);
236 return ret; 248 return ret;