summaryrefslogtreecommitdiffstats
path: root/fs/fuse/fuse_i.h
diff options
context:
space:
mode:
authorMiklos Szeredi2013-10-01 16:44:53 +0200
committerMiklos Szeredi2013-10-01 16:44:53 +0200
commit8b284dc47291daf72fe300e1138a2e7ed56f38ab (patch)
tree980b7fa50cd582b9e13da1458afd8d8921e0513c /fs/fuse/fuse_i.h
parentfuse: writepages: fix aggregation (diff)
downloadkernel-qcow2-linux-8b284dc47291daf72fe300e1138a2e7ed56f38ab.tar.gz
kernel-qcow2-linux-8b284dc47291daf72fe300e1138a2e7ed56f38ab.tar.xz
kernel-qcow2-linux-8b284dc47291daf72fe300e1138a2e7ed56f38ab.zip
fuse: writepages: handle same page rewrites
As Maxim Patlasov pointed out, it's possible to get a dirty page while it's copy is still under writeback, despite fuse_page_mkwrite() doing its thing (direct IO). This could result in two concurrent write request for the same offset, with data corruption if they get mixed up. To prevent this, fuse needs to check and delay such writes. This implementation does this by: 1. check if page is still under writeout, if so create a new, single page secondary request for it 2. chain this secondary request onto the in-flight request 2/a. if a seconday request for the same offset was already chained to the in-flight request, then just copy the contents of the page and discard the new secondary request. This makes sure that for each page will have at most two requests associated with it 3. when the in-flight request finished, send off all secondary requests chained onto it Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs/fuse/fuse_i.h')
-rw-r--r--fs/fuse/fuse_i.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 5b9e6f3b6aef..643274852c8b 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -321,6 +321,7 @@ struct fuse_req {
struct {
struct fuse_write_in in;
struct fuse_write_out out;
+ struct fuse_req *next;
} write;
struct fuse_notify_retrieve_in retrieve_in;
struct fuse_lk_in lk_in;