summaryrefslogtreecommitdiffstats
path: root/fs/afs/internal.h
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2017-11-02 15:27:52 +0000
committerDavid Howells <dhowells@redhat.com>2017-11-13 15:38:20 +0000
commitdab17c1add5c51b68027a9a3861af3a99cb5485a (patch)
tree17d9d716ff0903555bd1d4451974df3088625e33 /fs/afs/internal.h
parent2c099014a0a456012c1778e80adce839bf956b77 (diff)
downloadop-kernel-dev-dab17c1add5c51b68027a9a3861af3a99cb5485a.zip
op-kernel-dev-dab17c1add5c51b68027a9a3861af3a99cb5485a.tar.gz
afs: Fix directory read/modify race
Because parsing of the directory wasn't being done under any sort of lock, the pages holding the directory content can get invalidated whilst the parsing is ongoing. Further, the directory page check function gets called outside of the page lock, so if the page gets cleared or updated, this may return reports of bad magic numbers in the directory page. Also, the directory may change size whilst checking and parsing are ongoing, so more care needs to be taken here. Fix this by: (1) Perform the page check from the page filling function before we set PageUptodate and drop the page lock. (2) Check for the file having shrunk and the page having been abandoned before checking the page contents. (3) Lock the page whilst parsing it for the directory iterator. Whilst we're at it, add a tracepoint to report check failure. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs/internal.h')
-rw-r--r--fs/afs/internal.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index aad1254..6aa6e99 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -622,6 +622,7 @@ extern bool afs_cm_incoming_call(struct afs_call *);
/*
* dir.c
*/
+extern bool afs_dir_check_page(struct inode *, struct page *);
extern const struct inode_operations afs_dir_inode_operations;
extern const struct dentry_operations afs_fs_dentry_operations;
extern const struct file_operations afs_dir_file_operations;
OpenPOWER on IntegriCloud