aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-05-19 21:30:52 -0400
committerNiv Sardi <xaiki@debian.org>2008-07-28 02:58:20 -0400
commite48ad3160e5c5f5b952c7a7ed814f6f289a60100 (patch)
tree25f1c0d30cc6b88976ff5dd31f1f983248c238cf /fs
parent61436febae29085bffc7c291db03cbd709dc68a3 (diff)
[XFS] merge xfs_unmount into xfs_fs_put_super / xfs_fs_fill_super
xfs_unmount is small and already pretty Linux specific, so merge it into the callers. The real unmount path is simplified a little by doing a WARN_ON on the xfs_unmount_flush retval directly instead of propagating the error back to the caller, and the mout failure case in simplified significantly by removing the forced shutdown case and all the dmapi events that shouldn't be sent because the dmapi mount event hasn't been sent by that time either. SGI-PV: 981951 SGI-Modid: xfs-linux-melb:xfs-kern:31188a Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c71
-rw-r--r--fs/xfs/xfs_vfsops.c87
-rw-r--r--fs/xfs/xfs_vfsops.h1
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
1100STATIC void 1147STATIC void
@@ -1400,7 +1447,23 @@ fail_vnrele:
1400 } 1447 }
1401 1448
1402fail_unmount: 1449fail_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
1405fail_vfsop: 1468fail_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
561int
562xfs_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
622out:
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
648STATIC void 561STATIC void
649xfs_quiesce_fs( 562xfs_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
11int xfs_mount(struct xfs_mount *mp, struct xfs_mount_args *args, 11int xfs_mount(struct xfs_mount *mp, struct xfs_mount_args *args,
12 struct cred *credp); 12 struct cred *credp);
13int xfs_unmount(struct xfs_mount *mp, int flags, struct cred *credp);
14int xfs_sync(struct xfs_mount *mp, int flags); 13int xfs_sync(struct xfs_mount *mp, int flags);
15void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, 14void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
16 int lnnum); 15 int lnnum);