| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ffs_vnops.c,v 1.104 2008/10/10 09:21:58 hannken Exp $ */ | | 1 | /* $NetBSD: ffs_vnops.c,v 1.105 2008/12/21 10:44:32 ad Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2008 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Wasabi Systems, Inc. | | 8 | * by Wasabi Systems, Inc. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -51,27 +51,27 @@ | | | @@ -51,27 +51,27 @@ |
51 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 51 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
52 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 52 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
53 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 53 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
54 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 54 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
55 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 55 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
56 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 56 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
57 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 57 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
58 | * SUCH DAMAGE. | | 58 | * SUCH DAMAGE. |
59 | * | | 59 | * |
60 | * @(#)ffs_vnops.c 8.15 (Berkeley) 5/14/95 | | 60 | * @(#)ffs_vnops.c 8.15 (Berkeley) 5/14/95 |
61 | */ | | 61 | */ |
62 | | | 62 | |
63 | #include <sys/cdefs.h> | | 63 | #include <sys/cdefs.h> |
64 | __KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.104 2008/10/10 09:21:58 hannken Exp $"); | | 64 | __KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.105 2008/12/21 10:44:32 ad Exp $"); |
65 | | | 65 | |
66 | #if defined(_KERNEL_OPT) | | 66 | #if defined(_KERNEL_OPT) |
67 | #include "opt_ffs.h" | | 67 | #include "opt_ffs.h" |
68 | #include "opt_wapbl.h" | | 68 | #include "opt_wapbl.h" |
69 | #endif | | 69 | #endif |
70 | | | 70 | |
71 | #include <sys/param.h> | | 71 | #include <sys/param.h> |
72 | #include <sys/systm.h> | | 72 | #include <sys/systm.h> |
73 | #include <sys/resourcevar.h> | | 73 | #include <sys/resourcevar.h> |
74 | #include <sys/kernel.h> | | 74 | #include <sys/kernel.h> |
75 | #include <sys/file.h> | | 75 | #include <sys/file.h> |
76 | #include <sys/stat.h> | | 76 | #include <sys/stat.h> |
77 | #include <sys/buf.h> | | 77 | #include <sys/buf.h> |
| @@ -392,74 +392,81 @@ ffs_fsync(void *v) | | | @@ -392,74 +392,81 @@ ffs_fsync(void *v) |
392 | | | 392 | |
393 | out: | | 393 | out: |
394 | fstrans_done(vp->v_mount); | | 394 | fstrans_done(vp->v_mount); |
395 | return error; | | 395 | return error; |
396 | } | | 396 | } |
397 | | | 397 | |
398 | /* | | 398 | /* |
399 | * Synch an open file. | | 399 | * Synch an open file. |
400 | */ | | 400 | */ |
401 | /* ARGSUSED */ | | 401 | /* ARGSUSED */ |
402 | int | | 402 | int |
403 | ffs_full_fsync(struct vnode *vp, int flags) | | 403 | ffs_full_fsync(struct vnode *vp, int flags) |
404 | { | | 404 | { |
| | | 405 | extern struct vfsops ffs_vfsops; |
405 | struct buf *bp, *nbp; | | 406 | struct buf *bp, *nbp; |
406 | int error, passes, skipmeta, inodedeps_only, waitfor; | | 407 | int error, passes, skipmeta, inodedeps_only, waitfor; |
407 | struct mount *mp; | | 408 | struct mount *mp; |
| | | 409 | bool ffsino; |
408 | | | 410 | |
409 | error = 0; | | 411 | error = 0; |
410 | | | 412 | |
| | | 413 | if ((flags & FSYNC_VFS) != 0) { |
| | | 414 | KASSERT(vp->v_specmountpoint != NULL); |
| | | 415 | mp = vp->v_specmountpoint; |
| | | 416 | ffsino = (mp->mnt_op == &ffs_vfsops); |
| | | 417 | KASSERT(vp->v_type == VBLK); |
| | | 418 | } else { |
| | | 419 | mp = vp->v_mount; |
| | | 420 | ffsino = true; |
| | | 421 | KASSERT(vp->v_tag == VT_UFS); |
| | | 422 | } |
| | | 423 | |
411 | if (vp->v_type == VBLK && | | 424 | if (vp->v_type == VBLK && |
412 | vp->v_specmountpoint != NULL && | | 425 | vp->v_specmountpoint != NULL && |
413 | (vp->v_specmountpoint->mnt_flag & MNT_SOFTDEP)) | | 426 | (vp->v_specmountpoint->mnt_flag & MNT_SOFTDEP)) |
414 | softdep_fsync_mountdev(vp); | | 427 | softdep_fsync_mountdev(vp); |
415 | | | 428 | |
416 | mutex_enter(&vp->v_interlock); | | 429 | mutex_enter(&vp->v_interlock); |
417 | | | 430 | |
418 | inodedeps_only = DOINGSOFTDEP(vp) && (flags & FSYNC_RECLAIM) | | 431 | inodedeps_only = DOINGSOFTDEP(vp) && (flags & FSYNC_RECLAIM) |
419 | && UVM_OBJ_IS_CLEAN(&vp->v_uobj) && LIST_EMPTY(&vp->v_dirtyblkhd); | | 432 | && UVM_OBJ_IS_CLEAN(&vp->v_uobj) && LIST_EMPTY(&vp->v_dirtyblkhd); |
420 | | | 433 | |
421 | /* | | 434 | /* |
422 | * Flush all dirty data associated with a vnode. | | 435 | * Flush all dirty data associated with a vnode. |
423 | */ | | 436 | */ |
424 | | | 437 | |
425 | if (vp->v_type == VREG || vp->v_type == VBLK) { | | 438 | if (vp->v_type == VREG || vp->v_type == VBLK) { |
426 | int pflags = PGO_ALLPAGES | PGO_CLEANIT; | | 439 | int pflags = PGO_ALLPAGES | PGO_CLEANIT; |
427 | | | 440 | |
428 | if ((flags & FSYNC_VFS) != 0 && vp->v_specmountpoint != NULL) | | | |
429 | mp = vp->v_specmountpoint; | | | |
430 | else | | | |
431 | mp = vp->v_mount; | | | |
432 | | | | |
433 | if ((flags & FSYNC_WAIT)) | | 441 | if ((flags & FSYNC_WAIT)) |
434 | pflags |= PGO_SYNCIO; | | 442 | pflags |= PGO_SYNCIO; |
435 | if (vp->v_type == VREG && | | 443 | if (vp->v_type == VREG && |
436 | fstrans_getstate(mp) == FSTRANS_SUSPENDING) | | 444 | fstrans_getstate(mp) == FSTRANS_SUSPENDING) |
437 | pflags |= PGO_FREE; | | 445 | pflags |= PGO_FREE; |
438 | error = VOP_PUTPAGES(vp, 0, 0, pflags); | | 446 | error = VOP_PUTPAGES(vp, 0, 0, pflags); |
439 | if (error) | | 447 | if (error) |
440 | return error; | | 448 | return error; |
441 | } else { | | 449 | } else { |
442 | mp = vp->v_mount; | | | |
443 | mutex_exit(&vp->v_interlock); | | 450 | mutex_exit(&vp->v_interlock); |
444 | } | | 451 | } |
445 | | | 452 | |
446 | #ifdef WAPBL | | 453 | #ifdef WAPBL |
447 | if (mp && mp->mnt_wapbl) { | | 454 | if (mp && mp->mnt_wapbl) { |
448 | error = 0; | | 455 | error = 0; |
449 | if (flags & FSYNC_DATAONLY) | | 456 | if (flags & FSYNC_DATAONLY) |
450 | return error; | | 457 | return error; |
451 | | | 458 | |
452 | if (VTOI(vp) && (VTOI(vp)->i_flag & | | 459 | if (ffsino && VTOI(vp) && (VTOI(vp)->i_flag & |
453 | (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY | | | 460 | (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY | |
454 | IN_MODIFIED | IN_ACCESSED))) { | | 461 | IN_MODIFIED | IN_ACCESSED))) { |
455 | error = UFS_WAPBL_BEGIN(mp); | | 462 | error = UFS_WAPBL_BEGIN(mp); |
456 | if (error) | | 463 | if (error) |
457 | return error; | | 464 | return error; |
458 | error = ffs_update(vp, NULL, NULL, | | 465 | error = ffs_update(vp, NULL, NULL, |
459 | (flags & FSYNC_WAIT) ? UPDATE_WAIT : 0); | | 466 | (flags & FSYNC_WAIT) ? UPDATE_WAIT : 0); |
460 | UFS_WAPBL_END(mp); | | 467 | UFS_WAPBL_END(mp); |
461 | } | | 468 | } |
462 | if (error || (flags & FSYNC_NOLOG)) | | 469 | if (error || (flags & FSYNC_NOLOG)) |
463 | return error; | | 470 | return error; |
464 | /* | | 471 | /* |
465 | * Don't flush the log if the vnode being flushed | | 472 | * Don't flush the log if the vnode being flushed |
| @@ -559,32 +566,28 @@ loop: | | | @@ -559,32 +566,28 @@ loop: |
559 | } | | 566 | } |
560 | #ifdef DIAGNOSTIC | | 567 | #ifdef DIAGNOSTIC |
561 | if (vp->v_type != VBLK) | | 568 | if (vp->v_type != VBLK) |
562 | vprint("ffs_fsync: dirty", vp); | | 569 | vprint("ffs_fsync: dirty", vp); |
563 | #endif | | 570 | #endif |
564 | } | | 571 | } |
565 | } | | 572 | } |
566 | | | 573 | |
567 | if (inodedeps_only) | | 574 | if (inodedeps_only) |
568 | waitfor = 0; | | 575 | waitfor = 0; |
569 | else | | 576 | else |
570 | waitfor = (flags & FSYNC_WAIT) ? UPDATE_WAIT : 0; | | 577 | waitfor = (flags & FSYNC_WAIT) ? UPDATE_WAIT : 0; |
571 | | | 578 | |
572 | if (vp->v_tag == VT_UFS) | | 579 | if (ffsino) |
573 | error = ffs_update(vp, NULL, NULL, waitfor); | | 580 | error = ffs_update(vp, NULL, NULL, waitfor); |
574 | else { | | | |
575 | KASSERT(vp->v_type == VBLK); | | | |
576 | KASSERT((flags & FSYNC_VFS) != 0); | | | |
577 | } | | | |
578 | | | 581 | |
579 | if (error == 0 && flags & FSYNC_CACHE) { | | 582 | if (error == 0 && flags & FSYNC_CACHE) { |
580 | int i = 0; | | 583 | int i = 0; |
581 | if ((flags & FSYNC_VFS) == 0) { | | 584 | if ((flags & FSYNC_VFS) == 0) { |
582 | KASSERT(VTOI(vp) != NULL); | | 585 | KASSERT(VTOI(vp) != NULL); |
583 | vp = VTOI(vp)->i_devvp; | | 586 | vp = VTOI(vp)->i_devvp; |
584 | } | | 587 | } |
585 | VOP_IOCTL(vp, DIOCCACHESYNC, &i, FWRITE, curlwp->l_cred); | | 588 | VOP_IOCTL(vp, DIOCCACHESYNC, &i, FWRITE, curlwp->l_cred); |
586 | } | | 589 | } |
587 | | | 590 | |
588 | return error; | | 591 | return error; |
589 | } | | 592 | } |
590 | | | 593 | |