[PATCH] xfs:negative_icount.patch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxx>

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@xxxxxxx>

_______________________________________________
xfs mailing list
xfs@xxxxxxxxxxx
http://oss.sgi.com/mailman/listinfo/xfs


[Index of Archives]     [Linux XFS Devel]     [Linux Filesystem Development]     [Filesystem Testing]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux