diff options
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r-- | fs/xfs/xfs_mount.c | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 8ed164eb9544..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 | ||
47 | STATIC void xfs_mount_log_sb(xfs_mount_t *, __int64_t); | 48 | STATIC int xfs_mount_log_sb(xfs_mount_t *, __int64_t); |
48 | STATIC int xfs_uuid_mount(xfs_mount_t *); | 49 | STATIC int xfs_uuid_mount(xfs_mount_t *); |
49 | STATIC void xfs_uuid_unmount(xfs_mount_t *mp); | 50 | STATIC void xfs_uuid_unmount(xfs_mount_t *mp); |
50 | STATIC void xfs_unmountfs_wait(xfs_mount_t *); | 51 | STATIC void xfs_unmountfs_wait(xfs_mount_t *); |
@@ -57,7 +58,7 @@ STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, | |||
57 | STATIC void xfs_icsb_sync_counters(xfs_mount_t *); | 58 | STATIC void xfs_icsb_sync_counters(xfs_mount_t *); |
58 | STATIC int xfs_icsb_modify_counters(xfs_mount_t *, xfs_sb_field_t, | 59 | STATIC int xfs_icsb_modify_counters(xfs_mount_t *, xfs_sb_field_t, |
59 | int64_t, int); | 60 | int64_t, int); |
60 | STATIC int xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t); | 61 | STATIC void xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t); |
61 | 62 | ||
62 | #else | 63 | #else |
63 | 64 | ||
@@ -956,7 +957,6 @@ xfs_mountfs( | |||
956 | { | 957 | { |
957 | xfs_sb_t *sbp = &(mp->m_sb); | 958 | xfs_sb_t *sbp = &(mp->m_sb); |
958 | xfs_inode_t *rip; | 959 | xfs_inode_t *rip; |
959 | bhv_vnode_t *rvp = NULL; | ||
960 | __uint64_t resblks; | 960 | __uint64_t resblks; |
961 | __int64_t update_flags = 0LL; | 961 | __int64_t update_flags = 0LL; |
962 | uint quotamount, quotaflags; | 962 | uint quotamount, quotaflags; |
@@ -964,11 +964,6 @@ xfs_mountfs( | |||
964 | int uuid_mounted = 0; | 964 | int uuid_mounted = 0; |
965 | int error = 0; | 965 | int error = 0; |
966 | 966 | ||
967 | if (mp->m_sb_bp == NULL) { | ||
968 | error = xfs_readsb(mp, mfsi_flags); | ||
969 | if (error) | ||
970 | return error; | ||
971 | } | ||
972 | xfs_mount_common(mp, sbp); | 967 | xfs_mount_common(mp, sbp); |
973 | 968 | ||
974 | /* | 969 | /* |
@@ -1163,7 +1158,6 @@ xfs_mountfs( | |||
1163 | } | 1158 | } |
1164 | 1159 | ||
1165 | ASSERT(rip != NULL); | 1160 | ASSERT(rip != NULL); |
1166 | rvp = XFS_ITOV(rip); | ||
1167 | 1161 | ||
1168 | if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) { | 1162 | if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) { |
1169 | cmn_err(CE_WARN, "XFS: corrupted root inode"); | 1163 | cmn_err(CE_WARN, "XFS: corrupted root inode"); |
@@ -1195,8 +1189,13 @@ xfs_mountfs( | |||
1195 | /* | 1189 | /* |
1196 | * If fs is not mounted readonly, then update the superblock changes. | 1190 | * If fs is not mounted readonly, then update the superblock changes. |
1197 | */ | 1191 | */ |
1198 | if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) | 1192 | if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) { |
1199 | xfs_mount_log_sb(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 | } | ||
1200 | 1199 | ||
1201 | /* | 1200 | /* |
1202 | * Initialise the XFS quota management subsystem for this mount | 1201 | * Initialise the XFS quota management subsystem for this mount |
@@ -1233,12 +1232,15 @@ xfs_mountfs( | |||
1233 | * | 1232 | * |
1234 | * 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. |
1235 | * 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 |
1236 | * we were already there on the last unmount. | 1235 | * we were already there on the last unmount. Warn if this occurs. |
1237 | */ | 1236 | */ |
1238 | resblks = mp->m_sb.sb_dblocks; | 1237 | resblks = mp->m_sb.sb_dblocks; |
1239 | do_div(resblks, 20); | 1238 | do_div(resblks, 20); |
1240 | resblks = min_t(__uint64_t, resblks, 1024); | 1239 | resblks = min_t(__uint64_t, resblks, 1024); |
1241 | 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."); | ||
1242 | 1244 | ||
1243 | return 0; | 1245 | return 0; |
1244 | 1246 | ||
@@ -1246,7 +1248,7 @@ xfs_mountfs( | |||
1246 | /* | 1248 | /* |
1247 | * Free up the root inode. | 1249 | * Free up the root inode. |
1248 | */ | 1250 | */ |
1249 | VN_RELE(rvp); | 1251 | IRELE(rip); |
1250 | error3: | 1252 | error3: |
1251 | xfs_log_unmount_dealloc(mp); | 1253 | xfs_log_unmount_dealloc(mp); |
1252 | error2: | 1254 | error2: |
@@ -1274,6 +1276,7 @@ int | |||
1274 | xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | 1276 | xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) |
1275 | { | 1277 | { |
1276 | __uint64_t resblks; | 1278 | __uint64_t resblks; |
1279 | int error = 0; | ||
1277 | 1280 | ||
1278 | /* | 1281 | /* |
1279 | * We can potentially deadlock here if we have an inode cluster | 1282 | * We can potentially deadlock here if we have an inode cluster |
@@ -1317,9 +1320,15 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | |||
1317 | * value does not matter.... | 1320 | * value does not matter.... |
1318 | */ | 1321 | */ |
1319 | resblks = 0; | 1322 | resblks = 0; |
1320 | 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."); | ||
1321 | 1327 | ||
1322 | 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."); | ||
1323 | xfs_unmountfs_writesb(mp); | 1332 | xfs_unmountfs_writesb(mp); |
1324 | xfs_unmountfs_wait(mp); /* wait for async bufs */ | 1333 | xfs_unmountfs_wait(mp); /* wait for async bufs */ |
1325 | xfs_log_unmount(mp); /* Done! No more fs ops. */ | 1334 | xfs_log_unmount(mp); /* Done! No more fs ops. */ |
@@ -1411,9 +1420,8 @@ xfs_log_sbcount( | |||
1411 | 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); |
1412 | if (sync) | 1421 | if (sync) |
1413 | xfs_trans_set_sync(tp); | 1422 | xfs_trans_set_sync(tp); |
1414 | xfs_trans_commit(tp, 0); | 1423 | error = xfs_trans_commit(tp, 0); |
1415 | 1424 | return error; | |
1416 | return 0; | ||
1417 | } | 1425 | } |
1418 | 1426 | ||
1419 | STATIC void | 1427 | STATIC void |
@@ -1462,7 +1470,6 @@ xfs_unmountfs_writesb(xfs_mount_t *mp) | |||
1462 | XFS_BUF_UNASYNC(sbp); | 1470 | XFS_BUF_UNASYNC(sbp); |
1463 | ASSERT(XFS_BUF_TARGET(sbp) == mp->m_ddev_targp); | 1471 | ASSERT(XFS_BUF_TARGET(sbp) == mp->m_ddev_targp); |
1464 | xfsbdstrat(mp, sbp); | 1472 | xfsbdstrat(mp, sbp); |
1465 | /* Nevermind errors we might get here. */ | ||
1466 | error = xfs_iowait(sbp); | 1473 | error = xfs_iowait(sbp); |
1467 | if (error) | 1474 | if (error) |
1468 | xfs_ioerror_alert("xfs_unmountfs_writesb", | 1475 | xfs_ioerror_alert("xfs_unmountfs_writesb", |
@@ -1911,24 +1918,27 @@ xfs_uuid_unmount( | |||
1911 | * be altered by the mount options, as well as any potential sb_features2 | 1918 | * be altered by the mount options, as well as any potential sb_features2 |
1912 | * fixup. Only the first superblock is updated. | 1919 | * fixup. Only the first superblock is updated. |
1913 | */ | 1920 | */ |
1914 | STATIC void | 1921 | STATIC int |
1915 | xfs_mount_log_sb( | 1922 | xfs_mount_log_sb( |
1916 | xfs_mount_t *mp, | 1923 | xfs_mount_t *mp, |
1917 | __int64_t fields) | 1924 | __int64_t fields) |
1918 | { | 1925 | { |
1919 | xfs_trans_t *tp; | 1926 | xfs_trans_t *tp; |
1927 | int error; | ||
1920 | 1928 | ||
1921 | ASSERT(fields & (XFS_SB_UNIT | XFS_SB_WIDTH | XFS_SB_UUID | | 1929 | ASSERT(fields & (XFS_SB_UNIT | XFS_SB_WIDTH | XFS_SB_UUID | |
1922 | XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2)); | 1930 | XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2)); |
1923 | 1931 | ||
1924 | tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT); | 1932 | tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT); |
1925 | 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, |
1926 | XFS_DEFAULT_LOG_COUNT)) { | 1934 | XFS_DEFAULT_LOG_COUNT); |
1935 | if (error) { | ||
1927 | xfs_trans_cancel(tp, 0); | 1936 | xfs_trans_cancel(tp, 0); |
1928 | return; | 1937 | return error; |
1929 | } | 1938 | } |
1930 | xfs_mod_sb(tp, fields); | 1939 | xfs_mod_sb(tp, fields); |
1931 | xfs_trans_commit(tp, 0); | 1940 | error = xfs_trans_commit(tp, 0); |
1941 | return error; | ||
1932 | } | 1942 | } |
1933 | 1943 | ||
1934 | 1944 | ||
@@ -2189,7 +2199,7 @@ xfs_icsb_counter_disabled( | |||
2189 | return test_bit(field, &mp->m_icsb_counters); | 2199 | return test_bit(field, &mp->m_icsb_counters); |
2190 | } | 2200 | } |
2191 | 2201 | ||
2192 | STATIC int | 2202 | STATIC void |
2193 | xfs_icsb_disable_counter( | 2203 | xfs_icsb_disable_counter( |
2194 | xfs_mount_t *mp, | 2204 | xfs_mount_t *mp, |
2195 | xfs_sb_field_t field) | 2205 | xfs_sb_field_t field) |
@@ -2207,7 +2217,7 @@ xfs_icsb_disable_counter( | |||
2207 | * the m_icsb_mutex. | 2217 | * the m_icsb_mutex. |
2208 | */ | 2218 | */ |
2209 | if (xfs_icsb_counter_disabled(mp, field)) | 2219 | if (xfs_icsb_counter_disabled(mp, field)) |
2210 | return 0; | 2220 | return; |
2211 | 2221 | ||
2212 | xfs_icsb_lock_all_counters(mp); | 2222 | xfs_icsb_lock_all_counters(mp); |
2213 | if (!test_and_set_bit(field, &mp->m_icsb_counters)) { | 2223 | if (!test_and_set_bit(field, &mp->m_icsb_counters)) { |
@@ -2230,8 +2240,6 @@ xfs_icsb_disable_counter( | |||
2230 | } | 2240 | } |
2231 | 2241 | ||
2232 | xfs_icsb_unlock_all_counters(mp); | 2242 | xfs_icsb_unlock_all_counters(mp); |
2233 | |||
2234 | return 0; | ||
2235 | } | 2243 | } |
2236 | 2244 | ||
2237 | STATIC void | 2245 | STATIC void |