rpms/kernel/devel linux-2.6-xfs-filestreams-on-demand-MRU-reaping.patch, NONE, 1.1 linux-2.6-xfs-fix-filestreams-free-func-cast.patch, NONE, 1.1 linux-2.6-xfs-optimize-away-dmapi-tests.patch, NONE, 1.1 linux-2.6-xfs-optimize-away-realtime-tests.patch, NONE, 1.1 linux-2.6-xfs-quota-hashtable-allocation-fix.patch, NONE, 1.1 linux-2.6-xfs-refactor-xfs_mountfs.patch, NONE, 1.1 linux-2.6-xfs-sane-filestreams-object-timeout.patch, NONE, 1.1 kernel.spec, 1.115, 1.116

Eric Sandeen (sandeen) fedora-extras-commits at redhat.com
Fri Aug 24 04:18:23 UTC 2007


Author: sandeen

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv19479

Modified Files:
	kernel.spec 
Added Files:
	linux-2.6-xfs-filestreams-on-demand-MRU-reaping.patch 
	linux-2.6-xfs-fix-filestreams-free-func-cast.patch 
	linux-2.6-xfs-optimize-away-dmapi-tests.patch 
	linux-2.6-xfs-optimize-away-realtime-tests.patch 
	linux-2.6-xfs-quota-hashtable-allocation-fix.patch 
	linux-2.6-xfs-refactor-xfs_mountfs.patch 
	linux-2.6-xfs-sane-filestreams-object-timeout.patch 
Log Message:
* Thu Aug 23 2007 Eric Sandeen <sandeen at redhat.com>
- Update xfs filesystem for bug fixes & stack reduction


linux-2.6-xfs-filestreams-on-demand-MRU-reaping.patch:

--- NEW FILE linux-2.6-xfs-filestreams-on-demand-MRU-reaping.patch ---
From: David Chinner <dgc at sgi.com>
Date: Thu, 16 Aug 2007 05:21:11 +0000 (+1000)
Subject: [XFS] On-demand reaping of the MRU cache
X-Git-Url: http://oss.sgi.com/cgi-bin/gitweb.cgi?p=xfs%2Fxfs-2.6.git;a=commitdiff_plain;h=56da75ad2f62f69a9fc96ccb5cc279196a6d3fe1;hp=207358950497c7bdc63c37b6fa361108152816de

[XFS] On-demand reaping of the MRU cache

Instead of running the mru cache reaper all the time based on a timeout,
we should only run it when the cache has active objects. This allows CPUs
to sleep when there is no activity rather than be woken repeatedly just to
check if there is anything to do.

SGI-PV: 968554
SGI-Modid: xfs-linux-melb:xfs-kern:29305a

Signed-off-by: David Chinner <dgc at sgi.com>
Signed-off-by: Donald Douwsma <donaldd at sgi.com>
Signed-off-by: Tim Shimmin <tes at sgi.com>
---

Index: linux-2.6.22.i386/fs/xfs/xfs_filestream.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_filestream.c
+++ linux-2.6.22.i386/fs/xfs/xfs_filestream.c
@@ -467,8 +467,7 @@ void
 xfs_filestream_flush(
 	xfs_mount_t	*mp)
 {
-	/* point in time flush, so keep the reaper running */
-	xfs_mru_cache_flush(mp->m_filestream, 1);
+	xfs_mru_cache_flush(mp->m_filestream);
 }
 
 /*
Index: linux-2.6.22.i386/fs/xfs/xfs_mru_cache.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_mru_cache.c
+++ linux-2.6.22.i386/fs/xfs/xfs_mru_cache.c
@@ -206,8 +206,11 @@ _xfs_mru_cache_list_insert(
 	 */
 	if (!_xfs_mru_cache_migrate(mru, now)) {
 		mru->time_zero = now;
-		if (!mru->next_reap)
-			mru->next_reap = mru->grp_count * mru->grp_time;
+		if (!mru->queued) {
+			mru->queued = 1;
+			queue_delayed_work(xfs_mru_reap_wq, &mru->work,
+			                   mru->grp_count * mru->grp_time);
+		}
 	} else {
 		grp = (now - mru->time_zero) / mru->grp_time;
 		grp = (mru->lru_grp + grp) % mru->grp_count;
@@ -271,29 +274,26 @@ _xfs_mru_cache_reap(
 	struct work_struct	*work)
 {
 	xfs_mru_cache_t		*mru = container_of(work, xfs_mru_cache_t, work.work);
-	unsigned long		now;
+	unsigned long		now, next;
 
 	ASSERT(mru && mru->lists);
 	if (!mru || !mru->lists)
 		return;
 
 	mutex_spinlock(&mru->lock);
-	now = jiffies;
-	if (mru->reap_all ||
-	    (mru->next_reap && time_after(now, mru->next_reap))) {
-		if (mru->reap_all)
-			now += mru->grp_count * mru->grp_time * 2;
-		mru->next_reap = _xfs_mru_cache_migrate(mru, now);
-		_xfs_mru_cache_clear_reap_list(mru);
+	next = _xfs_mru_cache_migrate(mru, jiffies);
+	_xfs_mru_cache_clear_reap_list(mru);
+
+	mru->queued = next;
+	if ((mru->queued > 0)) {
+		now = jiffies;
+		if (next <= now)
+			next = 0;
+		else
+			next -= now;
+		queue_delayed_work(xfs_mru_reap_wq, &mru->work, next);
 	}
 
-	/*
-	 * the process that triggered the reap_all is responsible
-	 * for restating the periodic reap if it is required.
-	 */
-	if (!mru->reap_all)
-		queue_delayed_work(xfs_mru_reap_wq, &mru->work, mru->grp_time);
-	mru->reap_all = 0;
 	mutex_spinunlock(&mru->lock, 0);
 }
 
@@ -352,7 +352,7 @@ xfs_mru_cache_create(
 
 	/* An extra list is needed to avoid reaping up to a grp_time early. */
 	mru->grp_count = grp_count + 1;
-	mru->lists = kmem_alloc(mru->grp_count * sizeof(*mru->lists), KM_SLEEP);
+	mru->lists = kmem_zalloc(mru->grp_count * sizeof(*mru->lists), KM_SLEEP);
 
 	if (!mru->lists) {
 		err = ENOMEM;
@@ -374,11 +374,6 @@ xfs_mru_cache_create(
 	mru->grp_time  = grp_time;
 	mru->free_func = free_func;
 
-	/* start up the reaper event */
-	mru->next_reap = 0;
-	mru->reap_all = 0;
-	queue_delayed_work(xfs_mru_reap_wq, &mru->work, mru->grp_time);
-
 	*mrup = mru;
 
 exit:
@@ -394,35 +389,25 @@ exit:
  * Call xfs_mru_cache_flush() to flush out all cached entries, calling their
  * free functions as they're deleted.  When this function returns, the caller is
  * guaranteed that all the free functions for all the elements have finished
- * executing.
- *
- * While we are flushing, we stop the periodic reaper event from triggering.
- * Normally, we want to restart this periodic event, but if we are shutting
- * down the cache we do not want it restarted. hence the restart parameter
- * where 0 = do not restart reaper and 1 = restart reaper.
+ * executing and the reaper is not running.
  */
 void
 xfs_mru_cache_flush(
-	xfs_mru_cache_t		*mru,
-	int			restart)
+	xfs_mru_cache_t		*mru)
 {
 	if (!mru || !mru->lists)
 		return;
 
-	cancel_rearming_delayed_workqueue(xfs_mru_reap_wq, &mru->work);
-
 	mutex_spinlock(&mru->lock);
-	mru->reap_all = 1;
-	mutex_spinunlock(&mru->lock, 0);
+	if (mru->queued) {
+		mutex_spinunlock(&mru->lock, 0);
+		cancel_rearming_delayed_workqueue(xfs_mru_reap_wq, &mru->work);
+		mutex_spinlock(&mru->lock);
+	}
 
-	queue_work(xfs_mru_reap_wq, &mru->work.work);
-	flush_workqueue(xfs_mru_reap_wq);
+	_xfs_mru_cache_migrate(mru, jiffies + mru->grp_count * mru->grp_time);
+	_xfs_mru_cache_clear_reap_list(mru);
 
-	mutex_spinlock(&mru->lock);
-	WARN_ON_ONCE(mru->reap_all != 0);
-	mru->reap_all = 0;
-	if (restart)
-		queue_delayed_work(xfs_mru_reap_wq, &mru->work, mru->grp_time);
 	mutex_spinunlock(&mru->lock, 0);
 }
 
@@ -433,8 +418,7 @@ xfs_mru_cache_destroy(
 	if (!mru || !mru->lists)
 		return;
 
-	/* we don't want the reaper to restart here */
-	xfs_mru_cache_flush(mru, 0);
+	xfs_mru_cache_flush(mru);
 
 	kmem_free(mru->lists, mru->grp_count * sizeof(*mru->lists));
 	kmem_free(mru, sizeof(*mru));
Index: linux-2.6.22.i386/fs/xfs/xfs_mru_cache.h
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_mru_cache.h
+++ linux-2.6.22.i386/fs/xfs/xfs_mru_cache.h
@@ -32,11 +32,9 @@ typedef struct xfs_mru_cache
 	unsigned int		grp_time;  /* Time period spanned by grps.  */
 	unsigned int		lru_grp;   /* Group containing time zero.   */
 	unsigned long		time_zero; /* Time first element was added. */
-	unsigned long		next_reap; /* Time that the reaper should
-					      next do something. */
-	unsigned int		reap_all;  /* if set, reap all lists */
 	xfs_mru_cache_free_func_t free_func; /* Function pointer for freeing. */
 	struct delayed_work	work;      /* Workqueue data for reaping.   */
+	unsigned int		queued;	   /* work has been queued */
 } xfs_mru_cache_t;
 
 int xfs_mru_cache_init(void);
@@ -44,7 +42,7 @@ void xfs_mru_cache_uninit(void);
 int xfs_mru_cache_create(struct xfs_mru_cache **mrup, unsigned int lifetime_ms,
 			     unsigned int grp_count,
 			     xfs_mru_cache_free_func_t free_func);
-void xfs_mru_cache_flush(xfs_mru_cache_t *mru, int restart);
+void xfs_mru_cache_flush(xfs_mru_cache_t *mru);
 void xfs_mru_cache_destroy(struct xfs_mru_cache *mru);
 int xfs_mru_cache_insert(struct xfs_mru_cache *mru, unsigned long key,
 				void *value);

linux-2.6-xfs-fix-filestreams-free-func-cast.patch:

--- NEW FILE linux-2.6-xfs-fix-filestreams-free-func-cast.patch ---
xfs_filestream_mount() sets up an mru cache with:

        err = xfs_mru_cache_create(&mp->m_filestream, lifetime, grp_count,
                             (xfs_mru_cache_free_func_t)xfs_fstrm_free_func);

but that cast is causing problems...

typedef void (*xfs_mru_cache_free_func_t)(unsigned long, void*);

but:

void xfs_fstrm_free_func( 
        xfs_ino_t       ino,
        fstrm_item_t    *item)

so on a 32-bit box, it's casting (32, 32) args into (64, 32) and I assume 
it's getting garbage for *item, which subsequently causes an explosion.

With this change the filestreams xfsqa tests don't oops on my 32-bit box.

Signed-off-by: Eric Sandeen <sandeen at sandeen.net>

Index: linux-2.6.22.i386/fs/xfs/xfs_filestream.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_filestream.c
+++ linux-2.6.22.i386/fs/xfs/xfs_filestream.c
@@ -350,9 +350,10 @@ _xfs_filestream_update_ag(
 /* xfs_fstrm_free_func(): callback for freeing cached stream items. */
 void
 xfs_fstrm_free_func(
-	xfs_ino_t	ino,
-	fstrm_item_t	*item)
+	unsigned long	ino,
+	void		*data)
 {
+	fstrm_item_t	*item  = (fstrm_item_t *)data;
 	xfs_inode_t	*ip = item->ip;
 	int ref;
 
@@ -438,7 +439,7 @@ xfs_filestream_mount(
 	grp_count = 10;
 
 	err = xfs_mru_cache_create(&mp->m_filestream, lifetime, grp_count,
-	                     (xfs_mru_cache_free_func_t)xfs_fstrm_free_func);
+	                     xfs_fstrm_free_func);
 
 	return err;
 }

linux-2.6-xfs-optimize-away-dmapi-tests.patch:

--- NEW FILE linux-2.6-xfs-optimize-away-dmapi-tests.patch ---
From: Eric Sandeen <sandeen at sandeen.net>
Date: Thu, 23 Aug 2007 06:19:57 +0000 (+1000)
Subject: [XFS] optimize dmapi event tests w/o dmapi config
X-Git-Url: http://oss.sgi.com/cgi-bin/gitweb.cgi?p=xfs%2Fxfs-2.6.git;a=commitdiff_plain;h=c4389058a94b1b9c4be0484ca15368f560fb1ef7;hp=0a0aa86fe08645c72e5fa26770a70428f2c9ae3c

[XFS] optimize dmapi event tests w/o dmapi config

Defining XFS_DM_EVENT* macros to 0 in the absence of
CONFIG_XFS_DMAPI allows gcc to optimize away tests that
should never be true. Also wrap one hunk of xfs_unmount
in #ifdef CONFIG_XFS_DMAPI

Stack deltas on x86, gcc 4.1:

xfs_create              -16
xfs_free_file_space     -4
xfs_getbmap             +4
xfs_link                -8
xfs_mkidr               -20
xfs_read                -24
xfs_remove              -12
xfs_rename              -8
xfs_rmdir               -16
xfs_setattr             -20
xfs_splice_read         -20
xfs_splice_write        -20
xfs_unmount             -48
xfs_write               -20

SGI-PV: 969372
SGI-Modid: xfs-linux-melb:xfs-kern:29444a

Signed-off-by: Eric Sandeen <sandeen at sandeen.net>
Signed-off-by: Vlad Apostolov <vapo at sgi.com>
Signed-off-by: Tim Shimmin <tes at sgi.com>
---

Index: linux-2.6.22.i386/fs/xfs/xfs_dmapi.h
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_dmapi.h
+++ linux-2.6.22.i386/fs/xfs/xfs_dmapi.h
@@ -67,6 +67,7 @@ typedef enum {
 #define HAVE_DM_RIGHT_T
 
 /* Defines for determining if an event message should be sent. */
+#ifdef CONFIG_XFS_DMAPI
 #define	DM_EVENT_ENABLED(vfsp, ip, event) ( \
 	unlikely ((vfsp)->vfs_flag & VFS_DMI) && \
 		( ((ip)->i_d.di_dmevmask & (1 << event)) || \
@@ -78,6 +79,10 @@ typedef enum {
 		( ((io)->io_dmevmask & (1 << event)) || \
 		  ((io)->io_mount->m_dmevmask & (1 << event)) ) \
 	)
+#else
+#define DM_EVENT_ENABLED(vfsp, ip, event) (0)
+#define DM_EVENT_ENABLED_IO(vfsp, io, event) (0)
+#endif
 
 #define DM_XFS_VALID_FS_EVENTS		( \
 	(1 << DM_EVENT_PREUNMOUNT)	| \
Index: linux-2.6.22.i386/fs/xfs/xfs_vfsops.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_vfsops.c
+++ linux-2.6.22.i386/fs/xfs/xfs_vfsops.c
@@ -568,6 +568,7 @@ xfs_unmount(
 	rip = mp->m_rootip;
 	rvp = XFS_ITOV(rip);
 
+#ifdef HAVE_DMAPI
 	if (vfsp->vfs_flag & VFS_DMI) {
 		error = XFS_SEND_PREUNMOUNT(mp, vfsp,
 				rvp, DM_RIGHT_NULL, rvp, DM_RIGHT_NULL,
@@ -580,7 +581,7 @@ xfs_unmount(
 		unmount_event_flags = (mp->m_dmevmask & (1<<DM_EVENT_UNMOUNT))?
 					0 : DM_FLAGS_UNWANTED;
 	}
-
+#endif
 	/*
 	 * First blow any referenced inode from this file system
 	 * out of the reference cache, and delete the timer.

linux-2.6-xfs-optimize-away-realtime-tests.patch:

--- NEW FILE linux-2.6-xfs-optimize-away-realtime-tests.patch ---
Use XFS_IS_REALTIME_INODE in more places, and #define it to
0 if CONFIG_XFS_RT is off.  This should be safe because mount
checks in xfs_rtmount_init:

# define xfs_rtmount_init(m)    (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))

so if we get mounted w/o CONFIG_XFS_RT, no realtime inodes should
be encountered after that.

Defining XFS_IS_REALTIME_INODE to 0 saves a bit of stack space,
presumeably gcc can optimize around the various "if (0)" type
checks:

xfs_alloc_file_space	-8
xfs_bmap_adjacent	-16
xfs_bmapi		-8
xfs_bmap_rtalloc	-16
xfs_bunmapi		-28
xfs_free_file_space	-64
xfs_imap		+8  <-- ?  hmm.
xfs_iomap_write_direct	-12
xfs_qm_dqusage_adjust	-4
xfs_qm_vop_chown_reserve -4

Compile tested only at this point.

Signed-off-by: Eric Sandeen <sandeen at sandeen.net>

Index: linux-2.6.22.i386/fs/xfs/xfs_rtalloc.h
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_rtalloc.h
+++ linux-2.6.22.i386/fs/xfs/xfs_rtalloc.h
@@ -21,8 +21,6 @@
 struct xfs_mount;
 struct xfs_trans;
 
-#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME)
-
 /* Min and max rt extent sizes, specified in bytes */
 #define	XFS_MAX_RTEXTSIZE	(1024 * 1024 * 1024)	/* 1GB */
 #define	XFS_DFL_RTEXTSIZE	(64 * 1024)	        /* 64KB */
Index: linux-2.6.22.i386/fs/xfs/linux-2.6/xfs_ioctl.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/linux-2.6/xfs_ioctl.c
+++ linux-2.6.22.i386/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -736,7 +736,7 @@ xfs_ioctl(
 	case XFS_IOC_DIOINFO: {
 		struct dioattr	da;
 		xfs_buftarg_t	*target =
-			(ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
+			XFS_IS_REALTIME_INODE(ip) ?
 			mp->m_rtdev_targp : mp->m_ddev_targp;
 
 		da.d_mem = da.d_miniosz = 1 << target->bt_sshift;
Index: linux-2.6.22.i386/fs/xfs/linux-2.6/xfs_lrw.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/linux-2.6/xfs_lrw.c
+++ linux-2.6.22.i386/fs/xfs/linux-2.6/xfs_lrw.c
@@ -220,7 +220,7 @@ xfs_read(
 
 	if (unlikely(ioflags & IO_ISDIRECT)) {
 		xfs_buftarg_t	*target =
-			(ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
+			XFS_IS_REALTIME_INODE(ip) ?
 				mp->m_rtdev_targp : mp->m_ddev_targp;
 		if ((*offset & target->bt_smask) ||
 		    (size & target->bt_smask)) {
@@ -694,7 +694,7 @@ start:
 
 	if (ioflags & IO_ISDIRECT) {
 		xfs_buftarg_t	*target =
-			(xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
+			XFS_IS_REALTIME_INODE(xip) ?
 				mp->m_rtdev_targp : mp->m_ddev_targp;
 
 		if ((pos & target->bt_smask) || (count & target->bt_smask)) {
Index: linux-2.6.22.i386/fs/xfs/xfs_dfrag.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_dfrag.c
+++ linux-2.6.22.i386/fs/xfs/xfs_dfrag.c
@@ -184,8 +184,7 @@ xfs_swap_extents(
 	}
 
 	/* Verify both files are either real-time or non-realtime */
-	if ((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) !=
-	    (tip->i_d.di_flags & XFS_DIFLAG_REALTIME)) {
+	if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) {
 		error = XFS_ERROR(EINVAL);
 		goto error0;
 	}
Index: linux-2.6.22.i386/fs/xfs/xfs_iocore.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_iocore.c
+++ linux-2.6.22.i386/fs/xfs/xfs_iocore.c
@@ -94,7 +94,7 @@ xfs_iocore_inode_reinit(
 	xfs_iocore_t	*io = &ip->i_iocore;
 
 	io->io_flags = 0;
-	if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)
+	if (XFS_IS_REALTIME_INODE(ip))
 		io->io_flags |= XFS_IOCORE_RT;
 	io->io_dmevmask = ip->i_d.di_dmevmask;
 	io->io_dmstate = ip->i_d.di_dmstate;
Index: linux-2.6.22.i386/fs/xfs/xfs_rw.h
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_rw.h
+++ linux-2.6.22.i386/fs/xfs/xfs_rw.h
@@ -58,7 +58,7 @@ struct xfs_mount;
 static inline xfs_daddr_t
 xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb)
 {
-	return (((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) ? \
+	return (XFS_IS_REALTIME_INODE(ip) ? \
 		 (xfs_daddr_t)XFS_FSB_TO_BB((ip)->i_mount, (fsb)) : \
 		 XFS_FSB_TO_DADDR((ip)->i_mount, (fsb)));
 }
@@ -87,7 +87,7 @@ xfs_get_extsz_hint(
 {
 	xfs_extlen_t	extsz;
 
-	if (unlikely(ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) {
+	if (unlikely(XFS_IS_REALTIME_INODE(ip))) {
 		extsz = (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)
 				? ip->i_d.di_extsize
 				: ip->i_mount->m_sb.sb_rextsize;
Index: linux-2.6.22.i386/fs/xfs/xfs_vnodeops.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_vnodeops.c
+++ linux-2.6.22.i386/fs/xfs/xfs_vnodeops.c
@@ -144,7 +144,7 @@ xfs_getattr(
 	default:
 		vap->va_rdev = 0;
 
-		if (!(ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) {
+		if (!(XFS_IS_REALTIME_INODE(ip))) {
 			vap->va_blocksize = xfs_preferred_iosize(mp);
 		} else {
 
@@ -521,7 +521,7 @@ xfs_setattr(
 		 */
 		if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
 		    (mask & XFS_AT_XFLAGS) &&
-		    (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) !=
+		    (XFS_IS_REALTIME_INODE(ip)) !=
 		    (vap->va_xflags & XFS_XFLAG_REALTIME)) {
 			code = XFS_ERROR(EINVAL);	/* EFBIG? */
 			goto error_return;
@@ -533,7 +533,7 @@ xfs_setattr(
 		if ((mask & XFS_AT_EXTSIZE) && vap->va_extsize != 0) {
 			xfs_extlen_t	size;
 
-			if ((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ||
+			if (XFS_IS_REALTIME_INODE(ip) ||
 			    ((mask & XFS_AT_XFLAGS) &&
 			    (vap->va_xflags & XFS_XFLAG_REALTIME))) {
 				size = mp->m_sb.sb_rextsize <<
@@ -1188,7 +1188,7 @@ xfs_fsync(
 		 * If this inode is on the RT dev we need to flush that
 		 * cache as well.
 		 */
-		if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)
+		if (XFS_IS_REALTIME_INODE(ip))
 			xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp);
 	}
 
@@ -4263,7 +4263,7 @@ xfs_zero_remaining_bytes(
 	int			error = 0;
 
 	bp = xfs_buf_get_noaddr(mp->m_sb.sb_blocksize,
-				ip->i_d.di_flags & XFS_DIFLAG_REALTIME ?
+				XFS_IS_REALTIME_INODE(ip) ?
 				mp->m_rtdev_targp : mp->m_ddev_targp);
 
 	for (offset = startoff; offset <= endoff; offset = lastoffset + 1) {
@@ -4360,7 +4360,7 @@ xfs_free_file_space(
 	error = 0;
 	if (len <= 0)	/* if nothing being freed */
 		return error;
-	rt = (ip->i_d.di_flags & XFS_DIFLAG_REALTIME);
+	rt = XFS_IS_REALTIME_INODE(ip);
 	startoffset_fsb	= XFS_B_TO_FSB(mp, offset);
 	end_dmi_offset = offset + len;
 	endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset);
Index: linux-2.6.22.i386/fs/xfs/xfs_dinode.h
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_dinode.h
+++ linux-2.6.22.i386/fs/xfs/xfs_dinode.h
@@ -274,6 +274,12 @@ typedef enum xfs_dinode_fmt
 #define XFS_DIFLAG_NODEFRAG      (1 << XFS_DIFLAG_NODEFRAG_BIT)
 #define XFS_DIFLAG_FILESTREAM    (1 << XFS_DIFLAG_FILESTREAM_BIT)
 
+#ifdef CONFIG_XFS_RT
+#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME)
+#else
+#define XFS_IS_REALTIME_INODE(ip) (0)
+#endif
+
 #define XFS_DIFLAG_ANY \
 	(XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
 	 XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \

linux-2.6-xfs-quota-hashtable-allocation-fix.patch:

--- NEW FILE linux-2.6-xfs-quota-hashtable-allocation-fix.patch ---
From: Eric Sandeen <sandeen at sandeen.net>
Date: Thu, 16 Aug 2007 06:49:11 +0000 (+1000)
Subject: [XFS] fix nasty quota hashtable allocation bug
X-Git-Url: http://oss.sgi.com/cgi-bin/gitweb.cgi?p=xfs%2Fxfs-2.6.git;a=commitdiff_plain;h=e893ea73ade2caf1b22c4f268114fd6ca44b83db;hp=96739fb00f3f91f5ccfebb2a095bb55d1a03a6a4

[XFS] fix nasty quota hashtable allocation bug

This git mod: 77e4635ae191774526ed695482a151ac986f3806

converted to a "greedy" allocation interface, but for the quota hashtables
it switched from allocating XFS_QM_HASHSIZE (nr of elements)
xfs_dqhash_t's to allocating only XFS_QM_HASHSIZE *bytes* - quite a lot
smaller! Then when we converted hsize "back" to nr of elements (the
division line) hsize went to 0. This was leading to oopses when running
any quota tests on the Fedora 8 test kernel, but the problem has been
there for almost a year.

SGI-PV: 968837
SGI-Modid: xfs-linux-melb:xfs-kern:29354a

Signed-off-by: Eric Sandeen <sandeen at sandeen.net>
Signed-off-by: David Chinner <dgc at sgi.com>
Signed-off-by: Tim Shimmin <tes at sgi.com>
---

Index: linux-2.6.22.i386/fs/xfs/quota/xfs_qm.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/quota/xfs_qm.c
+++ linux-2.6.22.i386/fs/xfs/quota/xfs_qm.c
@@ -120,7 +120,8 @@ xfs_Gqm_init(void)
 	 * Initialize the dquot hash tables.
 	 */
 	udqhash = kmem_zalloc_greedy(&hsize,
-				     XFS_QM_HASHSIZE_LOW, XFS_QM_HASHSIZE_HIGH,
+				     XFS_QM_HASHSIZE_LOW * sizeof(xfs_dqhash_t),
+				     XFS_QM_HASHSIZE_HIGH * sizeof(xfs_dqhash_t),
 				     KM_SLEEP | KM_MAYFAIL | KM_LARGE);
 	gdqhash = kmem_zalloc(hsize, KM_SLEEP | KM_LARGE);
 	hsize /= sizeof(xfs_dqhash_t);

linux-2.6-xfs-refactor-xfs_mountfs.patch:

--- NEW FILE linux-2.6-xfs-refactor-xfs_mountfs.patch ---
Index: linux-2.6.22.i386/fs/xfs/xfs_mount.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_mount.c
+++ linux-2.6.22.i386/fs/xfs/xfs_mount.c
@@ -701,51 +701,13 @@ xfs_initialize_perag_data(xfs_mount_t *m
 	return 0;
 }
 
-/*
- * xfs_mountfs
- *
- * This function does the following on an initial mount of a file system:
- *	- reads the superblock from disk and init the mount struct
- *	- if we're a 32-bit kernel, do a size check on the superblock
- *		so we don't mount terabyte filesystems
- *	- init mount struct realtime fields
- *	- allocate inode hash table for fs
- *	- init directory manager
- *	- perform recovery and init the log manager
- */
-int
-xfs_mountfs(
-	bhv_vfs_t	*vfsp,
-	xfs_mount_t	*mp,
-	int		mfsi_flags)
+STATIC int
+xfs_update_alignment(xfs_mount_t *mp,
+			int mfsi_flags,
+		     __uint64_t *update_flags)
 {
-	xfs_buf_t	*bp;
 	xfs_sb_t	*sbp = &(mp->m_sb);
-	xfs_inode_t	*rip;
-	bhv_vnode_t	*rvp = NULL;
-	int		readio_log, writeio_log;
-	xfs_daddr_t	d;
-	__uint64_t	resblks;
-	__int64_t	update_flags;
-	uint		quotamount, quotaflags;
-	int		agno;
-	int		uuid_mounted = 0;
-	int		error = 0;
 
-	if (mp->m_sb_bp == NULL) {
-		if ((error = xfs_readsb(mp, mfsi_flags))) {
-			return error;
-		}
-	}
-	xfs_mount_common(mp, sbp);
-
-	/*
-	 * Check if sb_agblocks is aligned at stripe boundary
-	 * If sb_agblocks is NOT aligned turn off m_dalign since
-	 * allocator alignment is within an ag, therefore ag has
-	 * to be aligned at stripe boundary.
-	 */
-	update_flags = 0LL;
 	if (mp->m_dalign && !(mfsi_flags & XFS_MFSI_SECOND)) {
 		/*
 		 * If stripe unit and stripe width are not multiples
@@ -756,8 +718,7 @@ xfs_mountfs(
 			if (mp->m_flags & XFS_MOUNT_RETERR) {
 				cmn_err(CE_WARN,
 					"XFS: alignment check 1 failed");
-				error = XFS_ERROR(EINVAL);
-				goto error1;
+				return XFS_ERROR(EINVAL);
 			}
 			mp->m_dalign = mp->m_swidth = 0;
 		} else {
@@ -767,8 +728,7 @@ xfs_mountfs(
 			mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign);
 			if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) {
 				if (mp->m_flags & XFS_MOUNT_RETERR) {
-					error = XFS_ERROR(EINVAL);
-					goto error1;
+					return XFS_ERROR(EINVAL);
 				}
 				xfs_fs_cmn_err(CE_WARN, mp,
 "stripe alignment turned off: sunit(%d)/swidth(%d) incompatible with agsize(%d)",
@@ -783,10 +743,9 @@ xfs_mountfs(
 				if (mp->m_flags & XFS_MOUNT_RETERR) {
 					xfs_fs_cmn_err(CE_WARN, mp,
 "stripe alignment turned off: sunit(%d) less than bsize(%d)",
-                                        	mp->m_dalign,
+						mp->m_dalign,
 						mp->m_blockmask +1);
-					error = XFS_ERROR(EINVAL);
-					goto error1;
+					return XFS_ERROR(EINVAL);
 				}
 				mp->m_swidth = 0;
 			}
@@ -799,11 +758,11 @@ xfs_mountfs(
 		if (XFS_SB_VERSION_HASDALIGN(sbp)) {
 			if (sbp->sb_unit != mp->m_dalign) {
 				sbp->sb_unit = mp->m_dalign;
-				update_flags |= XFS_SB_UNIT;
+				*update_flags |= XFS_SB_UNIT;
 			}
 			if (sbp->sb_width != mp->m_swidth) {
 				sbp->sb_width = mp->m_swidth;
-				update_flags |= XFS_SB_WIDTH;
+				*update_flags |= XFS_SB_WIDTH;
 			}
 		}
 	} else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&
@@ -811,11 +770,13 @@ xfs_mountfs(
 			mp->m_dalign = sbp->sb_unit;
 			mp->m_swidth = sbp->sb_width;
 	}
+	return 0;
+}
 
-	xfs_alloc_compute_maxlevels(mp);
-	xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
-	xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
-	xfs_ialloc_compute_maxlevels(mp);
+STATIC void
+xfs_set_maxicount(xfs_mount_t *mp)
+{
+	xfs_sb_t	*sbp = &(mp->m_sb);
 
 	if (sbp->sb_imax_pct) {
 		__uint64_t	icount;
@@ -831,33 +792,20 @@ xfs_mountfs(
 				   sbp->sb_inopblog;
 	} else
 		mp->m_maxicount = 0;
+}
 
-	mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog);
-
-	/*
-	 * XFS uses the uuid from the superblock as the unique
-	 * identifier for fsid.  We can not use the uuid from the volume
-	 * since a single partition filesystem is identical to a single
-	 * partition volume/filesystem.
-	 */
-	if ((mfsi_flags & XFS_MFSI_SECOND) == 0 &&
-	    (mp->m_flags & XFS_MOUNT_NOUUID) == 0) {
-		__uint64_t	ret64;
-		if (xfs_uuid_mount(mp)) {
-			error = XFS_ERROR(EINVAL);
-			goto error1;
-		}
-		uuid_mounted=1;
-		ret64 = uuid_hash64(&sbp->sb_uuid);
-		memcpy(&vfsp->vfs_fsid, &ret64, sizeof(ret64));
-	}
+/*
+ * Set the default minimum read and write sizes unless
+ * already specified in a mount option.
+ * We use smaller I/O sizes when the file system
+ * is being used for NFS service (wsync mount option).
+ */
+STATIC
+void xfs_set_rw_sizes(xfs_mount_t *mp)
+{
+	xfs_sb_t	*sbp = &(mp->m_sb);
+	int		readio_log, writeio_log;
 
-	/*
-	 * Set the default minimum read and write sizes unless
-	 * already specified in a mount option.
-	 * We use smaller I/O sizes when the file system
-	 * is being used for NFS service (wsync mount option).
-	 */
 	if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)) {
 		if (mp->m_flags & XFS_MOUNT_WSYNC) {
 			readio_log = XFS_WSYNC_READIO_LOG;
@@ -893,43 +841,20 @@ xfs_mountfs(
 		mp->m_writeio_log = writeio_log;
 	}
 	mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog);
+}
+
+STATIC int
+xfs_size_checks(xfs_mount_t *mp,
+              int mfsi_flags)
+{
+      xfs_buf_t       *bp;
+      xfs_daddr_t     d;
+      int             error;
 
-	/*
-	 * Set the inode cluster size based on the physical memory
-	 * size.  This may still be overridden by the file system
-	 * block size if it is larger than the chosen cluster size.
-	 */
-	if (xfs_physmem <= btoc(32 * 1024 * 1024)) { /* <= 32 MB */
-		mp->m_inode_cluster_size = XFS_INODE_SMALL_CLUSTER_SIZE;
-	} else {
-		mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
-	}
-	/*
-	 * Set whether we're using inode alignment.
-	 */
-	if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) &&
-	    mp->m_sb.sb_inoalignmt >=
-	    XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
-		mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1;
-	else
-		mp->m_inoalign_mask = 0;
-	/*
-	 * If we are using stripe alignment, check whether
-	 * the stripe unit is a multiple of the inode alignment
-	 */
-	if (mp->m_dalign && mp->m_inoalign_mask &&
-	    !(mp->m_dalign & mp->m_inoalign_mask))
-		mp->m_sinoalign = mp->m_dalign;
-	else
-		mp->m_sinoalign = 0;
-	/*
-	 * Check that the data (and log if separate) are an ok size.
-	 */
 	d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
 	if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {
 		cmn_err(CE_WARN, "XFS: size check 1 failed");
-		error = XFS_ERROR(E2BIG);
-		goto error1;
+		return XFS_ERROR(E2BIG);
 	}
 	error = xfs_read_buf(mp, mp->m_ddev_targp,
 			     d - XFS_FSS_TO_BB(mp, 1),
@@ -941,7 +866,7 @@ xfs_mountfs(
 		if (error == ENOSPC) {
 			error = XFS_ERROR(E2BIG);
 		}
-		goto error1;
+		return error;
 	}
 
 	if (((mfsi_flags & XFS_MFSI_CLIENT) == 0) &&
@@ -949,8 +874,7 @@ xfs_mountfs(
 		d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
 		if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) {
 			cmn_err(CE_WARN, "XFS: size check 3 failed");
-			error = XFS_ERROR(E2BIG);
-			goto error1;
+			return XFS_ERROR(E2BIG);
 		}
 		error = xfs_read_buf(mp, mp->m_logdev_targp,
 				     d - XFS_FSB_TO_BB(mp, 1),
@@ -962,10 +886,118 @@ xfs_mountfs(
 			if (error == ENOSPC) {
 				error = XFS_ERROR(E2BIG);
 			}
+			return error;
+		}
+	}
+	return 0;
+}
+
+/*
+ * xfs_mountfs
+ *
+ * This function does the following on an initial mount of a file system:
+ *	- reads the superblock from disk and init the mount struct
+ *	- if we're a 32-bit kernel, do a size check on the superblock
+ *		so we don't mount terabyte filesystems
+ *	- init mount struct realtime fields
+ *	- allocate inode hash table for fs
+ *	- init directory manager
+ *	- perform recovery and init the log manager
+ */
+int
+xfs_mountfs(
+	bhv_vfs_t	*vfsp,
+	xfs_mount_t	*mp,
+	int		mfsi_flags)
+{
+	xfs_sb_t	*sbp = &(mp->m_sb);
+	xfs_inode_t	*rip;
+	bhv_vnode_t	*rvp = NULL;
+	__uint64_t	resblks;
+	__int64_t	update_flags;
+	uint		quotamount, quotaflags;
+	int		agno;
+	int		uuid_mounted = 0;
+	int		error = 0;
+
+	if (mp->m_sb_bp == NULL) {
+		if ((error = xfs_readsb(mp, mfsi_flags))) {
+			return error;
+		}
+	}
+	xfs_mount_common(mp, sbp);
+
+	/*
+	 * Check if sb_agblocks is aligned at stripe boundary
+	 * If sb_agblocks is NOT aligned turn off m_dalign since
+	 * allocator alignment is within an ag, therefore ag has
+	 * to be aligned at stripe boundary.
+	 */
+	update_flags = 0LL;
+	if ((error = xfs_update_alignment(mp, mfsi_flags, &update_flags)))
+		goto error1;
+
+	xfs_alloc_compute_maxlevels(mp);
+	xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
+	xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
+	xfs_ialloc_compute_maxlevels(mp);
+	xfs_set_maxicount(mp);
+	mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog);
+
+	/*
+	 * XFS uses the uuid from the superblock as the unique
+	 * identifier for fsid.  We can not use the uuid from the volume
+	 * since a single partition filesystem is identical to a single
+	 * partition volume/filesystem.
+	 */
+	if ((mfsi_flags & XFS_MFSI_SECOND) == 0 &&
+	    (mp->m_flags & XFS_MOUNT_NOUUID) == 0) {
+		__uint64_t	ret64;
+		if (xfs_uuid_mount(mp)) {
+			error = XFS_ERROR(EINVAL);
 			goto error1;
 		}
+		uuid_mounted=1;
+		ret64 = uuid_hash64(&sbp->sb_uuid);
+		memcpy(&vfsp->vfs_fsid, &ret64, sizeof(ret64));
 	}
 
+	xfs_set_rw_sizes(mp);
+
+	/*
+	 * Set the inode cluster size based on the physical memory
+	 * size.  This may still be overridden by the file system
+	 * block size if it is larger than the chosen cluster size.
+	 */
+	if (xfs_physmem <= btoc(32 * 1024 * 1024)) { /* <= 32 MB */
+		mp->m_inode_cluster_size = XFS_INODE_SMALL_CLUSTER_SIZE;
+	} else {
+		mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
+	}
+	/*
+	 * Set whether we're using inode alignment.
+	 */
+	if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) &&
+	    mp->m_sb.sb_inoalignmt >=
+	    XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
+		mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1;
+	else
+		mp->m_inoalign_mask = 0;
+	/*
+	 * If we are using stripe alignment, check whether
+	 * the stripe unit is a multiple of the inode alignment
+	 */
+	if (mp->m_dalign && mp->m_inoalign_mask &&
+	    !(mp->m_dalign & mp->m_inoalign_mask))
+		mp->m_sinoalign = mp->m_dalign;
+	else
+		mp->m_sinoalign = 0;
+	/*
+	 * Check that the data (and log if separate) are an ok size.
+	 */
+	if ((error = xfs_size_checks(mp, mfsi_flags)))
+		goto error1;
+
 	/*
 	 * Initialize realtime fields in the mount structure
 	 */

linux-2.6-xfs-sane-filestreams-object-timeout.patch:

--- NEW FILE linux-2.6-xfs-sane-filestreams-object-timeout.patch ---
From: David Chinner <dgc at sgi.com>
Date: Thu, 16 Aug 2007 05:20:56 +0000 (+1000)
Subject: [XFS] Set filestreams object timeout to something sane.
X-Git-Url: http://oss.sgi.com/cgi-bin/gitweb.cgi?p=xfs%2Fxfs-2.6.git;a=commitdiff_plain;h=207358950497c7bdc63c37b6fa361108152816de;hp=c467ff2970951c2ec1bdbf7cb029f2a9b107dec0

[XFS] Set filestreams object timeout to something sane.

SGI-PV: 968554
SGI-Modid: xfs-linux-melb:xfs-kern:29303a

Signed-off-by: David Chinner <dgc at sgi.com>
Signed-off-by: Christoph Hellwig <hch at infradead.org>
Signed-off-by: Tim Shimmin <tes at sgi.com>
---

Index: linux-2.6.22.i386/fs/xfs/linux-2.6/xfs_globals.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/linux-2.6/xfs_globals.c
+++ linux-2.6.22.i386/fs/xfs/linux-2.6/xfs_globals.c
@@ -46,7 +46,7 @@ xfs_param_t xfs_params = {
 	.inherit_nosym	= {	0,		0,		1	},
 	.rotorstep	= {	1,		1,		255	},
 	.inherit_nodfrg	= {	0,		1,		1	},
-	.fstrm_timer	= {	1,		50,		3600*100},
+	.fstrm_timer	= {	1,		30*100,		3600*100},
 };
 
 /*


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.115
retrieving revision 1.116
diff -u -r1.115 -r1.116
--- kernel.spec	24 Aug 2007 01:45:55 -0000	1.115
+++ kernel.spec	24 Aug 2007 04:17:51 -0000	1.116
@@ -657,6 +657,14 @@
 Patch1230: linux-2.6-powerpc-spu-vicinity.patch
 Patch1300: linux-2.6-usb-suspend-classes.patch
 Patch1400: linux-2.6-smarter-relatime.patch
+Patch1500: linux-2.6-xfs-sane-filestreams-object-timeout.patch
+Patch1501: linux-2.6-xfs-filestreams-on-demand-MRU-reaping.patch
+Patch1502: linux-2.6-xfs-quota-hashtable-allocation-fix.patch
+Patch1503: linux-2.6-xfs-optimize-away-dmapi-tests.patch
+Patch1504: linux-2.6-xfs-optimize-away-realtime-tests.patch
+Patch1505: linux-2.6-xfs-refactor-xfs_mountfs.patch
+Patch1506: linux-2.6-xfs-fix-filestreams-free-func-cast.patch
+
 %endif
 
 BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root-%{_target_cpu}
@@ -1139,6 +1147,15 @@
 # implement smarter atime updates support.
 ApplyPatch linux-2.6-smarter-relatime.patch
 
+# xfs bugfixes & stack reduction
+ApplyPatch linux-2.6-xfs-sane-filestreams-object-timeout.patch
+ApplyPatch linux-2.6-xfs-filestreams-on-demand-MRU-reaping.patch
+ApplyPatch linux-2.6-xfs-quota-hashtable-allocation-fix.patch
+ApplyPatch linux-2.6-xfs-optimize-away-dmapi-tests.patch
+ApplyPatch linux-2.6-xfs-optimize-away-realtime-tests.patch
+ApplyPatch linux-2.6-xfs-refactor-xfs_mountfs.patch
+ApplyPatch linux-2.6-xfs-fix-filestreams-free-func-cast.patch
+
 #
 # misc small stuff to make things compile
 #
@@ -1747,6 +1764,9 @@
 
 
 %changelog
+* Thu Aug 23 2007 Eric Sandeen <sandeen at redhat.com>
+- Update xfs filesystem for bug fixes & stack reduction
+
 * Thu Aug 23 2007 John W. Linville <linville at redhat.com>
 - Update wireless-dev bits (mac80211, rt2x00, b43, ssb)
 - Add b43legacy driver




More information about the fedora-extras-commits mailing list