summaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2007-04-02 19:29:52 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-04-30 22:17:06 -0700
commitc63c7b051395368573779c8309aa5c990dcf2f96 (patch)
treedb54090eef99349d15b95fcd8c2620a2403d8db8 /include/linux
parent8b09bee3083897e375bd0bf9d60f48daedfab3e0 (diff)
downloadlinux-c63c7b051395368573779c8309aa5c990dcf2f96.tar.gz
linux-c63c7b051395368573779c8309aa5c990dcf2f96.tar.bz2
linux-c63c7b051395368573779c8309aa5c990dcf2f96.zip
NFS: Fix a race when doing NFS write coalescing
Currently we do write coalescing in a very inefficient manner: one pass in generic_writepages() in order to lock the pages for writing, then one pass in nfs_flush_mapping() and/or nfs_sync_mapping_wait() in order to gather the locked pages for coalescing into RPC requests of size "wsize". In fact, it turns out there is actually a deadlock possible here since we only start I/O on the second pass. If the user signals the process while we're in nfs_sync_mapping_wait(), for instance, then we may exit before starting I/O on all the requests that have been queued up. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/nfs_page.h8
-rw-r--r--include/linux/writeback.h2
2 files changed, 3 insertions, 7 deletions
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index b8b7bca3bac8..e556e57ef7ad 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -21,8 +21,7 @@
/*
* Valid flags for the radix tree
*/
-#define NFS_PAGE_TAG_DIRTY 0
-#define NFS_PAGE_TAG_WRITEBACK 1
+#define NFS_PAGE_TAG_WRITEBACK 0
/*
* Valid flags for a dirty buffer
@@ -72,9 +71,6 @@ extern void nfs_clear_request(struct nfs_page *req);
extern void nfs_release_request(struct nfs_page *req);
-extern long nfs_scan_dirty(struct address_space *mapping,
- struct writeback_control *wbc,
- struct list_head *dst);
extern int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *head, struct list_head *dst,
unsigned long idx_start, unsigned int npages);
extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
@@ -84,8 +80,6 @@ extern void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
int how);
extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *,
struct nfs_page *);
-extern void nfs_pageio_add_list(struct nfs_pageio_descriptor *,
- struct list_head *);
extern void nfs_pageio_complete(struct nfs_pageio_descriptor *desc);
extern int nfs_wait_on_request(struct nfs_page *);
extern void nfs_unlock_request(struct nfs_page *req);
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 0c78f7f4a976..daa6c125f66e 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -59,6 +59,8 @@ struct writeback_control {
unsigned for_reclaim:1; /* Invoked from the page allocator */
unsigned for_writepages:1; /* This is a writepages() call */
unsigned range_cyclic:1; /* range_start is cyclic */
+
+ void *fs_private; /* For use by ->writepages() */
};
/*