aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorEric Sandeen <sandeen@sandeen.net>2010-02-05 17:59:53 -0500
committerAlex Elder <aelder@sgi.com>2010-02-08 18:41:48 -0500
commitd5db0f97fbbeff11c88dec1aaf1536a975afbaeb (patch)
tree3e81db2cb8c5004f3c30ccaa35e54fbf1549897f /fs/xfs
parent388f1f0c346b533b06d8bc792f7204ebc3e4b7da (diff)
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>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c3
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c51
-rw-r--r--fs/xfs/xfs_mount.c34
-rw-r--r--fs/xfs/xfs_mount.h1
4 files changed, 64 insertions, 25 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 3906e85abfdc..4ea1ee18aded 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -1431,6 +1431,9 @@ xfs_file_ioctl(
1431 if (!capable(CAP_SYS_ADMIN)) 1431 if (!capable(CAP_SYS_ADMIN))
1432 return -EPERM; 1432 return -EPERM;
1433 1433
1434 if (mp->m_flags & XFS_MOUNT_RDONLY)
1435 return -XFS_ERROR(EROFS);
1436
1434 if (copy_from_user(&inout, arg, sizeof(inout))) 1437 if (copy_from_user(&inout, arg, sizeof(inout)))
1435 return -XFS_ERROR(EFAULT); 1438 return -XFS_ERROR(EFAULT);
1436 1439
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index e9c21454b9e2..6ce828e0e17b 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1256,6 +1256,29 @@ xfs_fs_statfs(
1256 return 0; 1256 return 0;
1257} 1257}
1258 1258
1259STATIC void
1260xfs_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
1268STATIC void
1269xfs_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
1259STATIC int 1282STATIC int
1260xfs_fs_remount( 1283xfs_fs_remount(
1261 struct super_block *sb, 1284 struct super_block *sb,
@@ -1318,8 +1341,6 @@ xfs_fs_remount(
1318 1341
1319 /* ro -> rw */ 1342 /* ro -> rw */
1320 if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) { 1343 if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) {
1321 __uint64_t resblks;
1322
1323 mp->m_flags &= ~XFS_MOUNT_RDONLY; 1344 mp->m_flags &= ~XFS_MOUNT_RDONLY;
1324 if (mp->m_flags & XFS_MOUNT_BARRIER) 1345 if (mp->m_flags & XFS_MOUNT_BARRIER)
1325 xfs_mountfs_check_barriers(mp); 1346 xfs_mountfs_check_barriers(mp);
@@ -1342,15 +1363,7 @@ xfs_fs_remount(
1342 * Fill out the reserve pool if it is empty. Use the stashed 1363 * Fill out the reserve pool if it is empty. Use the stashed
1343 * value if it is non-zero, otherwise go with the default. 1364 * value if it is non-zero, otherwise go with the default.
1344 */ 1365 */
1345 if (mp->m_resblks_save) { 1366 xfs_restore_resvblks(mp);
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);
1354 } 1367 }
1355 1368
1356 /* rw -> ro */ 1369 /* rw -> ro */
@@ -1363,11 +1376,9 @@ xfs_fs_remount(
1363 * so that if we get remounted rw, we can return it to the same 1376 * so that if we get remounted rw, we can return it to the same
1364 * size. 1377 * size.
1365 */ 1378 */
1366 __uint64_t resblks = 0;
1367 1379
1368 xfs_quiesce_data(mp); 1380 xfs_quiesce_data(mp);
1369 mp->m_resblks_save = mp->m_resblks; 1381 xfs_save_resvblks(mp);
1370 xfs_reserve_blocks(mp, &resblks, NULL);
1371 xfs_quiesce_attr(mp); 1382 xfs_quiesce_attr(mp);
1372 mp->m_flags |= XFS_MOUNT_RDONLY; 1383 mp->m_flags |= XFS_MOUNT_RDONLY;
1373 } 1384 }
@@ -1386,11 +1397,22 @@ xfs_fs_freeze(
1386{ 1397{
1387 struct xfs_mount *mp = XFS_M(sb); 1398 struct xfs_mount *mp = XFS_M(sb);
1388 1399
1400 xfs_save_resvblks(mp);
1389 xfs_quiesce_attr(mp); 1401 xfs_quiesce_attr(mp);
1390 return -xfs_fs_log_dummy(mp); 1402 return -xfs_fs_log_dummy(mp);
1391} 1403}
1392 1404
1393STATIC int 1405STATIC int
1406xfs_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
1415STATIC int
1394xfs_fs_show_options( 1416xfs_fs_show_options(
1395 struct seq_file *m, 1417 struct seq_file *m,
1396 struct vfsmount *mnt) 1418 struct vfsmount *mnt)
@@ -1612,6 +1634,7 @@ static const struct super_operations xfs_super_operations = {
1612 .put_super = xfs_fs_put_super, 1634 .put_super = xfs_fs_put_super,
1613 .sync_fs = xfs_fs_sync_fs, 1635 .sync_fs = xfs_fs_sync_fs,
1614 .freeze_fs = xfs_fs_freeze, 1636 .freeze_fs = xfs_fs_freeze,
1637 .unfreeze_fs = xfs_fs_unfreeze,
1615 .statfs = xfs_fs_statfs, 1638 .statfs = xfs_fs_statfs,
1616 .remount_fs = xfs_fs_remount, 1639 .remount_fs = xfs_fs_remount,
1617 .show_options = xfs_fs_show_options, 1640 .show_options = xfs_fs_show_options,
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 7f81ed72c875..5061149b2cc4 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1091,6 +1091,22 @@ xfs_mount_reset_sbqflags(
1091 return xfs_trans_commit(tp, 0); 1091 return xfs_trans_commit(tp, 0);
1092} 1092}
1093 1093
1094__uint64_t
1095xfs_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 * This function does the following on an initial mount of a file system: 1111 * This function does the following on an initial mount of a file system:
1096 * - reads the superblock from disk and init the mount struct 1112 * - reads the superblock from disk and init the mount struct
@@ -1401,18 +1417,14 @@ xfs_mountfs(
1401 * when at ENOSPC. This is needed for operations like create with 1417 * when at ENOSPC. This is needed for operations like create with
1402 * attr, unwritten extent conversion at ENOSPC, etc. Data allocations 1418 * attr, unwritten extent conversion at ENOSPC, etc. Data allocations
1403 * are not allowed to use this reserved space. 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; 1421 if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
1410 do_div(resblks, 20); 1422 resblks = xfs_default_resblks(mp);
1411 resblks = min_t(__uint64_t, resblks, 1024); 1423 error = xfs_reserve_blocks(mp, &resblks, NULL);
1412 error = xfs_reserve_blocks(mp, &resblks, NULL); 1424 if (error)
1413 if (error) 1425 cmn_err(CE_WARN, "XFS: Unable to allocate reserve "
1414 cmn_err(CE_WARN, "XFS: Unable to allocate reserve blocks. " 1426 "blocks. Continuing without a reserve pool.");
1415 "Continuing without a reserve pool."); 1427 }
1416 1428
1417 return 0; 1429 return 0;
1418 1430
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 02d45f213e58..70504fcf14cd 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -421,6 +421,7 @@ typedef struct xfs_mod_sb {
421} xfs_mod_sb_t; 421} xfs_mod_sb_t;
422 422
423extern int xfs_log_sbcount(xfs_mount_t *, uint); 423extern int xfs_log_sbcount(xfs_mount_t *, uint);
424extern __uint64_t xfs_default_resblks(xfs_mount_t *mp);
424extern int xfs_mountfs(xfs_mount_t *mp); 425extern int xfs_mountfs(xfs_mount_t *mp);
425 426
426extern void xfs_unmountfs(xfs_mount_t *); 427extern void xfs_unmountfs(xfs_mount_t *);