aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_vfsops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_vfsops.c')
-rw-r--r--fs/xfs/xfs_vfsops.c351
1 files changed, 222 insertions, 129 deletions
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 11f5ea29a038..a5a8454f2a63 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -54,8 +54,9 @@
54#include "xfs_mru_cache.h" 54#include "xfs_mru_cache.h"
55#include "xfs_filestream.h" 55#include "xfs_filestream.h"
56#include "xfs_fsops.h" 56#include "xfs_fsops.h"
57#include "xfs_vnodeops.h"
58#include "xfs_vfsops.h"
57 59
58STATIC int xfs_sync(bhv_desc_t *, int, cred_t *);
59 60
60int 61int
61xfs_init(void) 62xfs_init(void)
@@ -117,8 +118,8 @@ xfs_init(void)
117 xfs_ili_zone = 118 xfs_ili_zone =
118 kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili", 119 kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili",
119 KM_ZONE_SPREAD, NULL); 120 KM_ZONE_SPREAD, NULL);
120 xfs_chashlist_zone = 121 xfs_icluster_zone =
121 kmem_zone_init_flags(sizeof(xfs_chashlist_t), "xfs_chashlist", 122 kmem_zone_init_flags(sizeof(xfs_icluster_t), "xfs_icluster",
122 KM_ZONE_SPREAD, NULL); 123 KM_ZONE_SPREAD, NULL);
123 124
124 /* 125 /*
@@ -163,7 +164,7 @@ xfs_cleanup(void)
163 extern kmem_zone_t *xfs_efd_zone; 164 extern kmem_zone_t *xfs_efd_zone;
164 extern kmem_zone_t *xfs_efi_zone; 165 extern kmem_zone_t *xfs_efi_zone;
165 extern kmem_zone_t *xfs_buf_item_zone; 166 extern kmem_zone_t *xfs_buf_item_zone;
166 extern kmem_zone_t *xfs_chashlist_zone; 167 extern kmem_zone_t *xfs_icluster_zone;
167 168
168 xfs_cleanup_procfs(); 169 xfs_cleanup_procfs();
169 xfs_sysctl_unregister(); 170 xfs_sysctl_unregister();
@@ -199,7 +200,7 @@ xfs_cleanup(void)
199 kmem_zone_destroy(xfs_efi_zone); 200 kmem_zone_destroy(xfs_efi_zone);
200 kmem_zone_destroy(xfs_ifork_zone); 201 kmem_zone_destroy(xfs_ifork_zone);
201 kmem_zone_destroy(xfs_ili_zone); 202 kmem_zone_destroy(xfs_ili_zone);
202 kmem_zone_destroy(xfs_chashlist_zone); 203 kmem_zone_destroy(xfs_icluster_zone);
203} 204}
204 205
205/* 206/*
@@ -210,7 +211,6 @@ xfs_cleanup(void)
210 */ 211 */
211STATIC int 212STATIC int
212xfs_start_flags( 213xfs_start_flags(
213 struct bhv_vfs *vfs,
214 struct xfs_mount_args *ap, 214 struct xfs_mount_args *ap,
215 struct xfs_mount *mp) 215 struct xfs_mount *mp)
216{ 216{
@@ -238,17 +238,14 @@ xfs_start_flags(
238 mp->m_logbufs = ap->logbufs; 238 mp->m_logbufs = ap->logbufs;
239 if (ap->logbufsize != -1 && 239 if (ap->logbufsize != -1 &&
240 ap->logbufsize != 0 && 240 ap->logbufsize != 0 &&
241 ap->logbufsize != 16 * 1024 && 241 (ap->logbufsize < XLOG_MIN_RECORD_BSIZE ||
242 ap->logbufsize != 32 * 1024 && 242 ap->logbufsize > XLOG_MAX_RECORD_BSIZE ||
243 ap->logbufsize != 64 * 1024 && 243 !is_power_of_2(ap->logbufsize))) {
244 ap->logbufsize != 128 * 1024 &&
245 ap->logbufsize != 256 * 1024) {
246 cmn_err(CE_WARN, 244 cmn_err(CE_WARN,
247 "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", 245 "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
248 ap->logbufsize); 246 ap->logbufsize);
249 return XFS_ERROR(EINVAL); 247 return XFS_ERROR(EINVAL);
250 } 248 }
251 mp->m_ihsize = ap->ihashsize;
252 mp->m_logbsize = ap->logbufsize; 249 mp->m_logbsize = ap->logbufsize;
253 mp->m_fsname_len = strlen(ap->fsname) + 1; 250 mp->m_fsname_len = strlen(ap->fsname) + 1;
254 mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP); 251 mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP);
@@ -295,8 +292,6 @@ xfs_start_flags(
295 mp->m_readio_log = mp->m_writeio_log = ap->iosizelog; 292 mp->m_readio_log = mp->m_writeio_log = ap->iosizelog;
296 } 293 }
297 294
298 if (ap->flags & XFSMNT_IHASHSIZE)
299 mp->m_flags |= XFS_MOUNT_IHASHSIZE;
300 if (ap->flags & XFSMNT_IDELETE) 295 if (ap->flags & XFSMNT_IDELETE)
301 mp->m_flags |= XFS_MOUNT_IDELETE; 296 mp->m_flags |= XFS_MOUNT_IDELETE;
302 if (ap->flags & XFSMNT_DIRSYNC) 297 if (ap->flags & XFSMNT_DIRSYNC)
@@ -311,7 +306,7 @@ xfs_start_flags(
311 * no recovery flag requires a read-only mount 306 * no recovery flag requires a read-only mount
312 */ 307 */
313 if (ap->flags & XFSMNT_NORECOVERY) { 308 if (ap->flags & XFSMNT_NORECOVERY) {
314 if (!(vfs->vfs_flag & VFS_RDONLY)) { 309 if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
315 cmn_err(CE_WARN, 310 cmn_err(CE_WARN,
316 "XFS: tried to mount a FS read-write without recovery!"); 311 "XFS: tried to mount a FS read-write without recovery!");
317 return XFS_ERROR(EINVAL); 312 return XFS_ERROR(EINVAL);
@@ -329,6 +324,8 @@ xfs_start_flags(
329 if (ap->flags2 & XFSMNT2_FILESTREAMS) 324 if (ap->flags2 & XFSMNT2_FILESTREAMS)
330 mp->m_flags |= XFS_MOUNT_FILESTREAMS; 325 mp->m_flags |= XFS_MOUNT_FILESTREAMS;
331 326
327 if (ap->flags & XFSMNT_DMAPI)
328 mp->m_flags |= XFS_MOUNT_DMAPI;
332 return 0; 329 return 0;
333} 330}
334 331
@@ -338,11 +335,10 @@ xfs_start_flags(
338 */ 335 */
339STATIC int 336STATIC int
340xfs_finish_flags( 337xfs_finish_flags(
341 struct bhv_vfs *vfs,
342 struct xfs_mount_args *ap, 338 struct xfs_mount_args *ap,
343 struct xfs_mount *mp) 339 struct xfs_mount *mp)
344{ 340{
345 int ronly = (vfs->vfs_flag & VFS_RDONLY); 341 int ronly = (mp->m_flags & XFS_MOUNT_RDONLY);
346 342
347 /* Fail a mount where the logbuf is smaller then the log stripe */ 343 /* Fail a mount where the logbuf is smaller then the log stripe */
348 if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) { 344 if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) {
@@ -403,6 +399,22 @@ xfs_finish_flags(
403 return XFS_ERROR(EINVAL); 399 return XFS_ERROR(EINVAL);
404 } 400 }
405 401
402 if (ap->flags & XFSMNT_UQUOTA) {
403 mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
404 if (ap->flags & XFSMNT_UQUOTAENF)
405 mp->m_qflags |= XFS_UQUOTA_ENFD;
406 }
407
408 if (ap->flags & XFSMNT_GQUOTA) {
409 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
410 if (ap->flags & XFSMNT_GQUOTAENF)
411 mp->m_qflags |= XFS_OQUOTA_ENFD;
412 } else if (ap->flags & XFSMNT_PQUOTA) {
413 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
414 if (ap->flags & XFSMNT_PQUOTAENF)
415 mp->m_qflags |= XFS_OQUOTA_ENFD;
416 }
417
406 return 0; 418 return 0;
407} 419}
408 420
@@ -418,30 +430,26 @@ xfs_finish_flags(
418 * they are present. The data subvolume has already been opened by 430 * they are present. The data subvolume has already been opened by
419 * get_sb_bdev() and is stored in vfsp->vfs_super->s_bdev. 431 * get_sb_bdev() and is stored in vfsp->vfs_super->s_bdev.
420 */ 432 */
421STATIC int 433int
422xfs_mount( 434xfs_mount(
423 struct bhv_desc *bhvp, 435 struct xfs_mount *mp,
424 struct xfs_mount_args *args, 436 struct xfs_mount_args *args,
425 cred_t *credp) 437 cred_t *credp)
426{ 438{
427 struct bhv_vfs *vfsp = bhvtovfs(bhvp);
428 struct bhv_desc *p;
429 struct xfs_mount *mp = XFS_BHVTOM(bhvp);
430 struct block_device *ddev, *logdev, *rtdev; 439 struct block_device *ddev, *logdev, *rtdev;
431 int flags = 0, error; 440 int flags = 0, error;
432 441
433 ddev = vfsp->vfs_super->s_bdev; 442 ddev = mp->m_super->s_bdev;
434 logdev = rtdev = NULL; 443 logdev = rtdev = NULL;
435 444
436 /* 445 error = xfs_dmops_get(mp, args);
437 * Setup xfs_mount function vectors from available behaviors 446 if (error)
438 */ 447 return error;
439 p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM); 448 error = xfs_qmops_get(mp, args);
440 mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub; 449 if (error)
441 p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM); 450 return error;
442 mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub; 451
443 p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO); 452 mp->m_io_ops = xfs_iocore_xfs;
444 mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs;
445 453
446 if (args->flags & XFSMNT_QUIET) 454 if (args->flags & XFSMNT_QUIET)
447 flags |= XFS_MFSI_QUIET; 455 flags |= XFS_MFSI_QUIET;
@@ -482,24 +490,30 @@ xfs_mount(
482 } 490 }
483 if (rtdev) { 491 if (rtdev) {
484 mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev, 1); 492 mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev, 1);
485 if (!mp->m_rtdev_targp) 493 if (!mp->m_rtdev_targp) {
494 xfs_blkdev_put(logdev);
495 xfs_blkdev_put(rtdev);
486 goto error0; 496 goto error0;
497 }
487 } 498 }
488 mp->m_logdev_targp = (logdev && logdev != ddev) ? 499 mp->m_logdev_targp = (logdev && logdev != ddev) ?
489 xfs_alloc_buftarg(logdev, 1) : mp->m_ddev_targp; 500 xfs_alloc_buftarg(logdev, 1) : mp->m_ddev_targp;
490 if (!mp->m_logdev_targp) 501 if (!mp->m_logdev_targp) {
502 xfs_blkdev_put(logdev);
503 xfs_blkdev_put(rtdev);
491 goto error0; 504 goto error0;
505 }
492 506
493 /* 507 /*
494 * Setup flags based on mount(2) options and then the superblock 508 * Setup flags based on mount(2) options and then the superblock
495 */ 509 */
496 error = xfs_start_flags(vfsp, args, mp); 510 error = xfs_start_flags(args, mp);
497 if (error) 511 if (error)
498 goto error1; 512 goto error1;
499 error = xfs_readsb(mp, flags); 513 error = xfs_readsb(mp, flags);
500 if (error) 514 if (error)
501 goto error1; 515 goto error1;
502 error = xfs_finish_flags(vfsp, args, mp); 516 error = xfs_finish_flags(args, mp);
503 if (error) 517 if (error)
504 goto error2; 518 goto error2;
505 519
@@ -530,10 +544,12 @@ xfs_mount(
530 if ((error = xfs_filestream_mount(mp))) 544 if ((error = xfs_filestream_mount(mp)))
531 goto error2; 545 goto error2;
532 546
533 error = XFS_IOINIT(vfsp, args, flags); 547 error = XFS_IOINIT(mp, args, flags);
534 if (error) 548 if (error)
535 goto error2; 549 goto error2;
536 550
551 XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, args->mtpt, args->fsname);
552
537 return 0; 553 return 0;
538 554
539error2: 555error2:
@@ -547,17 +563,17 @@ error1:
547 xfs_binval(mp->m_rtdev_targp); 563 xfs_binval(mp->m_rtdev_targp);
548error0: 564error0:
549 xfs_unmountfs_close(mp, credp); 565 xfs_unmountfs_close(mp, credp);
566 xfs_qmops_put(mp);
567 xfs_dmops_put(mp);
550 return error; 568 return error;
551} 569}
552 570
553STATIC int 571int
554xfs_unmount( 572xfs_unmount(
555 bhv_desc_t *bdp, 573 xfs_mount_t *mp,
556 int flags, 574 int flags,
557 cred_t *credp) 575 cred_t *credp)
558{ 576{
559 bhv_vfs_t *vfsp = bhvtovfs(bdp);
560 xfs_mount_t *mp = XFS_BHVTOM(bdp);
561 xfs_inode_t *rip; 577 xfs_inode_t *rip;
562 bhv_vnode_t *rvp; 578 bhv_vnode_t *rvp;
563 int unmount_event_wanted = 0; 579 int unmount_event_wanted = 0;
@@ -568,8 +584,9 @@ xfs_unmount(
568 rip = mp->m_rootip; 584 rip = mp->m_rootip;
569 rvp = XFS_ITOV(rip); 585 rvp = XFS_ITOV(rip);
570 586
571 if (vfsp->vfs_flag & VFS_DMI) { 587#ifdef HAVE_DMAPI
572 error = XFS_SEND_PREUNMOUNT(mp, vfsp, 588 if (mp->m_flags & XFS_MOUNT_DMAPI) {
589 error = XFS_SEND_PREUNMOUNT(mp,
573 rvp, DM_RIGHT_NULL, rvp, DM_RIGHT_NULL, 590 rvp, DM_RIGHT_NULL, rvp, DM_RIGHT_NULL,
574 NULL, NULL, 0, 0, 591 NULL, NULL, 0, 0,
575 (mp->m_dmevmask & (1<<DM_EVENT_PREUNMOUNT))? 592 (mp->m_dmevmask & (1<<DM_EVENT_PREUNMOUNT))?
@@ -580,7 +597,7 @@ xfs_unmount(
580 unmount_event_flags = (mp->m_dmevmask & (1<<DM_EVENT_UNMOUNT))? 597 unmount_event_flags = (mp->m_dmevmask & (1<<DM_EVENT_UNMOUNT))?
581 0 : DM_FLAGS_UNWANTED; 598 0 : DM_FLAGS_UNWANTED;
582 } 599 }
583 600#endif
584 /* 601 /*
585 * First blow any referenced inode from this file system 602 * First blow any referenced inode from this file system
586 * out of the reference cache, and delete the timer. 603 * out of the reference cache, and delete the timer.
@@ -612,8 +629,7 @@ xfs_unmount(
612 * referenced vnodes as well. 629 * referenced vnodes as well.
613 */ 630 */
614 if (XFS_FORCED_SHUTDOWN(mp)) { 631 if (XFS_FORCED_SHUTDOWN(mp)) {
615 error = xfs_sync(&mp->m_bhv, 632 error = xfs_sync(mp, SYNC_WAIT | SYNC_CLOSE);
616 (SYNC_WAIT | SYNC_CLOSE), credp);
617 ASSERT(error != EFSCORRUPTED); 633 ASSERT(error != EFSCORRUPTED);
618 } 634 }
619 xfs_unmountfs_needed = 1; 635 xfs_unmountfs_needed = 1;
@@ -627,7 +643,7 @@ out:
627 /* Note: mp structure must still exist for 643 /* Note: mp structure must still exist for
628 * XFS_SEND_UNMOUNT() call. 644 * XFS_SEND_UNMOUNT() call.
629 */ 645 */
630 XFS_SEND_UNMOUNT(mp, vfsp, error == 0 ? rvp : NULL, 646 XFS_SEND_UNMOUNT(mp, error == 0 ? rvp : NULL,
631 DM_RIGHT_NULL, 0, error, unmount_event_flags); 647 DM_RIGHT_NULL, 0, error, unmount_event_flags);
632 } 648 }
633 if (xfs_unmountfs_needed) { 649 if (xfs_unmountfs_needed) {
@@ -636,6 +652,9 @@ out:
636 * and free the super block buffer & mount structures. 652 * and free the super block buffer & mount structures.
637 */ 653 */
638 xfs_unmountfs(mp, credp); 654 xfs_unmountfs(mp, credp);
655 xfs_qmops_put(mp);
656 xfs_dmops_put(mp);
657 kmem_free(mp, sizeof(xfs_mount_t));
639 } 658 }
640 659
641 return XFS_ERROR(error); 660 return XFS_ERROR(error);
@@ -694,29 +713,26 @@ xfs_attr_quiesce(
694 xfs_unmountfs_writesb(mp); 713 xfs_unmountfs_writesb(mp);
695} 714}
696 715
697STATIC int 716int
698xfs_mntupdate( 717xfs_mntupdate(
699 bhv_desc_t *bdp, 718 struct xfs_mount *mp,
700 int *flags, 719 int *flags,
701 struct xfs_mount_args *args) 720 struct xfs_mount_args *args)
702{ 721{
703 bhv_vfs_t *vfsp = bhvtovfs(bdp);
704 xfs_mount_t *mp = XFS_BHVTOM(bdp);
705
706 if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */ 722 if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */
707 if (vfsp->vfs_flag & VFS_RDONLY) 723 if (mp->m_flags & XFS_MOUNT_RDONLY)
708 vfsp->vfs_flag &= ~VFS_RDONLY; 724 mp->m_flags &= ~XFS_MOUNT_RDONLY;
709 if (args->flags & XFSMNT_BARRIER) { 725 if (args->flags & XFSMNT_BARRIER) {
710 mp->m_flags |= XFS_MOUNT_BARRIER; 726 mp->m_flags |= XFS_MOUNT_BARRIER;
711 xfs_mountfs_check_barriers(mp); 727 xfs_mountfs_check_barriers(mp);
712 } else { 728 } else {
713 mp->m_flags &= ~XFS_MOUNT_BARRIER; 729 mp->m_flags &= ~XFS_MOUNT_BARRIER;
714 } 730 }
715 } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ 731 } else if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { /* rw -> ro */
716 xfs_filestream_flush(mp); 732 xfs_filestream_flush(mp);
717 bhv_vfs_sync(vfsp, SYNC_DATA_QUIESCE, NULL); 733 xfs_sync(mp, SYNC_DATA_QUIESCE);
718 xfs_attr_quiesce(mp); 734 xfs_attr_quiesce(mp);
719 vfsp->vfs_flag |= VFS_RDONLY; 735 mp->m_flags |= XFS_MOUNT_RDONLY;
720 } 736 }
721 return 0; 737 return 0;
722} 738}
@@ -811,14 +827,14 @@ fscorrupt_out2:
811 * vpp -- address of the caller's vnode pointer which should be 827 * vpp -- address of the caller's vnode pointer which should be
812 * set to the desired fs root vnode 828 * set to the desired fs root vnode
813 */ 829 */
814STATIC int 830int
815xfs_root( 831xfs_root(
816 bhv_desc_t *bdp, 832 xfs_mount_t *mp,
817 bhv_vnode_t **vpp) 833 bhv_vnode_t **vpp)
818{ 834{
819 bhv_vnode_t *vp; 835 bhv_vnode_t *vp;
820 836
821 vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip); 837 vp = XFS_ITOV(mp->m_rootip);
822 VN_HOLD(vp); 838 VN_HOLD(vp);
823 *vpp = vp; 839 *vpp = vp;
824 return 0; 840 return 0;
@@ -831,19 +847,17 @@ xfs_root(
831 * the superblock lock in the mount structure to ensure a consistent 847 * the superblock lock in the mount structure to ensure a consistent
832 * snapshot of the counters returned. 848 * snapshot of the counters returned.
833 */ 849 */
834STATIC int 850int
835xfs_statvfs( 851xfs_statvfs(
836 bhv_desc_t *bdp, 852 xfs_mount_t *mp,
837 bhv_statvfs_t *statp, 853 bhv_statvfs_t *statp,
838 bhv_vnode_t *vp) 854 bhv_vnode_t *vp)
839{ 855{
840 __uint64_t fakeinos; 856 __uint64_t fakeinos;
841 xfs_extlen_t lsize; 857 xfs_extlen_t lsize;
842 xfs_mount_t *mp;
843 xfs_sb_t *sbp; 858 xfs_sb_t *sbp;
844 unsigned long s; 859 unsigned long s;
845 860
846 mp = XFS_BHVTOM(bdp);
847 sbp = &(mp->m_sb); 861 sbp = &(mp->m_sb);
848 862
849 statp->f_type = XFS_SB_MAGIC; 863 statp->f_type = XFS_SB_MAGIC;
@@ -874,6 +888,8 @@ xfs_statvfs(
874 xfs_statvfs_fsid(statp, mp); 888 xfs_statvfs_fsid(statp, mp);
875 statp->f_namelen = MAXNAMELEN - 1; 889 statp->f_namelen = MAXNAMELEN - 1;
876 890
891 if (vp)
892 XFS_QM_DQSTATVFS(xfs_vtoi(vp), statp);
877 return 0; 893 return 0;
878} 894}
879 895
@@ -920,14 +936,30 @@ xfs_statvfs(
920 * filesystem. 936 * filesystem.
921 * 937 *
922 */ 938 */
923/*ARGSUSED*/ 939int
924STATIC int
925xfs_sync( 940xfs_sync(
926 bhv_desc_t *bdp, 941 xfs_mount_t *mp,
927 int flags, 942 int flags)
928 cred_t *credp)
929{ 943{
930 xfs_mount_t *mp = XFS_BHVTOM(bdp); 944 int error;
945
946 /*
947 * Get the Quota Manager to flush the dquots.
948 *
949 * If XFS quota support is not enabled or this filesystem
950 * instance does not use quotas XFS_QM_DQSYNC will always
951 * return zero.
952 */
953 error = XFS_QM_DQSYNC(mp, flags);
954 if (error) {
955 /*
956 * If we got an IO error, we will be shutting down.
957 * So, there's nothing more for us to do here.
958 */
959 ASSERT(error != EIO || XFS_FORCED_SHUTDOWN(mp));
960 if (XFS_FORCED_SHUTDOWN(mp))
961 return XFS_ERROR(error);
962 }
931 963
932 if (flags & SYNC_IOWAIT) 964 if (flags & SYNC_IOWAIT)
933 xfs_filestream_flush(mp); 965 xfs_filestream_flush(mp);
@@ -1015,7 +1047,7 @@ xfs_sync_inodes(
1015 1047
1016 if (bypassed) 1048 if (bypassed)
1017 *bypassed = 0; 1049 *bypassed = 0;
1018 if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) 1050 if (mp->m_flags & XFS_MOUNT_RDONLY)
1019 return 0; 1051 return 0;
1020 error = 0; 1052 error = 0;
1021 last_error = 0; 1053 last_error = 0;
@@ -1189,12 +1221,13 @@ xfs_sync_inodes(
1189 if (flags & SYNC_CLOSE) { 1221 if (flags & SYNC_CLOSE) {
1190 /* Shutdown case. Flush and invalidate. */ 1222 /* Shutdown case. Flush and invalidate. */
1191 if (XFS_FORCED_SHUTDOWN(mp)) 1223 if (XFS_FORCED_SHUTDOWN(mp))
1192 bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF); 1224 xfs_tosspages(ip, 0, -1,
1225 FI_REMAPF);
1193 else 1226 else
1194 error = bhv_vop_flushinval_pages(vp, 0, 1227 error = xfs_flushinval_pages(ip,
1195 -1, FI_REMAPF); 1228 0, -1, FI_REMAPF);
1196 } else if ((flags & SYNC_DELWRI) && VN_DIRTY(vp)) { 1229 } else if ((flags & SYNC_DELWRI) && VN_DIRTY(vp)) {
1197 error = bhv_vop_flush_pages(vp, (xfs_off_t)0, 1230 error = xfs_flush_pages(ip, 0,
1198 -1, fflag, FI_NONE); 1231 -1, fflag, FI_NONE);
1199 } 1232 }
1200 1233
@@ -1204,7 +1237,7 @@ xfs_sync_inodes(
1204 * place after this point 1237 * place after this point
1205 */ 1238 */
1206 if (flags & SYNC_IOWAIT) 1239 if (flags & SYNC_IOWAIT)
1207 vn_iowait(vp); 1240 vn_iowait(ip);
1208 1241
1209 xfs_ilock(ip, XFS_ILOCK_SHARED); 1242 xfs_ilock(ip, XFS_ILOCK_SHARED);
1210 } 1243 }
@@ -1598,13 +1631,12 @@ xfs_syncsub(
1598/* 1631/*
1599 * xfs_vget - called by DMAPI and NFSD to get vnode from file handle 1632 * xfs_vget - called by DMAPI and NFSD to get vnode from file handle
1600 */ 1633 */
1601STATIC int 1634int
1602xfs_vget( 1635xfs_vget(
1603 bhv_desc_t *bdp, 1636 xfs_mount_t *mp,
1604 bhv_vnode_t **vpp, 1637 bhv_vnode_t **vpp,
1605 fid_t *fidp) 1638 fid_t *fidp)
1606{ 1639{
1607 xfs_mount_t *mp = XFS_BHVTOM(bdp);
1608 xfs_fid_t *xfid = (struct xfs_fid *)fidp; 1640 xfs_fid_t *xfid = (struct xfs_fid *)fidp;
1609 xfs_inode_t *ip; 1641 xfs_inode_t *ip;
1610 int error; 1642 int error;
@@ -1668,7 +1700,6 @@ xfs_vget(
1668#define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */ 1700#define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */
1669#define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */ 1701#define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */
1670#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */ 1702#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */
1671#define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */
1672#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ 1703#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
1673#define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and 1704#define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and
1674 * unwritten extent conversion */ 1705 * unwritten extent conversion */
@@ -1683,6 +1714,21 @@ xfs_vget(
1683#define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ 1714#define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */
1684#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ 1715#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
1685#define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ 1716#define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */
1717#define MNTOPT_QUOTA "quota" /* disk quotas (user) */
1718#define MNTOPT_NOQUOTA "noquota" /* no quotas */
1719#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
1720#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
1721#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
1722#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
1723#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
1724#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
1725#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
1726#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
1727#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
1728#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
1729#define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */
1730#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */
1731#define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */
1686 1732
1687STATIC unsigned long 1733STATIC unsigned long
1688suffix_strtoul(char *s, char **endp, unsigned int base) 1734suffix_strtoul(char *s, char **endp, unsigned int base)
@@ -1707,19 +1753,18 @@ suffix_strtoul(char *s, char **endp, unsigned int base)
1707 return simple_strtoul((const char *)s, endp, base) << shift_left_factor; 1753 return simple_strtoul((const char *)s, endp, base) << shift_left_factor;
1708} 1754}
1709 1755
1710STATIC int 1756int
1711xfs_parseargs( 1757xfs_parseargs(
1712 struct bhv_desc *bhv, 1758 struct xfs_mount *mp,
1713 char *options, 1759 char *options,
1714 struct xfs_mount_args *args, 1760 struct xfs_mount_args *args,
1715 int update) 1761 int update)
1716{ 1762{
1717 bhv_vfs_t *vfsp = bhvtovfs(bhv);
1718 char *this_char, *value, *eov; 1763 char *this_char, *value, *eov;
1719 int dsunit, dswidth, vol_dsunit, vol_dswidth; 1764 int dsunit, dswidth, vol_dsunit, vol_dswidth;
1720 int iosize; 1765 int iosize;
1766 int ikeep = 0;
1721 1767
1722 args->flags |= XFSMNT_IDELETE;
1723 args->flags |= XFSMNT_BARRIER; 1768 args->flags |= XFSMNT_BARRIER;
1724 args->flags2 |= XFSMNT2_COMPAT_IOSIZE; 1769 args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
1725 1770
@@ -1794,21 +1839,12 @@ xfs_parseargs(
1794 iosize = suffix_strtoul(value, &eov, 10); 1839 iosize = suffix_strtoul(value, &eov, 10);
1795 args->flags |= XFSMNT_IOSIZE; 1840 args->flags |= XFSMNT_IOSIZE;
1796 args->iosizelog = ffs(iosize) - 1; 1841 args->iosizelog = ffs(iosize) - 1;
1797 } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) {
1798 if (!value || !*value) {
1799 cmn_err(CE_WARN,
1800 "XFS: %s option requires an argument",
1801 this_char);
1802 return EINVAL;
1803 }
1804 args->flags |= XFSMNT_IHASHSIZE;
1805 args->ihashsize = simple_strtoul(value, &eov, 10);
1806 } else if (!strcmp(this_char, MNTOPT_GRPID) || 1842 } else if (!strcmp(this_char, MNTOPT_GRPID) ||
1807 !strcmp(this_char, MNTOPT_BSDGROUPS)) { 1843 !strcmp(this_char, MNTOPT_BSDGROUPS)) {
1808 vfsp->vfs_flag |= VFS_GRPID; 1844 mp->m_flags |= XFS_MOUNT_GRPID;
1809 } else if (!strcmp(this_char, MNTOPT_NOGRPID) || 1845 } else if (!strcmp(this_char, MNTOPT_NOGRPID) ||
1810 !strcmp(this_char, MNTOPT_SYSVGROUPS)) { 1846 !strcmp(this_char, MNTOPT_SYSVGROUPS)) {
1811 vfsp->vfs_flag &= ~VFS_GRPID; 1847 mp->m_flags &= ~XFS_MOUNT_GRPID;
1812 } else if (!strcmp(this_char, MNTOPT_WSYNC)) { 1848 } else if (!strcmp(this_char, MNTOPT_WSYNC)) {
1813 args->flags |= XFSMNT_WSYNC; 1849 args->flags |= XFSMNT_WSYNC;
1814 } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) { 1850 } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {
@@ -1858,6 +1894,7 @@ xfs_parseargs(
1858 } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { 1894 } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
1859 args->flags &= ~XFSMNT_BARRIER; 1895 args->flags &= ~XFSMNT_BARRIER;
1860 } else if (!strcmp(this_char, MNTOPT_IKEEP)) { 1896 } else if (!strcmp(this_char, MNTOPT_IKEEP)) {
1897 ikeep = 1;
1861 args->flags &= ~XFSMNT_IDELETE; 1898 args->flags &= ~XFSMNT_IDELETE;
1862 } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { 1899 } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
1863 args->flags |= XFSMNT_IDELETE; 1900 args->flags |= XFSMNT_IDELETE;
@@ -1871,6 +1908,38 @@ xfs_parseargs(
1871 args->flags &= ~XFSMNT_ATTR2; 1908 args->flags &= ~XFSMNT_ATTR2;
1872 } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { 1909 } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
1873 args->flags2 |= XFSMNT2_FILESTREAMS; 1910 args->flags2 |= XFSMNT2_FILESTREAMS;
1911 } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
1912 args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA);
1913 args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA);
1914 } else if (!strcmp(this_char, MNTOPT_QUOTA) ||
1915 !strcmp(this_char, MNTOPT_UQUOTA) ||
1916 !strcmp(this_char, MNTOPT_USRQUOTA)) {
1917 args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;
1918 } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
1919 !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
1920 args->flags |= XFSMNT_UQUOTA;
1921 args->flags &= ~XFSMNT_UQUOTAENF;
1922 } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
1923 !strcmp(this_char, MNTOPT_PRJQUOTA)) {
1924 args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
1925 } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
1926 args->flags |= XFSMNT_PQUOTA;
1927 args->flags &= ~XFSMNT_PQUOTAENF;
1928 } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
1929 !strcmp(this_char, MNTOPT_GRPQUOTA)) {
1930 args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
1931 } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
1932 args->flags |= XFSMNT_GQUOTA;
1933 args->flags &= ~XFSMNT_GQUOTAENF;
1934 } else if (!strcmp(this_char, MNTOPT_DMAPI)) {
1935 args->flags |= XFSMNT_DMAPI;
1936 } else if (!strcmp(this_char, MNTOPT_XDSM)) {
1937 args->flags |= XFSMNT_DMAPI;
1938 } else if (!strcmp(this_char, MNTOPT_DMI)) {
1939 args->flags |= XFSMNT_DMAPI;
1940 } else if (!strcmp(this_char, "ihashsize")) {
1941 cmn_err(CE_WARN,
1942 "XFS: ihashsize no longer used, option is deprecated.");
1874 } else if (!strcmp(this_char, "osyncisdsync")) { 1943 } else if (!strcmp(this_char, "osyncisdsync")) {
1875 /* no-op, this is now the default */ 1944 /* no-op, this is now the default */
1876 cmn_err(CE_WARN, 1945 cmn_err(CE_WARN,
@@ -1886,7 +1955,7 @@ xfs_parseargs(
1886 } 1955 }
1887 1956
1888 if (args->flags & XFSMNT_NORECOVERY) { 1957 if (args->flags & XFSMNT_NORECOVERY) {
1889 if ((vfsp->vfs_flag & VFS_RDONLY) == 0) { 1958 if ((mp->m_flags & XFS_MOUNT_RDONLY) == 0) {
1890 cmn_err(CE_WARN, 1959 cmn_err(CE_WARN,
1891 "XFS: no-recovery mounts must be read-only."); 1960 "XFS: no-recovery mounts must be read-only.");
1892 return EINVAL; 1961 return EINVAL;
@@ -1899,6 +1968,18 @@ xfs_parseargs(
1899 return EINVAL; 1968 return EINVAL;
1900 } 1969 }
1901 1970
1971 if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
1972 cmn_err(CE_WARN,
1973 "XFS: cannot mount with both project and group quota");
1974 return EINVAL;
1975 }
1976
1977 if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') {
1978 printk("XFS: %s option needs the mount point option as well\n",
1979 MNTOPT_DMAPI);
1980 return EINVAL;
1981 }
1982
1902 if ((dsunit && !dswidth) || (!dsunit && dswidth)) { 1983 if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
1903 cmn_err(CE_WARN, 1984 cmn_err(CE_WARN,
1904 "XFS: sunit and swidth must be specified together"); 1985 "XFS: sunit and swidth must be specified together");
@@ -1912,6 +1993,18 @@ xfs_parseargs(
1912 return EINVAL; 1993 return EINVAL;
1913 } 1994 }
1914 1995
1996 /*
1997 * Applications using DMI filesystems often expect the
1998 * inode generation number to be monotonically increasing.
1999 * If we delete inode chunks we break this assumption, so
2000 * keep unused inode chunks on disk for DMI filesystems
2001 * until we come up with a better solution.
2002 * Note that if "ikeep" or "noikeep" mount options are
2003 * supplied, then they are honored.
2004 */
2005 if (!(args->flags & XFSMNT_DMAPI) && !ikeep)
2006 args->flags |= XFSMNT_IDELETE;
2007
1915 if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { 2008 if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
1916 if (dsunit) { 2009 if (dsunit) {
1917 args->sunit = dsunit; 2010 args->sunit = dsunit;
@@ -1927,15 +2020,15 @@ xfs_parseargs(
1927 2020
1928done: 2021done:
1929 if (args->flags & XFSMNT_32BITINODES) 2022 if (args->flags & XFSMNT_32BITINODES)
1930 vfsp->vfs_flag |= VFS_32BITINODES; 2023 mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
1931 if (args->flags2) 2024 if (args->flags2)
1932 args->flags |= XFSMNT_FLAGS2; 2025 args->flags |= XFSMNT_FLAGS2;
1933 return 0; 2026 return 0;
1934} 2027}
1935 2028
1936STATIC int 2029int
1937xfs_showargs( 2030xfs_showargs(
1938 struct bhv_desc *bhv, 2031 struct xfs_mount *mp,
1939 struct seq_file *m) 2032 struct seq_file *m)
1940{ 2033{
1941 static struct proc_xfs_info { 2034 static struct proc_xfs_info {
@@ -1953,17 +2046,12 @@ xfs_showargs(
1953 { 0, NULL } 2046 { 0, NULL }
1954 }; 2047 };
1955 struct proc_xfs_info *xfs_infop; 2048 struct proc_xfs_info *xfs_infop;
1956 struct xfs_mount *mp = XFS_BHVTOM(bhv);
1957 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
1958 2049
1959 for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) { 2050 for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
1960 if (mp->m_flags & xfs_infop->flag) 2051 if (mp->m_flags & xfs_infop->flag)
1961 seq_puts(m, xfs_infop->str); 2052 seq_puts(m, xfs_infop->str);
1962 } 2053 }
1963 2054
1964 if (mp->m_flags & XFS_MOUNT_IHASHSIZE)
1965 seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", (int)mp->m_ihsize);
1966
1967 if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) 2055 if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
1968 seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", 2056 seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk",
1969 (int)(1 << mp->m_writeio_log) >> 10); 2057 (int)(1 << mp->m_writeio_log) >> 10);
@@ -1990,11 +2078,37 @@ xfs_showargs(
1990 if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE)) 2078 if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE))
1991 seq_printf(m, "," MNTOPT_LARGEIO); 2079 seq_printf(m, "," MNTOPT_LARGEIO);
1992 2080
1993 if (!(vfsp->vfs_flag & VFS_32BITINODES)) 2081 if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS))
1994 seq_printf(m, "," MNTOPT_64BITINODE); 2082 seq_printf(m, "," MNTOPT_64BITINODE);
1995 if (vfsp->vfs_flag & VFS_GRPID) 2083 if (mp->m_flags & XFS_MOUNT_GRPID)
1996 seq_printf(m, "," MNTOPT_GRPID); 2084 seq_printf(m, "," MNTOPT_GRPID);
1997 2085
2086 if (mp->m_qflags & XFS_UQUOTA_ACCT) {
2087 if (mp->m_qflags & XFS_UQUOTA_ENFD)
2088 seq_puts(m, "," MNTOPT_USRQUOTA);
2089 else
2090 seq_puts(m, "," MNTOPT_UQUOTANOENF);
2091 }
2092
2093 if (mp->m_qflags & XFS_PQUOTA_ACCT) {
2094 if (mp->m_qflags & XFS_OQUOTA_ENFD)
2095 seq_puts(m, "," MNTOPT_PRJQUOTA);
2096 else
2097 seq_puts(m, "," MNTOPT_PQUOTANOENF);
2098 }
2099
2100 if (mp->m_qflags & XFS_GQUOTA_ACCT) {
2101 if (mp->m_qflags & XFS_OQUOTA_ENFD)
2102 seq_puts(m, "," MNTOPT_GRPQUOTA);
2103 else
2104 seq_puts(m, "," MNTOPT_GQUOTANOENF);
2105 }
2106
2107 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
2108 seq_puts(m, "," MNTOPT_NOQUOTA);
2109
2110 if (mp->m_flags & XFS_MOUNT_DMAPI)
2111 seq_puts(m, "," MNTOPT_DMAPI);
1998 return 0; 2112 return 0;
1999} 2113}
2000 2114
@@ -2003,31 +2117,10 @@ xfs_showargs(
2003 * need to take care of themetadata. Once that's done write a dummy 2117 * need to take care of themetadata. Once that's done write a dummy
2004 * record to dirty the log in case of a crash while frozen. 2118 * record to dirty the log in case of a crash while frozen.
2005 */ 2119 */
2006STATIC void 2120void
2007xfs_freeze( 2121xfs_freeze(
2008 bhv_desc_t *bdp) 2122 xfs_mount_t *mp)
2009{ 2123{
2010 xfs_mount_t *mp = XFS_BHVTOM(bdp);
2011
2012 xfs_attr_quiesce(mp); 2124 xfs_attr_quiesce(mp);
2013 xfs_fs_log_dummy(mp); 2125 xfs_fs_log_dummy(mp);
2014} 2126}
2015
2016
2017bhv_vfsops_t xfs_vfsops = {
2018 BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS),
2019 .vfs_parseargs = xfs_parseargs,
2020 .vfs_showargs = xfs_showargs,
2021 .vfs_mount = xfs_mount,
2022 .vfs_unmount = xfs_unmount,
2023 .vfs_mntupdate = xfs_mntupdate,
2024 .vfs_root = xfs_root,
2025 .vfs_statvfs = xfs_statvfs,
2026 .vfs_sync = xfs_sync,
2027 .vfs_vget = xfs_vget,
2028 .vfs_dmapiops = (vfs_dmapiops_t)fs_nosys,
2029 .vfs_quotactl = (vfs_quotactl_t)fs_nosys,
2030 .vfs_init_vnode = xfs_initialize_vnode,
2031 .vfs_force_shutdown = xfs_do_force_shutdown,
2032 .vfs_freeze = xfs_freeze,
2033};