public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* review [3 of 3]: lazy superblock counters - userspace bits
@ 2007-04-19 23:21 David Chinner
  2007-05-22  6:19 ` Barry Naujok
  0 siblings, 1 reply; 2+ messages in thread
From: David Chinner @ 2007-04-19 23:21 UTC (permalink / raw)
  To: xfs-dev; +Cc: xfs-oss


userspace tool support for lazy superblock accounting.

-- 
Dave Chinner
Principal Engineer
SGI Australian Software Group


---
 xfsprogs/db/agf.c                 |    1 
 xfsprogs/db/check.c               |   25 +++++++++++++++++
 xfsprogs/db/sb.c                  |    2 +
 xfsprogs/growfs/xfs_growfs.c      |   13 ++++++---
 xfsprogs/include/libxfs.h         |    1 
 xfsprogs/include/xfs_ag.h         |    8 ++++-
 xfsprogs/include/xfs_alloc.h      |    6 ++--
 xfsprogs/include/xfs_fs.h         |    1 
 xfsprogs/include/xfs_ialloc.h     |   10 +++++++
 xfsprogs/include/xfs_mount.h      |    5 ++-
 xfsprogs/include/xfs_sb.h         |   15 +++++++++-
 xfsprogs/include/xfs_trans.h      |    3 +-
 xfsprogs/libxfs/init.c            |   14 ++++++++++
 xfsprogs/libxfs/xfs.h             |    6 ++--
 xfsprogs/libxfs/xfs_alloc.c       |   49 +++++++++++++++++++++++++++--------
 xfsprogs/libxfs/xfs_alloc_btree.c |    8 ++---
 xfsprogs/libxfs/xfs_ialloc.c      |   21 +++++++++++++++
 xfsprogs/libxfs/xfs_mount.c       |   53 ++++++++++++++++++++++++++++++++++++++
 xfsprogs/man/man8/mkfs.xfs.8      |   23 +++++++++++++++-
 xfsprogs/mkfs/xfs_mkfs.c          |   22 ++++++++++++---
 xfsprogs/repair/phase5.c          |   22 +++++++++++++++
 21 files changed, 273 insertions(+), 35 deletions(-)

Index: xfs-cmds/xfsprogs/db/agf.c
===================================================================
--- xfs-cmds.orig/xfsprogs/db/agf.c	2006-11-15 19:00:28.000000000 +1100
+++ xfs-cmds/xfsprogs/db/agf.c	2007-04-03 14:52:51.659780004 +1000
@@ -68,6 +68,7 @@ const field_t	agf_flds[] = {
 	{ "flcount", FLDT_UINT32D, OI(OFF(flcount)), C1, 0, TYP_NONE },
 	{ "freeblks", FLDT_EXTLEN, OI(OFF(freeblks)), C1, 0, TYP_NONE },
 	{ "longest", FLDT_EXTLEN, OI(OFF(longest)), C1, 0, TYP_NONE },
+	{ "btreeblks", FLDT_UINT32D, OI(OFF(btreeblks)), C1, 0, TYP_NONE },
 	{ NULL }
 };
 
Index: xfs-cmds/xfsprogs/db/check.c
===================================================================
--- xfs-cmds.orig/xfsprogs/db/check.c	2006-12-22 11:49:54.000000000 +1100
+++ xfs-cmds/xfsprogs/db/check.c	2007-04-03 14:52:51.675777913 +1000
@@ -110,6 +110,9 @@ typedef struct dirhash {
 
 static xfs_extlen_t	agffreeblks;
 static xfs_extlen_t	agflongest;
+static __uint64_t	agf_aggr_freeblks;	/* aggregate count over all */
+static __uint32_t	agfbtreeblks;
+static int		lazycount;
 static xfs_agino_t	agicount;
 static xfs_agino_t	agifreecount;
 static xfs_fsblock_t	*blist;
@@ -854,6 +857,12 @@ blockget_f(
 				mp->m_sb.sb_fdblocks, fdblocks);
 		error++;
 	}
+	if (lazycount && mp->m_sb.sb_fdblocks != agf_aggr_freeblks) {
+		if (!sflag)
+			dbprintf("sb_fdblocks %lld, aggregate AGF count %lld\n",
+				mp->m_sb.sb_fdblocks, agf_aggr_freeblks);
+		error++;
+	}
 	if (mp->m_sb.sb_frextents != frextents) {
 		if (!sflag)
 			dbprintf("sb_frextents %lld, counted %lld\n",
@@ -3886,6 +3895,7 @@ scan_ag(
 	xfs_sb_t	*sb=&tsb;
 
 	agffreeblks = agflongest = 0;
+	agfbtreeblks = -2;
 	agicount = agifreecount = 0;
 	push_cur();
 	set_cur(&typtab[TYP_SB],
@@ -3914,6 +3924,9 @@ scan_ag(
 		error++;
 		sbver_err++;
 	}
+	if (!lazycount && XFS_SB_VERSION_LAZYSBCOUNT(sb)) {
+		lazycount = 1;
+	}
 	if (agno == 0 && sb->sb_inprogress != 0) {
 		if (!sflag)
 			dbprintf("mkfs not completed successfully\n");
@@ -4010,6 +4023,15 @@ scan_ag(
 				agflongest, agno);
 		error++;
 	}
+	if (lazycount &&
+	    INT_GET(agf->agf_btreeblks, ARCH_CONVERT) != agfbtreeblks) {
+		if (!sflag)
+			dbprintf("agf_btreeblks %u, counted %u in ag %u\n",
+				INT_GET(agf->agf_btreeblks, ARCH_CONVERT),
+				agfbtreeblks, agno);
+		error++;
+	}
+	agf_aggr_freeblks += agffreeblks + agfbtreeblks;
 	if (INT_GET(agi->agi_count, ARCH_CONVERT) != agicount) {
 		if (!sflag)
 			dbprintf("agi_count %u, counted %u in ag %u\n",
@@ -4086,6 +4108,7 @@ scan_freelist(
 		error++;
 	}
 	fdblocks += count;
+	agf_aggr_freeblks += count;
 	pop_cur();
 }
 
@@ -4242,6 +4265,7 @@ scanfunc_bno(
 		return;
 	}
 	fdblocks++;
+	agfbtreeblks++;
 	if (INT_GET(block->bb_level, ARCH_CONVERT) != level) {
 		if (!sflag)
 			dbprintf("expected level %d got %d in btbno block "
@@ -4317,6 +4341,7 @@ scanfunc_cnt(
 		return;
 	}
 	fdblocks++;
+	agfbtreeblks++;
 	if (INT_GET(block->bb_level, ARCH_CONVERT) != level) {
 		if (!sflag)
 			dbprintf("expected level %d got %d in btcnt block "
Index: xfs-cmds/xfsprogs/db/sb.c
===================================================================
--- xfs-cmds.orig/xfsprogs/db/sb.c	2006-11-15 19:00:29.000000000 +1100
+++ xfs-cmds/xfsprogs/db/sb.c	2007-04-03 14:52:51.683776868 +1000
@@ -608,6 +608,8 @@ version_string(
 		strcat(s, ",MOREBITS");
 	if (XFS_SB_VERSION_HASATTR2(sbp))
 		strcat(s, ",ATTR2");
+	if (XFS_SB_VERSION_LAZYSBCOUNT(sbp))
+		strcat(s, ",LAZYSBCOUNT");
 	return s;
 }
 
Index: xfs-cmds/xfsprogs/growfs/xfs_growfs.c
===================================================================
--- xfs-cmds.orig/xfsprogs/growfs/xfs_growfs.c	2006-12-22 11:49:54.000000000 +1100
+++ xfs-cmds/xfsprogs/growfs/xfs_growfs.c	2007-04-03 14:52:51.703774255 +1000
@@ -59,6 +59,7 @@ report_info(
 	char		*logname,
 	char		*rtname,
 	int		unwritten,
+	int		lazycount,
 	int		dirversion,
 	int		logversion,
 	int		attrversion)
@@ -70,7 +71,7 @@ report_info(
 	    "         =%-22s sunit=%-6u swidth=%u blks, unwritten=%u\n"
 	    "naming   =version %-14u bsize=%-6u\n"
 	    "log      =%-22s bsize=%-6u blocks=%u, version=%u\n"
-	    "         =%-22s sectsz=%-5u sunit=%u blks\n"
+	    "         =%-22s sectsz=%-5u sunit=%u blks, lazy-count=%u\n"
 	    "realtime =%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n"),
 
 		mntpoint, geo.inodesize, geo.agcount, geo.agblocks,
@@ -81,7 +82,7 @@ report_info(
   		dirversion, geo.dirblocksize,
 		isint ? _("internal") : logname ? logname : _("external"),
 			geo.blocksize, geo.logblocks, logversion,
-		"", geo.logsectsize, geo.logsunit / geo.blocksize,
+		"", geo.logsectsize, geo.logsunit / geo.blocksize, lazycount,
 		!geo.rtblocks ? _("none") : rtname ? rtname : _("external"),
 		geo.rtextsize * geo.blocksize, (unsigned long long)geo.rtblocks,
 			(unsigned long long)geo.rtextents);
@@ -115,6 +116,7 @@ main(int argc, char **argv)
 	int			rflag;	/* -r flag */
 	long long		rsize;	/* new rt size in fs blocks */
 	int			unwritten; /* unwritten extent flag */
+	int			lazycount; /* lazy superblock counters */
 	int			xflag;	/* -x flag */
 	char			*fname;	/* mount point name */
 	char			*datadev; /* data device name */
@@ -235,6 +237,7 @@ main(int argc, char **argv)
 	}
 	isint = geo.logstart > 0;
 	unwritten = geo.flags & XFS_FSOP_GEOM_FLAGS_EXTFLG ? 1 : 0;
+	lazycount = geo.flags & XFS_FSOP_GEOM_FLAGS_LAZYSB ? 1 : 0;
 	dirversion = geo.flags & XFS_FSOP_GEOM_FLAGS_DIRV2 ? 2 : 1;
 	logversion = geo.flags & XFS_FSOP_GEOM_FLAGS_LOGV2 ? 2 : 1;
 	attrversion = geo.flags & XFS_FSOP_GEOM_FLAGS_ATTR2 ? 2 : \
@@ -242,7 +245,8 @@ main(int argc, char **argv)
 
 	if (nflag) {
 		report_info(geo, datadev, isint, logdev, rtdev,
-				unwritten, dirversion, logversion, attrversion);
+				unwritten, lazycount, dirversion, logversion,
+				attrversion);
 		exit(0);
 	}
 
@@ -278,7 +282,8 @@ main(int argc, char **argv)
 	}
 
 	report_info(geo, datadev, isint, logdev, rtdev,
-			unwritten, dirversion, logversion, attrversion);
+			unwritten, lazycount, dirversion, logversion,
+			attrversion);
 
 	ddsize = xi.dsize;
 	dlsize = ( xi.logBBsize? xi.logBBsize :
Index: xfs-cmds/xfsprogs/include/xfs_fs.h
===================================================================
--- xfs-cmds.orig/xfsprogs/include/xfs_fs.h	2007-02-08 00:43:21.546422620 +1100
+++ xfs-cmds/xfsprogs/include/xfs_fs.h	2007-04-03 14:52:51.731770597 +1000
@@ -240,6 +240,7 @@ typedef struct xfs_fsop_resblks {
 #define XFS_FSOP_GEOM_FLAGS_LOGV2	0x0100	/* log format version 2	*/
 #define XFS_FSOP_GEOM_FLAGS_SECTOR	0x0200	/* sector sizes >1BB	*/
 #define XFS_FSOP_GEOM_FLAGS_ATTR2	0x0400	/* inline attributes rework */
+#define XFS_FSOP_GEOM_FLAGS_LAZYSB	0x4000	/* lazy superblock counters */
 
 
 /*
Index: xfs-cmds/xfsprogs/include/xfs_sb.h
===================================================================
--- xfs-cmds.orig/xfsprogs/include/xfs_sb.h	2006-11-15 19:00:30.000000000 +1100
+++ xfs-cmds/xfsprogs/include/xfs_sb.h	2007-04-03 14:52:51.739769552 +1000
@@ -87,7 +87,8 @@ struct xfs_mount;
 							   PROM and SASH */
 
 #define	XFS_SB_VERSION2_OKREALFBITS	\
-	(XFS_SB_VERSION2_ATTR2BIT)
+	(XFS_SB_VERSION2_ATTR2BIT |	\
+	 XFS_SB_VERSION2_LAZYSBCOUNTBIT)
 #define	XFS_SB_VERSION2_OKSASHFBITS	\
 	(0)
 #define XFS_SB_VERSION2_OKREALBITS	\
@@ -189,6 +190,9 @@ typedef enum {
 #define XFS_SB_SHARED_VN	XFS_SB_MVAL(SHARED_VN)
 #define XFS_SB_UNIT		XFS_SB_MVAL(UNIT)
 #define XFS_SB_WIDTH		XFS_SB_MVAL(WIDTH)
+#define XFS_SB_ICOUNT		XFS_SB_MVAL(ICOUNT)
+#define XFS_SB_IFREE		XFS_SB_MVAL(IFREE)
+#define XFS_SB_FDBLOCKS		XFS_SB_MVAL(FDBLOCKS)
 #define XFS_SB_FEATURES2	XFS_SB_MVAL(FEATURES2)
 #define	XFS_SB_NUM_BITS		((int)XFS_SBS_FIELDCOUNT)
 #define	XFS_SB_ALL_BITS		((1LL << XFS_SB_NUM_BITS) - 1)
@@ -196,7 +200,7 @@ typedef enum {
 	(XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \
 	 XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \
 	 XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \
-	 XFS_SB_FEATURES2)
+	 XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2)
 
 
 /*
@@ -428,6 +432,13 @@ static inline int xfs_sb_version_hasmore
  *	 ((sbp)->sb_features2 & XFS_SB_VERSION2_FUNBIT)
  */
 
+#define XFS_SB_VERSION_LAZYSBCOUNT(sbp)	xfs_sb_version_haslazysbcount(sbp)
+static inline int xfs_sb_version_haslazysbcount(xfs_sb_t *sbp)
+{
+	return (XFS_SB_VERSION_HASMOREBITS(sbp) &&
+		((sbp)->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT));
+}
+
 #define XFS_SB_VERSION_HASATTR2(sbp)	xfs_sb_version_hasattr2(sbp)
 static inline int xfs_sb_version_hasattr2(xfs_sb_t *sbp)
 {
Index: xfs-cmds/xfsprogs/mkfs/xfs_mkfs.c
===================================================================
--- xfs-cmds.orig/xfsprogs/mkfs/xfs_mkfs.c	2006-12-22 11:49:54.000000000 +1100
+++ xfs-cmds/xfsprogs/mkfs/xfs_mkfs.c	2007-04-03 14:52:51.771765371 +1000
@@ -118,6 +118,8 @@ char	*lopts[] = {
 	"file",
 #define	L_NAME		10
 	"name",
+#define	L_LAZYSBCNTR	11
+	"lazy-count",
 	NULL
 };
 
@@ -602,6 +604,7 @@ main(
 	libxfs_init_t		xi;
 	int 			xlv_dsunit;
 	int			xlv_dswidth;
+	int			lazy_sb_counters;
 
 	progname = basename(argv[0]);
 	setlocale(LC_ALL, "");
@@ -631,6 +634,7 @@ main(
 	extent_flagging = 1;
 	force_overwrite = 0;
 	worst_freelist = 0;
+	lazy_sb_counters = 0;
 	bzero(&fsx, sizeof(fsx));
 
 	bzero(&xi, sizeof(xi));
@@ -1082,6 +1086,15 @@ main(
 						libxfs_highbit32(lsectorsize);
 					lssflag = 1;
 					break;
+				case L_LAZYSBCNTR:
+					if (!value)
+						reqval('l', lopts,
+								L_LAZYSBCNTR);
+					c = atoi(value);
+					if (c < 0 || c > 1)
+						illegal(value, "l lazy-count");
+					lazy_sb_counters = c;
+					break;
 				default:
 					unknown('l', value);
 				}
@@ -1914,7 +1927,7 @@ an AG size that is one stripe unit small
 		   "         =%-22s sunit=%-6u swidth=%u blks, unwritten=%u\n"
 		   "naming   =version %-14u bsize=%-6u\n"
 		   "log      =%-22s bsize=%-6d blocks=%lld, version=%d\n"
-		   "         =%-22s sectsz=%-5u sunit=%d blks\n"
+		   "         =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n"
 		   "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"),
 			dfile, isize, (long long)agcount, (long long)agsize,
 			"", sectorsize, attrversion,
@@ -1923,7 +1936,7 @@ an AG size that is one stripe unit small
 			"", dsunit, dswidth, extent_flagging,
 			dirversion, dirversion == 1 ? blocksize : dirblocksize,
 			logfile, 1 << blocklog, (long long)logblocks,
-			logversion, "", lsectorsize, lsunit,
+			logversion, "", lsectorsize, lsunit, lazy_sb_counters,
 			rtfile, rtextblocks << blocklog,
 			(long long)rtblocks, (long long)rtextents);
 		if (Nflag)
@@ -1985,7 +1998,7 @@ an AG size that is one stripe unit small
 		sbp->sb_logsectlog = 0;
 		sbp->sb_logsectsize = 0;
 	}
-	sbp->sb_features2 = XFS_SB_VERSION2_MKFS(0, attrversion == 2, 0);
+	sbp->sb_features2 = XFS_SB_VERSION2_MKFS(lazy_sb_counters, attrversion == 2, 0);
 	sbp->sb_versionnum = XFS_SB_VERSION_MKFS(
 			iaflag, dsunit != 0, extent_flagging,
 			dirversion == 2, logversion == 2, attrversion == 1,
@@ -2457,7 +2470,8 @@ usage( void )
 			    sectlog=n|sectsize=num,unwritten=0|1]\n\
 /* inode size */	[-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2]\n\
 /* log subvol */	[-l agnum=n,internal,size=num,logdev=xxx,version=n\n\
-			    sunit=value|su=num,sectlog=n|sectsize=num]\n\
+			    sunit=value|su=num,sectlog=n|sectsize=num,\n\
+			    lazy-count=0|1]\n\
 /* label */		[-L label (maximum 12 characters)]\n\
 /* naming */		[-n log=n|size=num,version=n]\n\
 /* prototype file */	[-p fname]\n\
Index: xfs-cmds/xfsprogs/repair/phase5.c
===================================================================
--- xfs-cmds.orig/xfsprogs/repair/phase5.c	2006-11-15 19:00:34.000000000 +1100
+++ xfs-cmds/xfsprogs/repair/phase5.c	2007-04-03 14:52:51.795762235 +1000
@@ -333,6 +333,10 @@ write_cursor(bt_status_t *curs)
 #endif
 		if (curs->level[i].prev_buf_p != NULL)  {
 			ASSERT(curs->level[i].prev_agbno != NULLAGBLOCK);
+#if defined(XR_BLD_FREE_TRACE) || defined(XR_BLD_INO_TRACE)
+			fprintf(stderr, "writing bt prev block %u\n",
+						curs->level[i].prev_agbno);
+#endif
 			libxfs_writebuf(curs->level[i].prev_buf_p, 0);
 		}
 		libxfs_writebuf(curs->level[i].buf_p, 0);
@@ -1285,6 +1289,24 @@ build_agf_agfl(xfs_mount_t	*mp,
 			bcnt_bt->num_levels);
 	INT_SET(agf->agf_freeblks, ARCH_CONVERT, freeblks);
 
+	/*
+	 * Count and record the number of btree blocks consumed if required.
+	 */
+	if (XFS_SB_VERSION_LAZYSBCOUNT(&mp->m_sb)) {
+		/*
+		 * Don't count the root blocks as they are already
+		 * accounted for.
+		 */
+		INT_SET(agf->agf_btreeblks, ARCH_CONVERT,
+			(bno_bt->num_tot_blocks - bno_bt->num_free_blocks) +
+			(bcnt_bt->num_tot_blocks - bcnt_bt->num_free_blocks) -
+			2);
+#ifdef XR_BLD_FREE_TRACE
+		fprintf(stderr, "agf->agf_btreeblks = %u\n",
+				INT_GET(agf->agf_btreeblks, ARCH_CONVERT));
+#endif
+	}
+
 #ifdef XR_BLD_FREE_TRACE
 	fprintf(stderr, "bno root = %u, bcnt root = %u, indices = %u %u\n",
 			INT_GET(agf->agf_roots[XFS_BTNUM_BNO], ARCH_CONVERT),
Index: xfs-cmds/xfsprogs/include/xfs_mount.h
===================================================================
--- xfs-cmds.orig/xfsprogs/include/xfs_mount.h	2006-11-15 19:00:30.000000000 +1100
+++ xfs-cmds/xfsprogs/include/xfs_mount.h	2007-04-03 14:52:51.799761713 +1000
@@ -383,7 +383,7 @@ typedef struct xfs_mount {
 						   for space allocations */
 #define	XFS_MOUNT_INO64		(1ULL << 1)
 			     /* (1ULL << 2)	-- currently unused */
-			     /* (1ULL << 3)	-- currently unused */
+#define XFS_MOUNT_WAS_CLEAN	(1ULL << 3)
 #define XFS_MOUNT_FS_SHUTDOWN	(1ULL << 4)	/* atomic stop of all filesystem
 						   operations, typically for
 						   disk errors in metadata */
@@ -460,6 +460,8 @@ xfs_preferred_iosize(xfs_mount_t *mp)
 
 #define XFS_MAXIOFFSET(mp)	((mp)->m_maxioffset)
 
+#define XFS_LAST_UNMOUNT_WAS_CLEAN(mp)	\
+				((mp)->m_flags & XFS_MOUNT_WAS_CLEAN)
 #define XFS_FORCED_SHUTDOWN(mp)	((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
 #define xfs_force_shutdown(m,f)	\
 	VFS_FORCE_SHUTDOWN((XFS_MTOVFS(m)), f, __FILE__, __LINE__)
@@ -540,6 +542,7 @@ typedef struct xfs_mod_sb {
 
 extern xfs_mount_t *xfs_mount_init(void);
 extern void	xfs_mod_sb(xfs_trans_t *, __int64_t);
+extern int	xfs_log_sbcount(xfs_mount_t *, uint);
 extern void	xfs_mount_free(xfs_mount_t *mp, int remove_bhv);
 extern int	xfs_mountfs(struct vfs *, xfs_mount_t *mp, int);
 extern void	xfs_mountfs_check_barriers(xfs_mount_t *mp);
Index: xfs-cmds/xfsprogs/include/xfs_trans.h
===================================================================
--- xfs-cmds.orig/xfsprogs/include/xfs_trans.h	2006-11-15 19:00:30.000000000 +1100
+++ xfs-cmds/xfsprogs/include/xfs_trans.h	2007-04-03 14:52:51.803761190 +1000
@@ -98,7 +98,8 @@ typedef struct xfs_trans_header {
 #define	XFS_TRANS_GROWFSRT_ZERO		38
 #define	XFS_TRANS_GROWFSRT_FREE		39
 #define	XFS_TRANS_SWAPEXT		40
-#define	XFS_TRANS_TYPE_MAX		40
+#define	XFS_TRANS_SB_COUNT		41
+#define	XFS_TRANS_TYPE_MAX		41
 /* new transaction types need to be reflected in xfs_logprint(8) */
 
 
Index: xfs-cmds/xfsprogs/include/xfs_ag.h
===================================================================
--- xfs-cmds.orig/xfsprogs/include/xfs_ag.h	2006-11-15 19:00:30.000000000 +1100
+++ xfs-cmds/xfsprogs/include/xfs_ag.h	2007-04-03 14:52:51.811760145 +1000
@@ -68,6 +68,7 @@ typedef struct xfs_agf {
 	__be32		agf_flcount;	/* count of blocks in freelist */
 	__be32		agf_freeblks;	/* total free blocks */
 	__be32		agf_longest;	/* longest free space */
+	__be32		agf_btreeblks;	/* # of blocks held in AGF btrees */
 } xfs_agf_t;
 
 #define	XFS_AGF_MAGICNUM	0x00000001
@@ -81,7 +82,8 @@ typedef struct xfs_agf {
 #define	XFS_AGF_FLCOUNT		0x00000100
 #define	XFS_AGF_FREEBLKS	0x00000200
 #define	XFS_AGF_LONGEST		0x00000400
-#define	XFS_AGF_NUM_BITS	11
+#define	XFS_AGF_BTREEBLKS	0x00000800
+#define	XFS_AGF_NUM_BITS	12
 #define	XFS_AGF_ALL_BITS	((1 << XFS_AGF_NUM_BITS) - 1)
 
 /* disk block (xfs_daddr_t) in the AG */
@@ -186,11 +188,13 @@ typedef struct xfs_perag
 	__uint32_t	pagf_flcount;	/* count of blocks in freelist */
 	xfs_extlen_t	pagf_freeblks;	/* total free blocks */
 	xfs_extlen_t	pagf_longest;	/* longest free space */
+	__uint32_t	pagf_btreeblks;	/* # of blocks held in AGF btrees */
 	xfs_agino_t	pagi_freecount;	/* number of free inodes */
+	xfs_agino_t	pagi_count;	/* number of allocated inodes */
+	int		pagb_count;	/* pagb slots in use */
 #ifdef __KERNEL__
 	lock_t		pagb_lock;	/* lock for pagb_list */
 #endif
-	int		pagb_count;	/* pagb slots in use */
 	xfs_perag_busy_t *pagb_list;	/* unstable blocks */
 } xfs_perag_t;
 
Index: xfs-cmds/xfsprogs/include/xfs_ialloc.h
===================================================================
--- xfs-cmds.orig/xfsprogs/include/xfs_ialloc.h	2006-11-15 19:00:30.000000000 +1100
+++ xfs-cmds/xfsprogs/include/xfs_ialloc.h	2007-04-03 14:52:51.815759622 +1000
@@ -149,6 +149,16 @@ xfs_ialloc_read_agi(
 	xfs_agnumber_t	agno,		/* allocation group number */
 	struct xfs_buf	**bpp);		/* allocation group hdr buf */
 
+/*
+ * Read in the allocation group header to initialise the per-ag data
+ * in the mount structure
+ */
+int
+xfs_ialloc_pagi_init(
+	struct xfs_mount *mp,		/* file system mount structure */
+	struct xfs_trans *tp,		/* transaction pointer */
+        xfs_agnumber_t  agno);		/* allocation group number */
+
 #endif	/* __KERNEL__ */
 
 #endif	/* __XFS_IALLOC_H__ */
Index: xfs-cmds/xfsprogs/include/xfs_alloc.h
===================================================================
--- xfs-cmds.orig/xfsprogs/include/xfs_alloc.h	2006-11-15 19:00:30.000000000 +1100
+++ xfs-cmds/xfsprogs/include/xfs_alloc.h	2007-04-03 14:52:51.815759622 +1000
@@ -114,7 +114,8 @@ int				/* error */
 xfs_alloc_get_freelist(
 	struct xfs_trans *tp,	/* transaction pointer */
 	struct xfs_buf	*agbp,	/* buffer containing the agf structure */
-	xfs_agblock_t	*bnop);	/* block address retrieved from freelist */
+	xfs_agblock_t	*bnop,	/* block address retrieved from freelist */
+	int		btreeblk); /* destination is a AGF btree */
 
 /*
  * Log the given fields from the agf structure.
@@ -143,7 +144,8 @@ xfs_alloc_put_freelist(
 	struct xfs_trans *tp,	/* transaction pointer */
 	struct xfs_buf	*agbp,	/* buffer for a.g. freelist header */
 	struct xfs_buf	*agflbp,/* buffer for a.g. free block array */
-	xfs_agblock_t	bno);	/* block being freed */
+	xfs_agblock_t	bno,	/* block being freed */
+	int		btreeblk); /* owner was a AGF btree */
 
 /*
  * Read in the allocation group header (free/alloc section).
Index: xfs-cmds/xfsprogs/libxfs/xfs_alloc_btree.c
===================================================================
--- xfs-cmds.orig/xfsprogs/libxfs/xfs_alloc_btree.c	2006-11-15 19:00:31.000000000 +1100
+++ xfs-cmds/xfsprogs/libxfs/xfs_alloc_btree.c	2007-04-03 14:52:51.839756487 +1000
@@ -188,7 +188,7 @@ xfs_alloc_delrec(
 			 * Put this buffer/block on the ag's freelist.
 			 */
 			if ((error = xfs_alloc_put_freelist(cur->bc_tp,
-					cur->bc_private.a.agbp, NULL, bno)))
+					cur->bc_private.a.agbp, NULL, bno, 1)))
 				return error;
 			/*
 			 * Since blocks move to the free list without the
@@ -513,7 +513,7 @@ xfs_alloc_delrec(
 	 * Free the deleting block by putting it on the freelist.
 	 */
 	if ((error = xfs_alloc_put_freelist(cur->bc_tp, cur->bc_private.a.agbp,
-			NULL, rbno)))
+			NULL, rbno, 1)))
 		return error;
 	/*
 	 * Since blocks move to the free list without the coordination
@@ -1279,7 +1279,7 @@ xfs_alloc_newroot(
 	 * Get a buffer from the freelist blocks, for the new root.
 	 */
 	if ((error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_private.a.agbp,
-			&nbno)))
+			&nbno, 1)))
 		return error;
 	/*
 	 * None available, we fail.
@@ -1563,7 +1563,7 @@ xfs_alloc_split(
 	 * If we can't do it, we're toast.  Give up.
 	 */
 	if ((error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_private.a.agbp,
-			&rbno)))
+			&rbno, 1)))
 		return error;
 	if (rbno == NULLAGBLOCK) {
 		*stat = 0;
Index: xfs-cmds/xfsprogs/libxfs/xfs_alloc.c
===================================================================
--- xfs-cmds.orig/xfsprogs/libxfs/xfs_alloc.c	2006-11-15 19:00:31.000000000 +1100
+++ xfs-cmds/xfsprogs/libxfs/xfs_alloc.c	2007-04-03 14:52:51.843755964 +1000
@@ -1355,7 +1355,8 @@ xfs_alloc_ag_vextent_small(
 	else if (args->minlen == 1 && args->alignment == 1 && !args->isfl &&
 		 (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount)
 		  > args->minleft)) {
-		if ((error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno)))
+		error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0);
+		if (error)
 			goto error0;
 		if (fbno != NULLAGBLOCK) {
 			if (args->userdata) {
@@ -1819,7 +1820,7 @@ xfs_alloc_fix_freelist(
 	while (be32_to_cpu(agf->agf_flcount) > need) {
 		xfs_buf_t	*bp;
 
-		if ((error = xfs_alloc_get_freelist(tp, agbp, &bno)))
+		if ((error = xfs_alloc_get_freelist(tp, agbp, &bno, 0)))
 			return error;
 		if ((error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1)))
 			return error;
@@ -1865,7 +1866,7 @@ xfs_alloc_fix_freelist(
 		 */
 		for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) {
 			if ((error = xfs_alloc_put_freelist(tp, agbp, agflbp,
-					bno)))
+					bno, 0)))
 				return error;
 		}
 	}
@@ -1882,13 +1883,15 @@ int				/* error */
 xfs_alloc_get_freelist(
 	xfs_trans_t	*tp,	/* transaction pointer */
 	xfs_buf_t	*agbp,	/* buffer containing the agf structure */
-	xfs_agblock_t	*bnop)	/* block address retrieved from freelist */
+	xfs_agblock_t	*bnop,	/* block address retrieved from freelist */
+	int		btreeblk) /* destination is a AGF btree */
 {
 	xfs_agf_t	*agf;	/* a.g. freespace structure */
 	xfs_agfl_t	*agfl;	/* a.g. freelist structure */
 	xfs_buf_t	*agflbp;/* buffer for a.g. freelist structure */
 	xfs_agblock_t	bno;	/* block number returned */
 	int		error;
+	int		logflags;
 #ifdef XFS_ALLOC_TRACE
 	static char	fname[] = "xfs_alloc_get_freelist";
 #endif
@@ -1923,8 +1926,16 @@ xfs_alloc_get_freelist(
 	be32_add(&agf->agf_flcount, -1);
 	xfs_trans_agflist_delta(tp, -1);
 	pag->pagf_flcount--;
-	TRACE_MODAGF(NULL, agf, XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT);
-	xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT);
+
+	logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT;
+	if (btreeblk) {
+		be32_add(&agf->agf_btreeblks, 1);
+		pag->pagf_btreeblks++;
+		logflags |= XFS_AGF_BTREEBLKS;
+	}
+
+	TRACE_MODAGF(NULL, agf, logflags);
+	xfs_alloc_log_agf(tp, agbp, logflags);
 	*bnop = bno;
 
 	/*
@@ -1962,6 +1973,7 @@ xfs_alloc_log_agf(
 		offsetof(xfs_agf_t, agf_flcount),
 		offsetof(xfs_agf_t, agf_freeblks),
 		offsetof(xfs_agf_t, agf_longest),
+		offsetof(xfs_agf_t, agf_btreeblks),
 		sizeof(xfs_agf_t)
 	};
 
@@ -1997,12 +2009,14 @@ xfs_alloc_put_freelist(
 	xfs_trans_t		*tp,	/* transaction pointer */
 	xfs_buf_t		*agbp,	/* buffer for a.g. freelist header */
 	xfs_buf_t		*agflbp,/* buffer for a.g. free block array */
-	xfs_agblock_t		bno)	/* block being freed */
+	xfs_agblock_t		bno,	/* block being freed */
+	int			btreeblk) /* block came from a AGF btree */
 {
 	xfs_agf_t		*agf;	/* a.g. freespace structure */
 	xfs_agfl_t		*agfl;	/* a.g. free block array */
 	xfs_agblock_t		*blockp;/* pointer to array entry */
 	int			error;
+	int			logflags;
 #ifdef XFS_ALLOC_TRACE
 	static char		fname[] = "xfs_alloc_put_freelist";
 #endif
@@ -2023,11 +2037,19 @@ xfs_alloc_put_freelist(
 	be32_add(&agf->agf_flcount, 1);
 	xfs_trans_agflist_delta(tp, 1);
 	pag->pagf_flcount++;
+
+	logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT;
+	if (btreeblk) {
+		be32_add(&agf->agf_btreeblks, -1);
+		pag->pagf_btreeblks--;
+		logflags |= XFS_AGF_BTREEBLKS;
+	}
+
 	ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp));
 	blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)];
-	INT_SET(*blockp, ARCH_CONVERT, bno);
-	TRACE_MODAGF(NULL, agf, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
-	xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
+  	INT_SET(*blockp, ARCH_CONVERT, bno);
+	TRACE_MODAGF(NULL, agf, logflags);
+	xfs_alloc_log_agf(tp, agbp, logflags);
 	xfs_trans_log_buf(tp, agflbp,
 		(int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl),
 		(int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl +
@@ -2048,6 +2070,7 @@ xfs_alloc_read_agf(
 {
 	xfs_agf_t	*agf;		/* ag freelist header */
 	int		agf_ok;		/* set if agf is consistent */
+	int		agf_length;	/* ag length from agf */
 	xfs_buf_t	*bp;		/* return value */
 	xfs_perag_t	*pag;		/* per allocation group data */
 	int		error;
@@ -2070,10 +2093,12 @@ xfs_alloc_read_agf(
 	 * Validate the magic number of the agf block.
 	 */
 	agf = XFS_BUF_TO_AGF(bp);
+	agf_length = be32_to_cpu(agf->agf_length);
 	agf_ok =
 		be32_to_cpu(agf->agf_magicnum) == XFS_AGF_MAGIC &&
 		XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
-		be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) &&
+		be32_to_cpu(agf->agf_freeblks) <= agf_length &&
+		be32_to_cpu(agf->agf_btreeblks) <= agf_length &&
 		be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) &&
 		be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) &&
 		be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp);
@@ -2087,6 +2112,7 @@ xfs_alloc_read_agf(
 	pag = &mp->m_perag[agno];
 	if (!pag->pagf_init) {
 		pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
+		pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
 		pag->pagf_flcount = be32_to_cpu(agf->agf_flcount);
 		pag->pagf_longest = be32_to_cpu(agf->agf_longest);
 		pag->pagf_levels[XFS_BTNUM_BNOi] =
@@ -2101,6 +2127,7 @@ xfs_alloc_read_agf(
 #ifdef DEBUG
 	else if (!XFS_FORCED_SHUTDOWN(mp)) {
 		ASSERT(pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks));
+		ASSERT(pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks));
 		ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount));
 		ASSERT(pag->pagf_longest == be32_to_cpu(agf->agf_longest));
 		ASSERT(pag->pagf_levels[XFS_BTNUM_BNOi] ==
Index: xfs-cmds/xfsprogs/libxfs/xfs_ialloc.c
===================================================================
--- xfs-cmds.orig/xfsprogs/libxfs/xfs_ialloc.c	2006-11-15 19:00:32.000000000 +1100
+++ xfs-cmds/xfsprogs/libxfs/xfs_ialloc.c	2007-04-03 14:52:51.851754919 +1000
@@ -1128,6 +1128,7 @@ xfs_ialloc_read_agi(
 	pag = &mp->m_perag[agno];
 	if (!pag->pagi_init) {
 		pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
+		pag->pagi_count = be32_to_cpu(agi->agi_count);
 		pag->pagi_init = 1;
 	} else {
 		/*
@@ -1135,6 +1136,7 @@ xfs_ialloc_read_agi(
 		 * we are in the middle of a forced shutdown.
 		 */
 		ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
+			pag->pagi_count == be32_to_cpu(agi->agi_count) ||
 			XFS_FORCED_SHUTDOWN(mp));
 	}
 
@@ -1151,3 +1153,22 @@ xfs_ialloc_read_agi(
 	*bpp = bp;
 	return 0;
 }
+
+/*
+ * Read in the agi to initialise the per-ag data in the mount structure
+ */
+int
+xfs_ialloc_pagi_init(
+	xfs_mount_t	*mp,		/* file system mount structure */
+	xfs_trans_t	*tp,		/* transaction pointer */
+	xfs_agnumber_t	agno)		/* allocation group number */
+{
+	xfs_buf_t	*bp = NULL;
+	int		error;
+
+	if ((error = xfs_ialloc_read_agi(mp, tp, agno, &bp)))
+		return error;
+	if (bp)
+		xfs_trans_brelse(tp, bp);
+	return 0;
+}
Index: xfs-cmds/xfsprogs/libxfs/xfs.h
===================================================================
--- xfs-cmds.orig/xfsprogs/libxfs/xfs.h	2006-11-15 19:00:31.000000000 +1100
+++ xfs-cmds/xfsprogs/libxfs/xfs.h	2007-04-03 14:52:51.851754919 +1000
@@ -86,6 +86,7 @@
 
 #define xfs_mount_common		libxfs_mount_common
 #define xfs_initialize_perag		libxfs_initialize_perag
+#define xfs_initialize_perag_data	libxfs_initialize_perag_data
 #define xfs_rtmount_init		libxfs_rtmount_init
 #define xfs_alloc_fix_freelist		libxfs_alloc_fix_freelist
 #define xfs_idata_realloc		libxfs_idata_realloc
@@ -352,10 +353,10 @@ static inline int __do_div(unsigned long
  */
 
 /* xfs_alloc.c */
-int  xfs_alloc_get_freelist (xfs_trans_t *, xfs_buf_t *, xfs_agblock_t *);
+int  xfs_alloc_get_freelist (xfs_trans_t *, xfs_buf_t *, xfs_agblock_t *, int);
 void xfs_alloc_log_agf (xfs_trans_t *, xfs_buf_t *, int);
 int  xfs_alloc_put_freelist (xfs_trans_t *, xfs_buf_t *, xfs_buf_t *,
-			xfs_agblock_t);
+			xfs_agblock_t, int);
 int  xfs_alloc_read_agf (xfs_mount_t *, xfs_trans_t *, xfs_agnumber_t,
 			int, xfs_buf_t **);
 int  xfs_alloc_vextent (xfs_alloc_arg_t *);
@@ -372,6 +373,7 @@ int  xfs_dialloc (xfs_trans_t *, xfs_ino
 void xfs_ialloc_log_agi (xfs_trans_t *, xfs_buf_t *, int);
 int  xfs_ialloc_read_agi (xfs_mount_t *, xfs_trans_t *, xfs_agnumber_t,
 			xfs_buf_t **);
+int  xfs_ialloc_pagi_init (xfs_mount_t *, xfs_trans_t *, xfs_agnumber_t);
 int  xfs_dilocate (xfs_mount_t *, xfs_trans_t *, xfs_ino_t, xfs_fsblock_t *,
 			int *, int *, uint);
 
Index: xfs-cmds/xfsprogs/libxfs/xfs_mount.c
===================================================================
--- xfs-cmds.orig/xfsprogs/libxfs/xfs_mount.c	2006-11-15 19:00:32.000000000 +1100
+++ xfs-cmds/xfsprogs/libxfs/xfs_mount.c	2007-04-03 14:52:51.859753874 +1000
@@ -313,3 +313,56 @@ xfs_initialize_perag(xfs_mount_t *mp, xf
 	}
 	return index;
 }
+
+/*
+ * xfs_initialize_perag_data
+ *
+ * Read in each per-ag structure so we can count up the number of
+ * allocated inodes, free inodes and used filesystem blocks as this
+ * information is no longer persistent in the superblock. Once we have
+ * this information, write it into the in-core superblock structure.
+ */
+STATIC int
+xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount)
+{
+	xfs_agnumber_t	index;
+	xfs_perag_t	*pag;
+	xfs_sb_t	*sbp = &mp->m_sb;
+	__uint64_t	ifree = 0;
+	__uint64_t	ialloc = 0;
+	__uint64_t	bfree = 0;
+	__uint64_t	bfreelst = 0;
+	__uint64_t	btree = 0;
+	int		error;
+	int		s;
+
+	for (index = 0; index < agcount; index++) {
+		/*
+		 * read the agf, then the agi. This gets us
+		 * all the information we need and populates the
+		 * per-ag structures for us.
+		 */
+		error = xfs_alloc_pagf_init(mp, NULL, index, 0);
+		if (error)
+			return error;
+
+		error = xfs_ialloc_pagi_init(mp, NULL, index);
+		if (error)
+			return error;
+		pag = &mp->m_perag[index];
+		ifree += pag->pagi_freecount;
+		ialloc += pag->pagi_count;
+		bfree += pag->pagf_freeblks;
+		bfreelst += pag->pagf_flcount;
+		btree += pag->pagf_btreeblks;
+	}
+	/*
+	 * Overwrite incore superblock counters with just-read data
+	 */
+	s = XFS_SB_LOCK(mp);
+	sbp->sb_ifree = ifree;
+	sbp->sb_icount = ialloc;
+	sbp->sb_fdblocks = bfree + bfreelst + btree;
+	XFS_SB_UNLOCK(mp, s);
+	return 0;
+}
Index: xfs-cmds/xfsprogs/include/libxfs.h
===================================================================
--- xfs-cmds.orig/xfsprogs/include/libxfs.h	2006-12-22 11:49:54.000000000 +1100
+++ xfs-cmds/xfsprogs/include/libxfs.h	2007-04-03 14:52:51.863753351 +1000
@@ -197,6 +197,7 @@ extern xfs_mount_t	*libxfs_mount (xfs_mo
 				dev_t, dev_t, dev_t, int);
 extern void	libxfs_mount_common (xfs_mount_t *, xfs_sb_t *);
 extern xfs_agnumber_t	libxfs_initialize_perag (xfs_mount_t *, xfs_agnumber_t);
+extern int	libxfs_initialize_perag_data (xfs_mount_t *, xfs_agnumber_t);
 extern void	libxfs_umount (xfs_mount_t *);
 extern int	libxfs_rtmount_init (xfs_mount_t *);
 extern void	libxfs_rtmount_destroy (xfs_mount_t *);
Index: xfs-cmds/xfsprogs/libxfs/init.c
===================================================================
--- xfs-cmds.orig/xfsprogs/libxfs/init.c	2006-12-22 11:49:54.000000000 +1100
+++ xfs-cmds/xfsprogs/libxfs/init.c	2007-04-03 14:52:51.879751261 +1000
@@ -649,6 +649,20 @@ libxfs_mount(
 		libxfs_iput(mp->m_rootip, 0);
 		return NULL;
 	}
+
+	/*
+	 * mkfs calls mount before the AGF/AGI structures are written.
+	 */
+	if ((flags & LIBXFS_MOUNT_ROOTINOS) && sbp->sb_rootino != NULLFSINO &&
+	    XFS_SB_VERSION_LAZYSBCOUNT(&mp->m_sb)) {
+		error = libxfs_initialize_perag_data(mp, sbp->sb_agcount);
+		if (error) {
+			fprintf(stderr, _("%s: cannot init perag data (%d)\n"),
+				progname, error);
+			return NULL;
+		}
+	}
+
 	return mp;
 }
 
Index: xfs-cmds/xfsprogs/man/man8/mkfs.xfs.8
===================================================================
--- xfs-cmds.orig/xfsprogs/man/man8/mkfs.xfs.8	2006-11-15 19:00:33.000000000 +1100
+++ xfs-cmds/xfsprogs/man/man8/mkfs.xfs.8	2007-04-03 14:52:51.907747603 +1000
@@ -335,8 +335,9 @@ The valid suboptions are:
 \f3logdev=\f1\f2device\f1,
 \f3size=\f1\f2value\f1,
 \f3version=\f1\f2[1|2]\f1,
-\f3sunit=\f1\f2value\f1, and
-\f3su=\f1\f2value\f1.
+\f3sunit=\f1\f2value\f1,
+\f3su=\f1\f2value\f1 and
+\f3lazy-count=\f1\f2[0|1]\f1.
 .IP
 The
 .B internal
@@ -415,6 +416,24 @@ The suboption value has to be specified 
 This value must be a multiple of the filesystem block size.
 Version 2 logs are automatically selected if the log \f3su\f1
 suboption is specified.
+.IP
+The
+.B lazy-count
+suboption changes the method of logging various persistent counters
+in the superblock.  Under metadata intensive workloads, these
+counters are updated and logged frequently enough that the
+superblock updates become a serialisation point in the filesystem.
+.IP
+With
+.BR lazy-count=1 ,
+the superblock is not modified or logged on every change of the
+persistent counters. Instead, enough information is kept in
+other parts of the filesystem to be able to maintain the persistent
+counter values without needed to keep them in the superblock.
+This gives significant improvements in performance on some configurations.
+The default value is 0 (off) so you must specify
+.B lazy-count=1
+if you want to make use of this feature.
 .TP
 .B \-n
 Naming options.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: review [3 of 3]: lazy superblock counters - userspace bits
  2007-04-19 23:21 review [3 of 3]: lazy superblock counters - userspace bits David Chinner
@ 2007-05-22  6:19 ` Barry Naujok
  0 siblings, 0 replies; 2+ messages in thread
From: Barry Naujok @ 2007-05-22  6:19 UTC (permalink / raw)
  To: David Chinner, xfs-dev; +Cc: xfs-oss

On Fri, 20 Apr 2007 09:21:33 +1000, David Chinner <dgc@sgi.com> wrote:

>
> userspace tool support for lazy superblock accounting.
>

Looks fine to me.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2007-05-22  6:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-19 23:21 review [3 of 3]: lazy superblock counters - userspace bits David Chinner
2007-05-22  6:19 ` Barry Naujok

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox