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