hi, > Emmanuel Dreyfus <[email protected]> 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 > [email protected] 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;
