patch-2.1.61 linux/fs/nfs/write.c
Next file: linux/fs/nls/Config.in
Previous file: linux/fs/nfs/inode.c
Back to the patch index
Back to the overall index
- Lines: 164
- Date:
Wed Oct 29 14:07:39 1997
- Orig file:
v2.1.60/linux/fs/nfs/write.c
- Orig date:
Sat Oct 25 02:44:17 1997
diff -u --recursive --new-file v2.1.60/linux/fs/nfs/write.c linux/fs/nfs/write.c
@@ -286,16 +286,17 @@
* Find a failed write request by pid
*/
static struct nfs_wreq *
-find_failed_request(struct inode *inode, pid_t pid, int all)
+find_failed_request(struct inode *inode, pid_t pid)
{
struct nfs_wreq *head, *req;
- if (!(req = head = nfs_failed_requests))
- return NULL;
- do {
- if (req->wb_inode == inode && (all || req->wb_pid == pid))
+ req = head = nfs_failed_requests;
+ while (req != NULL) {
+ if (req->wb_inode == inode && (pid == 0 || req->wb_pid == pid))
return req;
- } while ((req = WB_NEXT(req)) != head);
+ if ((req = WB_NEXT(req)) == head)
+ break;
+ }
return NULL;
}
@@ -335,7 +336,7 @@
struct nfs_wreq * req;
int found = 0;
- while ((req = find_failed_request(inode, 0, 1)) != NULL) {
+ while ((req = find_failed_request(inode, 0)) != NULL) {
remove_failed_request(req);
found++;
}
@@ -561,12 +562,13 @@
}
/* Create the write request. */
- if (!(req = create_write_request(inode, page, offset, count))) {
- status = -ENOBUFS;
+ status = -ENOBUFS;
+ req = create_write_request(inode, page, offset, count);
+ if (!req)
goto done;
- }
/* Copy data to page buffer. */
+ /* N.B. should check for fault here ... */
copy_from_user(page_addr + offset, buffer, count);
/* Schedule request */
@@ -593,6 +595,7 @@
transfer_page_lock(req);
/* rpc_execute(&req->wb_task); */
if (sync) {
+ /* N.B. if signalled, result not ready? */
wait_on_write_request(req);
if ((count = nfs_write_error(inode)) < 0)
status = count;
@@ -652,10 +655,20 @@
if (rqoffset < end && offset < rqend
&& (pid == 0 || req->wb_pid == pid)) {
- if (!WB_HAVELOCK(req))
+ if (!WB_HAVELOCK(req)) {
+#ifdef NFS_PARANOIA
+printk("nfs_flush: flushing inode=%ld, %d @ %lu\n",
+req->wb_inode->i_ino, req->wb_bytes, rqoffset);
+#endif
nfs_flush_request(req);
+ }
last = req;
}
+ } else {
+#ifdef NFS_PARANOIA
+printk("nfs_flush_pages: in progress inode=%ld, %d @ %lu\n",
+req->wb_inode->i_ino, req->wb_bytes, rqoffset);
+#endif
}
if (invalidate)
req->wb_flags |= NFS_WRITE_INVALIDATE;
@@ -668,6 +681,10 @@
/*
* Cancel all writeback requests, both pending and in progress.
+ *
+ * N.B. This doesn't seem to wake up the tasks -- are we sure
+ * they will eventually complete? Also, this could overwrite a
+ * failed status code from an already-completed task.
*/
static void
nfs_cancel_dirty(struct inode *inode, pid_t pid)
@@ -676,7 +693,8 @@
req = head = NFS_WRITEBACK(inode);
while (req != NULL) {
- if (req->wb_pid == pid) {
+ /* N.B. check for task already finished? */
+ if (pid == 0 || req->wb_pid == pid) {
req->wb_flags |= NFS_WRITE_CANCELLED;
rpc_exit(&req->wb_task, 0);
}
@@ -694,24 +712,30 @@
* this isn't used by the nlm module yet.
*/
int
-nfs_flush_dirty_pages(struct inode *inode, off_t offset, off_t len)
+nfs_flush_dirty_pages(struct inode *inode, pid_t pid, off_t offset, off_t len)
{
struct nfs_wreq *last = NULL;
- int result = 0;
+ int result = 0, cancel = 0;
dprintk("NFS: flush_dirty_pages(%x/%ld for pid %d %ld/%ld)\n",
inode->i_dev, inode->i_ino, current->pid,
offset, len);
+ if (IS_SOFT && signalled()) {
+ nfs_cancel_dirty(inode, pid);
+ cancel = 1;
+ }
+
for (;;) {
if (IS_SOFT && signalled()) {
- nfs_cancel_dirty(inode, current->pid);
+ if (!cancel)
+ nfs_cancel_dirty(inode, pid);
result = -ERESTARTSYS;
break;
}
- /* Flush all pending writes for this pid and file region */
- last = nfs_flush_pages(inode, current->pid, offset, len, 0);
+ /* Flush all pending writes for the pid and file region */
+ last = nfs_flush_pages(inode, pid, offset, len, 0);
if (last == NULL)
break;
wait_on_write_request(last);
@@ -724,7 +748,7 @@
* Flush out any pending write requests and flag that they be discarded
* after the write is complete.
*
- * This function is called from nfs_revalidate_inode just before it calls
+ * This function is called from nfs_refresh_inode just before it calls
* invalidate_inode_pages. After nfs_flush_pages returns, we can be sure
* that all dirty pages are locked, so that invalidate_inode_pages does
* not throw away any dirty pages.
@@ -780,7 +804,7 @@
dprintk("nfs: checking for write error inode %04x/%ld\n",
inode->i_dev, inode->i_ino);
- req = find_failed_request(inode, current->pid, 0);
+ req = find_failed_request(inode, current->pid);
if (req) {
dprintk("nfs: write error %d inode %04x/%ld\n",
req->wb_task.tk_status, inode->i_dev, inode->i_ino);
@@ -869,7 +893,7 @@
* application by adding the request to the failed
* requests list.
*/
- if (find_failed_request(inode, req->wb_pid, 0))
+ if (find_failed_request(inode, req->wb_pid))
status = 0;
clear_bit(PG_uptodate, &page->flags);
} else if (!WB_CANCELLED(req)) {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov