[PATCH] xfs:negative_icount.patch
Stuart Brodsky
sbrodsky at sgi.com
Fri Jul 16 13:53:41 CDT 2010
This patch fixes the stat -f icount field going negative. The use of
lazy counts means that the super block field sb_icount is not updated
correctly and will allow over allocation of inodes above maxicount.
Signed-off-by: Stu Brodsky <sbrodsky at sgi.com>
Index: a/fs/xfs/xfs_ialloc.c
===================================================================
--- a/fs/xfs/xfs_ialloc.c.orig 2010-07-16 10:12:02.000000000 -0500
+++ b/fs/xfs/xfs_ialloc.c 2010-07-16 10:19:56.312633030 -0500
@@ -260,7 +260,7 @@
*/
newlen = XFS_IALLOC_INODES(args.mp);
if (args.mp->m_maxicount &&
- args.mp->m_sb.sb_icount + newlen > args.mp->m_maxicount)
+ atomic64_read(&args.mp->m_inodesinuse) + newlen >
args.mp->m_maxicount)
return XFS_ERROR(ENOSPC);
args.minlen = args.maxlen = XFS_IALLOC_BLOCKS(args.mp);
/*
@@ -708,7 +708,7 @@
*/
if (mp->m_maxicount &&
- mp->m_sb.sb_icount + XFS_IALLOC_INODES(mp) > mp->m_maxicount) {
+ atomic64_read(&mp->m_inodesinuse) + XFS_IALLOC_INODES(mp) >
mp->m_maxicount)
noroom = 1;
okalloc = 0;
}
Index: b/fs/xfs/xfs_mount.c
===================================================================
--- a/fs/xfs/xfs_mount.c.orig 2010-07-16 10:12:02.000000000 -0500
+++ b/fs/xfs/xfs_mount.c 2010-07-16 10:20:49.717572132 -0500
@@ -744,6 +744,7 @@
mp->m_blockmask = sbp->sb_blocksize - 1;
mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
mp->m_blockwmask = mp->m_blockwsize - 1;
+ atomic64_set(&mp->m_inodesinuse,sbp->sb_icount);
mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1);
mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);
Index: a/fs/xfs/xfs_mount.h
===================================================================
--- a/fs/xfs/xfs_mount.h.orig 2010-07-16 10:12:02.000000000 -0500
+++ b/fs/xfs/xfs_mount.h 2010-07-16 10:21:36.377577685 -0500
@@ -137,6 +137,7 @@
__uint8_t m_agno_log; /* log #ag's */
__uint8_t m_agino_log; /* #bits for agino in inum */
__uint16_t m_inode_cluster_size;/* min inode buf size */
+ atomic64_t m_inodesinuse; /* in use inodes */
uint m_blockmask; /* sb_blocksize-1 */
uint m_blockwsize; /* sb_blocksize in words */
uint m_blockwmask; /* blockwsize-1 */
Index: a/fs/xfs/xfs_trans.c
===================================================================
--- a/fs/xfs/xfs_trans.c.orig 2010-07-16 10:12:02.000000000 -0500
+++ b/fs/xfs/xfs_trans.c 2010-07-16 10:22:47.690249548 -0500
@@ -805,6 +805,7 @@
switch (field) {
case XFS_TRANS_SB_ICOUNT:
tp->t_icount_delta += delta;
+ atomic64_add(delta,&tp->t_mountp->m_inodesinuse);
if (xfs_sb_version_haslazysbcount(&mp->m_sb))
flags &= ~XFS_TRANS_SB_DIRTY;
break;
--
Stuart Brodsky
2750 Blue Water Road
Eagan, MN. 55121
651-683-7910
<sbrodsky at sgi.com>
More information about the xfs
mailing list