aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r--fs/xfs/xfs_mount.c121
1 files changed, 82 insertions, 39 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 6409b3762995..2fec452afbcc 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -43,8 +43,9 @@
43#include "xfs_rw.h" 43#include "xfs_rw.h"
44#include "xfs_quota.h" 44#include "xfs_quota.h"
45#include "xfs_fsops.h" 45#include "xfs_fsops.h"
46#include "xfs_utils.h"
46 47
47STATIC void xfs_mount_log_sbunit(xfs_mount_t *, __int64_t); 48STATIC int xfs_mount_log_sb(xfs_mount_t *, __int64_t);
48STATIC int xfs_uuid_mount(xfs_mount_t *); 49STATIC int xfs_uuid_mount(xfs_mount_t *);
49STATIC void xfs_uuid_unmount(xfs_mount_t *mp); 50STATIC void xfs_uuid_unmount(xfs_mount_t *mp);
50STATIC void xfs_unmountfs_wait(xfs_mount_t *); 51STATIC void xfs_unmountfs_wait(xfs_mount_t *);
@@ -57,7 +58,7 @@ STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t,
57STATIC void xfs_icsb_sync_counters(xfs_mount_t *); 58STATIC void xfs_icsb_sync_counters(xfs_mount_t *);
58STATIC int xfs_icsb_modify_counters(xfs_mount_t *, xfs_sb_field_t, 59STATIC int xfs_icsb_modify_counters(xfs_mount_t *, xfs_sb_field_t,
59 int64_t, int); 60 int64_t, int);
60STATIC int xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t); 61STATIC void xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t);
61 62
62#else 63#else
63 64
@@ -119,6 +120,7 @@ static const struct {
119 { offsetof(xfs_sb_t, sb_logsectsize),0 }, 120 { offsetof(xfs_sb_t, sb_logsectsize),0 },
120 { offsetof(xfs_sb_t, sb_logsunit), 0 }, 121 { offsetof(xfs_sb_t, sb_logsunit), 0 },
121 { offsetof(xfs_sb_t, sb_features2), 0 }, 122 { offsetof(xfs_sb_t, sb_features2), 0 },
123 { offsetof(xfs_sb_t, sb_bad_features2), 0 },
122 { sizeof(xfs_sb_t), 0 } 124 { sizeof(xfs_sb_t), 0 }
123}; 125};
124 126
@@ -225,7 +227,7 @@ xfs_mount_validate_sb(
225 return XFS_ERROR(EWRONGFS); 227 return XFS_ERROR(EWRONGFS);
226 } 228 }
227 229
228 if (!XFS_SB_GOOD_VERSION(sbp)) { 230 if (!xfs_sb_good_version(sbp)) {
229 xfs_fs_mount_cmn_err(flags, "bad version"); 231 xfs_fs_mount_cmn_err(flags, "bad version");
230 return XFS_ERROR(EWRONGFS); 232 return XFS_ERROR(EWRONGFS);
231 } 233 }
@@ -300,7 +302,7 @@ xfs_mount_validate_sb(
300 /* 302 /*
301 * Version 1 directory format has never worked on Linux. 303 * Version 1 directory format has never worked on Linux.
302 */ 304 */
303 if (unlikely(!XFS_SB_VERSION_HASDIRV2(sbp))) { 305 if (unlikely(!xfs_sb_version_hasdirv2(sbp))) {
304 xfs_fs_mount_cmn_err(flags, 306 xfs_fs_mount_cmn_err(flags,
305 "file system using version 1 directory format"); 307 "file system using version 1 directory format");
306 return XFS_ERROR(ENOSYS); 308 return XFS_ERROR(ENOSYS);
@@ -449,6 +451,7 @@ xfs_sb_from_disk(
449 to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize); 451 to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize);
450 to->sb_logsunit = be32_to_cpu(from->sb_logsunit); 452 to->sb_logsunit = be32_to_cpu(from->sb_logsunit);
451 to->sb_features2 = be32_to_cpu(from->sb_features2); 453 to->sb_features2 = be32_to_cpu(from->sb_features2);
454 to->sb_bad_features2 = be32_to_cpu(from->sb_bad_features2);
452} 455}
453 456
454/* 457/*
@@ -781,7 +784,7 @@ xfs_update_alignment(xfs_mount_t *mp, int mfsi_flags, __uint64_t *update_flags)
781 * Update superblock with new values 784 * Update superblock with new values
782 * and log changes 785 * and log changes
783 */ 786 */
784 if (XFS_SB_VERSION_HASDALIGN(sbp)) { 787 if (xfs_sb_version_hasdalign(sbp)) {
785 if (sbp->sb_unit != mp->m_dalign) { 788 if (sbp->sb_unit != mp->m_dalign) {
786 sbp->sb_unit = mp->m_dalign; 789 sbp->sb_unit = mp->m_dalign;
787 *update_flags |= XFS_SB_UNIT; 790 *update_flags |= XFS_SB_UNIT;
@@ -792,7 +795,7 @@ xfs_update_alignment(xfs_mount_t *mp, int mfsi_flags, __uint64_t *update_flags)
792 } 795 }
793 } 796 }
794 } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN && 797 } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&
795 XFS_SB_VERSION_HASDALIGN(&mp->m_sb)) { 798 xfs_sb_version_hasdalign(&mp->m_sb)) {
796 mp->m_dalign = sbp->sb_unit; 799 mp->m_dalign = sbp->sb_unit;
797 mp->m_swidth = sbp->sb_width; 800 mp->m_swidth = sbp->sb_width;
798 } 801 }
@@ -869,7 +872,7 @@ xfs_set_rw_sizes(xfs_mount_t *mp)
869STATIC void 872STATIC void
870xfs_set_inoalignment(xfs_mount_t *mp) 873xfs_set_inoalignment(xfs_mount_t *mp)
871{ 874{
872 if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) && 875 if (xfs_sb_version_hasalign(&mp->m_sb) &&
873 mp->m_sb.sb_inoalignmt >= 876 mp->m_sb.sb_inoalignmt >=
874 XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size)) 877 XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
875 mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1; 878 mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1;
@@ -954,7 +957,6 @@ xfs_mountfs(
954{ 957{
955 xfs_sb_t *sbp = &(mp->m_sb); 958 xfs_sb_t *sbp = &(mp->m_sb);
956 xfs_inode_t *rip; 959 xfs_inode_t *rip;
957 bhv_vnode_t *rvp = NULL;
958 __uint64_t resblks; 960 __uint64_t resblks;
959 __int64_t update_flags = 0LL; 961 __int64_t update_flags = 0LL;
960 uint quotamount, quotaflags; 962 uint quotamount, quotaflags;
@@ -962,14 +964,41 @@ xfs_mountfs(
962 int uuid_mounted = 0; 964 int uuid_mounted = 0;
963 int error = 0; 965 int error = 0;
964 966
965 if (mp->m_sb_bp == NULL) {
966 error = xfs_readsb(mp, mfsi_flags);
967 if (error)
968 return error;
969 }
970 xfs_mount_common(mp, sbp); 967 xfs_mount_common(mp, sbp);
971 968
972 /* 969 /*
970 * Check for a mismatched features2 values. Older kernels
971 * read & wrote into the wrong sb offset for sb_features2
972 * on some platforms due to xfs_sb_t not being 64bit size aligned
973 * when sb_features2 was added, which made older superblock
974 * reading/writing routines swap it as a 64-bit value.
975 *
976 * For backwards compatibility, we make both slots equal.
977 *
978 * If we detect a mismatched field, we OR the set bits into the
979 * existing features2 field in case it has already been modified; we
980 * don't want to lose any features. We then update the bad location
981 * with the ORed value so that older kernels will see any features2
982 * flags, and mark the two fields as needing updates once the
983 * transaction subsystem is online.
984 */
985 if (xfs_sb_has_mismatched_features2(sbp)) {
986 cmn_err(CE_WARN,
987 "XFS: correcting sb_features alignment problem");
988 sbp->sb_features2 |= sbp->sb_bad_features2;
989 sbp->sb_bad_features2 = sbp->sb_features2;
990 update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2;
991
992 /*
993 * Re-check for ATTR2 in case it was found in bad_features2
994 * slot.
995 */
996 if (xfs_sb_version_hasattr2(&mp->m_sb))
997 mp->m_flags |= XFS_MOUNT_ATTR2;
998
999 }
1000
1001 /*
973 * Check if sb_agblocks is aligned at stripe boundary 1002 * Check if sb_agblocks is aligned at stripe boundary
974 * If sb_agblocks is NOT aligned turn off m_dalign since 1003 * If sb_agblocks is NOT aligned turn off m_dalign since
975 * allocator alignment is within an ag, therefore ag has 1004 * allocator alignment is within an ag, therefore ag has
@@ -1129,7 +1158,6 @@ xfs_mountfs(
1129 } 1158 }
1130 1159
1131 ASSERT(rip != NULL); 1160 ASSERT(rip != NULL);
1132 rvp = XFS_ITOV(rip);
1133 1161
1134 if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) { 1162 if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) {
1135 cmn_err(CE_WARN, "XFS: corrupted root inode"); 1163 cmn_err(CE_WARN, "XFS: corrupted root inode");
@@ -1159,11 +1187,15 @@ xfs_mountfs(
1159 } 1187 }
1160 1188
1161 /* 1189 /*
1162 * If fs is not mounted readonly, then update the superblock 1190 * If fs is not mounted readonly, then update the superblock changes.
1163 * unit and width changes.
1164 */ 1191 */
1165 if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) 1192 if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) {
1166 xfs_mount_log_sbunit(mp, update_flags); 1193 error = xfs_mount_log_sb(mp, update_flags);
1194 if (error) {
1195 cmn_err(CE_WARN, "XFS: failed to write sb changes");
1196 goto error4;
1197 }
1198 }
1167 1199
1168 /* 1200 /*
1169 * Initialise the XFS quota management subsystem for this mount 1201 * Initialise the XFS quota management subsystem for this mount
@@ -1200,12 +1232,15 @@ xfs_mountfs(
1200 * 1232 *
1201 * We default to 5% or 1024 fsbs of space reserved, whichever is smaller. 1233 * We default to 5% or 1024 fsbs of space reserved, whichever is smaller.
1202 * This may drive us straight to ENOSPC on mount, but that implies 1234 * This may drive us straight to ENOSPC on mount, but that implies
1203 * we were already there on the last unmount. 1235 * we were already there on the last unmount. Warn if this occurs.
1204 */ 1236 */
1205 resblks = mp->m_sb.sb_dblocks; 1237 resblks = mp->m_sb.sb_dblocks;
1206 do_div(resblks, 20); 1238 do_div(resblks, 20);
1207 resblks = min_t(__uint64_t, resblks, 1024); 1239 resblks = min_t(__uint64_t, resblks, 1024);
1208 xfs_reserve_blocks(mp, &resblks, NULL); 1240 error = xfs_reserve_blocks(mp, &resblks, NULL);
1241 if (error)
1242 cmn_err(CE_WARN, "XFS: Unable to allocate reserve blocks. "
1243 "Continuing without a reserve pool.");
1209 1244
1210 return 0; 1245 return 0;
1211 1246
@@ -1213,7 +1248,7 @@ xfs_mountfs(
1213 /* 1248 /*
1214 * Free up the root inode. 1249 * Free up the root inode.
1215 */ 1250 */
1216 VN_RELE(rvp); 1251 IRELE(rip);
1217 error3: 1252 error3:
1218 xfs_log_unmount_dealloc(mp); 1253 xfs_log_unmount_dealloc(mp);
1219 error2: 1254 error2:
@@ -1241,6 +1276,7 @@ int
1241xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) 1276xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
1242{ 1277{
1243 __uint64_t resblks; 1278 __uint64_t resblks;
1279 int error = 0;
1244 1280
1245 /* 1281 /*
1246 * We can potentially deadlock here if we have an inode cluster 1282 * We can potentially deadlock here if we have an inode cluster
@@ -1284,9 +1320,15 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
1284 * value does not matter.... 1320 * value does not matter....
1285 */ 1321 */
1286 resblks = 0; 1322 resblks = 0;
1287 xfs_reserve_blocks(mp, &resblks, NULL); 1323 error = xfs_reserve_blocks(mp, &resblks, NULL);
1324 if (error)
1325 cmn_err(CE_WARN, "XFS: Unable to free reserved block pool. "
1326 "Freespace may not be correct on next mount.");
1288 1327
1289 xfs_log_sbcount(mp, 1); 1328 error = xfs_log_sbcount(mp, 1);
1329 if (error)
1330 cmn_err(CE_WARN, "XFS: Unable to update superblock counters. "
1331 "Freespace may not be correct on next mount.");
1290 xfs_unmountfs_writesb(mp); 1332 xfs_unmountfs_writesb(mp);
1291 xfs_unmountfs_wait(mp); /* wait for async bufs */ 1333 xfs_unmountfs_wait(mp); /* wait for async bufs */
1292 xfs_log_unmount(mp); /* Done! No more fs ops. */ 1334 xfs_log_unmount(mp); /* Done! No more fs ops. */
@@ -1378,9 +1420,8 @@ xfs_log_sbcount(
1378 xfs_mod_sb(tp, XFS_SB_IFREE | XFS_SB_ICOUNT | XFS_SB_FDBLOCKS); 1420 xfs_mod_sb(tp, XFS_SB_IFREE | XFS_SB_ICOUNT | XFS_SB_FDBLOCKS);
1379 if (sync) 1421 if (sync)
1380 xfs_trans_set_sync(tp); 1422 xfs_trans_set_sync(tp);
1381 xfs_trans_commit(tp, 0); 1423 error = xfs_trans_commit(tp, 0);
1382 1424 return error;
1383 return 0;
1384} 1425}
1385 1426
1386STATIC void 1427STATIC void
@@ -1429,7 +1470,6 @@ xfs_unmountfs_writesb(xfs_mount_t *mp)
1429 XFS_BUF_UNASYNC(sbp); 1470 XFS_BUF_UNASYNC(sbp);
1430 ASSERT(XFS_BUF_TARGET(sbp) == mp->m_ddev_targp); 1471 ASSERT(XFS_BUF_TARGET(sbp) == mp->m_ddev_targp);
1431 xfsbdstrat(mp, sbp); 1472 xfsbdstrat(mp, sbp);
1432 /* Nevermind errors we might get here. */
1433 error = xfs_iowait(sbp); 1473 error = xfs_iowait(sbp);
1434 if (error) 1474 if (error)
1435 xfs_ioerror_alert("xfs_unmountfs_writesb", 1475 xfs_ioerror_alert("xfs_unmountfs_writesb",
@@ -1875,25 +1915,30 @@ xfs_uuid_unmount(
1875 1915
1876/* 1916/*
1877 * Used to log changes to the superblock unit and width fields which could 1917 * Used to log changes to the superblock unit and width fields which could
1878 * be altered by the mount options. Only the first superblock is updated. 1918 * be altered by the mount options, as well as any potential sb_features2
1919 * fixup. Only the first superblock is updated.
1879 */ 1920 */
1880STATIC void 1921STATIC int
1881xfs_mount_log_sbunit( 1922xfs_mount_log_sb(
1882 xfs_mount_t *mp, 1923 xfs_mount_t *mp,
1883 __int64_t fields) 1924 __int64_t fields)
1884{ 1925{
1885 xfs_trans_t *tp; 1926 xfs_trans_t *tp;
1927 int error;
1886 1928
1887 ASSERT(fields & (XFS_SB_UNIT|XFS_SB_WIDTH|XFS_SB_UUID)); 1929 ASSERT(fields & (XFS_SB_UNIT | XFS_SB_WIDTH | XFS_SB_UUID |
1930 XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2));
1888 1931
1889 tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT); 1932 tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT);
1890 if (xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, 1933 error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,
1891 XFS_DEFAULT_LOG_COUNT)) { 1934 XFS_DEFAULT_LOG_COUNT);
1935 if (error) {
1892 xfs_trans_cancel(tp, 0); 1936 xfs_trans_cancel(tp, 0);
1893 return; 1937 return error;
1894 } 1938 }
1895 xfs_mod_sb(tp, fields); 1939 xfs_mod_sb(tp, fields);
1896 xfs_trans_commit(tp, 0); 1940 error = xfs_trans_commit(tp, 0);
1941 return error;
1897} 1942}
1898 1943
1899 1944
@@ -2154,7 +2199,7 @@ xfs_icsb_counter_disabled(
2154 return test_bit(field, &mp->m_icsb_counters); 2199 return test_bit(field, &mp->m_icsb_counters);
2155} 2200}
2156 2201
2157STATIC int 2202STATIC void
2158xfs_icsb_disable_counter( 2203xfs_icsb_disable_counter(
2159 xfs_mount_t *mp, 2204 xfs_mount_t *mp,
2160 xfs_sb_field_t field) 2205 xfs_sb_field_t field)
@@ -2172,7 +2217,7 @@ xfs_icsb_disable_counter(
2172 * the m_icsb_mutex. 2217 * the m_icsb_mutex.
2173 */ 2218 */
2174 if (xfs_icsb_counter_disabled(mp, field)) 2219 if (xfs_icsb_counter_disabled(mp, field))
2175 return 0; 2220 return;
2176 2221
2177 xfs_icsb_lock_all_counters(mp); 2222 xfs_icsb_lock_all_counters(mp);
2178 if (!test_and_set_bit(field, &mp->m_icsb_counters)) { 2223 if (!test_and_set_bit(field, &mp->m_icsb_counters)) {
@@ -2195,8 +2240,6 @@ xfs_icsb_disable_counter(
2195 } 2240 }
2196 2241
2197 xfs_icsb_unlock_all_counters(mp); 2242 xfs_icsb_unlock_all_counters(mp);
2198
2199 return 0;
2200} 2243}
2201 2244
2202STATIC void 2245STATIC void