tech-kern archive

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

Re: zero-filed page on VOP_PUTPAGES



hi,

> Emmanuel Dreyfus <manu%netbsd.org@localhost> wrote:
> 
>> That is not something like this: it occurs at offsets as low as 16384,
>> and there is always valid data after the zeroed chunk.
> 
> I think I found the culprit: VOP_FSYNC cause a call do dosettattr, which
> sends the SETATTR message. I never noticed that the file size was set
> from the filesystem value on completion, using uvm_vnp_setsize(). If
> write operations have been sent before the VOP_FSYNC and are not yet
> completed, the size is set to a smaller value than the right one, and
> the ongoing writes are discarded.
> 
> So you were right, Pooka, this was again a file size in distributed
> filesystem problem.

i found the following patch in my tree.
unfortunately i forgot details and if there were more cases which needs
similar barriers.

YAMAMOTO Takashi

> 
> -- 
> Emmanuel Dreyfus
> http://hcpnet.free.fr/pubz
> manu%netbsd.org@localhost

Index: puffs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/puffs/puffs_vnops.c,v
retrieving revision 1.154
diff -u -p -r1.154 puffs_vnops.c
--- puffs_vnops.c       4 Jul 2011 08:07:30 -0000       1.154
+++ puffs_vnops.c       16 Aug 2011 02:47:02 -0000
@@ -931,9 +931,26 @@ dosetattr(struct vnode *vp, struct vattr
                    && vap->va_size == VNOVAL)
                        vap->va_size = pn->pn_mc_size;
 
-               pn->pn_stat &= ~PNODE_METACACHE_MASK;
        }
 
+       /*
+        * ensure that any write requests, which can modify the size and
+        * timestamps, complete.
+        */
+       if (vap->va_size != VNOVAL) {
+               if (flags & SETATTR_CHSIZE)
+                       uvm_vnp_setsize(vp, vap->va_size);
+       }
+       if (vap->va_mtime.tv_sec != VNOVAL) {
+               mutex_enter(vp->v_interlock);
+               error = VOP_PUTPAGES(vp, 0, 0, PGO_CLEANIT | PGO_SYNCIO);
+               if (error != 0) {
+                       return error;
+               }
+       }
+
+       pn->pn_stat &= ~PNODE_METACACHE_MASK;
+
        PUFFS_MSG_ALLOC(vn, setattr);
        (void)memcpy(&setattr_msg->pvnr_va, vap, sizeof(struct vattr));
        puffs_credcvt(&setattr_msg->pvnr_cred, cred);
@@ -956,8 +973,6 @@ dosetattr(struct vnode *vp, struct vattr
 
        if (vap->va_size != VNOVAL) {
                pn->pn_serversize = vap->va_size;
-               if (flags & SETATTR_CHSIZE)
-                       uvm_vnp_setsize(vp, vap->va_size);
        }
 
        return 0;


Home | Main Index | Thread Index | Old Index