diff options
Diffstat (limited to 'fs/xfs/xfs_super.c')
-rw-r--r-- | fs/xfs/xfs_super.c | 105 |
1 files changed, 78 insertions, 27 deletions
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 58453e3255f8..f32ad64c4d05 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -1013,24 +1013,6 @@ xfs_free_fsname( | |||
1013 | kfree(mp->m_logname); | 1013 | kfree(mp->m_logname); |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | STATIC void | ||
1017 | xfs_fs_put_super( | ||
1018 | struct super_block *sb) | ||
1019 | { | ||
1020 | struct xfs_mount *mp = XFS_M(sb); | ||
1021 | |||
1022 | xfs_notice(mp, "Unmounting Filesystem"); | ||
1023 | xfs_filestream_unmount(mp); | ||
1024 | xfs_unmountfs(mp); | ||
1025 | |||
1026 | xfs_freesb(mp); | ||
1027 | xfs_icsb_destroy_counters(mp); | ||
1028 | xfs_destroy_mount_workqueues(mp); | ||
1029 | xfs_close_devices(mp); | ||
1030 | xfs_free_fsname(mp); | ||
1031 | kfree(mp); | ||
1032 | } | ||
1033 | |||
1034 | STATIC int | 1016 | STATIC int |
1035 | xfs_fs_sync_fs( | 1017 | xfs_fs_sync_fs( |
1036 | struct super_block *sb, | 1018 | struct super_block *sb, |
@@ -1066,6 +1048,9 @@ xfs_fs_statfs( | |||
1066 | xfs_sb_t *sbp = &mp->m_sb; | 1048 | xfs_sb_t *sbp = &mp->m_sb; |
1067 | struct xfs_inode *ip = XFS_I(dentry->d_inode); | 1049 | struct xfs_inode *ip = XFS_I(dentry->d_inode); |
1068 | __uint64_t fakeinos, id; | 1050 | __uint64_t fakeinos, id; |
1051 | __uint64_t icount; | ||
1052 | __uint64_t ifree; | ||
1053 | __uint64_t fdblocks; | ||
1069 | xfs_extlen_t lsize; | 1054 | xfs_extlen_t lsize; |
1070 | __int64_t ffree; | 1055 | __int64_t ffree; |
1071 | 1056 | ||
@@ -1076,17 +1061,21 @@ xfs_fs_statfs( | |||
1076 | statp->f_fsid.val[0] = (u32)id; | 1061 | statp->f_fsid.val[0] = (u32)id; |
1077 | statp->f_fsid.val[1] = (u32)(id >> 32); | 1062 | statp->f_fsid.val[1] = (u32)(id >> 32); |
1078 | 1063 | ||
1079 | xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT); | 1064 | icount = percpu_counter_sum(&mp->m_icount); |
1065 | ifree = percpu_counter_sum(&mp->m_ifree); | ||
1066 | fdblocks = percpu_counter_sum(&mp->m_fdblocks); | ||
1080 | 1067 | ||
1081 | spin_lock(&mp->m_sb_lock); | 1068 | spin_lock(&mp->m_sb_lock); |
1082 | statp->f_bsize = sbp->sb_blocksize; | 1069 | statp->f_bsize = sbp->sb_blocksize; |
1083 | lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0; | 1070 | lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0; |
1084 | statp->f_blocks = sbp->sb_dblocks - lsize; | 1071 | statp->f_blocks = sbp->sb_dblocks - lsize; |
1085 | statp->f_bfree = statp->f_bavail = | 1072 | spin_unlock(&mp->m_sb_lock); |
1086 | sbp->sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); | 1073 | |
1074 | statp->f_bfree = fdblocks - XFS_ALLOC_SET_ASIDE(mp); | ||
1075 | statp->f_bavail = statp->f_bfree; | ||
1076 | |||
1087 | fakeinos = statp->f_bfree << sbp->sb_inopblog; | 1077 | fakeinos = statp->f_bfree << sbp->sb_inopblog; |
1088 | statp->f_files = | 1078 | statp->f_files = MIN(icount + fakeinos, (__uint64_t)XFS_MAXINUMBER); |
1089 | MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER); | ||
1090 | if (mp->m_maxicount) | 1079 | if (mp->m_maxicount) |
1091 | statp->f_files = min_t(typeof(statp->f_files), | 1080 | statp->f_files = min_t(typeof(statp->f_files), |
1092 | statp->f_files, | 1081 | statp->f_files, |
@@ -1098,10 +1087,9 @@ xfs_fs_statfs( | |||
1098 | sbp->sb_icount); | 1087 | sbp->sb_icount); |
1099 | 1088 | ||
1100 | /* make sure statp->f_ffree does not underflow */ | 1089 | /* make sure statp->f_ffree does not underflow */ |
1101 | ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree); | 1090 | ffree = statp->f_files - (icount - ifree); |
1102 | statp->f_ffree = max_t(__int64_t, ffree, 0); | 1091 | statp->f_ffree = max_t(__int64_t, ffree, 0); |
1103 | 1092 | ||
1104 | spin_unlock(&mp->m_sb_lock); | ||
1105 | 1093 | ||
1106 | if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && | 1094 | if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && |
1107 | ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))) == | 1095 | ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_PQUOTA_ENFD))) == |
@@ -1382,6 +1370,51 @@ xfs_finish_flags( | |||
1382 | return 0; | 1370 | return 0; |
1383 | } | 1371 | } |
1384 | 1372 | ||
1373 | static int | ||
1374 | xfs_init_percpu_counters( | ||
1375 | struct xfs_mount *mp) | ||
1376 | { | ||
1377 | int error; | ||
1378 | |||
1379 | error = percpu_counter_init(&mp->m_icount, 0, GFP_KERNEL); | ||
1380 | if (error) | ||
1381 | return ENOMEM; | ||
1382 | |||
1383 | error = percpu_counter_init(&mp->m_ifree, 0, GFP_KERNEL); | ||
1384 | if (error) | ||
1385 | goto free_icount; | ||
1386 | |||
1387 | error = percpu_counter_init(&mp->m_fdblocks, 0, GFP_KERNEL); | ||
1388 | if (error) | ||
1389 | goto free_ifree; | ||
1390 | |||
1391 | return 0; | ||
1392 | |||
1393 | free_ifree: | ||
1394 | percpu_counter_destroy(&mp->m_ifree); | ||
1395 | free_icount: | ||
1396 | percpu_counter_destroy(&mp->m_icount); | ||
1397 | return -ENOMEM; | ||
1398 | } | ||
1399 | |||
1400 | void | ||
1401 | xfs_reinit_percpu_counters( | ||
1402 | struct xfs_mount *mp) | ||
1403 | { | ||
1404 | percpu_counter_set(&mp->m_icount, mp->m_sb.sb_icount); | ||
1405 | percpu_counter_set(&mp->m_ifree, mp->m_sb.sb_ifree); | ||
1406 | percpu_counter_set(&mp->m_fdblocks, mp->m_sb.sb_fdblocks); | ||
1407 | } | ||
1408 | |||
1409 | static void | ||
1410 | xfs_destroy_percpu_counters( | ||
1411 | struct xfs_mount *mp) | ||
1412 | { | ||
1413 | percpu_counter_destroy(&mp->m_icount); | ||
1414 | percpu_counter_destroy(&mp->m_ifree); | ||
1415 | percpu_counter_destroy(&mp->m_fdblocks); | ||
1416 | } | ||
1417 | |||
1385 | STATIC int | 1418 | STATIC int |
1386 | xfs_fs_fill_super( | 1419 | xfs_fs_fill_super( |
1387 | struct super_block *sb, | 1420 | struct super_block *sb, |
@@ -1430,7 +1463,7 @@ xfs_fs_fill_super( | |||
1430 | if (error) | 1463 | if (error) |
1431 | goto out_close_devices; | 1464 | goto out_close_devices; |
1432 | 1465 | ||
1433 | error = xfs_icsb_init_counters(mp); | 1466 | error = xfs_init_percpu_counters(mp); |
1434 | if (error) | 1467 | if (error) |
1435 | goto out_destroy_workqueues; | 1468 | goto out_destroy_workqueues; |
1436 | 1469 | ||
@@ -1488,7 +1521,7 @@ xfs_fs_fill_super( | |||
1488 | out_free_sb: | 1521 | out_free_sb: |
1489 | xfs_freesb(mp); | 1522 | xfs_freesb(mp); |
1490 | out_destroy_counters: | 1523 | out_destroy_counters: |
1491 | xfs_icsb_destroy_counters(mp); | 1524 | xfs_destroy_percpu_counters(mp); |
1492 | out_destroy_workqueues: | 1525 | out_destroy_workqueues: |
1493 | xfs_destroy_mount_workqueues(mp); | 1526 | xfs_destroy_mount_workqueues(mp); |
1494 | out_close_devices: | 1527 | out_close_devices: |
@@ -1505,6 +1538,24 @@ out_destroy_workqueues: | |||
1505 | goto out_free_sb; | 1538 | goto out_free_sb; |
1506 | } | 1539 | } |
1507 | 1540 | ||
1541 | STATIC void | ||
1542 | xfs_fs_put_super( | ||
1543 | struct super_block *sb) | ||
1544 | { | ||
1545 | struct xfs_mount *mp = XFS_M(sb); | ||
1546 | |||
1547 | xfs_notice(mp, "Unmounting Filesystem"); | ||
1548 | xfs_filestream_unmount(mp); | ||
1549 | xfs_unmountfs(mp); | ||
1550 | |||
1551 | xfs_freesb(mp); | ||
1552 | xfs_destroy_percpu_counters(mp); | ||
1553 | xfs_destroy_mount_workqueues(mp); | ||
1554 | xfs_close_devices(mp); | ||
1555 | xfs_free_fsname(mp); | ||
1556 | kfree(mp); | ||
1557 | } | ||
1558 | |||
1508 | STATIC struct dentry * | 1559 | STATIC struct dentry * |
1509 | xfs_fs_mount( | 1560 | xfs_fs_mount( |
1510 | struct file_system_type *fs_type, | 1561 | struct file_system_type *fs_type, |