]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/gnu/fs/xfs/xfs_vfsops.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / gnu / fs / xfs / xfs_vfsops.c
1 /*
2  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include "xfs.h"
19 #include "xfs_fs.h"
20 #include "xfs_types.h"
21 #include "xfs_bit.h"
22 #include "xfs_log.h"
23 #include "xfs_inum.h"
24 #include "xfs_trans.h"
25 #include "xfs_sb.h"
26 #include "xfs_ag.h"
27 #include "xfs_dir.h"
28 #include "xfs_dir2.h"
29 #include "xfs_dmapi.h"
30 #include "xfs_mount.h"
31 #include "xfs_da_btree.h"
32 #include "xfs_bmap_btree.h"
33 #include "xfs_ialloc_btree.h"
34 #include "xfs_alloc_btree.h"
35 #include "xfs_dir_sf.h"
36 #include "xfs_dir2_sf.h"
37 #include "xfs_attr_sf.h"
38 #include "xfs_dinode.h"
39 #include "xfs_inode.h"
40 #include "xfs_inode_item.h"
41 #include "xfs_btree.h"
42 #include "xfs_alloc.h"
43 #include "xfs_ialloc.h"
44 #include "xfs_quota.h"
45 #include "xfs_error.h"
46 #include "xfs_bmap.h"
47 #include "xfs_rw.h"
48 #include "xfs_refcache.h"
49 #include "xfs_buf_item.h"
50 #include "xfs_log_priv.h"
51 #include "xfs_dir2_trace.h"
52 #include "xfs_extfree_item.h"
53 #include "xfs_acl.h"
54 #include "xfs_attr.h"
55 #include "xfs_clnt.h"
56 #include "xfs_fsops.h"
57 #include "xfs_vnode.h"
58
59 STATIC int      xfs_sync(bhv_desc_t *, int, cred_t *);
60
61         extern kmem_zone_t      *xfs_bmap_free_item_zone;
62         extern kmem_zone_t      *xfs_btree_cur_zone;
63         extern kmem_zone_t      *xfs_trans_zone;
64         extern kmem_zone_t      *xfs_dabuf_zone;
65         extern kmem_zone_t      *xfs_buf_item_zone;
66
67 #ifdef XFS_DABUF_DEBUG
68         extern lock_t           xfs_dabuf_global_lock;
69 #endif
70
71 int
72 xfs_init(void)
73 {
74 #if 0
75         extern kmem_zone_t      *xfs_bmap_free_item_zone;
76         extern kmem_zone_t      *xfs_btree_cur_zone;
77         extern kmem_zone_t      *xfs_trans_zone;
78         extern kmem_zone_t      *xfs_buf_item_zone;
79         extern kmem_zone_t      *xfs_dabuf_zone;
80 #endif
81 #ifdef XFS_DABUF_DEBUG
82         spinlock_init(&xfs_dabuf_global_lock, "xfsda");
83 #endif
84         /*
85          * Initialize all of the zone allocators we use.
86          */
87         xfs_bmap_free_item_zone = kmem_zone_init(sizeof(xfs_bmap_free_item_t),
88                                                  "xfs_bmap_free_item");
89         xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t),
90                                             "xfs_btree_cur");
91         xfs_trans_zone = kmem_zone_init(sizeof(xfs_trans_t), "xfs_trans");
92         xfs_da_state_zone =
93                 kmem_zone_init(sizeof(xfs_da_state_t), "xfs_da_state");
94         xfs_dabuf_zone = kmem_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf");
95         xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork");
96         xfs_acl_zone_init(xfs_acl_zone, "xfs_acl");
97
98         /*
99          * The size of the zone allocated buf log item is the maximum
100          * size possible under XFS.  This wastes a little bit of memory,
101          * but it is much faster.
102          */
103         xfs_buf_item_zone =
104                 kmem_zone_init((sizeof(xfs_buf_log_item_t) +
105                                 (((XFS_MAX_BLOCKSIZE / XFS_BLI_CHUNK) /
106                                   NBWORD) * sizeof(int))),
107                                "xfs_buf_item");
108         xfs_efd_zone =
109                 kmem_zone_init((sizeof(xfs_efd_log_item_t) +
110                                ((XFS_EFD_MAX_FAST_EXTENTS - 1) *
111                                  sizeof(xfs_extent_t))),
112                                       "xfs_efd_item");
113         xfs_efi_zone =
114                 kmem_zone_init((sizeof(xfs_efi_log_item_t) +
115                                ((XFS_EFI_MAX_FAST_EXTENTS - 1) *
116                                  sizeof(xfs_extent_t))),
117                                       "xfs_efi_item");
118
119         /*
120          * These zones warrant special memory allocator hints
121          */
122         xfs_inode_zone =
123                 kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode",
124                                         KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
125                                         KM_ZONE_SPREAD, NULL);
126         xfs_ili_zone =
127                 kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili",
128                                         KM_ZONE_SPREAD, NULL);
129         xfs_chashlist_zone =
130                 kmem_zone_init_flags(sizeof(xfs_chashlist_t), "xfs_chashlist",
131                                         KM_ZONE_SPREAD, NULL);
132
133         /*
134          * Allocate global trace buffers.
135          */
136 #ifdef XFS_ALLOC_TRACE
137         xfs_alloc_trace_buf = ktrace_alloc(XFS_ALLOC_TRACE_SIZE, KM_SLEEP);
138 #endif
139 #ifdef XFS_BMAP_TRACE
140         xfs_bmap_trace_buf = ktrace_alloc(XFS_BMAP_TRACE_SIZE, KM_SLEEP);
141 #endif
142 #ifdef XFS_BMBT_TRACE
143         xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_SLEEP);
144 #endif
145 #ifdef XFS_DIR_TRACE
146         xfs_dir_trace_buf = ktrace_alloc(XFS_DIR_TRACE_SIZE, KM_SLEEP);
147 #endif
148 #ifdef XFS_ATTR_TRACE
149         xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_SLEEP);
150 #endif
151 #ifdef XFS_DIR2_TRACE
152         xfs_dir2_trace_buf = ktrace_alloc(XFS_DIR2_GTRACE_SIZE, KM_SLEEP);
153 #endif
154
155         xfs_dir_startup();
156
157 #if (defined(DEBUG) || defined(INDUCE_IO_ERROR))
158         xfs_error_test_init();
159 #endif /* DEBUG || INDUCE_IO_ERROR */
160
161         xfs_refcache_init();
162         xfs_init_procfs();
163         xfs_sysctl_register();
164         return 0;
165 }
166
167 void
168 xfs_cleanup(void)
169 {
170 #if 0
171         extern kmem_zone_t      *xfs_bmap_free_item_zone;
172         extern kmem_zone_t      *xfs_btree_cur_zone;
173         extern kmem_zone_t      *xfs_inode_zone;
174         extern kmem_zone_t      *xfs_trans_zone;
175         extern kmem_zone_t      *xfs_da_state_zone;
176         extern kmem_zone_t      *xfs_dabuf_zone;
177         extern kmem_zone_t      *xfs_efd_zone;
178         extern kmem_zone_t      *xfs_efi_zone;
179         extern kmem_zone_t      *xfs_buf_item_zone;
180         extern kmem_zone_t      *xfs_chashlist_zone;
181 #endif
182
183         xfs_cleanup_procfs();
184         xfs_sysctl_unregister();
185         xfs_refcache_destroy();
186         xfs_acl_zone_destroy(xfs_acl_zone);
187
188 #ifdef XFS_DIR2_TRACE
189         ktrace_free(xfs_dir2_trace_buf);
190 #endif
191 #ifdef XFS_ATTR_TRACE
192         ktrace_free(xfs_attr_trace_buf);
193 #endif
194 #ifdef XFS_DIR_TRACE
195         ktrace_free(xfs_dir_trace_buf);
196 #endif
197 #ifdef XFS_BMBT_TRACE
198         ktrace_free(xfs_bmbt_trace_buf);
199 #endif
200 #ifdef XFS_BMAP_TRACE
201         ktrace_free(xfs_bmap_trace_buf);
202 #endif
203 #ifdef XFS_ALLOC_TRACE
204         ktrace_free(xfs_alloc_trace_buf);
205 #endif
206
207         kmem_zone_destroy(xfs_bmap_free_item_zone);
208         kmem_zone_destroy(xfs_btree_cur_zone);
209         kmem_zone_destroy(xfs_inode_zone);
210         kmem_zone_destroy(xfs_trans_zone);
211         kmem_zone_destroy(xfs_da_state_zone);
212         kmem_zone_destroy(xfs_dabuf_zone);
213         kmem_zone_destroy(xfs_buf_item_zone);
214         kmem_zone_destroy(xfs_efd_zone);
215         kmem_zone_destroy(xfs_efi_zone);
216         kmem_zone_destroy(xfs_ifork_zone);
217         kmem_zone_destroy(xfs_ili_zone);
218         kmem_zone_destroy(xfs_chashlist_zone);
219 }
220
221 /*
222  * xfs_start_flags
223  *
224  * This function fills in xfs_mount_t fields based on mount args.
225  * Note: the superblock has _not_ yet been read in.
226  */
227 STATIC int
228 xfs_start_flags(
229         struct xfs_vfs          *vfs,
230         struct xfs_mount_args   *ap,
231         struct xfs_mount        *mp)
232 {
233         /* Values are in BBs */
234         if ((ap->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
235                 /*
236                  * At this point the superblock has not been read
237                  * in, therefore we do not know the block size.
238                  * Before the mount call ends we will convert
239                  * these to FSBs.
240                  */
241                 mp->m_dalign = ap->sunit;
242                 mp->m_swidth = ap->swidth;
243         }
244
245         if (ap->logbufs != -1 &&
246             ap->logbufs != 0 &&
247             (ap->logbufs < XLOG_MIN_ICLOGS ||
248              ap->logbufs > XLOG_MAX_ICLOGS)) {
249                 cmn_err(CE_WARN,
250                         "XFS: invalid logbufs value: %d [not %d-%d]",
251                         ap->logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS);
252                 return XFS_ERROR(EINVAL);
253         }
254         mp->m_logbufs = ap->logbufs;
255         if (ap->logbufsize != -1 &&
256             ap->logbufsize !=  0 &&
257             ap->logbufsize != 16 * 1024 &&
258             ap->logbufsize != 32 * 1024 &&
259             ap->logbufsize != 64 * 1024 &&
260             ap->logbufsize != 128 * 1024 &&
261             ap->logbufsize != 256 * 1024) {
262                 cmn_err(CE_WARN,
263         "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
264                         ap->logbufsize);
265                 return XFS_ERROR(EINVAL);
266         }
267         mp->m_ihsize = ap->ihashsize;
268         mp->m_logbsize = ap->logbufsize;
269         mp->m_fsname_len = strlen(ap->fsname) + 1;
270         mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP);
271         strcpy(mp->m_fsname, ap->fsname);
272         if (ap->rtname[0]) {
273                 mp->m_rtname = kmem_alloc(strlen(ap->rtname) + 1, KM_SLEEP);
274                 strcpy(mp->m_rtname, ap->rtname);
275         }
276         if (ap->logname[0]) {
277                 mp->m_logname = kmem_alloc(strlen(ap->logname) + 1, KM_SLEEP);
278                 strcpy(mp->m_logname, ap->logname);
279         }
280
281         if (ap->flags & XFSMNT_WSYNC)
282                 mp->m_flags |= XFS_MOUNT_WSYNC;
283 #if XFS_BIG_INUMS
284         if (ap->flags & XFSMNT_INO64) {
285                 mp->m_flags |= XFS_MOUNT_INO64;
286                 mp->m_inoadd = XFS_INO64_OFFSET;
287         }
288 #endif
289         if (ap->flags & XFSMNT_RETERR)
290                 mp->m_flags |= XFS_MOUNT_RETERR;
291         if (ap->flags & XFSMNT_NOALIGN)
292                 mp->m_flags |= XFS_MOUNT_NOALIGN;
293         if (ap->flags & XFSMNT_SWALLOC)
294                 mp->m_flags |= XFS_MOUNT_SWALLOC;
295         if (ap->flags & XFSMNT_OSYNCISOSYNC)
296                 mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC;
297         if (ap->flags & XFSMNT_32BITINODES)
298                 mp->m_flags |= XFS_MOUNT_32BITINODES;
299
300         if (ap->flags & XFSMNT_IOSIZE) {
301                 if (ap->iosizelog > XFS_MAX_IO_LOG ||
302                     ap->iosizelog < XFS_MIN_IO_LOG) {
303                         cmn_err(CE_WARN,
304                 "XFS: invalid log iosize: %d [not %d-%d]",
305                                 ap->iosizelog, XFS_MIN_IO_LOG,
306                                 XFS_MAX_IO_LOG);
307                         return XFS_ERROR(EINVAL);
308                 }
309
310                 mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
311                 mp->m_readio_log = mp->m_writeio_log = ap->iosizelog;
312         }
313
314         if (ap->flags & XFSMNT_IHASHSIZE)
315                 mp->m_flags |= XFS_MOUNT_IHASHSIZE;
316         if (ap->flags & XFSMNT_IDELETE)
317                 mp->m_flags |= XFS_MOUNT_IDELETE;
318         if (ap->flags & XFSMNT_DIRSYNC)
319                 mp->m_flags |= XFS_MOUNT_DIRSYNC;
320         if (ap->flags & XFSMNT_ATTR2)
321                 mp->m_flags |= XFS_MOUNT_ATTR2;
322
323         if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE)
324                 mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
325
326         /*
327          * no recovery flag requires a read-only mount
328          */
329         if (ap->flags & XFSMNT_NORECOVERY) {
330                 if (!(vfs->vfs_flag & VFS_RDONLY)) {
331                         cmn_err(CE_WARN,
332         "XFS: tried to mount a FS read-write without recovery!");
333                         return XFS_ERROR(EINVAL);
334                 }
335                 mp->m_flags |= XFS_MOUNT_NORECOVERY;
336         }
337
338         if (ap->flags & XFSMNT_NOUUID)
339                 mp->m_flags |= XFS_MOUNT_NOUUID;
340         if (ap->flags & XFSMNT_BARRIER)
341                 mp->m_flags |= XFS_MOUNT_BARRIER;
342         else
343                 mp->m_flags &= ~XFS_MOUNT_BARRIER;
344
345         return 0;
346 }
347
348 /*
349  * This function fills in xfs_mount_t fields based on mount args.
350  * Note: the superblock _has_ now been read in.
351  */
352 STATIC int
353 xfs_finish_flags(
354         struct xfs_vfs          *vfs,
355         struct xfs_mount_args   *ap,
356         struct xfs_mount        *mp)
357 {
358         int                     ronly = (vfs->vfs_flag & VFS_RDONLY);
359
360         /* Fail a mount where the logbuf is smaller then the log stripe */
361         if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) {
362                 if ((ap->logbufsize <= 0) &&
363                     (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) {
364                         mp->m_logbsize = mp->m_sb.sb_logsunit;
365                 } else if (ap->logbufsize > 0 &&
366                            ap->logbufsize < mp->m_sb.sb_logsunit) {
367                         cmn_err(CE_WARN,
368         "XFS: logbuf size must be greater than or equal to log stripe size");
369                         return XFS_ERROR(EINVAL);
370                 }
371         } else {
372                 /* Fail a mount if the logbuf is larger than 32K */
373                 if (ap->logbufsize > XLOG_BIG_RECORD_BSIZE) {
374                         cmn_err(CE_WARN,
375         "XFS: logbuf size for version 1 logs must be 16K or 32K");
376                         return XFS_ERROR(EINVAL);
377                 }
378         }
379
380         if (XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
381                 mp->m_flags |= XFS_MOUNT_ATTR2;
382         }
383
384         /*
385          * prohibit r/w mounts of read-only filesystems
386          */
387         if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !ronly) {
388                 cmn_err(CE_WARN,
389         "XFS: cannot mount a read-only filesystem as read-write");
390                 return XFS_ERROR(EROFS);
391         }
392
393         /*
394          * check for shared mount.
395          */
396         if (ap->flags & XFSMNT_SHARED) {
397                 if (!XFS_SB_VERSION_HASSHARED(&mp->m_sb))
398                         return XFS_ERROR(EINVAL);
399
400                 /*
401                  * For IRIX 6.5, shared mounts must have the shared
402                  * version bit set, have the persistent readonly
403                  * field set, must be version 0 and can only be mounted
404                  * read-only.
405                  */
406                 if (!ronly || !(mp->m_sb.sb_flags & XFS_SBF_READONLY) ||
407                      (mp->m_sb.sb_shared_vn != 0))
408                         return XFS_ERROR(EINVAL);
409
410                 mp->m_flags |= XFS_MOUNT_SHARED;
411
412                 /*
413                  * Shared XFS V0 can't deal with DMI.  Return EINVAL.
414                  */
415                 if (mp->m_sb.sb_shared_vn == 0 && (ap->flags & XFSMNT_DMAPI))
416                         return XFS_ERROR(EINVAL);
417         }
418
419         return 0;
420 }
421
422 /*
423  * xfs_mount
424  *
425  * The file system configurations are:
426  *      (1) device (partition) with data and internal log
427  *      (2) logical volume with data and log subvolumes.
428  *      (3) logical volume with data, log, and realtime subvolumes.
429  *
430  * We only have to handle opening the log and realtime volumes here if
431  * they are present.  The data subvolume has already been opened by
432  * get_sb_bdev() and is stored in vfsp->vfs_super->s_bdev.
433  */
434 STATIC int
435 xfs_mount(
436         struct bhv_desc         *bhvp,
437         struct xfs_mount_args   *args,
438         cred_t                  *credp)
439 {
440         struct xfs_vfs          *vfsp = bhvtovfs(bhvp);
441         struct bhv_desc         *p;
442         struct xfs_mount        *mp = XFS_BHVTOM(bhvp);
443         struct vnode            *ddev, *logdev, *rtdev;
444         int                     flags = 0, error;
445
446         ddev = logdev = rtdev = NULL;
447
448         error = xfs_blkdev_get(mp, args->fsname, &ddev);
449         if (error)
450                 return error;
451
452         /*
453          * Setup xfs_mount function vectors from available behaviors
454          */
455         p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM);
456         mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub;
457         p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM);
458         mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub;
459         p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO);
460         mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs;
461
462         if (args->flags & XFSMNT_QUIET)
463                 flags |= XFS_MFSI_QUIET;
464
465         /*
466          * Open real time and log devices - order is important.
467          */
468         if (args->logname[0]) {
469                 error = xfs_blkdev_get(mp, args->logname, &logdev);
470                 if (error) {
471                         xfs_blkdev_put(ddev);
472                         return error;
473                 }
474         }
475         if (args->rtname[0]) {
476                 error = xfs_blkdev_get(mp, args->rtname, &rtdev);
477                 if (error) {
478                         xfs_blkdev_put(logdev);
479                         xfs_blkdev_put(ddev);
480                         return error;
481                 }
482
483                 if (rtdev == ddev || rtdev == logdev) {
484                         cmn_err(CE_WARN,
485         "XFS: Cannot mount filesystem with identical rtdev and ddev/logdev.");
486                         xfs_blkdev_put(logdev);
487                         xfs_blkdev_put(rtdev);
488                         xfs_blkdev_put(ddev);
489                         return EINVAL;
490                 }
491         }
492
493         /*
494          * Setup xfs_mount buffer target pointers
495          */
496         error = ENOMEM;
497         mp->m_ddev_targp = xfs_alloc_buftarg(ddev, 0);
498         if (!mp->m_ddev_targp) {
499                 xfs_blkdev_put(logdev);
500                 xfs_blkdev_put(rtdev);
501                 return error;
502         }
503         if (rtdev) {
504                 mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev, 1);
505                 if (!mp->m_rtdev_targp)
506                         goto error0;
507         }
508         mp->m_logdev_targp = (logdev && logdev != ddev) ?
509                                 xfs_alloc_buftarg(logdev, 1) : mp->m_ddev_targp;
510         if (!mp->m_logdev_targp)
511                 goto error0;
512
513         /*
514          * Setup flags based on mount(2) options and then the superblock
515          */
516         error = xfs_start_flags(vfsp, args, mp);
517         if (error)
518                 goto error1;
519         error = xfs_readsb(mp, flags);
520         if (error)
521                 goto error1;
522         error = xfs_finish_flags(vfsp, args, mp);
523         if (error)
524                 goto error2;
525
526         /*
527          * Setup xfs_mount buffer target pointers based on superblock
528          */
529         error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize,
530                                     mp->m_sb.sb_sectsize);
531         if (!error && logdev && logdev != ddev) {
532                 unsigned int    log_sector_size = BBSIZE;
533
534                 if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb))
535                         log_sector_size = mp->m_sb.sb_logsectsize;
536                 error = xfs_setsize_buftarg(mp->m_logdev_targp,
537                                             mp->m_sb.sb_blocksize,
538                                             log_sector_size);
539         }
540         if (!error && rtdev)
541                 error = xfs_setsize_buftarg(mp->m_rtdev_targp,
542                                             mp->m_sb.sb_blocksize,
543                                             mp->m_sb.sb_sectsize);
544         if (error)
545                 goto error2;
546
547         if ((mp->m_flags & XFS_MOUNT_BARRIER) && !(vfsp->vfs_flag & VFS_RDONLY))
548                 xfs_mountfs_check_barriers(mp);
549
550         error = XFS_IOINIT(vfsp, args, flags);
551         if (error)
552                 goto error2;
553
554         return 0;
555
556 error2:
557         if (mp->m_sb_bp)
558                 xfs_freesb(mp);
559 error1:
560         xfs_binval(mp->m_ddev_targp);
561         if (logdev && logdev != ddev)
562                 xfs_binval(mp->m_logdev_targp);
563         if (rtdev)
564                 xfs_binval(mp->m_rtdev_targp);
565 error0:
566         xfs_unmountfs_close(mp, credp);
567         return error;
568 }
569
570 STATIC int
571 xfs_unmount(
572         bhv_desc_t      *bdp,
573         int             flags,
574         cred_t          *credp)
575 {
576         struct xfs_vfs  *vfsp = bhvtovfs(bdp);
577         xfs_mount_t     *mp = XFS_BHVTOM(bdp);
578         xfs_inode_t     *rip;
579         xfs_vnode_t     *rvp;
580         int             unmount_event_wanted = 0;
581         int             unmount_event_flags = 0;
582         int             xfs_unmountfs_needed = 0;
583         int             error;
584
585         rip = mp->m_rootip;
586         rvp = XFS_ITOV(rip);
587
588         if (vfsp->vfs_flag & VFS_DMI) {
589                 error = XFS_SEND_PREUNMOUNT(mp, vfsp,
590                                 rvp, DM_RIGHT_NULL, rvp, DM_RIGHT_NULL,
591                                 NULL, NULL, 0, 0,
592                                 (mp->m_dmevmask & (1<<DM_EVENT_PREUNMOUNT))?
593                                         0:DM_FLAGS_UNWANTED);
594                         if (error)
595                                 return XFS_ERROR(error);
596                 unmount_event_wanted = 1;
597                 unmount_event_flags = (mp->m_dmevmask & (1<<DM_EVENT_UNMOUNT))?
598                                         0 : DM_FLAGS_UNWANTED;
599         }
600
601         /*
602          * Linux (& presumably Irix) do not reach this code if
603          * any of this FS vnodes have active references. FreeBSD
604          * relies on FS to clean after itself.
605          */
606         xfs_iflush_all(mp);
607
608         /*
609          * First blow any referenced inode from this file system
610          * out of the reference cache, and delete the timer.
611          */
612         xfs_refcache_purge_mp(mp);
613
614         XFS_bflush(mp->m_ddev_targp);
615         error = xfs_unmount_flush(mp, 0);
616         if (error)
617                 goto out;
618
619         ASSERT(vn_count(rvp) == 1);
620
621         /*
622          * Drop the reference count
623          */
624         VN_RELE(rvp);
625
626         /*
627          * If we're forcing a shutdown, typically because of a media error,
628          * we want to make sure we invalidate dirty pages that belong to
629          * referenced vnodes as well.
630          */
631         if (XFS_FORCED_SHUTDOWN(mp)) {
632                 error = xfs_sync(&mp->m_bhv,
633                          (SYNC_WAIT | SYNC_CLOSE), credp);
634                 ASSERT(error != EFSCORRUPTED);
635         }
636         xfs_unmountfs_needed = 1;
637
638 out:
639         /*      Send DMAPI event, if required.
640          *      Then do xfs_unmountfs() if needed.
641          *      Then return error (or zero).
642          */
643         if (unmount_event_wanted) {
644                 /* Note: mp structure must still exist for
645                  * XFS_SEND_UNMOUNT() call.
646                  */
647                 XFS_SEND_UNMOUNT(mp, vfsp, error == 0 ? rvp : NULL,
648                         DM_RIGHT_NULL, 0, error, unmount_event_flags);
649         }
650         if (xfs_unmountfs_needed) {
651                 /*
652                  * Call common unmount function to flush to disk
653                  * and free the super block buffer & mount structures.
654                  */
655                 xfs_unmountfs(mp, credp);
656         }
657
658         return XFS_ERROR(error);
659 }
660
661 STATIC int
662 xfs_quiesce_fs(
663         xfs_mount_t             *mp)
664 {
665         int                     count = 0, pincount;
666
667         xfs_refcache_purge_mp(mp);
668         xfs_flush_buftarg(mp->m_ddev_targp, 0);
669         xfs_finish_reclaim_all(mp, 0);
670
671         /* This loop must run at least twice.
672          * The first instance of the loop will flush
673          * most meta data but that will generate more
674          * meta data (typically directory updates).
675          * Which then must be flushed and logged before
676          * we can write the unmount record.
677          */
678         do {
679                 xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, 0, NULL);
680                 pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
681                 if (!pincount) {
682                         delay(50);
683                         count++;
684                 }
685         } while (count < 2);
686
687         return 0;
688 }
689
690 /* XXXKAN */
691 #define pagebuf_delwri_flush(a,b,c)                     \
692         do {                                            \
693                 printf("pagebuf_delwri_flush NI\n");    \
694                 if (c) *((int *)(c)) = 0;               \
695         } while(0)
696
697 STATIC int
698 xfs_mntupdate(
699         bhv_desc_t                      *bdp,
700         int                             *flags,
701         struct xfs_mount_args           *args)
702 {
703         struct xfs_vfs  *vfsp = bhvtovfs(bdp);
704         xfs_mount_t     *mp = XFS_BHVTOM(bdp);
705         int             error;
706
707 #ifdef RMC
708         if (!(*flags & MS_RDONLY)) {                    /* rw/ro -> rw */
709 #endif
710           if (!(*flags & VFS_RDONLY)) {                 /* rw/ro -> rw */
711                 if (vfsp->vfs_flag & VFS_RDONLY)
712                         vfsp->vfs_flag &= ~VFS_RDONLY;
713                 if (args->flags & XFSMNT_BARRIER) {
714                         mp->m_flags |= XFS_MOUNT_BARRIER;
715                         xfs_mountfs_check_barriers(mp);
716                 } else {
717                         mp->m_flags &= ~XFS_MOUNT_BARRIER;
718                 }
719         } else if (!(vfsp->vfs_flag & VFS_RDONLY)) {    /* rw -> ro */
720                 XVFS_SYNC(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL, error);
721                 xfs_quiesce_fs(mp);
722                 xfs_log_unmount_write(mp);
723                 xfs_unmountfs_writesb(mp);
724                 vfsp->vfs_flag |= VFS_RDONLY;
725         }
726         return 0;
727 }
728
729 /*
730  * xfs_unmount_flush implements a set of flush operation on special
731  * inodes, which are needed as a separate set of operations so that
732  * they can be called as part of relocation process.
733  */
734 int
735 xfs_unmount_flush(
736         xfs_mount_t     *mp,            /* Mount structure we are getting
737                                            rid of. */
738         int             relocation)     /* Called from vfs relocation. */
739 {
740         xfs_inode_t     *rip = mp->m_rootip;
741         xfs_inode_t     *rbmip;
742         xfs_inode_t     *rsumip = NULL;
743         xfs_vnode_t     *rvp = XFS_ITOV_NULL(rip);
744         int             error;
745
746         if (rvp == NULL)
747                 return (0);
748         xfs_ilock(rip, XFS_ILOCK_EXCL);
749         xfs_iflock(rip);
750
751         /*
752          * Flush out the real time inodes.
753          */
754         if ((rbmip = mp->m_rbmip) != NULL) {
755                 xfs_ilock(rbmip, XFS_ILOCK_EXCL);
756                 xfs_iflock(rbmip);
757                 error = xfs_iflush(rbmip, XFS_IFLUSH_SYNC);
758                 xfs_iunlock(rbmip, XFS_ILOCK_EXCL);
759
760                 if (error == EFSCORRUPTED)
761                         goto fscorrupt_out;
762
763                 ASSERT(vn_count(XFS_ITOV(rbmip)) == 1);
764
765                 rsumip = mp->m_rsumip;
766                 xfs_ilock(rsumip, XFS_ILOCK_EXCL);
767                 xfs_iflock(rsumip);
768                 error = xfs_iflush(rsumip, XFS_IFLUSH_SYNC);
769                 xfs_iunlock(rsumip, XFS_ILOCK_EXCL);
770
771                 if (error == EFSCORRUPTED)
772                         goto fscorrupt_out;
773
774                 ASSERT(vn_count(XFS_ITOV(rsumip)) == 1);
775         }
776
777         /*
778          * Synchronously flush root inode to disk
779          */
780         error = xfs_iflush(rip, XFS_IFLUSH_SYNC);
781         if (error == EFSCORRUPTED)
782                 goto fscorrupt_out2;
783
784         if (vn_count(rvp) != 1 && !relocation) {
785                 xfs_iunlock(rip, XFS_ILOCK_EXCL);
786                 return XFS_ERROR(EBUSY);
787         }
788
789         /*
790          * Release dquot that rootinode, rbmino and rsumino might be holding,
791          * flush and purge the quota inodes.
792          */
793         error = XFS_QM_UNMOUNT(mp);
794         if (error == EFSCORRUPTED)
795                 goto fscorrupt_out2;
796
797         if (rbmip) {
798                 VN_RELE(XFS_ITOV(rbmip));
799                 VN_RELE(XFS_ITOV(rsumip));
800         }
801
802         xfs_iunlock(rip, XFS_ILOCK_EXCL);
803         return 0;
804
805 fscorrupt_out:
806         xfs_ifunlock(rip);
807
808 fscorrupt_out2:
809         xfs_iunlock(rip, XFS_ILOCK_EXCL);
810
811         return XFS_ERROR(EFSCORRUPTED);
812 }
813
814 /*
815  * xfs_root extracts the root vnode from a vfs.
816  *
817  * vfsp -- the vfs struct for the desired file system
818  * vpp  -- address of the caller's vnode pointer which should be
819  *         set to the desired fs root vnode
820  */
821 STATIC int
822 xfs_root(
823         bhv_desc_t      *bdp,
824         xfs_vnode_t     **vpp)
825 {
826         xfs_vnode_t     *vp;
827
828         vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip);
829         VN_HOLD(vp);
830         *vpp = vp;
831         return 0;
832 }
833
834 /*
835  * xfs_statvfs
836  *
837  * Fill in the statvfs structure for the given file system.  We use
838  * the superblock lock in the mount structure to ensure a consistent
839  * snapshot of the counters returned.
840  */
841 STATIC int
842 xfs_statvfs(
843         bhv_desc_t      *bdp,
844         xfs_statfs_t    *statp,
845         xfs_vnode_t     *vp)
846 {
847         __uint64_t      fakeinos;
848         xfs_extlen_t    lsize;
849         xfs_mount_t     *mp;
850         xfs_sb_t        *sbp;
851         unsigned long   s;
852
853         mp = XFS_BHVTOM(bdp);
854         sbp = &(mp->m_sb);
855
856         statp->f_type = XFS_SB_MAGIC;
857
858         xfs_icsb_sync_counters_lazy(mp);
859         s = XFS_SB_LOCK(mp);
860         statp->f_bsize = sbp->sb_blocksize;
861         lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0;
862         statp->f_blocks = sbp->sb_dblocks - lsize;
863         statp->f_bfree = statp->f_bavail = sbp->sb_fdblocks;
864         fakeinos = statp->f_bfree << sbp->sb_inopblog;
865 #if XFS_BIG_INUMS
866         fakeinos += mp->m_inoadd;
867 #endif
868         statp->f_files =
869             MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER);
870         if (mp->m_maxicount)
871 #if XFS_BIG_INUMS
872                 if (!mp->m_inoadd)
873 #endif
874                         statp->f_files = min_t(typeof(statp->f_files),
875                                                 statp->f_files,
876                                                 mp->m_maxicount);
877         statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
878         XFS_SB_UNLOCK(mp, s);
879
880         xfs_statvfs_fsid(statp, mp);
881         return 0;
882 }
883
884
885 /*
886  * xfs_sync flushes any pending I/O to file system vfsp.
887  *
888  * This routine is called by vfs_sync() to make sure that things make it
889  * out to disk eventually, on sync() system calls to flush out everything,
890  * and when the file system is unmounted.  For the vfs_sync() case, all
891  * we really need to do is sync out the log to make all of our meta-data
892  * updates permanent (except for timestamps).  For calls from pflushd(),
893  * dirty pages are kept moving by calling pdflush() on the inodes
894  * containing them.  We also flush the inodes that we can lock without
895  * sleeping and the superblock if we can lock it without sleeping from
896  * vfs_sync() so that items at the tail of the log are always moving out.
897  *
898  * Flags:
899  *      SYNC_BDFLUSH - We're being called from vfs_sync() so we don't want
900  *                     to sleep if we can help it.  All we really need
901  *                     to do is ensure that the log is synced at least
902  *                     periodically.  We also push the inodes and
903  *                     superblock if we can lock them without sleeping
904  *                      and they are not pinned.
905  *      SYNC_ATTR    - We need to flush the inodes.  If SYNC_BDFLUSH is not
906  *                     set, then we really want to lock each inode and flush
907  *                     it.
908  *      SYNC_WAIT    - All the flushes that take place in this call should
909  *                     be synchronous.
910  *      SYNC_DELWRI  - This tells us to push dirty pages associated with
911  *                     inodes.  SYNC_WAIT and SYNC_BDFLUSH are used to
912  *                     determine if they should be flushed sync, async, or
913  *                     delwri.
914  *      SYNC_CLOSE   - This flag is passed when the system is being
915  *                     unmounted.  We should sync and invalidate everything.
916  *      SYNC_FSDATA  - This indicates that the caller would like to make
917  *                     sure the superblock is safe on disk.  We can ensure
918  *                     this by simply making sure the log gets flushed
919  *                     if SYNC_BDFLUSH is set, and by actually writing it
920  *                     out otherwise.
921  *
922  */
923 /*ARGSUSED*/
924 STATIC int
925 xfs_sync(
926         bhv_desc_t      *bdp,
927         int             flags,
928         cred_t          *credp)
929 {
930         xfs_mount_t     *mp = XFS_BHVTOM(bdp);
931
932         if (unlikely(flags == SYNC_QUIESCE))
933                 return xfs_quiesce_fs(mp);
934         else
935                 return xfs_syncsub(mp, flags, 0, NULL);
936 }
937
938 /*
939  * xfs sync routine for internal use
940  *
941  * This routine supports all of the flags defined for the generic VFS_SYNC
942  * interface as explained above under xfs_sync.  In the interests of not
943  * changing interfaces within the 6.5 family, additional internally-
944  * required functions are specified within a separate xflags parameter,
945  * only available by calling this routine.
946  *
947  */
948 int
949 xfs_sync_inodes(
950         xfs_mount_t     *mp,
951         int             flags,
952         int             xflags,
953         int             *bypassed)
954 {
955         xfs_inode_t     *ip = NULL;
956         xfs_inode_t     *ip_next;
957         xfs_buf_t       *bp;
958         xfs_vnode_t     *vp = NULL;
959         int             error;
960         int             last_error;
961         uint64_t        fflag;
962         uint            lock_flags;
963         uint            base_lock_flags;
964         boolean_t       mount_locked;
965         boolean_t       vnode_refed;
966         int             preempt;
967         xfs_dinode_t    *dip;
968         xfs_iptr_t      *ipointer;
969 #ifdef DEBUG
970         boolean_t       ipointer_in = B_FALSE;
971
972 #define IPOINTER_SET    ipointer_in = B_TRUE
973 #define IPOINTER_CLR    ipointer_in = B_FALSE
974 #else
975 #define IPOINTER_SET
976 #define IPOINTER_CLR
977 #endif
978
979
980 /* Insert a marker record into the inode list after inode ip. The list
981  * must be locked when this is called. After the call the list will no
982  * longer be locked.
983  */
984 #define IPOINTER_INSERT(ip, mp) { \
985                 ASSERT(ipointer_in == B_FALSE); \
986                 ipointer->ip_mnext = ip->i_mnext; \
987                 ipointer->ip_mprev = ip; \
988                 ip->i_mnext = (xfs_inode_t *)ipointer; \
989                 ipointer->ip_mnext->i_mprev = (xfs_inode_t *)ipointer; \
990                 preempt = 0; \
991                 XFS_MOUNT_IUNLOCK(mp); \
992                 mount_locked = B_FALSE; \
993                 IPOINTER_SET; \
994         }
995
996 /* Remove the marker from the inode list. If the marker was the only item
997  * in the list then there are no remaining inodes and we should zero out
998  * the whole list. If we are the current head of the list then move the head
999  * past us.
1000  */
1001 #define IPOINTER_REMOVE(ip, mp) { \
1002                 ASSERT(ipointer_in == B_TRUE); \
1003                 if (ipointer->ip_mnext != (xfs_inode_t *)ipointer) { \
1004                         ip = ipointer->ip_mnext; \
1005                         ip->i_mprev = ipointer->ip_mprev; \
1006                         ipointer->ip_mprev->i_mnext = ip; \
1007                         if (mp->m_inodes == (xfs_inode_t *)ipointer) { \
1008                                 mp->m_inodes = ip; \
1009                         } \
1010                 } else { \
1011                         ASSERT(mp->m_inodes == (xfs_inode_t *)ipointer); \
1012                         mp->m_inodes = NULL; \
1013                         ip = NULL; \
1014                 } \
1015                 IPOINTER_CLR; \
1016         }
1017
1018 #define XFS_PREEMPT_MASK        0x7f
1019
1020         if (bypassed)
1021                 *bypassed = 0;
1022         if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY)
1023                 return 0;
1024         error = 0;
1025         last_error = 0;
1026         preempt = 0;
1027
1028         /* Allocate a reference marker */
1029         ipointer = (xfs_iptr_t *)kmem_zalloc(sizeof(xfs_iptr_t), KM_SLEEP);
1030
1031         fflag = XFS_B_ASYNC;            /* default is don't wait */
1032         if (flags & (SYNC_BDFLUSH | SYNC_DELWRI))
1033                 fflag = XFS_B_DELWRI;
1034         if (flags & SYNC_WAIT)
1035                 fflag = 0;              /* synchronous overrides all */
1036
1037         base_lock_flags = XFS_ILOCK_SHARED;
1038         if (flags & (SYNC_DELWRI | SYNC_CLOSE)) {
1039                 /*
1040                  * We need the I/O lock if we're going to call any of
1041                  * the flush/inval routines.
1042                  */
1043                 base_lock_flags |= XFS_IOLOCK_SHARED;
1044         }
1045
1046         XFS_MOUNT_ILOCK(mp);
1047
1048         ip = mp->m_inodes;
1049
1050         mount_locked = B_TRUE;
1051         vnode_refed  = B_FALSE;
1052
1053         IPOINTER_CLR;
1054
1055         do {
1056                 ASSERT(ipointer_in == B_FALSE);
1057                 ASSERT(vnode_refed == B_FALSE);
1058
1059                 lock_flags = base_lock_flags;
1060
1061                 /*
1062                  * There were no inodes in the list, just break out
1063                  * of the loop.
1064                  */
1065                 if (ip == NULL) {
1066                         break;
1067                 }
1068
1069                 /*
1070                  * We found another sync thread marker - skip it
1071                  */
1072                 if (ip->i_mount == NULL) {
1073                         ip = ip->i_mnext;
1074                         continue;
1075                 }
1076
1077                 vp = XFS_ITOV_NULL(ip);
1078
1079                 /*
1080                  * If the vnode is gone then this is being torn down,
1081                  * call reclaim if it is flushed, else let regular flush
1082                  * code deal with it later in the loop.
1083                  */
1084
1085                 if (vp == NULL) {
1086                         /* Skip ones already in reclaim */
1087                         if (ip->i_flags & XFS_IRECLAIM) {
1088                                 ip = ip->i_mnext;
1089                                 continue;
1090                         }
1091                         if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL) == 0) {
1092                                 ip = ip->i_mnext;
1093                         } else if ((xfs_ipincount(ip) == 0) &&
1094                                     xfs_iflock_nowait(ip)) {
1095                                 IPOINTER_INSERT(ip, mp);
1096
1097                                 xfs_finish_reclaim(ip, 1,
1098                                                 XFS_IFLUSH_DELWRI_ELSE_ASYNC);
1099
1100                                 XFS_MOUNT_ILOCK(mp);
1101                                 mount_locked = B_TRUE;
1102                                 IPOINTER_REMOVE(ip, mp);
1103                         } else {
1104                                 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1105                                 ip = ip->i_mnext;
1106                         }
1107                         continue;
1108                 }
1109
1110                 if (VN_BAD(vp)) {
1111                         ip = ip->i_mnext;
1112                         continue;
1113                 }
1114
1115                 if (XFS_FORCED_SHUTDOWN(mp) && !(flags & SYNC_CLOSE)) {
1116                         XFS_MOUNT_IUNLOCK(mp);
1117                         kmem_free(ipointer, sizeof(xfs_iptr_t));
1118                         return 0;
1119                 }
1120
1121                 /*
1122                  * If this is just vfs_sync() or pflushd() calling
1123                  * then we can skip inodes for which it looks like
1124                  * there is nothing to do.  Since we don't have the
1125                  * inode locked this is racy, but these are periodic
1126                  * calls so it doesn't matter.  For the others we want
1127                  * to know for sure, so we at least try to lock them.
1128                  */
1129                 if (flags & SYNC_BDFLUSH) {
1130                         if (((ip->i_itemp == NULL) ||
1131                              !(ip->i_itemp->ili_format.ilf_fields &
1132                                XFS_ILOG_ALL)) &&
1133                             (ip->i_update_core == 0)) {
1134                                 ip = ip->i_mnext;
1135                                 continue;
1136                         }
1137                 }
1138
1139                 /*
1140                  * Try to lock without sleeping.  We're out of order with
1141                  * the inode list lock here, so if we fail we need to drop
1142                  * the mount lock and try again.  If we're called from
1143                  * bdflush() here, then don't bother.
1144                  *
1145                  * The inode lock here actually coordinates with the
1146                  * almost spurious inode lock in xfs_ireclaim() to prevent
1147                  * the vnode we handle here without a reference from
1148                  * being freed while we reference it.  If we lock the inode
1149                  * while it's on the mount list here, then the spurious inode
1150                  * lock in xfs_ireclaim() after the inode is pulled from
1151                  * the mount list will sleep until we release it here.
1152                  * This keeps the vnode from being freed while we reference
1153                  * it.
1154                  */
1155                 if (xfs_ilock_nowait(ip, lock_flags) == 0) {
1156                         if ((flags & SYNC_BDFLUSH) || (vp == NULL)) {
1157                                 ip = ip->i_mnext;
1158                                 continue;
1159                         }
1160
1161                         vp = vn_grab(vp);
1162                         if (vp == NULL) {
1163                                 ip = ip->i_mnext;
1164                                 continue;
1165                         }
1166
1167                         IPOINTER_INSERT(ip, mp);
1168                         xfs_ilock(ip, lock_flags);
1169
1170                         ASSERT(vp == XFS_ITOV(ip));
1171                         ASSERT(ip->i_mount == mp);
1172
1173                         vnode_refed = B_TRUE;
1174                 }
1175
1176                 /* From here on in the loop we may have a marker record
1177                  * in the inode list.
1178                  */
1179
1180                 if ((flags & SYNC_CLOSE)  && (vp != NULL)) {
1181                         /*
1182                          * This is the shutdown case.  We just need to
1183                          * flush and invalidate all the pages associated
1184                          * with the inode.  Drop the inode lock since
1185                          * we can't hold it across calls to the buffer
1186                          * cache.
1187                          *
1188                          * We don't set the VREMAPPING bit in the vnode
1189                          * here, because we don't hold the vnode lock
1190                          * exclusively.  It doesn't really matter, though,
1191                          * because we only come here when we're shutting
1192                          * down anyway.
1193                          */
1194                         xfs_iunlock(ip, XFS_ILOCK_SHARED);
1195
1196                         if (XFS_FORCED_SHUTDOWN(mp)) {
1197                                 XVOP_TOSS_PAGES(vp, 0, -1, FI_REMAPF);
1198                         } else {
1199                                 XVOP_FLUSHINVAL_PAGES(vp, 0, -1, FI_REMAPF);
1200                         }
1201
1202                         xfs_ilock(ip, XFS_ILOCK_SHARED);
1203
1204                 } else if ((flags & SYNC_DELWRI) && (vp != NULL)) {
1205                         if (VN_DIRTY(vp)) {
1206                                 /* We need to have dropped the lock here,
1207                                  * so insert a marker if we have not already
1208                                  * done so.
1209                                  */
1210                                 if (mount_locked) {
1211                                         IPOINTER_INSERT(ip, mp);
1212                                 }
1213
1214                                 /*
1215                                  * Drop the inode lock since we can't hold it
1216                                  * across calls to the buffer cache.
1217                                  */
1218                                 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1219                                 XVOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1,
1220                                                         fflag, FI_NONE, error);
1221                                 xfs_ilock(ip, XFS_ILOCK_SHARED);
1222                         }
1223
1224                 }
1225
1226                 if (flags & SYNC_BDFLUSH) {
1227                         if ((flags & SYNC_ATTR) &&
1228                             ((ip->i_update_core) ||
1229                              ((ip->i_itemp != NULL) &&
1230                               (ip->i_itemp->ili_format.ilf_fields != 0)))) {
1231
1232                                 /* Insert marker and drop lock if not already
1233                                  * done.
1234                                  */
1235                                 if (mount_locked) {
1236                                         IPOINTER_INSERT(ip, mp);
1237                                 }
1238
1239                                 /*
1240                                  * We don't want the periodic flushing of the
1241                                  * inodes by vfs_sync() to interfere with
1242                                  * I/O to the file, especially read I/O
1243                                  * where it is only the access time stamp
1244                                  * that is being flushed out.  To prevent
1245                                  * long periods where we have both inode
1246                                  * locks held shared here while reading the
1247                                  * inode's buffer in from disk, we drop the
1248                                  * inode lock while reading in the inode
1249                                  * buffer.  We have to release the buffer
1250                                  * and reacquire the inode lock so that they
1251                                  * are acquired in the proper order (inode
1252                                  * locks first).  The buffer will go at the
1253                                  * end of the lru chain, though, so we can
1254                                  * expect it to still be there when we go
1255                                  * for it again in xfs_iflush().
1256                                  */
1257                                 if ((xfs_ipincount(ip) == 0) &&
1258                                     xfs_iflock_nowait(ip)) {
1259
1260                                         xfs_ifunlock(ip);
1261                                         xfs_iunlock(ip, XFS_ILOCK_SHARED);
1262
1263                                         error = xfs_itobp(mp, NULL, ip,
1264                                                           &dip, &bp, 0, 0);
1265                                         if (!error) {
1266                                                 xfs_buf_relse(bp);
1267                                         } else {
1268                                                 /* Bailing out, remove the
1269                                                  * marker and free it.
1270                                                  */
1271                                                 XFS_MOUNT_ILOCK(mp);
1272
1273                                                 IPOINTER_REMOVE(ip, mp);
1274
1275                                                 XFS_MOUNT_IUNLOCK(mp);
1276
1277                                                 ASSERT(!(lock_flags &
1278                                                         XFS_IOLOCK_SHARED));
1279
1280                                                 kmem_free(ipointer,
1281                                                         sizeof(xfs_iptr_t));
1282                                                 return (0);
1283                                         }
1284
1285                                         /*
1286                                          * Since we dropped the inode lock,
1287                                          * the inode may have been reclaimed.
1288                                          * Therefore, we reacquire the mount
1289                                          * lock and check to see if we were the
1290                                          * inode reclaimed. If this happened
1291                                          * then the ipointer marker will no
1292                                          * longer point back at us. In this
1293                                          * case, move ip along to the inode
1294                                          * after the marker, remove the marker
1295                                          * and continue.
1296                                          */
1297                                         XFS_MOUNT_ILOCK(mp);
1298                                         mount_locked = B_TRUE;
1299
1300                                         if (ip != ipointer->ip_mprev) {
1301                                                 IPOINTER_REMOVE(ip, mp);
1302
1303                                                 ASSERT(!vnode_refed);
1304                                                 ASSERT(!(lock_flags &
1305                                                         XFS_IOLOCK_SHARED));
1306                                                 continue;
1307                                         }
1308
1309                                         ASSERT(ip->i_mount == mp);
1310
1311                                         if (xfs_ilock_nowait(ip,
1312                                                     XFS_ILOCK_SHARED) == 0) {
1313                                                 ASSERT(ip->i_mount == mp);
1314                                                 /*
1315                                                  * We failed to reacquire
1316                                                  * the inode lock without
1317                                                  * sleeping, so just skip
1318                                                  * the inode for now.  We
1319                                                  * clear the ILOCK bit from
1320                                                  * the lock_flags so that we
1321                                                  * won't try to drop a lock
1322                                                  * we don't hold below.
1323                                                  */
1324                                                 lock_flags &= ~XFS_ILOCK_SHARED;
1325                                                 IPOINTER_REMOVE(ip_next, mp);
1326                                         } else if ((xfs_ipincount(ip) == 0) &&
1327                                                    xfs_iflock_nowait(ip)) {
1328                                                 ASSERT(ip->i_mount == mp);
1329                                                 /*
1330                                                  * Since this is vfs_sync()
1331                                                  * calling we only flush the
1332                                                  * inode out if we can lock
1333                                                  * it without sleeping and
1334                                                  * it is not pinned.  Drop
1335                                                  * the mount lock here so
1336                                                  * that we don't hold it for
1337                                                  * too long. We already have
1338                                                  * a marker in the list here.
1339                                                  */
1340                                                 XFS_MOUNT_IUNLOCK(mp);
1341                                                 mount_locked = B_FALSE;
1342                                                 error = xfs_iflush(ip,
1343                                                            XFS_IFLUSH_DELWRI);
1344                                         } else {
1345                                                 ASSERT(ip->i_mount == mp);
1346                                                 IPOINTER_REMOVE(ip_next, mp);
1347                                         }
1348                                 }
1349
1350                         }
1351
1352                 } else {
1353                         if ((flags & SYNC_ATTR) &&
1354                             ((ip->i_update_core) ||
1355                              ((ip->i_itemp != NULL) &&
1356                               (ip->i_itemp->ili_format.ilf_fields != 0)))) {
1357                                 if (mount_locked) {
1358                                         IPOINTER_INSERT(ip, mp);
1359                                 }
1360
1361                                 if (flags & SYNC_WAIT) {
1362                                         xfs_iflock(ip);
1363                                         error = xfs_iflush(ip,
1364                                                            XFS_IFLUSH_SYNC);
1365                                 } else {
1366                                         /*
1367                                          * If we can't acquire the flush
1368                                          * lock, then the inode is already
1369                                          * being flushed so don't bother
1370                                          * waiting.  If we can lock it then
1371                                          * do a delwri flush so we can
1372                                          * combine multiple inode flushes
1373                                          * in each disk write.
1374                                          */
1375                                         if (xfs_iflock_nowait(ip)) {
1376                                                 error = xfs_iflush(ip,
1377                                                            XFS_IFLUSH_DELWRI);
1378                                         }
1379                                         else if (bypassed)
1380                                                 (*bypassed)++;
1381                                 }
1382                         }
1383                 }
1384
1385                 if (lock_flags != 0) {
1386                         xfs_iunlock(ip, lock_flags);
1387                 }
1388
1389                 if (vnode_refed) {
1390                         /*
1391                          * If we had to take a reference on the vnode
1392                          * above, then wait until after we've unlocked
1393                          * the inode to release the reference.  This is
1394                          * because we can be already holding the inode
1395                          * lock when VN_RELE() calls xfs_inactive().
1396                          *
1397                          * Make sure to drop the mount lock before calling
1398                          * VN_RELE() so that we don't trip over ourselves if
1399                          * we have to go for the mount lock again in the
1400                          * inactive code.
1401                          */
1402                         if (mount_locked) {
1403                                 IPOINTER_INSERT(ip, mp);
1404                         }
1405
1406                         VN_RELE(vp);
1407
1408                         vnode_refed = B_FALSE;
1409                 }
1410
1411                 if (error) {
1412                         last_error = error;
1413                 }
1414
1415                 /*
1416                  * bail out if the filesystem is corrupted.
1417                  */
1418                 if (error == EFSCORRUPTED)  {
1419                         if (!mount_locked) {
1420                                 XFS_MOUNT_ILOCK(mp);
1421                                 IPOINTER_REMOVE(ip, mp);
1422                         }
1423                         XFS_MOUNT_IUNLOCK(mp);
1424                         ASSERT(ipointer_in == B_FALSE);
1425                         kmem_free(ipointer, sizeof(xfs_iptr_t));
1426                         return XFS_ERROR(error);
1427                 }
1428
1429                 /* Let other threads have a chance at the mount lock
1430                  * if we have looped many times without dropping the
1431                  * lock.
1432                  */
1433                 if ((++preempt & XFS_PREEMPT_MASK) == 0) {
1434                         if (mount_locked) {
1435                                 IPOINTER_INSERT(ip, mp);
1436                         }
1437                 }
1438
1439                 if (mount_locked == B_FALSE) {
1440                         XFS_MOUNT_ILOCK(mp);
1441                         mount_locked = B_TRUE;
1442                         IPOINTER_REMOVE(ip, mp);
1443                         continue;
1444                 }
1445
1446                 ASSERT(ipointer_in == B_FALSE);
1447                 ip = ip->i_mnext;
1448
1449         } while (ip != mp->m_inodes);
1450
1451         XFS_MOUNT_IUNLOCK(mp);
1452
1453         ASSERT(ipointer_in == B_FALSE);
1454
1455         kmem_free(ipointer, sizeof(xfs_iptr_t));
1456         return XFS_ERROR(last_error);
1457 }
1458
1459 /*
1460  * xfs sync routine for internal use
1461  *
1462  * This routine supports all of the flags defined for the generic VFS_SYNC
1463  * interface as explained above under xfs_sync.  In the interests of not
1464  * changing interfaces within the 6.5 family, additional internally-
1465  * required functions are specified within a separate xflags parameter,
1466  * only available by calling this routine.
1467  *
1468  */
1469 int
1470 xfs_syncsub(
1471         xfs_mount_t     *mp,
1472         int             flags,
1473         int             xflags,
1474         int             *bypassed)
1475 {
1476         int             error = 0;
1477         int             last_error = 0;
1478         uint            log_flags = XFS_LOG_FORCE;
1479         xfs_buf_t       *bp;
1480         xfs_buf_log_item_t      *bip;
1481
1482         /*
1483          * Sync out the log.  This ensures that the log is periodically
1484          * flushed even if there is not enough activity to fill it up.
1485          */
1486         if (flags & SYNC_WAIT)
1487                 log_flags |= XFS_LOG_SYNC;
1488
1489         xfs_log_force(mp, (xfs_lsn_t)0, log_flags);
1490
1491         if (flags & (SYNC_ATTR|SYNC_DELWRI)) {
1492                 if (flags & SYNC_BDFLUSH)
1493                         xfs_finish_reclaim_all(mp, 1);
1494                 else
1495                         error = xfs_sync_inodes(mp, flags, xflags, bypassed);
1496         }
1497
1498         /*
1499          * Flushing out dirty data above probably generated more
1500          * log activity, so if this isn't vfs_sync() then flush
1501          * the log again.
1502          */
1503         if (flags & SYNC_DELWRI) {
1504                 xfs_log_force(mp, (xfs_lsn_t)0, log_flags);
1505         }
1506
1507         if (flags & SYNC_FSDATA) {
1508                 /*
1509                  * If this is vfs_sync() then only sync the superblock
1510                  * if we can lock it without sleeping and it is not pinned.
1511                  */
1512                 if (flags & SYNC_BDFLUSH) {
1513                         bp = xfs_getsb(mp, XFS_BUF_TRYLOCK);
1514                         if (bp != NULL) {
1515                                 bip = XFS_BUF_FSPRIVATE(bp,xfs_buf_log_item_t*);
1516                                 if ((bip != NULL) &&
1517                                     xfs_buf_item_dirty(bip)) {
1518                                         if (!(XFS_BUF_ISPINNED(bp))) {
1519                                                 XFS_BUF_ASYNC(bp);
1520                                                 error = xfs_bwrite(mp, bp);
1521                                         } else {
1522                                                 xfs_buf_relse(bp);
1523                                         }
1524                                 } else {
1525                                         xfs_buf_relse(bp);
1526                                 }
1527                         }
1528                 } else {
1529                         bp = xfs_getsb(mp, 0);
1530                         /*
1531                          * If the buffer is pinned then push on the log so
1532                          * we won't get stuck waiting in the write for
1533                          * someone, maybe ourselves, to flush the log.
1534                          * Even though we just pushed the log above, we
1535                          * did not have the superblock buffer locked at
1536                          * that point so it can become pinned in between
1537                          * there and here.
1538                          */
1539                         if (XFS_BUF_ISPINNED(bp))
1540                                 xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE);
1541                         if (flags & SYNC_WAIT)
1542                                 XFS_BUF_UNASYNC(bp);
1543                         else
1544                                 XFS_BUF_ASYNC(bp);
1545                         error = xfs_bwrite(mp, bp);
1546                 }
1547                 if (error) {
1548                         last_error = error;
1549                 }
1550         }
1551
1552         /*
1553          * If this is the periodic sync, then kick some entries out of
1554          * the reference cache.  This ensures that idle entries are
1555          * eventually kicked out of the cache.
1556          */
1557         if (flags & SYNC_REFCACHE) {
1558                 if (flags & SYNC_WAIT)
1559                         xfs_refcache_purge_mp(mp);
1560                 else
1561                         xfs_refcache_purge_some(mp);
1562         }
1563
1564         /*
1565          * Now check to see if the log needs a "dummy" transaction.
1566          */
1567
1568         if (!(flags & SYNC_REMOUNT) && xfs_log_need_covered(mp)) {
1569                 xfs_trans_t *tp;
1570                 xfs_inode_t *ip;
1571
1572                 /*
1573                  * Put a dummy transaction in the log to tell
1574                  * recovery that all others are OK.
1575                  */
1576                 tp = xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
1577                 if ((error = xfs_trans_reserve(tp, 0,
1578                                 XFS_ICHANGE_LOG_RES(mp),
1579                                 0, 0, 0)))  {
1580                         xfs_trans_cancel(tp, 0);
1581                         return error;
1582                 }
1583
1584                 ip = mp->m_rootip;
1585                 xfs_ilock(ip, XFS_ILOCK_EXCL);
1586
1587                 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
1588                 xfs_trans_ihold(tp, ip);
1589                 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1590                 error = xfs_trans_commit(tp, 0, NULL);
1591                 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1592                 xfs_log_force(mp, (xfs_lsn_t)0, log_flags);
1593         }
1594
1595         /*
1596          * When shutting down, we need to insure that the AIL is pushed
1597          * to disk or the filesystem can appear corrupt from the PROM.
1598          */
1599         if ((flags & (SYNC_CLOSE|SYNC_WAIT)) == (SYNC_CLOSE|SYNC_WAIT)) {
1600                 XFS_bflush(mp->m_ddev_targp);
1601                 if (mp->m_rtdev_targp) {
1602                         XFS_bflush(mp->m_rtdev_targp);
1603                 }
1604         }
1605
1606         return XFS_ERROR(last_error);
1607 }
1608
1609 /*
1610  * xfs_vget - called by DMAPI and NFSD to get vnode from file handle
1611  */
1612 STATIC int
1613 xfs_vget(
1614         bhv_desc_t      *bdp,
1615         xfs_vnode_t     **vpp,
1616         fid_t           *fidp)
1617 {
1618         xfs_mount_t     *mp = XFS_BHVTOM(bdp);
1619         xfs_fid_t       *xfid = (struct xfs_fid *)fidp;
1620         xfs_inode_t     *ip;
1621         int             error;
1622         xfs_ino_t       ino;
1623         unsigned int    igen;
1624
1625         /*
1626          * Invalid.  Since handles can be created in user space and passed in
1627          * via gethandle(), this is not cause for a panic.
1628          */
1629         if (xfid->xfs_fid_len != sizeof(*xfid) - sizeof(xfid->xfs_fid_len))
1630                 return XFS_ERROR(EINVAL);
1631
1632         ino  = xfid->xfs_fid_ino;
1633         igen = xfid->xfs_fid_gen;
1634
1635         /*
1636          * NFS can sometimes send requests for ino 0.  Fail them gracefully.
1637          */
1638         if (ino == 0)
1639                 return XFS_ERROR(ESTALE);
1640
1641         error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0);
1642         if (error) {
1643                 *vpp = NULL;
1644                 return error;
1645         }
1646
1647         if (ip == NULL) {
1648                 *vpp = NULL;
1649                 return XFS_ERROR(EIO);
1650         }
1651
1652         if (ip->i_d.di_mode == 0 || ip->i_d.di_gen != igen) {
1653                 xfs_iput_new(ip, XFS_ILOCK_SHARED);
1654                 *vpp = NULL;
1655                 return XFS_ERROR(ENOENT);
1656         }
1657
1658         *vpp = XFS_ITOV(ip);
1659         xfs_iunlock(ip, XFS_ILOCK_SHARED);
1660         return 0;
1661 }
1662
1663
1664 #define MNTOPT_LOGBUFS          "logbufs"       /* number of XFS log buffers */
1665 #define MNTOPT_LOGBSIZE         "logbsize"      /* size of XFS log buffers */
1666 #define MNTOPT_LOGDEV           "logdev"        /* log device */
1667 #define MNTOPT_RTDEV            "rtdev"         /* realtime I/O device */
1668 #define MNTOPT_BIOSIZE          "biosize"       /* log2 of preferred buffered io size */
1669 #define MNTOPT_WSYNC            "wsync"         /* safe-mode nfs compatible mount */
1670 #define MNTOPT_INO64            "ino64"         /* force inodes into 64-bit range */
1671 #define MNTOPT_NOALIGN          "noalign"       /* turn off stripe alignment */
1672 #define MNTOPT_SWALLOC          "swalloc"       /* turn on stripe width allocation */
1673 #define MNTOPT_SUNIT            "sunit"         /* data volume stripe unit */
1674 #define MNTOPT_SWIDTH           "swidth"        /* data volume stripe width */
1675 #define MNTOPT_NOUUID           "nouuid"        /* ignore filesystem UUID */
1676 #define MNTOPT_MTPT             "mtpt"          /* filesystem mount point */
1677 #define MNTOPT_GRPID            "grpid"         /* group-ID from parent directory */
1678 #define MNTOPT_NOGRPID          "nogrpid"       /* group-ID from current process */
1679 #define MNTOPT_BSDGROUPS        "bsdgroups"    /* group-ID from parent directory */
1680 #define MNTOPT_SYSVGROUPS       "sysvgroups"   /* group-ID from current process */
1681 #define MNTOPT_ALLOCSIZE        "allocsize"    /* preferred allocation size */
1682 #define MNTOPT_IHASHSIZE        "ihashsize"    /* size of inode hash table */
1683 #define MNTOPT_NORECOVERY       "norecovery"   /* don't run XFS recovery */
1684 #define MNTOPT_BARRIER          "barrier"       /* use writer barriers for log write and
1685                                          * unwritten extent conversion */
1686 #define MNTOPT_NOBARRIER        "nobarrier"     /* .. disable */
1687 #define MNTOPT_OSYNCISOSYNC     "osyncisosync" /* o_sync is REALLY o_sync */
1688 #define MNTOPT_64BITINODE       "inode64"       /* inodes can be allocated anywhere */
1689 #define MNTOPT_IKEEP            "ikeep"         /* do not free empty inode clusters */
1690 #define MNTOPT_NOIKEEP          "noikeep"       /* free empty inode clusters */
1691 #define MNTOPT_LARGEIO          "largeio"       /* report large I/O sizes in stat() */
1692 #define MNTOPT_NOLARGEIO        "nolargeio"     /* do not report large I/O sizes
1693                                          * in stat(). */
1694 #define MNTOPT_ATTR2            "attr2"         /* do use attr2 attribute format */
1695 #define MNTOPT_NOATTR2          "noattr2"       /* do not use attr2 attribute format */
1696 #define simple_strtoul          strtoul
1697
1698 STATIC unsigned long
1699 suffix_strtoul(char *cp, char **endp, unsigned int base)
1700 {
1701         int     last, shift_left_factor = 0;
1702         char    *value = (char *)cp;
1703
1704         last = strlen(value) - 1;
1705         if (value[last] == 'K' || value[last] == 'k') {
1706                 shift_left_factor = 10;
1707                 value[last] = '\0';
1708         }
1709         if (value[last] == 'M' || value[last] == 'm') {
1710                 shift_left_factor = 20;
1711                 value[last] = '\0';
1712         }
1713         if (value[last] == 'G' || value[last] == 'g') {
1714                 shift_left_factor = 30;
1715                 value[last] = '\0';
1716         }
1717
1718         return simple_strtoul(cp, endp, base) << shift_left_factor;
1719 }
1720
1721
1722 STATIC int
1723 xfs_parseargs(
1724         struct bhv_desc         *bhv,
1725         char                    *options,
1726         struct xfs_mount_args   *args,
1727         int                     update)
1728 {
1729         struct xfs_vfs          *vfsp = bhvtovfs(bhv);
1730         char                    *this_char, *value, *eov;
1731         int                     dsunit, dswidth, vol_dsunit, vol_dswidth;
1732         int                     iosize;
1733
1734         args->flags |= XFSMNT_IDELETE;
1735         args->flags |= XFSMNT_BARRIER;
1736         args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
1737
1738         if (!options)
1739                 goto done;
1740
1741         iosize = dsunit = dswidth = vol_dsunit = vol_dswidth = 0;
1742
1743         while ((this_char = strsep(&options, ",")) != NULL) {
1744                 if (!*this_char)
1745                         continue;
1746
1747                 if ((value = index(this_char, '=')) != NULL)
1748                         *value++ = 0;
1749
1750                 if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
1751                         if (!value || !*value) {
1752                                 printf("XFS: %s option requires an argument\n",
1753                                         this_char);
1754                                 return EINVAL;
1755                         }
1756                         args->logbufs = simple_strtoul(value, &eov, 10);
1757                 } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
1758                         if (!value || !*value) {
1759                                 printf("XFS: %s option requires an argument\n",
1760                                         this_char);
1761                                 return EINVAL;
1762                         }
1763                         args->logbufsize = suffix_strtoul(value, &eov, 10);
1764                 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
1765                         if (!value || !*value) {
1766                                 printf("XFS: %s option requires an argument\n",
1767                                         this_char);
1768                                 return EINVAL;
1769                         }
1770                         strncpy(args->logname, value, MAXNAMELEN);
1771                 } else if (!strcmp(this_char, MNTOPT_MTPT)) {
1772                         if (!value || !*value) {
1773                                 printf("XFS: %s option requires an argument\n",
1774                                         this_char);
1775                                 return EINVAL;
1776                         }
1777                         strncpy(args->mtpt, value, MAXNAMELEN);
1778                 } else if (!strcmp(this_char, MNTOPT_RTDEV)) {
1779                         if (!value || !*value) {
1780                                 printf("XFS: %s option requires an argument\n",
1781                                         this_char);
1782                                 return EINVAL;
1783                         }
1784                         strncpy(args->rtname, value, MAXNAMELEN);
1785                 } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
1786                         if (!value || !*value) {
1787                                 printf("XFS: %s option requires an argument\n",
1788                                         this_char);
1789                                 return EINVAL;
1790                         }
1791                         iosize = simple_strtoul(value, &eov, 10);
1792                         args->flags |= XFSMNT_IOSIZE;
1793                         args->iosizelog = (uint8_t) iosize;
1794                 } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
1795                         if (!value || !*value) {
1796                                 printk("XFS: %s option requires an argument\n",
1797                                         this_char);
1798                                 return EINVAL;
1799                         }
1800                         iosize = suffix_strtoul(value, &eov, 10);
1801                         args->flags |= XFSMNT_IOSIZE;
1802                         args->iosizelog = ffs(iosize) - 1;
1803                 } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) {
1804                         if (!value || !*value) {
1805                                 printk("XFS: %s option requires an argument\n",
1806                                         this_char);
1807                                 return EINVAL;
1808                         }
1809                         args->flags |= XFSMNT_IHASHSIZE;
1810                         args->ihashsize = simple_strtoul(value, &eov, 10);
1811                 } else if (!strcmp(this_char, MNTOPT_GRPID) ||
1812                            !strcmp(this_char, MNTOPT_BSDGROUPS)) {
1813                         vfsp->vfs_flag |= VFS_GRPID;
1814                 } else if (!strcmp(this_char, MNTOPT_NOGRPID) ||
1815                            !strcmp(this_char, MNTOPT_SYSVGROUPS)) {
1816                         vfsp->vfs_flag &= ~VFS_GRPID;
1817                 } else if (!strcmp(this_char, MNTOPT_WSYNC)) {
1818                         args->flags |= XFSMNT_WSYNC;
1819                 } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {
1820                         args->flags |= XFSMNT_OSYNCISOSYNC;
1821                 } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
1822                         args->flags |= XFSMNT_NORECOVERY;
1823                 } else if (!strcmp(this_char, MNTOPT_INO64)) {
1824                         args->flags |= XFSMNT_INO64;
1825 #if !XFS_BIG_INUMS
1826
1827                         printf("XFS: %s option not allowed on this system\n",
1828                                 this_char);
1829                         return EINVAL;
1830 #endif
1831                 } else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
1832                         args->flags |= XFSMNT_NOALIGN;
1833                 } else if (!strcmp(this_char, MNTOPT_SWALLOC)) {
1834                         args->flags |= XFSMNT_SWALLOC;
1835                 } else if (!strcmp(this_char, MNTOPT_SUNIT)) {
1836                         if (!value || !*value) {
1837                                 printf("XFS: %s option requires an argument\n",
1838                                         this_char);
1839                                 return EINVAL;
1840                         }
1841                         dsunit = simple_strtoul(value, &eov, 10);
1842                 } else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
1843                         if (!value || !*value) {
1844                                 printf("XFS: %s option requires an argument\n",
1845                                         this_char);
1846                                 return EINVAL;
1847                         }
1848                         dswidth = simple_strtoul(value, &eov, 10);
1849                 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
1850                         args->flags &= ~XFSMNT_32BITINODES;
1851 #if !XFS_BIG_INUMS
1852
1853                         printf("XFS: %s option not allowed on this system\n",
1854                                 this_char);
1855                         return EINVAL;
1856 #endif
1857                 } else if (!strcmp(this_char, MNTOPT_NOUUID)) {
1858                         args->flags |= XFSMNT_NOUUID;
1859                 } else if (!strcmp(this_char, MNTOPT_BARRIER)) {
1860                         args->flags |= XFSMNT_BARRIER;
1861                 } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
1862                         args->flags &= ~XFSMNT_BARRIER;
1863                 } else if (!strcmp(this_char, MNTOPT_IKEEP)) {
1864                         args->flags &= ~XFSMNT_IDELETE;
1865                 } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
1866                         args->flags |= XFSMNT_IDELETE;
1867                 } else if (!strcmp(this_char, MNTOPT_LARGEIO)) {
1868                         args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE;
1869                 } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {
1870                         args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
1871                 } else if (!strcmp(this_char, MNTOPT_ATTR2)) {
1872                         args->flags |= XFSMNT_ATTR2;
1873                 } else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
1874                         args->flags &= ~XFSMNT_ATTR2;
1875                 } else if (!strcmp(this_char, "osyncisdsync")) {
1876                         /* no-op, this is now the default */
1877 printf("XFS: osyncisdsync is now the default, option is deprecated.\n");
1878                 } else if (!strcmp(this_char, "irixsgid")) {
1879 printf("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n");
1880                 } else {
1881                         printf("XFS: unknown mount option [%s].\n", this_char);
1882                         return EINVAL;
1883                 }
1884         }
1885
1886         if (args->flags & XFSMNT_NORECOVERY) {
1887                 if ((vfsp->vfs_flag & VFS_RDONLY) == 0) {
1888                         printf("XFS: no-recovery mounts must be read-only.\n");
1889                         return EINVAL;
1890                 }
1891         }
1892
1893         if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) {
1894                 printf(
1895         "XFS: sunit and swidth options incompatible with the noalign option\n");
1896                 return EINVAL;
1897         }
1898
1899         if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
1900                 printf("XFS: sunit and swidth must be specified together\n");
1901                 return EINVAL;
1902         }
1903
1904         if (dsunit && (dswidth % dsunit != 0)) {
1905                 printf(
1906         "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)\n",
1907                         dswidth, dsunit);
1908                 return EINVAL;
1909         }
1910
1911         if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
1912                 if (dsunit) {
1913                         args->sunit = dsunit;
1914                         args->flags |= XFSMNT_RETERR;
1915                 } else {
1916                         args->sunit = vol_dsunit;
1917                 }
1918                 dswidth ? (args->swidth = dswidth) :
1919                           (args->swidth = vol_dswidth);
1920         } else {
1921                 args->sunit = args->swidth = 0;
1922         }
1923
1924 done:
1925         if (args->flags & XFSMNT_32BITINODES)
1926                 vfsp->vfs_flag |= VFS_32BITINODES;
1927         if (args->flags2)
1928                 args->flags |= XFSMNT_FLAGS2;
1929         return 0;
1930 }
1931
1932 #define seq_printf sbuf_printf
1933 STATIC int
1934 xfs_showargs(
1935         struct bhv_desc         *bhv,
1936         struct sbuf             *m)
1937 {
1938         static struct proc_xfs_info {
1939                 int     flag;
1940                 char    *str;
1941         } xfs_info[] = {
1942                 /* the few simple ones we can get from the mount struct */
1943                 { XFS_MOUNT_WSYNC,              "," MNTOPT_WSYNC },
1944                 { XFS_MOUNT_INO64,              "," MNTOPT_INO64 },
1945                 { XFS_MOUNT_NOALIGN,            "," MNTOPT_NOALIGN },
1946                 { XFS_MOUNT_SWALLOC,            "," MNTOPT_SWALLOC },
1947                 { XFS_MOUNT_NOUUID,             "," MNTOPT_NOUUID },
1948                 { XFS_MOUNT_NORECOVERY,         "," MNTOPT_NORECOVERY },
1949                 { XFS_MOUNT_OSYNCISOSYNC,       "," MNTOPT_OSYNCISOSYNC },
1950                 { 0, NULL }
1951         };
1952         struct proc_xfs_info    *xfs_infop;
1953         struct xfs_mount        *mp = XFS_BHVTOM(bhv);
1954         struct xfs_vfs          *vfsp = XFS_MTOVFS(mp);
1955
1956         for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
1957                 if (mp->m_flags & xfs_infop->flag)
1958                         sbuf_printf(m, "%s", xfs_infop->str);
1959         }
1960
1961         if (mp->m_flags & XFS_MOUNT_IHASHSIZE)
1962                 seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize);
1963
1964         if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
1965                 seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk",
1966                                 (int)(1 << mp->m_writeio_log) >> 10);
1967
1968         if (mp->m_logbufs > 0)
1969                 sbuf_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);
1970         if (mp->m_logbsize > 0)
1971                 seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10);
1972
1973         if (mp->m_logname)
1974                 seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname);
1975         if (mp->m_rtname)
1976                 seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname);
1977
1978         if (mp->m_dalign > 0)
1979                 sbuf_printf(m, "," MNTOPT_SUNIT "=%d",
1980                                 (int)XFS_FSB_TO_BB(mp, mp->m_dalign));
1981         if (mp->m_swidth > 0)
1982                 sbuf_printf(m, "," MNTOPT_SWIDTH "=%d",
1983                                 (int)XFS_FSB_TO_BB(mp, mp->m_swidth));
1984
1985         if (!(mp->m_flags & XFS_MOUNT_IDELETE))
1986                 seq_printf(m, "," MNTOPT_IKEEP);
1987         if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE))
1988                 seq_printf(m, "," MNTOPT_LARGEIO);
1989
1990         if (!(vfsp->vfs_flag & VFS_32BITINODES))
1991                 sbuf_printf(m, "," MNTOPT_64BITINODE);
1992         if (vfsp->vfs_flag & VFS_GRPID)
1993                 seq_printf(m, "," MNTOPT_GRPID);
1994
1995         return 0;
1996 }
1997
1998 STATIC void
1999 xfs_freeze(
2000         bhv_desc_t      *bdp)
2001 {
2002         xfs_mount_t     *mp = XFS_BHVTOM(bdp);
2003
2004         while (atomic_read(&mp->m_active_trans) > 0)
2005                 delay(100);
2006
2007         /* Push the superblock and write an unmount record */
2008         xfs_log_unmount_write(mp);
2009         xfs_unmountfs_writesb(mp);
2010         xfs_fs_log_dummy(mp);
2011 }
2012
2013
2014 xvfsops_t xfs_vfsops = {
2015         BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS),
2016         .xvfs_parseargs         = xfs_parseargs,
2017         .xvfs_showargs          = xfs_showargs,
2018         .xvfs_mount             = xfs_mount,
2019         .xvfs_unmount           = xfs_unmount,
2020         .xvfs_mntupdate         = xfs_mntupdate,
2021         .xvfs_root              = xfs_root,
2022         .xvfs_statvfs           = xfs_statvfs,
2023         .xvfs_sync              = xfs_sync,
2024         .xvfs_vget              = xfs_vget,
2025         .xvfs_dmapiops          = (xvfs_dmapiops_t)fs_nosys,
2026         .xvfs_quotactl          = (xvfs_quotactl_t)fs_nosys,
2027         .xvfs_get_inode         = (xvfs_get_inode_t)fs_nosys,
2028         .xvfs_init_vnode        = xfs_initialize_vnode,
2029         .xvfs_force_shutdown    = xfs_do_force_shutdown,
2030         .xvfs_freeze            = xfs_freeze,
2031 };