patch-2.1.129 linux/fs/nfs/write.c
Next file: linux/fs/open.c
Previous file: linux/fs/nfs/read.c
Back to the patch index
Back to the overall index
- Lines: 170
- Date:
Sun Nov 15 12:13:04 1998
- Orig file:
v2.1.128/linux/fs/nfs/write.c
- Orig date:
Thu Nov 12 16:21:23 1998
diff -u --recursive --new-file v2.1.128/linux/fs/nfs/write.c linux/fs/nfs/write.c
@@ -46,7 +46,6 @@
* Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de>
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/malloc.h>
#include <linux/swap.h>
@@ -332,8 +331,6 @@
wreq->wb_bytes = bytes;
wreq->wb_count = 2; /* One for the IO, one for us */
- atomic_inc(&page->count);
-
append_write_request(&NFS_WRITEBACK(inode), wreq);
if (nr_write_requests++ > NFS_WRITEBACK_MAX*3/4)
@@ -480,8 +477,7 @@
/*
* Ok, there's another user of this page with the new request..
- * Increment the usage count, and schedule the request (the
- * end of the request will drop the usage count..)
+ * The IO completion will then free the page.
*/
atomic_inc(&page->count);
@@ -546,65 +542,101 @@
}
/*
- * Try to flush any dirty pages, returning a success marker..
- *
- * Unlike "nfs_flush_dirty_pages()" this does not invalidate
- * the writes if it is interrupted. The caller will instead
- * look at the error code and gracefully fail to do what it
- * wanted to do.
+ * If we're waiting on somebody else's request
+ * we need to increment the counter during the
+ * wait so that the request doesn't disappear
+ * from under us during the wait..
*/
-int
-nfs_flush_pages(struct inode *inode, pid_t pid, off_t offset, off_t len)
+static int FASTCALL(wait_on_other_req(struct nfs_wreq *));
+static int wait_on_other_req(struct nfs_wreq *req)
{
int retval;
+ req->wb_count++;
+ retval = wait_on_write_request(req);
+ free_write_request(req);
+ return retval;
+}
- do {
- struct nfs_wreq *req = NFS_WRITEBACK(inode);
- struct nfs_wreq *head = req;
+/*
+ * This writes back a set of requests according to the condition.
+ *
+ * If this ever gets much more convoluted, use a fn pointer for
+ * the condition..
+ */
+#define NFS_WB(inode, cond) { int retval = 0 ; \
+ do { \
+ struct nfs_wreq *req = NFS_WRITEBACK(inode); \
+ struct nfs_wreq *head = req; \
+ if (!req) break; \
+ for (;;) { \
+ if (!(req->wb_flags & NFS_WRITE_COMPLETE)) \
+ if (cond) break; \
+ req = WB_NEXT(req); \
+ if (req == head) goto out; \
+ } \
+ retval = wait_on_other_req(req); \
+ } while (!retval); \
+out: return retval; \
+}
- if (!req)
- return 0;
+int
+nfs_wb_all(struct inode *inode)
+{
+ NFS_WB(inode, 1);
+}
- /*
- * Iterate over all outstanding write requests,
- * looking for any that are ours..
- */
- for (;;) {
- if (!(req->wb_flags & NFS_WRITE_COMPLETE)) {
- if (!pid || req->wb_pid == pid)
- break;
- }
- req = WB_NEXT(req);
- if (req == head)
- return 0;
- }
+/*
+ * Write back all requests on one page - we do this before reading it.
+ */
+int
+nfs_wb_page(struct inode *inode, struct page *page)
+{
+ NFS_WB(inode, req->wb_page == page);
+}
- req->wb_count++;
- retval = wait_on_write_request(req);
- free_write_request(req);
- } while (!retval);
- return retval;
-}
+/*
+ * Write back all pending writes for one user..
+ */
+int
+nfs_wb_pid(struct inode *inode, pid_t pid)
+{
+ NFS_WB(inode, req->wb_pid == pid);
+}
/*
- * Flush out all dirty pages belonging to a certain user process and
- * maybe wait for the RPC calls to complete.
- *
- * Another purpose of this function is sync()ing a file range before a
- * write lock is released. This is what offset and length are for, even if
- * this isn't used by the nlm module yet.
+ * Write back everything in a specific area for locking purposes..
*/
int
-nfs_flush_dirty_pages(struct inode *inode, pid_t pid, off_t offset, off_t len)
+nfs_wb_area(struct inode *inode, off_t offset, off_t len)
+{
+ NFS_WB(inode, 1);
+}
+
+/*
+ * Write back and invalidate. Sometimes we can't leave the stuff
+ * hanging if we can't write it out.
+ */
+int
+nfs_wbinval(struct inode *inode)
+{
+ int retval = nfs_wb_all(inode);
+
+ if (retval)
+ nfs_cancel_dirty(inode,0);
+ return retval;
+}
+
+int nfs_wbinval_pid(struct inode *inode, pid_t pid)
{
- int retval = nfs_flush_pages(inode, pid, offset, len);
+ int retval = nfs_wb_pid(inode, pid);
+
if (retval)
nfs_cancel_dirty(inode,pid);
return retval;
}
void
-nfs_invalidate_pages(struct inode *inode)
+nfs_inval(struct inode *inode)
{
nfs_cancel_dirty(inode,0);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov