diff options
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r-- | fs/xfs/xfs_mount.c | 253 |
1 files changed, 141 insertions, 112 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 35300250e86d..b101990df027 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include "xfs_fsops.h" | 45 | #include "xfs_fsops.h" |
46 | #include "xfs_utils.h" | 46 | #include "xfs_utils.h" |
47 | 47 | ||
48 | STATIC int xfs_uuid_mount(xfs_mount_t *); | ||
49 | STATIC void xfs_unmountfs_wait(xfs_mount_t *); | 48 | STATIC void xfs_unmountfs_wait(xfs_mount_t *); |
50 | 49 | ||
51 | 50 | ||
@@ -121,6 +120,84 @@ static const struct { | |||
121 | { sizeof(xfs_sb_t), 0 } | 120 | { sizeof(xfs_sb_t), 0 } |
122 | }; | 121 | }; |
123 | 122 | ||
123 | static DEFINE_MUTEX(xfs_uuid_table_mutex); | ||
124 | static int xfs_uuid_table_size; | ||
125 | static uuid_t *xfs_uuid_table; | ||
126 | |||
127 | /* | ||
128 | * See if the UUID is unique among mounted XFS filesystems. | ||
129 | * Mount fails if UUID is nil or a FS with the same UUID is already mounted. | ||
130 | */ | ||
131 | STATIC int | ||
132 | xfs_uuid_mount( | ||
133 | struct xfs_mount *mp) | ||
134 | { | ||
135 | uuid_t *uuid = &mp->m_sb.sb_uuid; | ||
136 | int hole, i; | ||
137 | |||
138 | if (mp->m_flags & XFS_MOUNT_NOUUID) | ||
139 | return 0; | ||
140 | |||
141 | if (uuid_is_nil(uuid)) { | ||
142 | cmn_err(CE_WARN, | ||
143 | "XFS: Filesystem %s has nil UUID - can't mount", | ||
144 | mp->m_fsname); | ||
145 | return XFS_ERROR(EINVAL); | ||
146 | } | ||
147 | |||
148 | mutex_lock(&xfs_uuid_table_mutex); | ||
149 | for (i = 0, hole = -1; i < xfs_uuid_table_size; i++) { | ||
150 | if (uuid_is_nil(&xfs_uuid_table[i])) { | ||
151 | hole = i; | ||
152 | continue; | ||
153 | } | ||
154 | if (uuid_equal(uuid, &xfs_uuid_table[i])) | ||
155 | goto out_duplicate; | ||
156 | } | ||
157 | |||
158 | if (hole < 0) { | ||
159 | xfs_uuid_table = kmem_realloc(xfs_uuid_table, | ||
160 | (xfs_uuid_table_size + 1) * sizeof(*xfs_uuid_table), | ||
161 | xfs_uuid_table_size * sizeof(*xfs_uuid_table), | ||
162 | KM_SLEEP); | ||
163 | hole = xfs_uuid_table_size++; | ||
164 | } | ||
165 | xfs_uuid_table[hole] = *uuid; | ||
166 | mutex_unlock(&xfs_uuid_table_mutex); | ||
167 | |||
168 | return 0; | ||
169 | |||
170 | out_duplicate: | ||
171 | mutex_unlock(&xfs_uuid_table_mutex); | ||
172 | cmn_err(CE_WARN, "XFS: Filesystem %s has duplicate UUID - can't mount", | ||
173 | mp->m_fsname); | ||
174 | return XFS_ERROR(EINVAL); | ||
175 | } | ||
176 | |||
177 | STATIC void | ||
178 | xfs_uuid_unmount( | ||
179 | struct xfs_mount *mp) | ||
180 | { | ||
181 | uuid_t *uuid = &mp->m_sb.sb_uuid; | ||
182 | int i; | ||
183 | |||
184 | if (mp->m_flags & XFS_MOUNT_NOUUID) | ||
185 | return; | ||
186 | |||
187 | mutex_lock(&xfs_uuid_table_mutex); | ||
188 | for (i = 0; i < xfs_uuid_table_size; i++) { | ||
189 | if (uuid_is_nil(&xfs_uuid_table[i])) | ||
190 | continue; | ||
191 | if (!uuid_equal(uuid, &xfs_uuid_table[i])) | ||
192 | continue; | ||
193 | memset(&xfs_uuid_table[i], 0, sizeof(uuid_t)); | ||
194 | break; | ||
195 | } | ||
196 | ASSERT(i < xfs_uuid_table_size); | ||
197 | mutex_unlock(&xfs_uuid_table_mutex); | ||
198 | } | ||
199 | |||
200 | |||
124 | /* | 201 | /* |
125 | * Free up the resources associated with a mount structure. Assume that | 202 | * Free up the resources associated with a mount structure. Assume that |
126 | * the structure was initially zeroed, so we can tell which fields got | 203 | * the structure was initially zeroed, so we can tell which fields got |
@@ -256,6 +333,22 @@ xfs_mount_validate_sb( | |||
256 | return XFS_ERROR(ENOSYS); | 333 | return XFS_ERROR(ENOSYS); |
257 | } | 334 | } |
258 | 335 | ||
336 | /* | ||
337 | * Currently only very few inode sizes are supported. | ||
338 | */ | ||
339 | switch (sbp->sb_inodesize) { | ||
340 | case 256: | ||
341 | case 512: | ||
342 | case 1024: | ||
343 | case 2048: | ||
344 | break; | ||
345 | default: | ||
346 | xfs_fs_mount_cmn_err(flags, | ||
347 | "inode size of %d bytes not supported", | ||
348 | sbp->sb_inodesize); | ||
349 | return XFS_ERROR(ENOSYS); | ||
350 | } | ||
351 | |||
259 | if (xfs_sb_validate_fsb_count(sbp, sbp->sb_dblocks) || | 352 | if (xfs_sb_validate_fsb_count(sbp, sbp->sb_dblocks) || |
260 | xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) { | 353 | xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) { |
261 | xfs_fs_mount_cmn_err(flags, | 354 | xfs_fs_mount_cmn_err(flags, |
@@ -574,32 +667,10 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp) | |||
574 | mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; | 667 | mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; |
575 | mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1; | 668 | mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1; |
576 | mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog; | 669 | mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog; |
577 | mp->m_litino = sbp->sb_inodesize - sizeof(struct xfs_dinode); | ||
578 | mp->m_blockmask = sbp->sb_blocksize - 1; | 670 | mp->m_blockmask = sbp->sb_blocksize - 1; |
579 | mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; | 671 | mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG; |
580 | mp->m_blockwmask = mp->m_blockwsize - 1; | 672 | mp->m_blockwmask = mp->m_blockwsize - 1; |
581 | 673 | ||
582 | /* | ||
583 | * Setup for attributes, in case they get created. | ||
584 | * This value is for inodes getting attributes for the first time, | ||
585 | * the per-inode value is for old attribute values. | ||
586 | */ | ||
587 | ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048); | ||
588 | switch (sbp->sb_inodesize) { | ||
589 | case 256: | ||
590 | mp->m_attroffset = XFS_LITINO(mp) - | ||
591 | XFS_BMDR_SPACE_CALC(MINABTPTRS); | ||
592 | break; | ||
593 | case 512: | ||
594 | case 1024: | ||
595 | case 2048: | ||
596 | mp->m_attroffset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS); | ||
597 | break; | ||
598 | default: | ||
599 | ASSERT(0); | ||
600 | } | ||
601 | ASSERT(mp->m_attroffset < XFS_LITINO(mp)); | ||
602 | |||
603 | mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1); | 674 | mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1); |
604 | mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0); | 675 | mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0); |
605 | mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2; | 676 | mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2; |
@@ -645,7 +716,7 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount) | |||
645 | for (index = 0; index < agcount; index++) { | 716 | for (index = 0; index < agcount; index++) { |
646 | /* | 717 | /* |
647 | * read the agf, then the agi. This gets us | 718 | * read the agf, then the agi. This gets us |
648 | * all the inforamtion we need and populates the | 719 | * all the information we need and populates the |
649 | * per-ag structures for us. | 720 | * per-ag structures for us. |
650 | */ | 721 | */ |
651 | error = xfs_alloc_pagf_init(mp, NULL, index, 0); | 722 | error = xfs_alloc_pagf_init(mp, NULL, index, 0); |
@@ -886,8 +957,6 @@ xfs_check_sizes(xfs_mount_t *mp) | |||
886 | } | 957 | } |
887 | 958 | ||
888 | /* | 959 | /* |
889 | * xfs_mountfs | ||
890 | * | ||
891 | * This function does the following on an initial mount of a file system: | 960 | * This function does the following on an initial mount of a file system: |
892 | * - reads the superblock from disk and init the mount struct | 961 | * - reads the superblock from disk and init the mount struct |
893 | * - if we're a 32-bit kernel, do a size check on the superblock | 962 | * - if we're a 32-bit kernel, do a size check on the superblock |
@@ -905,7 +974,6 @@ xfs_mountfs( | |||
905 | xfs_inode_t *rip; | 974 | xfs_inode_t *rip; |
906 | __uint64_t resblks; | 975 | __uint64_t resblks; |
907 | uint quotamount, quotaflags; | 976 | uint quotamount, quotaflags; |
908 | int uuid_mounted = 0; | ||
909 | int error = 0; | 977 | int error = 0; |
910 | 978 | ||
911 | xfs_mount_common(mp, sbp); | 979 | xfs_mount_common(mp, sbp); |
@@ -960,7 +1028,7 @@ xfs_mountfs( | |||
960 | */ | 1028 | */ |
961 | error = xfs_update_alignment(mp); | 1029 | error = xfs_update_alignment(mp); |
962 | if (error) | 1030 | if (error) |
963 | goto error1; | 1031 | goto out; |
964 | 1032 | ||
965 | xfs_alloc_compute_maxlevels(mp); | 1033 | xfs_alloc_compute_maxlevels(mp); |
966 | xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK); | 1034 | xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK); |
@@ -971,19 +1039,9 @@ xfs_mountfs( | |||
971 | 1039 | ||
972 | mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog); | 1040 | mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog); |
973 | 1041 | ||
974 | /* | 1042 | error = xfs_uuid_mount(mp); |
975 | * XFS uses the uuid from the superblock as the unique | 1043 | if (error) |
976 | * identifier for fsid. We can not use the uuid from the volume | 1044 | goto out; |
977 | * since a single partition filesystem is identical to a single | ||
978 | * partition volume/filesystem. | ||
979 | */ | ||
980 | if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0) { | ||
981 | if (xfs_uuid_mount(mp)) { | ||
982 | error = XFS_ERROR(EINVAL); | ||
983 | goto error1; | ||
984 | } | ||
985 | uuid_mounted=1; | ||
986 | } | ||
987 | 1045 | ||
988 | /* | 1046 | /* |
989 | * Set the minimum read and write sizes | 1047 | * Set the minimum read and write sizes |
@@ -1007,7 +1065,7 @@ xfs_mountfs( | |||
1007 | */ | 1065 | */ |
1008 | error = xfs_check_sizes(mp); | 1066 | error = xfs_check_sizes(mp); |
1009 | if (error) | 1067 | if (error) |
1010 | goto error1; | 1068 | goto out_remove_uuid; |
1011 | 1069 | ||
1012 | /* | 1070 | /* |
1013 | * Initialize realtime fields in the mount structure | 1071 | * Initialize realtime fields in the mount structure |
@@ -1015,7 +1073,7 @@ xfs_mountfs( | |||
1015 | error = xfs_rtmount_init(mp); | 1073 | error = xfs_rtmount_init(mp); |
1016 | if (error) { | 1074 | if (error) { |
1017 | cmn_err(CE_WARN, "XFS: RT mount failed"); | 1075 | cmn_err(CE_WARN, "XFS: RT mount failed"); |
1018 | goto error1; | 1076 | goto out_remove_uuid; |
1019 | } | 1077 | } |
1020 | 1078 | ||
1021 | /* | 1079 | /* |
@@ -1045,26 +1103,26 @@ xfs_mountfs( | |||
1045 | mp->m_perag = kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), | 1103 | mp->m_perag = kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), |
1046 | KM_MAYFAIL); | 1104 | KM_MAYFAIL); |
1047 | if (!mp->m_perag) | 1105 | if (!mp->m_perag) |
1048 | goto error1; | 1106 | goto out_remove_uuid; |
1049 | 1107 | ||
1050 | mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount); | 1108 | mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount); |
1051 | 1109 | ||
1110 | if (!sbp->sb_logblocks) { | ||
1111 | cmn_err(CE_WARN, "XFS: no log defined"); | ||
1112 | XFS_ERROR_REPORT("xfs_mountfs", XFS_ERRLEVEL_LOW, mp); | ||
1113 | error = XFS_ERROR(EFSCORRUPTED); | ||
1114 | goto out_free_perag; | ||
1115 | } | ||
1116 | |||
1052 | /* | 1117 | /* |
1053 | * log's mount-time initialization. Perform 1st part recovery if needed | 1118 | * log's mount-time initialization. Perform 1st part recovery if needed |
1054 | */ | 1119 | */ |
1055 | if (likely(sbp->sb_logblocks > 0)) { /* check for volume case */ | 1120 | error = xfs_log_mount(mp, mp->m_logdev_targp, |
1056 | error = xfs_log_mount(mp, mp->m_logdev_targp, | 1121 | XFS_FSB_TO_DADDR(mp, sbp->sb_logstart), |
1057 | XFS_FSB_TO_DADDR(mp, sbp->sb_logstart), | 1122 | XFS_FSB_TO_BB(mp, sbp->sb_logblocks)); |
1058 | XFS_FSB_TO_BB(mp, sbp->sb_logblocks)); | 1123 | if (error) { |
1059 | if (error) { | 1124 | cmn_err(CE_WARN, "XFS: log mount failed"); |
1060 | cmn_err(CE_WARN, "XFS: log mount failed"); | 1125 | goto out_free_perag; |
1061 | goto error2; | ||
1062 | } | ||
1063 | } else { /* No log has been defined */ | ||
1064 | cmn_err(CE_WARN, "XFS: no log defined"); | ||
1065 | XFS_ERROR_REPORT("xfs_mountfs_int(1)", XFS_ERRLEVEL_LOW, mp); | ||
1066 | error = XFS_ERROR(EFSCORRUPTED); | ||
1067 | goto error2; | ||
1068 | } | 1126 | } |
1069 | 1127 | ||
1070 | /* | 1128 | /* |
@@ -1086,15 +1144,14 @@ xfs_mountfs( | |||
1086 | * If we are currently making the filesystem, the initialisation will | 1144 | * If we are currently making the filesystem, the initialisation will |
1087 | * fail as the perag data is in an undefined state. | 1145 | * fail as the perag data is in an undefined state. |
1088 | */ | 1146 | */ |
1089 | |||
1090 | if (xfs_sb_version_haslazysbcount(&mp->m_sb) && | 1147 | if (xfs_sb_version_haslazysbcount(&mp->m_sb) && |
1091 | !XFS_LAST_UNMOUNT_WAS_CLEAN(mp) && | 1148 | !XFS_LAST_UNMOUNT_WAS_CLEAN(mp) && |
1092 | !mp->m_sb.sb_inprogress) { | 1149 | !mp->m_sb.sb_inprogress) { |
1093 | error = xfs_initialize_perag_data(mp, sbp->sb_agcount); | 1150 | error = xfs_initialize_perag_data(mp, sbp->sb_agcount); |
1094 | if (error) { | 1151 | if (error) |
1095 | goto error2; | 1152 | goto out_free_perag; |
1096 | } | ||
1097 | } | 1153 | } |
1154 | |||
1098 | /* | 1155 | /* |
1099 | * Get and sanity-check the root inode. | 1156 | * Get and sanity-check the root inode. |
1100 | * Save the pointer to it in the mount structure. | 1157 | * Save the pointer to it in the mount structure. |
@@ -1102,7 +1159,7 @@ xfs_mountfs( | |||
1102 | error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip, 0); | 1159 | error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip, 0); |
1103 | if (error) { | 1160 | if (error) { |
1104 | cmn_err(CE_WARN, "XFS: failed to read root inode"); | 1161 | cmn_err(CE_WARN, "XFS: failed to read root inode"); |
1105 | goto error3; | 1162 | goto out_log_dealloc; |
1106 | } | 1163 | } |
1107 | 1164 | ||
1108 | ASSERT(rip != NULL); | 1165 | ASSERT(rip != NULL); |
@@ -1116,7 +1173,7 @@ xfs_mountfs( | |||
1116 | XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW, | 1173 | XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW, |
1117 | mp); | 1174 | mp); |
1118 | error = XFS_ERROR(EFSCORRUPTED); | 1175 | error = XFS_ERROR(EFSCORRUPTED); |
1119 | goto error4; | 1176 | goto out_rele_rip; |
1120 | } | 1177 | } |
1121 | mp->m_rootip = rip; /* save it */ | 1178 | mp->m_rootip = rip; /* save it */ |
1122 | 1179 | ||
@@ -1131,7 +1188,7 @@ xfs_mountfs( | |||
1131 | * Free up the root inode. | 1188 | * Free up the root inode. |
1132 | */ | 1189 | */ |
1133 | cmn_err(CE_WARN, "XFS: failed to read RT inodes"); | 1190 | cmn_err(CE_WARN, "XFS: failed to read RT inodes"); |
1134 | goto error4; | 1191 | goto out_rele_rip; |
1135 | } | 1192 | } |
1136 | 1193 | ||
1137 | /* | 1194 | /* |
@@ -1143,7 +1200,7 @@ xfs_mountfs( | |||
1143 | error = xfs_mount_log_sb(mp, mp->m_update_flags); | 1200 | error = xfs_mount_log_sb(mp, mp->m_update_flags); |
1144 | if (error) { | 1201 | if (error) { |
1145 | cmn_err(CE_WARN, "XFS: failed to write sb changes"); | 1202 | cmn_err(CE_WARN, "XFS: failed to write sb changes"); |
1146 | goto error4; | 1203 | goto out_rtunmount; |
1147 | } | 1204 | } |
1148 | } | 1205 | } |
1149 | 1206 | ||
@@ -1152,7 +1209,7 @@ xfs_mountfs( | |||
1152 | */ | 1209 | */ |
1153 | error = XFS_QM_INIT(mp, "amount, "aflags); | 1210 | error = XFS_QM_INIT(mp, "amount, "aflags); |
1154 | if (error) | 1211 | if (error) |
1155 | goto error4; | 1212 | goto out_rtunmount; |
1156 | 1213 | ||
1157 | /* | 1214 | /* |
1158 | * Finish recovering the file system. This part needed to be | 1215 | * Finish recovering the file system. This part needed to be |
@@ -1162,7 +1219,7 @@ xfs_mountfs( | |||
1162 | error = xfs_log_mount_finish(mp); | 1219 | error = xfs_log_mount_finish(mp); |
1163 | if (error) { | 1220 | if (error) { |
1164 | cmn_err(CE_WARN, "XFS: log mount finish failed"); | 1221 | cmn_err(CE_WARN, "XFS: log mount finish failed"); |
1165 | goto error4; | 1222 | goto out_rtunmount; |
1166 | } | 1223 | } |
1167 | 1224 | ||
1168 | /* | 1225 | /* |
@@ -1170,7 +1227,7 @@ xfs_mountfs( | |||
1170 | */ | 1227 | */ |
1171 | error = XFS_QM_MOUNT(mp, quotamount, quotaflags); | 1228 | error = XFS_QM_MOUNT(mp, quotamount, quotaflags); |
1172 | if (error) | 1229 | if (error) |
1173 | goto error4; | 1230 | goto out_rtunmount; |
1174 | 1231 | ||
1175 | /* | 1232 | /* |
1176 | * Now we are mounted, reserve a small amount of unused space for | 1233 | * Now we are mounted, reserve a small amount of unused space for |
@@ -1194,18 +1251,17 @@ xfs_mountfs( | |||
1194 | 1251 | ||
1195 | return 0; | 1252 | return 0; |
1196 | 1253 | ||
1197 | error4: | 1254 | out_rtunmount: |
1198 | /* | 1255 | xfs_rtunmount_inodes(mp); |
1199 | * Free up the root inode. | 1256 | out_rele_rip: |
1200 | */ | ||
1201 | IRELE(rip); | 1257 | IRELE(rip); |
1202 | error3: | 1258 | out_log_dealloc: |
1203 | xfs_log_unmount_dealloc(mp); | 1259 | xfs_log_unmount(mp); |
1204 | error2: | 1260 | out_free_perag: |
1205 | xfs_free_perag(mp); | 1261 | xfs_free_perag(mp); |
1206 | error1: | 1262 | out_remove_uuid: |
1207 | if (uuid_mounted) | 1263 | xfs_uuid_unmount(mp); |
1208 | uuid_table_remove(&mp->m_sb.sb_uuid); | 1264 | out: |
1209 | return error; | 1265 | return error; |
1210 | } | 1266 | } |
1211 | 1267 | ||
@@ -1226,15 +1282,12 @@ xfs_unmountfs( | |||
1226 | */ | 1282 | */ |
1227 | XFS_QM_UNMOUNT(mp); | 1283 | XFS_QM_UNMOUNT(mp); |
1228 | 1284 | ||
1229 | if (mp->m_rbmip) | 1285 | xfs_rtunmount_inodes(mp); |
1230 | IRELE(mp->m_rbmip); | ||
1231 | if (mp->m_rsumip) | ||
1232 | IRELE(mp->m_rsumip); | ||
1233 | IRELE(mp->m_rootip); | 1286 | IRELE(mp->m_rootip); |
1234 | 1287 | ||
1235 | /* | 1288 | /* |
1236 | * We can potentially deadlock here if we have an inode cluster | 1289 | * We can potentially deadlock here if we have an inode cluster |
1237 | * that has been freed has it's buffer still pinned in memory because | 1290 | * that has been freed has its buffer still pinned in memory because |
1238 | * the transaction is still sitting in a iclog. The stale inodes | 1291 | * the transaction is still sitting in a iclog. The stale inodes |
1239 | * on that buffer will have their flush locks held until the | 1292 | * on that buffer will have their flush locks held until the |
1240 | * transaction hits the disk and the callbacks run. the inode | 1293 | * transaction hits the disk and the callbacks run. the inode |
@@ -1266,7 +1319,7 @@ xfs_unmountfs( | |||
1266 | * Unreserve any blocks we have so that when we unmount we don't account | 1319 | * Unreserve any blocks we have so that when we unmount we don't account |
1267 | * the reserved free space as used. This is really only necessary for | 1320 | * the reserved free space as used. This is really only necessary for |
1268 | * lazy superblock counting because it trusts the incore superblock | 1321 | * lazy superblock counting because it trusts the incore superblock |
1269 | * counters to be aboslutely correct on clean unmount. | 1322 | * counters to be absolutely correct on clean unmount. |
1270 | * | 1323 | * |
1271 | * We don't bother correcting this elsewhere for lazy superblock | 1324 | * We don't bother correcting this elsewhere for lazy superblock |
1272 | * counting because on mount of an unclean filesystem we reconstruct the | 1325 | * counting because on mount of an unclean filesystem we reconstruct the |
@@ -1288,10 +1341,9 @@ xfs_unmountfs( | |||
1288 | "Freespace may not be correct on next mount."); | 1341 | "Freespace may not be correct on next mount."); |
1289 | xfs_unmountfs_writesb(mp); | 1342 | xfs_unmountfs_writesb(mp); |
1290 | xfs_unmountfs_wait(mp); /* wait for async bufs */ | 1343 | xfs_unmountfs_wait(mp); /* wait for async bufs */ |
1291 | xfs_log_unmount(mp); /* Done! No more fs ops. */ | 1344 | xfs_log_unmount_write(mp); |
1292 | 1345 | xfs_log_unmount(mp); | |
1293 | if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0) | 1346 | xfs_uuid_unmount(mp); |
1294 | uuid_table_remove(&mp->m_sb.sb_uuid); | ||
1295 | 1347 | ||
1296 | #if defined(DEBUG) | 1348 | #if defined(DEBUG) |
1297 | xfs_errortag_clearall(mp, 0); | 1349 | xfs_errortag_clearall(mp, 0); |
@@ -1793,29 +1845,6 @@ xfs_freesb( | |||
1793 | } | 1845 | } |
1794 | 1846 | ||
1795 | /* | 1847 | /* |
1796 | * See if the UUID is unique among mounted XFS filesystems. | ||
1797 | * Mount fails if UUID is nil or a FS with the same UUID is already mounted. | ||
1798 | */ | ||
1799 | STATIC int | ||
1800 | xfs_uuid_mount( | ||
1801 | xfs_mount_t *mp) | ||
1802 | { | ||
1803 | if (uuid_is_nil(&mp->m_sb.sb_uuid)) { | ||
1804 | cmn_err(CE_WARN, | ||
1805 | "XFS: Filesystem %s has nil UUID - can't mount", | ||
1806 | mp->m_fsname); | ||
1807 | return -1; | ||
1808 | } | ||
1809 | if (!uuid_table_insert(&mp->m_sb.sb_uuid)) { | ||
1810 | cmn_err(CE_WARN, | ||
1811 | "XFS: Filesystem %s has duplicate UUID - can't mount", | ||
1812 | mp->m_fsname); | ||
1813 | return -1; | ||
1814 | } | ||
1815 | return 0; | ||
1816 | } | ||
1817 | |||
1818 | /* | ||
1819 | * Used to log changes to the superblock unit and width fields which could | 1848 | * Used to log changes to the superblock unit and width fields which could |
1820 | * be altered by the mount options, as well as any potential sb_features2 | 1849 | * be altered by the mount options, as well as any potential sb_features2 |
1821 | * fixup. Only the first superblock is updated. | 1850 | * fixup. Only the first superblock is updated. |
@@ -1868,7 +1897,7 @@ xfs_mount_log_sb( | |||
1868 | * we disable the per-cpu counter and go through the slow path. | 1897 | * we disable the per-cpu counter and go through the slow path. |
1869 | * | 1898 | * |
1870 | * The slow path is the current xfs_mod_incore_sb() function. This means that | 1899 | * The slow path is the current xfs_mod_incore_sb() function. This means that |
1871 | * when we disable a per-cpu counter, we need to drain it's resources back to | 1900 | * when we disable a per-cpu counter, we need to drain its resources back to |
1872 | * the global superblock. We do this after disabling the counter to prevent | 1901 | * the global superblock. We do this after disabling the counter to prevent |
1873 | * more threads from queueing up on the counter. | 1902 | * more threads from queueing up on the counter. |
1874 | * | 1903 | * |