Commit d5db0f97fbbeff11c88dec1aaf1536a975afbaeb
Committed by
Alex Elder
1 parent
388f1f0c34
Exists in
master
and in
7 other branches
xfs: more reserved blocks fixups
This mangles the reserved blocks counts a little more. 1) add a helper function for the default reserved count 2) add helper functions to save/restore counts on ro/rw 3) save/restore reserved blocks on freeze/thaw 4) disallow changing reserved count while readonly V2: changed field name to match Dave's changes Signed-off-by: Eric Sandeen <sandeen@sandeen.net> Signed-off-by: Alex Elder <aelder@sgi.com>
Showing 4 changed files with 64 additions and 25 deletions Side-by-side Diff
fs/xfs/linux-2.6/xfs_ioctl.c
fs/xfs/linux-2.6/xfs_super.c
... | ... | @@ -1256,6 +1256,29 @@ |
1256 | 1256 | return 0; |
1257 | 1257 | } |
1258 | 1258 | |
1259 | +STATIC void | |
1260 | +xfs_save_resvblks(struct xfs_mount *mp) | |
1261 | +{ | |
1262 | + __uint64_t resblks = 0; | |
1263 | + | |
1264 | + mp->m_resblks_save = mp->m_resblks; | |
1265 | + xfs_reserve_blocks(mp, &resblks, NULL); | |
1266 | +} | |
1267 | + | |
1268 | +STATIC void | |
1269 | +xfs_restore_resvblks(struct xfs_mount *mp) | |
1270 | +{ | |
1271 | + __uint64_t resblks; | |
1272 | + | |
1273 | + if (mp->m_resblks_save) { | |
1274 | + resblks = mp->m_resblks_save; | |
1275 | + mp->m_resblks_save = 0; | |
1276 | + } else | |
1277 | + resblks = xfs_default_resblks(mp); | |
1278 | + | |
1279 | + xfs_reserve_blocks(mp, &resblks, NULL); | |
1280 | +} | |
1281 | + | |
1259 | 1282 | STATIC int |
1260 | 1283 | xfs_fs_remount( |
1261 | 1284 | struct super_block *sb, |
... | ... | @@ -1318,8 +1341,6 @@ |
1318 | 1341 | |
1319 | 1342 | /* ro -> rw */ |
1320 | 1343 | if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) { |
1321 | - __uint64_t resblks; | |
1322 | - | |
1323 | 1344 | mp->m_flags &= ~XFS_MOUNT_RDONLY; |
1324 | 1345 | if (mp->m_flags & XFS_MOUNT_BARRIER) |
1325 | 1346 | xfs_mountfs_check_barriers(mp); |
... | ... | @@ -1342,15 +1363,7 @@ |
1342 | 1363 | * Fill out the reserve pool if it is empty. Use the stashed |
1343 | 1364 | * value if it is non-zero, otherwise go with the default. |
1344 | 1365 | */ |
1345 | - if (mp->m_resblks_save) { | |
1346 | - resblks = mp->m_resblks_save; | |
1347 | - mp->m_resblks_save = 0; | |
1348 | - } else { | |
1349 | - resblks = mp->m_sb.sb_dblocks; | |
1350 | - do_div(resblks, 20); | |
1351 | - resblks = min_t(__uint64_t, resblks, 1024); | |
1352 | - } | |
1353 | - xfs_reserve_blocks(mp, &resblks, NULL); | |
1366 | + xfs_restore_resvblks(mp); | |
1354 | 1367 | } |
1355 | 1368 | |
1356 | 1369 | /* rw -> ro */ |
1357 | 1370 | |
... | ... | @@ -1363,11 +1376,9 @@ |
1363 | 1376 | * so that if we get remounted rw, we can return it to the same |
1364 | 1377 | * size. |
1365 | 1378 | */ |
1366 | - __uint64_t resblks = 0; | |
1367 | 1379 | |
1368 | 1380 | xfs_quiesce_data(mp); |
1369 | - mp->m_resblks_save = mp->m_resblks; | |
1370 | - xfs_reserve_blocks(mp, &resblks, NULL); | |
1381 | + xfs_save_resvblks(mp); | |
1371 | 1382 | xfs_quiesce_attr(mp); |
1372 | 1383 | mp->m_flags |= XFS_MOUNT_RDONLY; |
1373 | 1384 | } |
1374 | 1385 | |
... | ... | @@ -1386,11 +1397,22 @@ |
1386 | 1397 | { |
1387 | 1398 | struct xfs_mount *mp = XFS_M(sb); |
1388 | 1399 | |
1400 | + xfs_save_resvblks(mp); | |
1389 | 1401 | xfs_quiesce_attr(mp); |
1390 | 1402 | return -xfs_fs_log_dummy(mp); |
1391 | 1403 | } |
1392 | 1404 | |
1393 | 1405 | STATIC int |
1406 | +xfs_fs_unfreeze( | |
1407 | + struct super_block *sb) | |
1408 | +{ | |
1409 | + struct xfs_mount *mp = XFS_M(sb); | |
1410 | + | |
1411 | + xfs_restore_resvblks(mp); | |
1412 | + return 0; | |
1413 | +} | |
1414 | + | |
1415 | +STATIC int | |
1394 | 1416 | xfs_fs_show_options( |
1395 | 1417 | struct seq_file *m, |
1396 | 1418 | struct vfsmount *mnt) |
... | ... | @@ -1612,6 +1634,7 @@ |
1612 | 1634 | .put_super = xfs_fs_put_super, |
1613 | 1635 | .sync_fs = xfs_fs_sync_fs, |
1614 | 1636 | .freeze_fs = xfs_fs_freeze, |
1637 | + .unfreeze_fs = xfs_fs_unfreeze, | |
1615 | 1638 | .statfs = xfs_fs_statfs, |
1616 | 1639 | .remount_fs = xfs_fs_remount, |
1617 | 1640 | .show_options = xfs_fs_show_options, |
fs/xfs/xfs_mount.c
... | ... | @@ -1091,6 +1091,22 @@ |
1091 | 1091 | return xfs_trans_commit(tp, 0); |
1092 | 1092 | } |
1093 | 1093 | |
1094 | +__uint64_t | |
1095 | +xfs_default_resblks(xfs_mount_t *mp) | |
1096 | +{ | |
1097 | + __uint64_t resblks; | |
1098 | + | |
1099 | + /* | |
1100 | + * We default to 5% or 1024 fsbs of space reserved, whichever is smaller. | |
1101 | + * This may drive us straight to ENOSPC on mount, but that implies | |
1102 | + * we were already there on the last unmount. Warn if this occurs. | |
1103 | + */ | |
1104 | + resblks = mp->m_sb.sb_dblocks; | |
1105 | + do_div(resblks, 20); | |
1106 | + resblks = min_t(__uint64_t, resblks, 1024); | |
1107 | + return resblks; | |
1108 | +} | |
1109 | + | |
1094 | 1110 | /* |
1095 | 1111 | * This function does the following on an initial mount of a file system: |
1096 | 1112 | * - reads the superblock from disk and init the mount struct |
1097 | 1113 | |
... | ... | @@ -1401,18 +1417,14 @@ |
1401 | 1417 | * when at ENOSPC. This is needed for operations like create with |
1402 | 1418 | * attr, unwritten extent conversion at ENOSPC, etc. Data allocations |
1403 | 1419 | * are not allowed to use this reserved space. |
1404 | - * | |
1405 | - * We default to 5% or 1024 fsbs of space reserved, whichever is smaller. | |
1406 | - * This may drive us straight to ENOSPC on mount, but that implies | |
1407 | - * we were already there on the last unmount. Warn if this occurs. | |
1408 | 1420 | */ |
1409 | - resblks = mp->m_sb.sb_dblocks; | |
1410 | - do_div(resblks, 20); | |
1411 | - resblks = min_t(__uint64_t, resblks, 1024); | |
1412 | - error = xfs_reserve_blocks(mp, &resblks, NULL); | |
1413 | - if (error) | |
1414 | - cmn_err(CE_WARN, "XFS: Unable to allocate reserve blocks. " | |
1415 | - "Continuing without a reserve pool."); | |
1421 | + if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { | |
1422 | + resblks = xfs_default_resblks(mp); | |
1423 | + error = xfs_reserve_blocks(mp, &resblks, NULL); | |
1424 | + if (error) | |
1425 | + cmn_err(CE_WARN, "XFS: Unable to allocate reserve " | |
1426 | + "blocks. Continuing without a reserve pool."); | |
1427 | + } | |
1416 | 1428 | |
1417 | 1429 | return 0; |
1418 | 1430 |
fs/xfs/xfs_mount.h