1159451Srodrigc/* 2159451Srodrigc * Copyright (c) 2001,2006 Alexander Kabaev, Russell Cattelan Digital Elves Inc. 3159451Srodrigc * All rights reserved. 4159451Srodrigc * 5159451Srodrigc * Redistribution and use in source and binary forms, with or without 6159451Srodrigc * modification, are permitted provided that the following conditions 7159451Srodrigc * are met: 8159451Srodrigc * 1. Redistributions of source code must retain the above copyright 9159451Srodrigc * notice, this list of conditions and the following disclaimer. 10159451Srodrigc * 2. Redistributions in binary form must reproduce the above copyright 11159451Srodrigc * notice, this list of conditions and the following disclaimer in the 12159451Srodrigc * documentation and/or other materials provided with the distribution. 13159451Srodrigc * 14159451Srodrigc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15159451Srodrigc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16159451Srodrigc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17159451Srodrigc * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18159451Srodrigc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19159451Srodrigc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20159451Srodrigc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21159451Srodrigc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22159451Srodrigc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23159451Srodrigc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24159451Srodrigc * SUCH DAMAGE. 25159451Srodrigc * 26159451Srodrigc * $FreeBSD$ 27159451Srodrigc */ 28159451Srodrigc 29153323Srodrigc#include <sys/param.h> 30153323Srodrigc#include <sys/systm.h> 31153323Srodrigc#include <sys/kernel.h> 32153323Srodrigc#include <sys/proc.h> 33153323Srodrigc#include <sys/malloc.h> 34153323Srodrigc#include <sys/vnode.h> 35153323Srodrigc#include <sys/mount.h> 36153323Srodrigc#include <sys/namei.h> 37153323Srodrigc 38153323Srodrigc#include <geom/geom.h> 39153323Srodrigc#include <geom/geom_vfs.h> 40153323Srodrigc 41153323Srodrigc#include "xfs.h" 42153323Srodrigc#include "xfs_types.h" 43159451Srodrigc#include "xfs_bit.h" 44153323Srodrigc#include "xfs_inum.h" 45153323Srodrigc#include "xfs_log.h" 46153323Srodrigc#include "xfs_trans.h" 47153323Srodrigc#include "xfs_sb.h" 48153323Srodrigc#include "xfs_ag.h" 49153323Srodrigc#include "xfs_dir.h" 50153323Srodrigc#include "xfs_dir2.h" 51153323Srodrigc#include "xfs_dmapi.h" 52153323Srodrigc#include "xfs_mount.h" 53153323Srodrigc#include "xfs_alloc_btree.h" 54153323Srodrigc#include "xfs_bmap_btree.h" 55153323Srodrigc#include "xfs_ialloc_btree.h" 56153323Srodrigc#include "xfs_btree.h" 57153323Srodrigc#include "xfs_attr_sf.h" 58153323Srodrigc#include "xfs_dir_sf.h" 59153323Srodrigc#include "xfs_dir2_sf.h" 60153323Srodrigc#include "xfs_dinode.h" 61159451Srodrigc#include "xfs_ialloc.h" 62153323Srodrigc#include "xfs_inode.h" 63153323Srodrigc#include "xfs_alloc.h" 64153323Srodrigc#include "xfs_rtalloc.h" 65153323Srodrigc#include "xfs_bmap.h" 66153323Srodrigc#include "xfs_error.h" 67153323Srodrigc#include "xfs_rw.h" 68153323Srodrigc#include "xfs_quota.h" 69153323Srodrigc#include "xfs_fsops.h" 70153323Srodrigc#include "xfs_clnt.h" 71153323Srodrigc 72153323Srodrigc#include <xfs_mountops.h> 73153323Srodrigc 74249132Smavstatic MALLOC_DEFINE(M_XFSNODE, "XFS node", "XFS vnode private part"); 75153323Srodrigc 76153323Srodrigcstatic vfs_mount_t _xfs_mount; 77153323Srodrigcstatic vfs_unmount_t _xfs_unmount; 78153323Srodrigcstatic vfs_root_t _xfs_root; 79153323Srodrigcstatic vfs_quotactl_t _xfs_quotactl; 80153323Srodrigcstatic vfs_statfs_t _xfs_statfs; 81153323Srodrigcstatic vfs_sync_t _xfs_sync; 82153323Srodrigcstatic vfs_vget_t _xfs_vget; 83153323Srodrigcstatic vfs_fhtovp_t _xfs_fhtovp; 84153323Srodrigcstatic vfs_init_t _xfs_init; 85153323Srodrigcstatic vfs_uninit_t _xfs_uninit; 86153323Srodrigcstatic vfs_extattrctl_t _xfs_extattrctl; 87153323Srodrigc 88153323Srodrigcstatic b_strategy_t xfs_geom_strategy; 89153323Srodrigc 90153323Srodrigcstatic const char *xfs_opts[] = 91153323Srodrigc { "from", "flags", "logbufs", "logbufsize", 92153323Srodrigc "rtname", "logname", "iosizelog", "sunit", 93158953Srodrigc "swidth", "export", 94153323Srodrigc NULL }; 95153323Srodrigc 96153323Srodrigcstatic void 97153323Srodrigcparse_int(struct mount *mp, const char *opt, int *val, int *error) 98153323Srodrigc{ 99153323Srodrigc char *tmp, *ep; 100153323Srodrigc 101153323Srodrigc tmp = vfs_getopts(mp->mnt_optnew, opt, error); 102153323Srodrigc if (*error != 0) { 103153323Srodrigc return; 104153323Srodrigc } 105153323Srodrigc if (tmp != NULL) { 106153323Srodrigc *val = (int)strtol(tmp, &ep, 10); 107153323Srodrigc if (*ep) { 108153323Srodrigc *error = EINVAL; 109153323Srodrigc return; 110153323Srodrigc } 111153323Srodrigc } 112153323Srodrigc} 113153323Srodrigc 114153323Srodrigcstatic int 115153323Srodrigc_xfs_param_copyin(struct mount *mp, struct thread *td) 116153323Srodrigc{ 117153323Srodrigc struct xfsmount *xmp = MNTTOXFS(mp); 118153323Srodrigc struct xfs_mount_args *args = &xmp->m_args; 119153323Srodrigc char *path; 120153323Srodrigc char *fsname; 121153323Srodrigc char *rtname; 122153323Srodrigc char *logname; 123153323Srodrigc int error; 124153323Srodrigc 125153323Srodrigc path = vfs_getopts(mp->mnt_optnew, "fspath", &error); 126153323Srodrigc if (error) 127153323Srodrigc return (error); 128153323Srodrigc 129153323Srodrigc bzero(args, sizeof(struct xfs_mount_args)); 130153323Srodrigc args->logbufs = -1; 131153323Srodrigc args->logbufsize = -1; 132153323Srodrigc 133153323Srodrigc parse_int(mp, "flags", &args->flags, &error); 134171905Scognet if (error != 0 && error != ENOENT) 135153323Srodrigc return error; 136153323Srodrigc 137153323Srodrigc args->flags |= XFSMNT_32BITINODES; 138153323Srodrigc 139153323Srodrigc parse_int(mp, "sunit", &args->sunit, &error); 140171905Scognet if (error != 0 && error != ENOENT) 141153323Srodrigc return error; 142153323Srodrigc 143153323Srodrigc parse_int(mp, "swidth", &args->swidth, &error); 144171905Scognet if (error != 0 && error != ENOENT) 145153323Srodrigc return error; 146153323Srodrigc 147153323Srodrigc parse_int(mp, "logbufs", &args->logbufs, &error); 148171905Scognet if (error != 0 && error != ENOENT) 149153323Srodrigc return error; 150153323Srodrigc 151153323Srodrigc parse_int(mp, "logbufsize", &args->logbufsize, &error); 152171905Scognet if (error != 0 && error != ENOENT) 153153323Srodrigc return error; 154153323Srodrigc 155153323Srodrigc fsname = vfs_getopts(mp->mnt_optnew, "from", &error); 156153323Srodrigc if (error == 0 && fsname != NULL) { 157153323Srodrigc strncpy(args->fsname, fsname, sizeof(args->fsname) - 1); 158153323Srodrigc } 159153323Srodrigc 160153323Srodrigc logname = vfs_getopts(mp->mnt_optnew, "logname", &error); 161153323Srodrigc if (error == 0 && logname != NULL) { 162153323Srodrigc strncpy(args->logname, logname, sizeof(args->logname) - 1); 163153323Srodrigc } 164153323Srodrigc 165153323Srodrigc rtname = vfs_getopts(mp->mnt_optnew, "rtname", &error); 166153323Srodrigc if (error == 0 && rtname != NULL) { 167153323Srodrigc strncpy(args->rtname, rtname, sizeof(args->rtname) - 1); 168153323Srodrigc } 169153323Srodrigc 170153323Srodrigc strncpy(args->mtpt, path, sizeof(args->mtpt)); 171153323Srodrigc 172153323Srodrigc printf("fsname '%s' logname '%s' rtname '%s'\n" 173153323Srodrigc "flags 0x%x sunit %d swidth %d logbufs %d logbufsize %d\n", 174153323Srodrigc args->fsname, args->logname, args->rtname, args->flags, 175153323Srodrigc args->sunit, args->swidth, args->logbufs, args->logbufsize); 176153323Srodrigc 177153323Srodrigc vfs_mountedfrom(mp, args->fsname); 178153323Srodrigc 179153323Srodrigc return (0); 180153323Srodrigc} 181153323Srodrigc 182153323Srodrigcstatic int 183191990Sattilio_xfs_mount(struct mount *mp) 184153323Srodrigc{ 185153323Srodrigc struct xfsmount *xmp; 186153323Srodrigc struct xfs_vnode *rootvp; 187153323Srodrigc struct ucred *curcred; 188159489Srodrigc struct vnode *rvp, *devvp; 189153323Srodrigc struct cdev *ddev; 190159489Srodrigc struct g_consumer *cp; 191191990Sattilio struct thread *td; 192153323Srodrigc int error; 193159489Srodrigc 194191990Sattilio td = curthread; 195159489Srodrigc ddev = NULL; 196159489Srodrigc cp = NULL; 197153323Srodrigc 198153323Srodrigc if (vfs_filteropt(mp->mnt_optnew, xfs_opts)) 199153323Srodrigc return (EINVAL); 200153323Srodrigc 201159451Srodrigc if (mp->mnt_flag & MNT_UPDATE) 202159451Srodrigc return (0); 203180682Sattilio if ((mp->mnt_flag & MNT_RDONLY) == 0) 204180682Sattilio return (EPERM); 205158953Srodrigc 206153323Srodrigc xmp = xfsmount_allocate(mp); 207153323Srodrigc if (xmp == NULL) 208153323Srodrigc return (ENOMEM); 209153323Srodrigc 210153323Srodrigc if((error = _xfs_param_copyin(mp, td)) != 0) 211153323Srodrigc goto fail; 212153323Srodrigc 213153323Srodrigc curcred = td->td_ucred; 214153323Srodrigc XVFS_MOUNT(XFSTOVFS(xmp), &xmp->m_args, curcred, error); 215153323Srodrigc if (error) 216153323Srodrigc goto fail; 217153323Srodrigc 218153323Srodrigc XVFS_ROOT(XFSTOVFS(xmp), &rootvp, error); 219159489Srodrigc ddev = XFS_VFSTOM(XFSTOVFS(xmp))->m_ddev_targp->dev; 220159489Srodrigc devvp = XFS_VFSTOM(XFSTOVFS(xmp))->m_ddev_targp->specvp; 221153323Srodrigc if (error) 222153323Srodrigc goto fail_unmount; 223153323Srodrigc 224153323Srodrigc if (ddev->si_iosize_max != 0) 225153323Srodrigc mp->mnt_iosize_max = ddev->si_iosize_max; 226153323Srodrigc if (mp->mnt_iosize_max > MAXPHYS) 227153323Srodrigc mp->mnt_iosize_max = MAXPHYS; 228153323Srodrigc 229159451Srodrigc mp->mnt_flag |= MNT_LOCAL; 230153323Srodrigc mp->mnt_stat.f_fsid.val[0] = dev2udev(ddev); 231153323Srodrigc mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; 232153323Srodrigc 233191990Sattilio if ((error = VFS_STATFS(mp, &mp->mnt_stat)) != 0) 234153323Srodrigc goto fail_unmount; 235153323Srodrigc 236153323Srodrigc rvp = rootvp->v_vnode; 237153323Srodrigc rvp->v_vflag |= VV_ROOT; 238153323Srodrigc VN_RELE(rootvp); 239153323Srodrigc 240153323Srodrigc return (0); 241153323Srodrigc 242153323Srodrigc fail_unmount: 243153323Srodrigc XVFS_UNMOUNT(XFSTOVFS(xmp), 0, curcred, error); 244153323Srodrigc 245159489Srodrigc if (devvp != NULL) { 246159489Srodrigc cp = devvp->v_bufobj.bo_private; 247159489Srodrigc if (cp != NULL) { 248159489Srodrigc DROP_GIANT(); 249159489Srodrigc g_topology_lock(); 250183754Sattilio g_vfs_close(cp); 251159489Srodrigc g_topology_unlock(); 252159489Srodrigc PICKUP_GIANT(); 253159489Srodrigc } 254159489Srodrigc } 255159489Srodrigc 256153323Srodrigc fail: 257153323Srodrigc if (xmp != NULL) 258153323Srodrigc xfsmount_deallocate(xmp); 259153323Srodrigc 260153323Srodrigc return (error); 261153323Srodrigc} 262153323Srodrigc 263153323Srodrigc/* 264153323Srodrigc * Free reference to null layer 265153323Srodrigc */ 266153323Srodrigcstatic int 267191990Sattilio_xfs_unmount(mp, mntflags) 268153323Srodrigc struct mount *mp; 269153323Srodrigc int mntflags; 270153323Srodrigc{ 271159489Srodrigc struct vnode *devvp; 272159489Srodrigc struct g_consumer *cp; 273153323Srodrigc int error; 274159489Srodrigc cp = NULL; 275159489Srodrigc devvp = NULL; 276153323Srodrigc 277159489Srodrigc devvp = XFS_VFSTOM((MNTTOVFS(mp)))->m_ddev_targp->specvp; 278159489Srodrigc if (devvp != NULL) 279159489Srodrigc cp = devvp->v_bufobj.bo_private; 280159489Srodrigc 281191990Sattilio XVFS_UNMOUNT(MNTTOVFS(mp), 0, curthread->td_ucred, error); 282159489Srodrigc if (error == 0) { 283159489Srodrigc if (cp != NULL) { 284159489Srodrigc DROP_GIANT(); 285159489Srodrigc g_topology_lock(); 286183754Sattilio g_vfs_close(cp); 287159489Srodrigc g_topology_unlock(); 288159489Srodrigc PICKUP_GIANT(); 289159489Srodrigc } 290159489Srodrigc } 291153323Srodrigc return (error); 292153323Srodrigc} 293153323Srodrigc 294153323Srodrigcstatic int 295191990Sattilio_xfs_root(mp, flags, vpp) 296153323Srodrigc struct mount *mp; 297153323Srodrigc int flags; 298153323Srodrigc struct vnode **vpp; 299153323Srodrigc{ 300153323Srodrigc xfs_vnode_t *vp; 301153323Srodrigc int error; 302153323Srodrigc 303153323Srodrigc XVFS_ROOT(MNTTOVFS(mp), &vp, error); 304153323Srodrigc if (error == 0) { 305153323Srodrigc *vpp = vp->v_vnode; 306175294Sattilio VOP_LOCK(*vpp, flags); 307153323Srodrigc } 308153323Srodrigc return (error); 309153323Srodrigc} 310153323Srodrigc 311153323Srodrigcstatic int 312191990Sattilio_xfs_quotactl(mp, cmd, uid, arg) 313153323Srodrigc struct mount *mp; 314153323Srodrigc int cmd; 315153323Srodrigc uid_t uid; 316153400Sdes void *arg; 317153323Srodrigc{ 318153323Srodrigc printf("xfs_quotactl\n"); 319159451Srodrigc return EOPNOTSUPP; 320153323Srodrigc} 321153323Srodrigc 322153323Srodrigcstatic int 323191990Sattilio_xfs_statfs(mp, sbp) 324153323Srodrigc struct mount *mp; 325153323Srodrigc struct statfs *sbp; 326153323Srodrigc{ 327153323Srodrigc int error; 328153323Srodrigc 329153323Srodrigc XVFS_STATVFS(MNTTOVFS(mp), sbp, NULL, error); 330153323Srodrigc if (error) 331153323Srodrigc return error; 332153323Srodrigc 333153323Srodrigc /* Fix up the values XFS statvfs calls does not know about. */ 334153323Srodrigc sbp->f_iosize = sbp->f_bsize; 335153323Srodrigc 336153323Srodrigc return (error); 337153323Srodrigc} 338153323Srodrigc 339153323Srodrigcstatic int 340191990Sattilio_xfs_sync(mp, waitfor) 341153323Srodrigc struct mount *mp; 342153323Srodrigc int waitfor; 343153323Srodrigc{ 344153323Srodrigc int error; 345153323Srodrigc int flags = SYNC_FSDATA|SYNC_ATTR|SYNC_REFCACHE; 346153323Srodrigc 347153323Srodrigc if (waitfor == MNT_WAIT) 348153323Srodrigc flags |= SYNC_WAIT; 349153323Srodrigc else if (waitfor == MNT_LAZY) 350153323Srodrigc flags |= SYNC_BDFLUSH; 351191990Sattilio XVFS_SYNC(MNTTOVFS(mp), flags, curthread->td_ucred, error); 352153323Srodrigc return (error); 353153323Srodrigc} 354153323Srodrigc 355153323Srodrigcstatic int 356153323Srodrigc_xfs_vget(mp, ino, flags, vpp) 357153323Srodrigc struct mount *mp; 358153323Srodrigc ino_t ino; 359153323Srodrigc int flags; 360153323Srodrigc struct vnode **vpp; 361153323Srodrigc{ 362170124Skan xfs_vnode_t *vp = NULL; 363153323Srodrigc int error; 364153323Srodrigc 365153323Srodrigc printf("XVFS_GET_VNODE(MNTTOVFS(mp), &vp, ino, error);\n"); 366153323Srodrigc error = ENOSYS; 367153323Srodrigc if (error == 0) 368153323Srodrigc *vpp = vp->v_vnode; 369153323Srodrigc return (error); 370153323Srodrigc} 371153323Srodrigc 372153323Srodrigcstatic int 373222167Srmacklem_xfs_fhtovp(mp, fidp, flags, vpp) 374153323Srodrigc struct mount *mp; 375153323Srodrigc struct fid *fidp; 376222167Srmacklem int flags; 377153323Srodrigc struct vnode **vpp; 378153323Srodrigc{ 379153323Srodrigc printf("xfs_fhtovp\n"); 380153323Srodrigc return ENOSYS; 381153323Srodrigc} 382153323Srodrigc 383153323Srodrigcstatic int 384153323Srodrigc_xfs_extattrctl(struct mount *mp, int cm, 385153323Srodrigc struct vnode *filename_v, 386191990Sattilio int attrnamespace, const char *attrname) 387153323Srodrigc{ 388153323Srodrigc printf("xfs_extattrctl\n"); 389153323Srodrigc return ENOSYS; 390153323Srodrigc} 391153323Srodrigc 392153323Srodrigcint 393153323Srodrigc_xfs_init(vfsp) 394153323Srodrigc struct vfsconf *vfsp; 395153323Srodrigc{ 396153323Srodrigc int error; 397153323Srodrigc 398153323Srodrigc error = init_xfs_fs(); 399153323Srodrigc 400153323Srodrigc return (error); 401153323Srodrigc} 402153323Srodrigc 403153323Srodrigcint 404153323Srodrigc_xfs_uninit(vfsp) 405153323Srodrigc struct vfsconf *vfsp; 406153323Srodrigc{ 407153323Srodrigc exit_xfs_fs(); 408153323Srodrigc return 0; 409153323Srodrigc} 410153323Srodrigc 411153323Srodrigcstatic struct vfsops xfs_fsops = { 412153323Srodrigc .vfs_mount = _xfs_mount, 413153323Srodrigc .vfs_unmount = _xfs_unmount, 414153323Srodrigc .vfs_root = _xfs_root, 415153323Srodrigc .vfs_quotactl = _xfs_quotactl, 416153323Srodrigc .vfs_statfs = _xfs_statfs, 417153323Srodrigc .vfs_sync = _xfs_sync, 418153323Srodrigc .vfs_vget = _xfs_vget, 419153323Srodrigc .vfs_fhtovp = _xfs_fhtovp, 420153323Srodrigc .vfs_init = _xfs_init, 421153323Srodrigc .vfs_uninit = _xfs_uninit, 422153323Srodrigc .vfs_extattrctl = _xfs_extattrctl, 423153323Srodrigc}; 424153323Srodrigc 425159451SrodrigcVFS_SET(xfs_fsops, xfs, 0); 426153323Srodrigc 427153323Srodrigc/* 428153323Srodrigc * Copy GEOM VFS functions here to provide a conveniet place to 429153323Srodrigc * track all XFS-related IO without being distracted by other 430153323Srodrigc * filesystems which happen to be mounted on the machine at the 431153323Srodrigc * same time. 432153323Srodrigc */ 433153323Srodrigc 434153323Srodrigcstatic void 435153323Srodrigcxfs_geom_biodone(struct bio *bip) 436153323Srodrigc{ 437153323Srodrigc struct buf *bp; 438153323Srodrigc 439153323Srodrigc if (bip->bio_error) { 440153323Srodrigc printf("g_vfs_done():"); 441153323Srodrigc g_print_bio(bip); 442153323Srodrigc printf("error = %d\n", bip->bio_error); 443153323Srodrigc } 444153323Srodrigc bp = bip->bio_caller2; 445153323Srodrigc bp->b_error = bip->bio_error; 446153323Srodrigc bp->b_ioflags = bip->bio_flags; 447153323Srodrigc if (bip->bio_error) 448153323Srodrigc bp->b_ioflags |= BIO_ERROR; 449153323Srodrigc bp->b_resid = bp->b_bcount - bip->bio_completed; 450153323Srodrigc g_destroy_bio(bip); 451153323Srodrigc mtx_lock(&Giant); 452153323Srodrigc bufdone(bp); 453153323Srodrigc mtx_unlock(&Giant); 454153323Srodrigc} 455153323Srodrigc 456153323Srodrigcstatic void 457153323Srodrigcxfs_geom_strategy(struct bufobj *bo, struct buf *bp) 458153323Srodrigc{ 459153323Srodrigc struct g_consumer *cp; 460153323Srodrigc struct bio *bip; 461153323Srodrigc 462153323Srodrigc cp = bo->bo_private; 463153323Srodrigc G_VALID_CONSUMER(cp); 464153323Srodrigc 465153323Srodrigc bip = g_alloc_bio(); 466153323Srodrigc bip->bio_cmd = bp->b_iocmd; 467153323Srodrigc bip->bio_offset = bp->b_iooffset; 468153323Srodrigc bip->bio_data = bp->b_data; 469153323Srodrigc bip->bio_done = xfs_geom_biodone; 470153323Srodrigc bip->bio_caller2 = bp; 471153323Srodrigc bip->bio_length = bp->b_bcount; 472153323Srodrigc g_io_request(bip, cp); 473153323Srodrigc} 474153323Srodrigc 475153323Srodrigcstatic int 476153323Srodrigcxfs_geom_bufwrite(struct buf *bp) 477153323Srodrigc{ 478153323Srodrigc return bufwrite(bp); 479153323Srodrigc} 480153323Srodrigc 481159451Srodrigcstatic int 482183754Sattilioxfs_geom_bufsync(struct bufobj *bo, int waitfor) 483159451Srodrigc{ 484183754Sattilio 485183754Sattilio return (bufsync(bo, waitfor)); 486159451Srodrigc} 487159451Srodrigc 488166193Skibstatic void 489166193Skibxfs_geom_bufbdflush(struct bufobj *bo, struct buf *bp) 490166193Skib{ 491166193Skib bufbdflush(bo, bp); 492166193Skib} 493166193Skib 494159451Srodrigcstruct buf_ops xfs_bo_ops = { 495153323Srodrigc .bop_name = "XFS", 496153323Srodrigc .bop_write = xfs_geom_bufwrite, 497153323Srodrigc .bop_strategy = xfs_geom_strategy, 498159451Srodrigc .bop_sync = xfs_geom_bufsync, 499166193Skib .bop_bdflush = xfs_geom_bufbdflush, 500153323Srodrigc}; 501