2 * Copyright (c) 2001,2006 Alexander Kabaev, Russell Cattelan Digital Elves Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/kernel.h>
33 #include <sys/malloc.h>
34 #include <sys/vnode.h>
35 #include <sys/mount.h>
36 #include <sys/namei.h>
38 #include <geom/geom.h>
39 #include <geom/geom_vfs.h>
42 #include "xfs_types.h"
46 #include "xfs_trans.h"
51 #include "xfs_dmapi.h"
52 #include "xfs_mount.h"
53 #include "xfs_alloc_btree.h"
54 #include "xfs_bmap_btree.h"
55 #include "xfs_ialloc_btree.h"
56 #include "xfs_btree.h"
57 #include "xfs_attr_sf.h"
58 #include "xfs_dir_sf.h"
59 #include "xfs_dir2_sf.h"
60 #include "xfs_dinode.h"
61 #include "xfs_ialloc.h"
62 #include "xfs_inode.h"
63 #include "xfs_alloc.h"
64 #include "xfs_rtalloc.h"
66 #include "xfs_error.h"
68 #include "xfs_quota.h"
69 #include "xfs_fsops.h"
72 #include <xfs_mountops.h>
74 MALLOC_DEFINE(M_XFSNODE, "XFS node", "XFS vnode private part");
76 static vfs_mount_t _xfs_mount;
77 static vfs_unmount_t _xfs_unmount;
78 static vfs_root_t _xfs_root;
79 static vfs_quotactl_t _xfs_quotactl;
80 static vfs_statfs_t _xfs_statfs;
81 static vfs_sync_t _xfs_sync;
82 static vfs_vget_t _xfs_vget;
83 static vfs_fhtovp_t _xfs_fhtovp;
84 static vfs_init_t _xfs_init;
85 static vfs_uninit_t _xfs_uninit;
86 static vfs_extattrctl_t _xfs_extattrctl;
88 static b_strategy_t xfs_geom_strategy;
90 static const char *xfs_opts[] =
91 { "from", "flags", "logbufs", "logbufsize",
92 "rtname", "logname", "iosizelog", "sunit",
97 parse_int(struct mount *mp, const char *opt, int *val, int *error)
101 tmp = vfs_getopts(mp->mnt_optnew, opt, error);
106 *val = (int)strtol(tmp, &ep, 10);
115 _xfs_param_copyin(struct mount *mp, struct thread *td)
117 struct xfsmount *xmp = MNTTOXFS(mp);
118 struct xfs_mount_args *args = &xmp->m_args;
125 path = vfs_getopts(mp->mnt_optnew, "fspath", &error);
129 bzero(args, sizeof(struct xfs_mount_args));
131 args->logbufsize = -1;
133 parse_int(mp, "flags", &args->flags, &error);
134 if (error != 0 && error != ENOENT)
137 args->flags |= XFSMNT_32BITINODES;
139 parse_int(mp, "sunit", &args->sunit, &error);
140 if (error != 0 && error != ENOENT)
143 parse_int(mp, "swidth", &args->swidth, &error);
144 if (error != 0 && error != ENOENT)
147 parse_int(mp, "logbufs", &args->logbufs, &error);
148 if (error != 0 && error != ENOENT)
151 parse_int(mp, "logbufsize", &args->logbufsize, &error);
152 if (error != 0 && error != ENOENT)
155 fsname = vfs_getopts(mp->mnt_optnew, "from", &error);
156 if (error == 0 && fsname != NULL) {
157 strncpy(args->fsname, fsname, sizeof(args->fsname) - 1);
160 logname = vfs_getopts(mp->mnt_optnew, "logname", &error);
161 if (error == 0 && logname != NULL) {
162 strncpy(args->logname, logname, sizeof(args->logname) - 1);
165 rtname = vfs_getopts(mp->mnt_optnew, "rtname", &error);
166 if (error == 0 && rtname != NULL) {
167 strncpy(args->rtname, rtname, sizeof(args->rtname) - 1);
170 strncpy(args->mtpt, path, sizeof(args->mtpt));
172 printf("fsname '%s' logname '%s' rtname '%s'\n"
173 "flags 0x%x sunit %d swidth %d logbufs %d logbufsize %d\n",
174 args->fsname, args->logname, args->rtname, args->flags,
175 args->sunit, args->swidth, args->logbufs, args->logbufsize);
177 vfs_mountedfrom(mp, args->fsname);
183 _xfs_mount(struct mount *mp,
186 struct xfsmount *xmp;
187 struct xfs_vnode *rootvp;
188 struct ucred *curcred;
189 struct vnode *rvp, *devvp;
191 struct g_consumer *cp;
197 if (vfs_filteropt(mp->mnt_optnew, xfs_opts))
200 if (mp->mnt_flag & MNT_UPDATE)
203 xmp = xfsmount_allocate(mp);
207 if((error = _xfs_param_copyin(mp, td)) != 0)
210 curcred = td->td_ucred;
211 XVFS_MOUNT(XFSTOVFS(xmp), &xmp->m_args, curcred, error);
215 XVFS_ROOT(XFSTOVFS(xmp), &rootvp, error);
216 ddev = XFS_VFSTOM(XFSTOVFS(xmp))->m_ddev_targp->dev;
217 devvp = XFS_VFSTOM(XFSTOVFS(xmp))->m_ddev_targp->specvp;
221 if (ddev->si_iosize_max != 0)
222 mp->mnt_iosize_max = ddev->si_iosize_max;
223 if (mp->mnt_iosize_max > MAXPHYS)
224 mp->mnt_iosize_max = MAXPHYS;
226 mp->mnt_flag |= MNT_LOCAL;
227 mp->mnt_stat.f_fsid.val[0] = dev2udev(ddev);
228 mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
230 if ((error = VFS_STATFS(mp, &mp->mnt_stat, td)) != 0)
233 rvp = rootvp->v_vnode;
234 rvp->v_vflag |= VV_ROOT;
240 XVFS_UNMOUNT(XFSTOVFS(xmp), 0, curcred, error);
243 cp = devvp->v_bufobj.bo_private;
255 xfsmount_deallocate(xmp);
261 * Free reference to null layer
264 _xfs_unmount(mp, mntflags, td)
270 struct g_consumer *cp;
275 devvp = XFS_VFSTOM((MNTTOVFS(mp)))->m_ddev_targp->specvp;
277 cp = devvp->v_bufobj.bo_private;
279 XVFS_UNMOUNT(MNTTOVFS(mp), 0, td->td_ucred, error);
293 _xfs_root(mp, flags, vpp, td)
302 XVFS_ROOT(MNTTOVFS(mp), &vp, error);
305 VOP_LOCK(*vpp, flags, curthread);
311 _xfs_quotactl(mp, cmd, uid, arg, td)
318 printf("xfs_quotactl\n");
323 _xfs_statfs(mp, sbp, td)
330 XVFS_STATVFS(MNTTOVFS(mp), sbp, NULL, error);
334 /* Fix up the values XFS statvfs calls does not know about. */
335 sbp->f_iosize = sbp->f_bsize;
341 _xfs_sync(mp, waitfor, td)
347 int flags = SYNC_FSDATA|SYNC_ATTR|SYNC_REFCACHE;
349 if (waitfor == MNT_WAIT)
351 else if (waitfor == MNT_LAZY)
352 flags |= SYNC_BDFLUSH;
353 XVFS_SYNC(MNTTOVFS(mp), flags, td->td_ucred, error);
358 _xfs_vget(mp, ino, flags, vpp)
364 xfs_vnode_t *vp = NULL;
367 printf("XVFS_GET_VNODE(MNTTOVFS(mp), &vp, ino, error);\n");
375 _xfs_fhtovp(mp, fidp, vpp)
380 printf("xfs_fhtovp\n");
385 _xfs_extattrctl(struct mount *mp, int cm,
386 struct vnode *filename_v,
387 int attrnamespace, const char *attrname,
390 printf("xfs_extattrctl\n");
396 struct vfsconf *vfsp;
400 error = init_xfs_fs();
407 struct vfsconf *vfsp;
413 static struct vfsops xfs_fsops = {
414 .vfs_mount = _xfs_mount,
415 .vfs_unmount = _xfs_unmount,
416 .vfs_root = _xfs_root,
417 .vfs_quotactl = _xfs_quotactl,
418 .vfs_statfs = _xfs_statfs,
419 .vfs_sync = _xfs_sync,
420 .vfs_vget = _xfs_vget,
421 .vfs_fhtovp = _xfs_fhtovp,
422 .vfs_init = _xfs_init,
423 .vfs_uninit = _xfs_uninit,
424 .vfs_extattrctl = _xfs_extattrctl,
427 VFS_SET(xfs_fsops, xfs, 0);
430 * Copy GEOM VFS functions here to provide a conveniet place to
431 * track all XFS-related IO without being distracted by other
432 * filesystems which happen to be mounted on the machine at the
437 xfs_geom_biodone(struct bio *bip)
441 if (bip->bio_error) {
442 printf("g_vfs_done():");
444 printf("error = %d\n", bip->bio_error);
446 bp = bip->bio_caller2;
447 bp->b_error = bip->bio_error;
448 bp->b_ioflags = bip->bio_flags;
450 bp->b_ioflags |= BIO_ERROR;
451 bp->b_resid = bp->b_bcount - bip->bio_completed;
459 xfs_geom_strategy(struct bufobj *bo, struct buf *bp)
461 struct g_consumer *cp;
465 G_VALID_CONSUMER(cp);
468 bip->bio_cmd = bp->b_iocmd;
469 bip->bio_offset = bp->b_iooffset;
470 bip->bio_data = bp->b_data;
471 bip->bio_done = xfs_geom_biodone;
472 bip->bio_caller2 = bp;
473 bip->bio_length = bp->b_bcount;
474 g_io_request(bip, cp);
478 xfs_geom_bufwrite(struct buf *bp)
484 xfs_geom_bufsync(struct bufobj *bo, int waitfor, struct thread *td)
486 return bufsync(bo,waitfor,td);
490 xfs_geom_bufbdflush(struct bufobj *bo, struct buf *bp)
495 struct buf_ops xfs_bo_ops = {
497 .bop_write = xfs_geom_bufwrite,
498 .bop_strategy = xfs_geom_strategy,
499 .bop_sync = xfs_geom_bufsync,
500 .bop_bdflush = xfs_geom_bufbdflush,