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