]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c
This commit was generated by cvs2svn to compensate for changes in r156283,
[FreeBSD/FreeBSD.git] / sys / gnu / fs / xfs / FreeBSD / xfs_mountops.c
1 #include <sys/param.h>
2 #include <sys/systm.h>
3 #include <sys/kernel.h>
4 #include <sys/proc.h>
5 #include <sys/malloc.h>
6 #include <sys/vnode.h>
7 #include <sys/mount.h>
8 #include <sys/namei.h>
9
10 #include <geom/geom.h>
11 #include <geom/geom_vfs.h>
12
13 #include "xfs.h"
14 #include "xfs_macros.h"
15 #include "xfs_types.h"
16 #include "xfs_inum.h"
17 #include "xfs_log.h"
18 #include "xfs_trans.h"
19 #include "xfs_sb.h"
20 #include "xfs_ag.h"
21 #include "xfs_dir.h"
22 #include "xfs_dir2.h"
23 #include "xfs_dmapi.h"
24 #include "xfs_mount.h"
25 #include "xfs_alloc_btree.h"
26 #include "xfs_bmap_btree.h"
27 #include "xfs_ialloc_btree.h"
28 #include "xfs_btree.h"
29 #include "xfs_ialloc.h"
30 #include "xfs_attr_sf.h"
31 #include "xfs_dir_sf.h"
32 #include "xfs_dir2_sf.h"
33 #include "xfs_dinode.h"
34 #include "xfs_inode.h"
35 #include "xfs_alloc.h"
36 #include "xfs_rtalloc.h"
37 #include "xfs_bmap.h"
38 #include "xfs_error.h"
39 #include "xfs_bit.h"
40 #include "xfs_rw.h"
41 #include "xfs_quota.h"
42 #include "xfs_fsops.h"
43 #include "xfs_clnt.h"
44
45 #include <xfs_mountops.h>
46
47 MALLOC_DEFINE(M_XFSNODE, "XFS node", "XFS vnode private part");
48
49 static vfs_mount_t      _xfs_mount;
50 static vfs_unmount_t    _xfs_unmount;
51 static vfs_root_t       _xfs_root;
52 static vfs_quotactl_t   _xfs_quotactl;
53 static vfs_statfs_t     _xfs_statfs;
54 static vfs_sync_t       _xfs_sync;
55 static vfs_vget_t       _xfs_vget;
56 static vfs_fhtovp_t     _xfs_fhtovp;
57 static vfs_checkexp_t   _xfs_checkexp;
58 static vfs_vptofh_t     _xfs_vptofh;
59 static vfs_init_t       _xfs_init;
60 static vfs_uninit_t     _xfs_uninit;
61 static vfs_extattrctl_t _xfs_extattrctl;
62
63 static b_strategy_t     xfs_geom_strategy;
64
65 static const char *xfs_opts[] =
66         { "from", "flags", "logbufs", "logbufsize",
67           "rtname", "logname", "iosizelog", "sunit",
68           "swidth",
69           NULL };
70
71 static void
72 parse_int(struct mount *mp, const char *opt, int *val, int *error)
73 {
74         char *tmp, *ep;
75
76         tmp = vfs_getopts(mp->mnt_optnew, opt, error);
77         if (*error != 0) {
78                 return;
79         }
80         if (tmp != NULL) {
81                 *val = (int)strtol(tmp, &ep, 10);
82                 if (*ep) {
83                         *error = EINVAL;
84                         return;
85                 }
86         }
87 }
88
89 static int
90 _xfs_param_copyin(struct mount *mp, struct thread *td)
91 {
92         struct xfsmount *xmp = MNTTOXFS(mp);
93         struct xfs_mount_args *args = &xmp->m_args;
94         char *path;
95         char *fsname;
96         char *rtname;
97         char *logname;
98         int error;
99
100         path = vfs_getopts(mp->mnt_optnew, "fspath", &error);
101         if  (error)
102                 return (error);
103
104         bzero(args, sizeof(struct xfs_mount_args));
105         args->logbufs = -1;
106         args->logbufsize = -1;
107
108         parse_int(mp, "flags", &args->flags, &error);
109         if (error != 0)
110                 return error;
111
112         args->flags |= XFSMNT_32BITINODES;
113
114         parse_int(mp, "sunit", &args->sunit, &error);
115         if (error != 0)
116                 return error;
117
118         parse_int(mp, "swidth", &args->swidth, &error);
119         if (error != 0)
120                 return error;
121
122         parse_int(mp, "logbufs", &args->logbufs, &error);
123         if (error != 0)
124                 return error;
125
126         parse_int(mp, "logbufsize", &args->logbufsize, &error);
127         if (error != 0)
128                 return error;
129
130         fsname = vfs_getopts(mp->mnt_optnew, "from", &error);
131         if (error == 0 && fsname != NULL) {
132                 strncpy(args->fsname, fsname, sizeof(args->fsname) - 1);
133         }
134
135         logname = vfs_getopts(mp->mnt_optnew, "logname", &error);
136         if (error == 0 && logname != NULL) {
137                 strncpy(args->logname, logname, sizeof(args->logname) - 1);
138         }
139
140         rtname = vfs_getopts(mp->mnt_optnew, "rtname", &error);
141         if (error == 0 && rtname != NULL) {
142                 strncpy(args->rtname, rtname, sizeof(args->rtname) - 1);
143         }
144
145         strncpy(args->mtpt, path, sizeof(args->mtpt));
146
147         printf("fsname '%s' logname '%s' rtname '%s'\n"
148                "flags 0x%x sunit %d swidth %d logbufs %d logbufsize %d\n",
149                args->fsname, args->logname, args->rtname, args->flags,
150                args->sunit, args->swidth, args->logbufs, args->logbufsize);
151
152         vfs_mountedfrom(mp, args->fsname);
153
154         return (0);
155 }
156
157 static int
158 _xfs_mount(struct mount         *mp,
159            struct thread        *td)
160 {
161         struct xfsmount         *xmp;
162         struct xfs_vnode        *rootvp;
163         struct ucred            *curcred;
164         struct vnode            *rvp;
165         struct cdev             *ddev;
166         int                     error;
167
168         if (vfs_filteropt(mp->mnt_optnew, xfs_opts))
169                 return (EINVAL);
170
171         xmp = xfsmount_allocate(mp);
172         if (xmp == NULL)
173                 return (ENOMEM);
174
175         if((error = _xfs_param_copyin(mp, td)) != 0)
176                 goto fail;
177
178         /* Force read-only mounts in this branch. */
179         XFSTOVFS(xmp)->vfs_flag |= VFS_RDONLY;
180         mp->mnt_flag |= MNT_RDONLY;
181
182         /* XXX: Do not support MNT_UPDATE yet */
183         if (mp->mnt_flag & MNT_UPDATE)
184                 return EOPNOTSUPP; 
185
186         curcred = td->td_ucred;
187         XVFS_MOUNT(XFSTOVFS(xmp), &xmp->m_args, curcred, error);
188         if (error)
189                 goto fail;
190
191         XVFS_ROOT(XFSTOVFS(xmp), &rootvp, error);
192         if (error)
193                 goto fail_unmount;
194
195         ddev = XFS_VFSTOM(XFSTOVFS(xmp))->m_dev;
196         if (ddev->si_iosize_max != 0)
197                 mp->mnt_iosize_max = ddev->si_iosize_max;
198         if (mp->mnt_iosize_max > MAXPHYS)
199                 mp->mnt_iosize_max = MAXPHYS;
200
201         mp->mnt_flag |= MNT_LOCAL | MNT_RDONLY;
202         mp->mnt_stat.f_fsid.val[0] = dev2udev(ddev);
203         mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
204
205         VFS_STATFS(mp, &mp->mnt_stat, td);
206         if (error)
207                 goto fail_unmount;
208
209         rvp = rootvp->v_vnode;
210         rvp->v_vflag |= VV_ROOT;
211         VN_RELE(rootvp);
212
213         return (0);
214
215  fail_unmount:
216         XVFS_UNMOUNT(XFSTOVFS(xmp), 0, curcred, error);
217
218  fail:
219         if (xmp != NULL)
220                 xfsmount_deallocate(xmp);
221
222         return (error);
223 }
224
225 /*
226  * Free reference to null layer
227  */
228 static int
229 _xfs_unmount(mp, mntflags, td)
230         struct mount *mp;
231         int mntflags;
232         struct thread *td;
233 {
234         int error;
235
236         XVFS_UNMOUNT(MNTTOVFS(mp), 0, td->td_ucred, error);
237         return (error);
238 }
239
240 static int
241 _xfs_root(mp, flags, vpp, td)
242         struct mount *mp;
243         int flags;
244         struct vnode **vpp;
245         struct thread *td;
246 {
247         xfs_vnode_t *vp;
248         int error;
249
250         XVFS_ROOT(MNTTOVFS(mp), &vp, error);
251         if (error == 0) {
252                 *vpp = vp->v_vnode;
253                 VOP_LOCK(*vpp, flags, curthread);
254         }
255         return (error);
256 }
257
258 static int
259 _xfs_quotactl(mp, cmd, uid, arg, td)
260         struct mount *mp;
261         int cmd;
262         uid_t uid;
263         void *arg;
264         struct thread *td;
265 {
266         printf("xfs_quotactl\n");
267         return ENOSYS;
268 }
269
270 static int
271 _xfs_statfs(mp, sbp, td)
272         struct mount *mp;
273         struct statfs *sbp;
274         struct thread *td;
275 {
276         int error;
277
278         XVFS_STATVFS(MNTTOVFS(mp), sbp, NULL, error);
279         if (error)
280                 return error;
281
282         /* Fix up the values XFS statvfs calls does not know about. */
283         sbp->f_iosize = sbp->f_bsize;
284
285         return (error);
286 }
287
288 static int
289 _xfs_sync(mp, waitfor, td)
290         struct mount *mp;
291         int waitfor;
292         struct thread *td;
293 {
294         int error;
295         int flags = SYNC_FSDATA|SYNC_ATTR|SYNC_REFCACHE;
296
297         if (waitfor == MNT_WAIT)
298                 flags |= SYNC_WAIT;
299         else if (waitfor == MNT_LAZY)
300                 flags |= SYNC_BDFLUSH;
301         XVFS_SYNC(MNTTOVFS(mp), flags, td->td_ucred, error);
302         return (error);
303 }
304
305 static int
306 _xfs_vget(mp, ino, flags, vpp)
307         struct mount *mp;
308         ino_t ino;
309         int flags;
310         struct vnode **vpp;
311 {
312         xfs_vnode_t *vp;
313         int error;
314
315         printf("XVFS_GET_VNODE(MNTTOVFS(mp), &vp, ino, error);\n");
316         error = ENOSYS;
317         if (error == 0)
318                 *vpp = vp->v_vnode;
319         return (error);
320 }
321
322 static int
323 _xfs_fhtovp(mp, fidp, vpp)
324         struct mount *mp;
325         struct fid *fidp;
326         struct vnode **vpp;
327 {
328         printf("xfs_fhtovp\n");
329         return ENOSYS;
330 }
331
332 static int
333 _xfs_checkexp(mp, nam, extflagsp, credanonp)
334         struct mount *mp;
335         struct sockaddr *nam;
336         int *extflagsp;
337         struct ucred **credanonp;
338 {
339         printf("xfs_checkexp\n");
340         return ENOSYS;
341 }
342
343 static int
344 _xfs_vptofh(vp, fhp)
345         struct vnode *vp;
346         struct fid *fhp;
347 {
348         printf("xfs_vptofh");
349         return ENOSYS;
350 }
351
352 static int
353 _xfs_extattrctl(struct mount *mp, int cm,
354                 struct vnode *filename_v,
355                 int attrnamespace, const char *attrname,
356                 struct thread *td)
357 {
358         printf("xfs_extattrctl\n");
359         return ENOSYS;
360 }
361
362 int
363 _xfs_init(vfsp)
364         struct vfsconf *vfsp;
365 {
366         int error;
367
368         error = init_xfs_fs();
369
370         return (error);
371 }
372
373 int
374 _xfs_uninit(vfsp)
375         struct vfsconf *vfsp;
376 {
377         exit_xfs_fs();
378         return 0;
379 }
380
381 static struct vfsops xfs_fsops = {
382         .vfs_mount =    _xfs_mount,
383         .vfs_unmount =  _xfs_unmount,
384         .vfs_root =     _xfs_root,
385         .vfs_quotactl = _xfs_quotactl,
386         .vfs_statfs =   _xfs_statfs,
387         .vfs_sync =     _xfs_sync,
388         .vfs_vget =     _xfs_vget,
389         .vfs_fhtovp =   _xfs_fhtovp,
390         .vfs_checkexp = _xfs_checkexp,
391         .vfs_vptofh =   _xfs_vptofh,
392         .vfs_init =     _xfs_init,
393         .vfs_uninit =   _xfs_uninit,
394         .vfs_extattrctl = _xfs_extattrctl,
395 };
396
397 /* XXX: Read-only for now */
398 VFS_SET(xfs_fsops, xfs, VFCF_READONLY);
399
400 /*
401  *  Copy GEOM VFS functions here to provide a conveniet place to
402  *  track all XFS-related IO without being distracted by other
403  *  filesystems which happen to be mounted on the machine at the
404  *  same time.
405  */
406
407 static void
408 xfs_geom_biodone(struct bio *bip)
409 {
410         struct buf *bp;
411
412         if (bip->bio_error) {
413                 printf("g_vfs_done():");
414                 g_print_bio(bip);
415                 printf("error = %d\n", bip->bio_error);
416         }
417         bp = bip->bio_caller2;
418         bp->b_error = bip->bio_error;
419         bp->b_ioflags = bip->bio_flags;
420         if (bip->bio_error)
421                 bp->b_ioflags |= BIO_ERROR;
422         bp->b_resid = bp->b_bcount - bip->bio_completed;
423         g_destroy_bio(bip);
424         mtx_lock(&Giant);
425         bufdone(bp);
426         mtx_unlock(&Giant);
427 }
428
429 static void
430 xfs_geom_strategy(struct bufobj *bo, struct buf *bp)
431 {
432         struct g_consumer *cp;
433         struct bio *bip;
434
435         cp = bo->bo_private;
436         G_VALID_CONSUMER(cp);
437
438         bip = g_alloc_bio();
439         bip->bio_cmd = bp->b_iocmd;
440         bip->bio_offset = bp->b_iooffset;
441         bip->bio_data = bp->b_data;
442         bip->bio_done = xfs_geom_biodone;
443         bip->bio_caller2 = bp;
444         bip->bio_length = bp->b_bcount;
445         g_io_request(bip, cp);
446 }
447
448 static int
449 xfs_geom_bufwrite(struct buf *bp)
450 {
451         return bufwrite(bp);
452 }
453
454 struct buf_ops xfs_ops = {
455         .bop_name =     "XFS",
456         .bop_write =    xfs_geom_bufwrite,
457         .bop_strategy = xfs_geom_strategy,
458         .bop_sync =     bufsync,
459 };