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 |
