diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 71 | ||||
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 87 | ||||
-rw-r--r-- | fs/xfs/xfs_vfsops.h | 1 |
3 files changed, 67 insertions, 92 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index a3ecdf442465..28132e643953 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -1087,14 +1087,61 @@ xfs_fs_put_super( | |||
1087 | struct super_block *sb) | 1087 | struct super_block *sb) |
1088 | { | 1088 | { |
1089 | struct xfs_mount *mp = XFS_M(sb); | 1089 | struct xfs_mount *mp = XFS_M(sb); |
1090 | struct xfs_inode *rip = mp->m_rootip; | ||
1091 | int unmount_event_flags = 0; | ||
1090 | int error; | 1092 | int error; |
1091 | 1093 | ||
1092 | kthread_stop(mp->m_sync_task); | 1094 | kthread_stop(mp->m_sync_task); |
1093 | 1095 | ||
1094 | xfs_sync(mp, SYNC_ATTR | SYNC_DELWRI); | 1096 | xfs_sync(mp, SYNC_ATTR | SYNC_DELWRI); |
1095 | error = xfs_unmount(mp, 0, NULL); | 1097 | |
1096 | if (error) | 1098 | #ifdef HAVE_DMAPI |
1097 | printk("XFS: unmount got error=%d\n", error); | 1099 | if (mp->m_flags & XFS_MOUNT_DMAPI) { |
1100 | unmount_event_flags = | ||
1101 | (mp->m_dmevmask & (1 << DM_EVENT_UNMOUNT)) ? | ||
1102 | 0 : DM_FLAGS_UNWANTED; | ||
1103 | /* | ||
1104 | * Ignore error from dmapi here, first unmount is not allowed | ||
1105 | * to fail anyway, and second we wouldn't want to fail a | ||
1106 | * unmount because of dmapi. | ||
1107 | */ | ||
1108 | XFS_SEND_PREUNMOUNT(mp, rip, DM_RIGHT_NULL, rip, DM_RIGHT_NULL, | ||
1109 | NULL, NULL, 0, 0, unmount_event_flags); | ||
1110 | } | ||
1111 | #endif | ||
1112 | |||
1113 | /* | ||
1114 | * Blow away any referenced inode in the filestreams cache. | ||
1115 | * This can and will cause log traffic as inodes go inactive | ||
1116 | * here. | ||
1117 | */ | ||
1118 | xfs_filestream_unmount(mp); | ||
1119 | |||
1120 | XFS_bflush(mp->m_ddev_targp); | ||
1121 | error = xfs_unmount_flush(mp, 0); | ||
1122 | WARN_ON(error); | ||
1123 | |||
1124 | IRELE(rip); | ||
1125 | |||
1126 | /* | ||
1127 | * If we're forcing a shutdown, typically because of a media error, | ||
1128 | * we want to make sure we invalidate dirty pages that belong to | ||
1129 | * referenced vnodes as well. | ||
1130 | */ | ||
1131 | if (XFS_FORCED_SHUTDOWN(mp)) { | ||
1132 | error = xfs_sync(mp, SYNC_WAIT | SYNC_CLOSE); | ||
1133 | ASSERT(error != EFSCORRUPTED); | ||
1134 | } | ||
1135 | |||
1136 | if (mp->m_flags & XFS_MOUNT_DMAPI) { | ||
1137 | XFS_SEND_UNMOUNT(mp, rip, DM_RIGHT_NULL, 0, 0, | ||
1138 | unmount_event_flags); | ||
1139 | } | ||
1140 | |||
1141 | xfs_unmountfs(mp, NULL); | ||
1142 | xfs_qmops_put(mp); | ||
1143 | xfs_dmops_put(mp); | ||
1144 | kmem_free(mp); | ||
1098 | } | 1145 | } |
1099 | 1146 | ||
1100 | STATIC void | 1147 | STATIC void |
@@ -1400,7 +1447,23 @@ fail_vnrele: | |||
1400 | } | 1447 | } |
1401 | 1448 | ||
1402 | fail_unmount: | 1449 | fail_unmount: |
1403 | xfs_unmount(mp, 0, NULL); | 1450 | /* |
1451 | * Blow away any referenced inode in the filestreams cache. | ||
1452 | * This can and will cause log traffic as inodes go inactive | ||
1453 | * here. | ||
1454 | */ | ||
1455 | xfs_filestream_unmount(mp); | ||
1456 | |||
1457 | XFS_bflush(mp->m_ddev_targp); | ||
1458 | error = xfs_unmount_flush(mp, 0); | ||
1459 | WARN_ON(error); | ||
1460 | |||
1461 | IRELE(mp->m_rootip); | ||
1462 | |||
1463 | xfs_unmountfs(mp, NULL); | ||
1464 | xfs_qmops_put(mp); | ||
1465 | xfs_dmops_put(mp); | ||
1466 | kmem_free(mp); | ||
1404 | 1467 | ||
1405 | fail_vfsop: | 1468 | fail_vfsop: |
1406 | kmem_free(args); | 1469 | kmem_free(args); |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index e223aeab68be..bc34f90e7eea 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -558,93 +558,6 @@ error0: | |||
558 | return error; | 558 | return error; |
559 | } | 559 | } |
560 | 560 | ||
561 | int | ||
562 | xfs_unmount( | ||
563 | xfs_mount_t *mp, | ||
564 | int flags, | ||
565 | cred_t *credp) | ||
566 | { | ||
567 | xfs_inode_t *rip; | ||
568 | bhv_vnode_t *rvp; | ||
569 | int unmount_event_wanted = 0; | ||
570 | int unmount_event_flags = 0; | ||
571 | int xfs_unmountfs_needed = 0; | ||
572 | int error; | ||
573 | |||
574 | rip = mp->m_rootip; | ||
575 | rvp = XFS_ITOV(rip); | ||
576 | |||
577 | #ifdef HAVE_DMAPI | ||
578 | if (mp->m_flags & XFS_MOUNT_DMAPI) { | ||
579 | error = XFS_SEND_PREUNMOUNT(mp, | ||
580 | rip, DM_RIGHT_NULL, rip, DM_RIGHT_NULL, | ||
581 | NULL, NULL, 0, 0, | ||
582 | (mp->m_dmevmask & (1<<DM_EVENT_PREUNMOUNT))? | ||
583 | 0:DM_FLAGS_UNWANTED); | ||
584 | if (error) | ||
585 | return XFS_ERROR(error); | ||
586 | unmount_event_wanted = 1; | ||
587 | unmount_event_flags = (mp->m_dmevmask & (1<<DM_EVENT_UNMOUNT))? | ||
588 | 0 : DM_FLAGS_UNWANTED; | ||
589 | } | ||
590 | #endif | ||
591 | |||
592 | /* | ||
593 | * Blow away any referenced inode in the filestreams cache. | ||
594 | * This can and will cause log traffic as inodes go inactive | ||
595 | * here. | ||
596 | */ | ||
597 | xfs_filestream_unmount(mp); | ||
598 | |||
599 | XFS_bflush(mp->m_ddev_targp); | ||
600 | error = xfs_unmount_flush(mp, 0); | ||
601 | if (error) | ||
602 | goto out; | ||
603 | |||
604 | ASSERT(vn_count(rvp) == 1); | ||
605 | |||
606 | /* | ||
607 | * Drop the reference count | ||
608 | */ | ||
609 | IRELE(rip); | ||
610 | |||
611 | /* | ||
612 | * If we're forcing a shutdown, typically because of a media error, | ||
613 | * we want to make sure we invalidate dirty pages that belong to | ||
614 | * referenced vnodes as well. | ||
615 | */ | ||
616 | if (XFS_FORCED_SHUTDOWN(mp)) { | ||
617 | error = xfs_sync(mp, SYNC_WAIT | SYNC_CLOSE); | ||
618 | ASSERT(error != EFSCORRUPTED); | ||
619 | } | ||
620 | xfs_unmountfs_needed = 1; | ||
621 | |||
622 | out: | ||
623 | /* Send DMAPI event, if required. | ||
624 | * Then do xfs_unmountfs() if needed. | ||
625 | * Then return error (or zero). | ||
626 | */ | ||
627 | if (unmount_event_wanted) { | ||
628 | /* Note: mp structure must still exist for | ||
629 | * XFS_SEND_UNMOUNT() call. | ||
630 | */ | ||
631 | XFS_SEND_UNMOUNT(mp, error == 0 ? rip : NULL, | ||
632 | DM_RIGHT_NULL, 0, error, unmount_event_flags); | ||
633 | } | ||
634 | if (xfs_unmountfs_needed) { | ||
635 | /* | ||
636 | * Call common unmount function to flush to disk | ||
637 | * and free the super block buffer & mount structures. | ||
638 | */ | ||
639 | xfs_unmountfs(mp, credp); | ||
640 | xfs_qmops_put(mp); | ||
641 | xfs_dmops_put(mp); | ||
642 | kmem_free(mp); | ||
643 | } | ||
644 | |||
645 | return XFS_ERROR(error); | ||
646 | } | ||
647 | |||
648 | STATIC void | 561 | STATIC void |
649 | xfs_quiesce_fs( | 562 | xfs_quiesce_fs( |
650 | xfs_mount_t *mp) | 563 | xfs_mount_t *mp) |
diff --git a/fs/xfs/xfs_vfsops.h b/fs/xfs/xfs_vfsops.h index 995091f19499..de64bb6542df 100644 --- a/fs/xfs/xfs_vfsops.h +++ b/fs/xfs/xfs_vfsops.h | |||
@@ -10,7 +10,6 @@ struct xfs_mount_args; | |||
10 | 10 | ||
11 | int xfs_mount(struct xfs_mount *mp, struct xfs_mount_args *args, | 11 | int xfs_mount(struct xfs_mount *mp, struct xfs_mount_args *args, |
12 | struct cred *credp); | 12 | struct cred *credp); |
13 | int xfs_unmount(struct xfs_mount *mp, int flags, struct cred *credp); | ||
14 | int xfs_sync(struct xfs_mount *mp, int flags); | 13 | int xfs_sync(struct xfs_mount *mp, int flags); |
15 | void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, | 14 | void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, |
16 | int lnnum); | 15 | int lnnum); |