Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/uvm in uvn_flush(), when PGO_SYNCIO is specified then we...



details:   https://anonhg.NetBSD.org/src/rev/144960a17824
branches:  trunk
changeset: 501826:144960a17824
user:      chs <chs%NetBSD.org@localhost>
date:      Mon Jan 08 06:21:13 2001 +0000

description:
in uvn_flush(), when PGO_SYNCIO is specified then we should wait for
pending i/os to complete before returning even if PGO_CLEANIT is not
specified.  this fixes two races:

 (1) NFS write rpcs vs. setattr operations which truncate the file.
     if the truncate doesn't wait for pending writes to complete then
     a later write rpc completion can undo the effect of the truncate.
     this problem has been reported by several people.

 (2) write i/os in disk-based filesystem vs. the disk block being
     freed by a truncation, allocated to a new file, and written
     again with different data.  if the disk driver reorders the requests
     and does the second i/o first, the old data will clobber the new,
     corrupting the new file.  I haven't heard of anyone experiencing
     this problem yet, but it's fixed now anyway.

diffstat:

 sys/uvm/uvm_vnode.c |  20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)

diffs (42 lines):

diff -r 1c0d00a633f3 -r 144960a17824 sys/uvm/uvm_vnode.c
--- a/sys/uvm/uvm_vnode.c       Mon Jan 08 06:12:46 2001 +0000
+++ b/sys/uvm/uvm_vnode.c       Mon Jan 08 06:21:13 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_vnode.c,v 1.40 2000/12/16 06:17:09 chs Exp $       */
+/*     $NetBSD: uvm_vnode.c,v 1.41 2001/01/08 06:21:13 chs Exp $       */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -343,14 +343,15 @@
  * uvn_flush: flush pages out of a uvm object.
  *
  * => object should be locked by caller.   we may _unlock_ the object
- *     if (and only if) we need to clean a page (PGO_CLEANIT).
+ *     if (and only if) we need to clean a page (PGO_CLEANIT), or
+ *     if PGO_SYNCIO is set and there are pages busy.
  *     we return with the object locked.
- * => if PGO_CLEANIT is set, we may block (due to I/O).   thus, a caller
- *     might want to unlock higher level resources (e.g. vm_map)
- *     before calling flush.
- * => if PGO_CLEANIT is not set, then we will neither unlock the object
- *     or block.
- * => if PGO_ALLPAGE is set, then all pages in the object are valid targets
+ * => if PGO_CLEANIT or PGO_SYNCIO is set, we may block (due to I/O).
+ *     thus, a caller might want to unlock higher level resources
+ *     (e.g. vm_map) before calling flush.
+ * => if neither PGO_CLEANIT nor PGO_SYNCIO is set, then we will neither
+ *     unlock the object nor block.
+ * => if PGO_ALLPAGES is set, then all pages in the object are valid targets
  *     for flushing.
  * => NOTE: we rely on the fact that the object's memq is a TAILQ and
  *     that new pages are inserted on the tail end of the list.   thus,
@@ -529,8 +530,7 @@
 
                if ((flags & PGO_CLEANIT) == 0 || (pp->flags & PG_BUSY) != 0) {
                        needs_clean = FALSE;
-                       if ((flags & (PGO_CLEANIT|PGO_SYNCIO)) ==
-                                    (PGO_CLEANIT|PGO_SYNCIO))
+                       if (flags & PGO_SYNCIO)
                                need_iosync = TRUE;
                } else {
 



Home | Main Index | Thread Index | Old Index