Mon Sep 14 21:10:44 2009 UTC ()
Rework simplistic UBC flushing. Recent changes to genfs made the old flush
system generate heaps of odd allocations since the end of write request was
overwritten by the start of the second resulting in another relocation.

Also added a full flush of the file on a VOP_CLOSE(). This automatically
flushes file tails to disc.


(reinoud)
diff -r1.54 -r1.55 src/sys/fs/udf/udf_vnops.c

cvs diff -r1.54 -r1.55 src/sys/fs/udf/udf_vnops.c (expand / switch to unified diff)

--- src/sys/fs/udf/udf_vnops.c 2009/07/30 12:13:51 1.54
+++ src/sys/fs/udf/udf_vnops.c 2009/09/14 21:10:44 1.55
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: udf_vnops.c,v 1.54 2009/07/30 12:13:51 reinoud Exp $ */ 1/* $NetBSD: udf_vnops.c,v 1.55 2009/09/14 21:10:44 reinoud Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006, 2008 Reinoud Zandijk 4 * Copyright (c) 2006, 2008 Reinoud Zandijk
5 * All rights reserved. 5 * All rights reserved.
6 *  6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -22,27 +22,27 @@ @@ -22,27 +22,27 @@
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *  26 *
27 * Generic parts are derived from software contributed to The NetBSD Foundation 27 * Generic parts are derived from software contributed to The NetBSD Foundation
28 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code 28 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code
29 * 2005 program. 29 * 2005 program.
30 * 30 *
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34#ifndef lint 34#ifndef lint
35__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.54 2009/07/30 12:13:51 reinoud Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.55 2009/09/14 21:10:44 reinoud Exp $");
36#endif /* not lint */ 36#endif /* not lint */
37 37
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/systm.h> 40#include <sys/systm.h>
41#include <sys/namei.h> 41#include <sys/namei.h>
42#include <sys/resourcevar.h> /* defines plimit structure in proc struct */ 42#include <sys/resourcevar.h> /* defines plimit structure in proc struct */
43#include <sys/kernel.h> 43#include <sys/kernel.h>
44#include <sys/file.h> /* define FWRITE ... */ 44#include <sys/file.h> /* define FWRITE ... */
45#include <sys/stat.h> 45#include <sys/stat.h>
46#include <sys/buf.h> 46#include <sys/buf.h>
47#include <sys/proc.h> 47#include <sys/proc.h>
48#include <sys/mount.h> 48#include <sys/mount.h>
@@ -354,36 +354,34 @@ udf_write(void *v) @@ -354,36 +354,34 @@ udf_write(void *v)
354 if (error) 354 if (error)
355 break; 355 break;
356 356
357 /* ubc, here we come, prepare to trap */ 357 /* ubc, here we come, prepare to trap */
358 error = ubc_uiomove(uobj, uio, len, advice, 358 error = ubc_uiomove(uobj, uio, len, advice,
359 UBC_WRITE | UBC_UNMAP_FLAG(vp)); 359 UBC_WRITE | UBC_UNMAP_FLAG(vp));
360 if (error) 360 if (error)
361 break; 361 break;
362 362
363 /* 363 /*
364 * flush what we just wrote if necessary. 364 * flush what we just wrote if necessary.
365 * XXXUBC simplistic async flushing. 365 * XXXUBC simplistic async flushing.
366 * 366 *
367 * this one works on page sizes. Directories are excluded 367 * Directories are excluded since its file data that we want
368 * since its file data that we want to purge. 368 * to purge.
369 */ 369 */
370 if (!async && (vp->v_type != VDIR) && 370 if (!async && (vp->v_type != VDIR) &&
371 (uio->uio_offset - old_offset >= PAGE_SIZE)) { 371 (old_offset >> 16 != uio->uio_offset >> 16)) {
372 mutex_enter(&vp->v_interlock); 372 mutex_enter(&vp->v_interlock);
373 error = VOP_PUTPAGES(vp, 373 error = VOP_PUTPAGES(vp, (old_offset >> 16) << 16,
374 ptoa(atop(old_offset)), 374 (uio->uio_offset >> 16) << 16, PGO_CLEANIT);
375 ptoa(atop(uio->uio_offset + PAGE_SIZE-1)), 
376 PGO_CLEANIT); 
377 old_offset = uio->uio_offset; 375 old_offset = uio->uio_offset;
378 } 376 }
379 } 377 }
380 uvm_vnp_setsize(vp, file_size); 378 uvm_vnp_setsize(vp, file_size);
381 379
382 /* mark node changed and request update */ 380 /* mark node changed and request update */
383 udf_node->i_flags |= IN_CHANGE | IN_UPDATE; 381 udf_node->i_flags |= IN_CHANGE | IN_UPDATE;
384 382
385 /* 383 /*
386 * XXX TODO FFS has code here to reset setuid & setgid when we're not 384 * XXX TODO FFS has code here to reset setuid & setgid when we're not
387 * the superuser as a precaution against tampering. 385 * the superuser as a precaution against tampering.
388 */ 386 */
389 387
@@ -1287,30 +1285,39 @@ udf_open(void *v) @@ -1287,30 +1285,39 @@ udf_open(void *v)
1287/* --------------------------------------------------------------------- */ 1285/* --------------------------------------------------------------------- */
1288 1286
1289int 1287int
1290udf_close(void *v) 1288udf_close(void *v)
1291{ 1289{
1292 struct vop_close_args /* { 1290 struct vop_close_args /* {
1293 struct vnode *a_vp; 1291 struct vnode *a_vp;
1294 int a_fflag; 1292 int a_fflag;
1295 kauth_cred_t a_cred; 1293 kauth_cred_t a_cred;
1296 struct proc *a_p; 1294 struct proc *a_p;
1297 } */ *ap = v; 1295 } */ *ap = v;
1298 struct vnode *vp = ap->a_vp; 1296 struct vnode *vp = ap->a_vp;
1299 struct udf_node *udf_node = VTOI(vp); 1297 struct udf_node *udf_node = VTOI(vp);
 1298 int async = vp->v_mount->mnt_flag & MNT_ASYNC;
 1299 int error;
1300 1300
1301 DPRINTF(CALL, ("udf_close called\n")); 1301 DPRINTF(CALL, ("udf_close called\n"));
1302 udf_node = udf_node; /* shut up gcc */ 1302 udf_node = udf_node; /* shut up gcc */
1303 1303
 1304 if (!async && (vp->v_type != VDIR)) {
 1305 mutex_enter(&vp->v_interlock);
 1306 error = VOP_PUTPAGES(vp, 0, 0, PGO_CLEANIT);
 1307 if (error)
 1308 return error;
 1309 }
 1310
1304 mutex_enter(&vp->v_interlock); 1311 mutex_enter(&vp->v_interlock);
1305 if (vp->v_usecount > 1) 1312 if (vp->v_usecount > 1)
1306 udf_itimes(udf_node, NULL, NULL, NULL); 1313 udf_itimes(udf_node, NULL, NULL, NULL);
1307 mutex_exit(&vp->v_interlock); 1314 mutex_exit(&vp->v_interlock);
1308 1315
1309 return 0; 1316 return 0;
1310} 1317}
1311 1318
1312 1319
1313/* --------------------------------------------------------------------- */ 1320/* --------------------------------------------------------------------- */
1314 1321
1315static int 1322static int
1316udf_check_possible(struct vnode *vp, struct vattr *vap, mode_t mode) 1323udf_check_possible(struct vnode *vp, struct vattr *vap, mode_t mode)