| 3459 | #endif |
| 3460 | |
| 3461 | int |
| 3462 | kern_fsync(struct thread *td, int fd, bool fullsync) |
| 3463 | { |
| 3464 | struct vnode *vp; |
| 3465 | struct mount *mp; |
| 3466 | struct file *fp; |
| 3467 | int error, lock_flags; |
| 3468 | |
| 3469 | AUDIT_ARG_FD(fd); |
| 3470 | error = getvnode(td, fd, &cap_fsync_rights, &fp); |
| 3471 | if (error != 0) |
| 3472 | return (error); |
| 3473 | vp = fp->f_vnode; |
| 3474 | #if 0 |
| 3475 | if (!fullsync) |
| 3476 | /* XXXKIB: compete outstanding aio writes */; |
| 3477 | #endif |
| 3478 | retry: |
| 3479 | error = vn_start_write(vp, &mp, V_WAIT | PCATCH); |
| 3480 | if (error != 0) |
| 3481 | goto drop; |
| 3482 | if (MNT_SHARED_WRITES(mp) || |
| 3483 | ((mp == NULL) && MNT_SHARED_WRITES(vp->v_mount))) { |
| 3484 | lock_flags = LK_SHARED; |
| 3485 | } else { |
| 3486 | lock_flags = LK_EXCLUSIVE; |
| 3487 | } |
| 3488 | vn_lock(vp, lock_flags | LK_RETRY); |
| 3489 | AUDIT_ARG_VNODE1(vp); |
| 3490 | if (vp->v_object != NULL) { |
| 3491 | VM_OBJECT_WLOCK(vp->v_object); |
| 3492 | vm_object_page_clean(vp->v_object, 0, 0, 0); |
| 3493 | VM_OBJECT_WUNLOCK(vp->v_object); |
| 3494 | } |
| 3495 | error = fullsync ? VOP_FSYNC(vp, MNT_WAIT, td) : VOP_FDATASYNC(vp, td); |
| 3496 | VOP_UNLOCK(vp); |
| 3497 | vn_finished_write(mp); |
| 3498 | if (error == ERELOOKUP) |
| 3499 | goto retry; |
| 3500 | drop: |
| 3501 | fdrop(fp, td); |
| 3502 | return (error); |
| 3503 | } |
| 3504 | |
| 3505 | /* |
| 3506 | * Sync an open file. |
no test coverage detected