public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* [REVIEW 1 of 4] Clean up i_flags handling
@ 2006-10-24  7:17 David Chinner
  2006-10-24 21:38 ` Christoph Hellwig
  0 siblings, 1 reply; 4+ messages in thread
From: David Chinner @ 2006-10-24  7:17 UTC (permalink / raw)
  To: xfs; +Cc: t-nagano, xfs-dev


-- 
Dave Chinner
Principal Engineer
SGI Australian Software Group

Clean up new iflags locking and flags handling.
---
 fs/xfs/linux-2.6/xfs_super.c |    4 +---
 fs/xfs/xfs_iget.c            |   20 ++++++--------------
 fs/xfs/xfs_inode.c           |   17 +++++------------
 fs/xfs/xfs_inode.h           |   41 +++++++++++++++++++++++++++++++++++++++++
 fs/xfs/xfs_vnodeops.c        |   10 ++++------
 5 files changed, 57 insertions(+), 35 deletions(-)

Index: 2.6.x-xfs-new/fs/xfs/linux-2.6/xfs_super.c
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/linux-2.6/xfs_super.c	2006-10-19 10:22:12.769108692 +1000
+++ 2.6.x-xfs-new/fs/xfs/linux-2.6/xfs_super.c	2006-10-19 10:25:07.330516048 +1000
@@ -227,9 +227,7 @@ xfs_initialize_vnode(
 		xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip);
 		xfs_set_inodeops(inode);
 
-		spin_lock(&ip->i_flags_lock);
-		ip->i_flags &= ~XFS_INEW;
-		spin_unlock(&ip->i_flags_lock);
+		xfs_iflags_clear(ip, XFS_INEW);
 		barrier();
 
 		unlock_new_inode(inode);
Index: 2.6.x-xfs-new/fs/xfs/xfs_iget.c
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_iget.c	2006-10-19 10:22:12.769108692 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_iget.c	2006-10-19 10:25:07.330516048 +1000
@@ -215,7 +215,7 @@ again:
 			 * If INEW is set this inode is being set up
 			 * we need to pause and try again.
 			 */
-			if (ip->i_flags & XFS_INEW) {
+			if (xfs_iflags_test(ip, XFS_INEW)) {
 				read_unlock(&ih->ih_lock);
 				delay(1);
 				XFS_STATS_INC(xs_ig_frecycle);
@@ -230,7 +230,7 @@ again:
 				 * on its way out of the system,
 				 * we need to pause and try again.
 				 */
-				if (ip->i_flags & XFS_IRECLAIM) {
+				if (xfs_iflags_test(ip, XFS_IRECLAIM)) {
 					read_unlock(&ih->ih_lock);
 					delay(1);
 					XFS_STATS_INC(xs_ig_frecycle);
@@ -243,9 +243,7 @@ again:
 
 				XFS_STATS_INC(xs_ig_found);
 
-				spin_lock(&ip->i_flags_lock);
-				ip->i_flags &= ~XFS_IRECLAIMABLE;
-				spin_unlock(&ip->i_flags_lock);
+				xfs_iflags_clear(ip, XFS_IRECLAIMABLE);
 				version = ih->ih_version;
 				read_unlock(&ih->ih_lock);
 				xfs_ihash_promote(ih, ip, version);
@@ -299,10 +297,7 @@ finish_inode:
 			if (lock_flags != 0)
 				xfs_ilock(ip, lock_flags);
 
-			spin_lock(&ip->i_flags_lock);
-			ip->i_flags &= ~XFS_ISTALE;
-			spin_unlock(&ip->i_flags_lock);
-
+			xfs_iflags_clear(ip, XFS_ISTALE);
 			vn_trace_exit(vp, "xfs_iget.found",
 						(inst_t *)__return_address);
 			goto return_ip;
@@ -371,10 +366,7 @@ finish_inode:
 	ih->ih_next = ip;
 	ip->i_udquot = ip->i_gdquot = NULL;
 	ih->ih_version++;
-	spin_lock(&ip->i_flags_lock);
-	ip->i_flags |= XFS_INEW;
-	spin_unlock(&ip->i_flags_lock);
-
+	xfs_iflags_set(ip, XFS_INEW);
 	write_unlock(&ih->ih_lock);
 
 	/*
@@ -625,7 +617,7 @@ xfs_iput_new(xfs_inode_t	*ip,
 	vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);
 
 	if ((ip->i_d.di_mode == 0)) {
-		ASSERT(!(ip->i_flags & XFS_IRECLAIMABLE));
+		ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE));
 		vn_mark_bad(vp);
 	}
 	if (inode->i_state & I_NEW)
Index: 2.6.x-xfs-new/fs/xfs/xfs_inode.c
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_inode.c	2006-10-19 10:22:12.769108692 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_inode.c	2006-10-19 10:25:07.334515530 +1000
@@ -2193,7 +2193,7 @@ xfs_ifree_cluster(
 			/* Inode not in memory or we found it already,
 			 * nothing to do
 			 */
-			if (!ip || (ip->i_flags & XFS_ISTALE)) {
+			if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) {
 				read_unlock(&ih->ih_lock);
 				continue;
 			}
@@ -2215,10 +2215,7 @@ xfs_ifree_cluster(
 
 			if (ip == free_ip) {
 				if (xfs_iflock_nowait(ip)) {
-					spin_lock(&ip->i_flags_lock);
-					ip->i_flags |= XFS_ISTALE;
-					spin_unlock(&ip->i_flags_lock);
-
+					xfs_iflags_set(ip, XFS_ISTALE);
 					if (xfs_inode_clean(ip)) {
 						xfs_ifunlock(ip);
 					} else {
@@ -2231,9 +2228,7 @@ xfs_ifree_cluster(
 
 			if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
 				if (xfs_iflock_nowait(ip)) {
-					spin_lock(&ip->i_flags_lock);
-					ip->i_flags |= XFS_ISTALE;
-					spin_unlock(&ip->i_flags_lock);
+					xfs_iflags_set(ip, XFS_ISTALE);
 
 					if (xfs_inode_clean(ip)) {
 						xfs_ifunlock(ip);
@@ -2263,9 +2258,7 @@ xfs_ifree_cluster(
 				AIL_LOCK(mp,s);
 				iip->ili_flush_lsn = iip->ili_item.li_lsn;
 				AIL_UNLOCK(mp, s);
-				spin_lock(&iip->ili_inode->i_flags_lock);
-				iip->ili_inode->i_flags |= XFS_ISTALE;
-				spin_unlock(&iip->ili_inode->i_flags_lock);
+				xfs_iflags_set(ip, XFS_ISTALE);
 				pre_flushed++;
 			}
 			lip = lip->li_bio_list;
@@ -2764,7 +2757,7 @@ xfs_iunpin(
 		struct inode *inode = NULL;
 
 		spin_lock(&ip->i_flags_lock);
-		if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) {
+		if (!__xfs_iflags_test(ip, XFS_IRECLAIM|XFS_IRECLAIMABLE)) {
 			bhv_vnode_t	*vp = XFS_ITOV_NULL(ip);
 
 			/* make sync come back and flush this inode */
Index: 2.6.x-xfs-new/fs/xfs/xfs_inode.h
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_inode.h	2006-10-19 10:22:12.769108692 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_inode.h	2006-10-19 10:25:07.334515530 +1000
@@ -305,6 +305,47 @@ typedef struct xfs_inode {
 #endif
 } xfs_inode_t;
 
+
+/*
+ * i_flags helper functions
+ */
+static inline void
+__xfs_iflags_set(xfs_inode_t *ip, unsigned short flags)
+{
+	ip->i_flags |= flags;
+}
+
+static inline void
+xfs_iflags_set(xfs_inode_t *ip, unsigned short flags)
+{
+	spin_lock(&ip->i_flags_lock);
+	__xfs_iflags_set(ip, flags);
+	spin_unlock(&ip->i_flags_lock);
+}
+
+static inline void
+xfs_iflags_clear(xfs_inode_t *ip, unsigned short flags)
+{
+	spin_lock(&ip->i_flags_lock);
+	ip->i_flags &= ~flags;
+	spin_unlock(&ip->i_flags_lock);
+}
+
+static inline int
+__xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
+{
+	return (ip->i_flags & flags);
+}
+
+static inline int
+xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
+{
+	int ret;
+	spin_lock(&ip->i_flags_lock);
+	ret = __xfs_iflags_test(ip, flags);
+	spin_unlock(&ip->i_flags_lock);
+	return ret;
+}
 #endif	/* __KERNEL__ */
 
 
Index: 2.6.x-xfs-new/fs/xfs/xfs_vnodeops.c
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_vnodeops.c	2006-10-19 10:22:12.769108692 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_vnodeops.c	2006-10-19 10:25:07.338515013 +1000
@@ -3844,9 +3844,7 @@ xfs_reclaim(
 		XFS_MOUNT_ILOCK(mp);
 		vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip));
 		list_add_tail(&ip->i_reclaim, &mp->m_del_inodes);
-		spin_lock(&ip->i_flags_lock);
-		ip->i_flags |= XFS_IRECLAIMABLE;
-		spin_unlock(&ip->i_flags_lock);
+		xfs_iflags_set(ip, XFS_IRECLAIMABLE);
 		XFS_MOUNT_IUNLOCK(mp);
 	}
 	return 0;
@@ -3872,8 +3870,8 @@ xfs_finish_reclaim(
 	 */
 	write_lock(&ih->ih_lock);
 	spin_lock(&ip->i_flags_lock);
-	if ((ip->i_flags & XFS_IRECLAIM) ||
-	    (!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) {
+	if (__xfs_iflags_test(ip, XFS_IRECLAIM) ||
+	    (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) {
 		spin_unlock(&ip->i_flags_lock);
 		write_unlock(&ih->ih_lock);
 		if (locked) {
@@ -3882,7 +3880,7 @@ xfs_finish_reclaim(
 		}
 		return 1;
 	}
-	ip->i_flags |= XFS_IRECLAIM;
+	__xfs_iflags_set(ip, XFS_IRECLAIM);
 	spin_unlock(&ip->i_flags_lock);
 	write_unlock(&ih->ih_lock);
 

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

* Re: [REVIEW 1 of 4] Clean up i_flags handling
  2006-10-24  7:17 [REVIEW 1 of 4] Clean up i_flags handling David Chinner
@ 2006-10-24 21:38 ` Christoph Hellwig
  2006-10-24 22:15   ` Shailendra Tripathi
  2006-10-26  9:46   ` David Chinner
  0 siblings, 2 replies; 4+ messages in thread
From: Christoph Hellwig @ 2006-10-24 21:38 UTC (permalink / raw)
  To: David Chinner; +Cc: xfs, t-nagano, xfs-dev

> +/*
> + * i_flags helper functions
> + */
> +static inline void
> +__xfs_iflags_set(xfs_inode_t *ip, unsigned short flags)
> +{
> +	ip->i_flags |= flags;
> +}
> +
> +static inline void
> +xfs_iflags_set(xfs_inode_t *ip, unsigned short flags)
> +{
> +	spin_lock(&ip->i_flags_lock);
> +	__xfs_iflags_set(ip, flags);
> +	spin_unlock(&ip->i_flags_lock);
> +}

This is not actually 

> +
> +static inline void
> +xfs_iflags_clear(xfs_inode_t *ip, unsigned short flags)
> +{
> +	spin_lock(&ip->i_flags_lock);
> +	ip->i_flags &= ~flags;
> +	spin_unlock(&ip->i_flags_lock);
> +}
> +
> +static inline int
> +__xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
> +{
> +	return (ip->i_flags & flags);
> +}
> +
> +static inline int
> +xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
> +{
> +	int ret;
> +	spin_lock(&ip->i_flags_lock);
> +	ret = __xfs_iflags_test(ip, flags);
> +	spin_unlock(&ip->i_flags_lock);
> +	return ret;

This is not actually guaranteed to work on machiens with very weak
memory ordering.  Please use the *_bit routines from bitops.h instead.

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

* Re: [REVIEW 1 of 4] Clean up i_flags handling
  2006-10-24 21:38 ` Christoph Hellwig
@ 2006-10-24 22:15   ` Shailendra Tripathi
  2006-10-26  9:46   ` David Chinner
  1 sibling, 0 replies; 4+ messages in thread
From: Shailendra Tripathi @ 2006-10-24 22:15 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: David Chinner, xfs, t-nagano, xfs-dev

Christoph Hellwig wrote:
>> +/*
>> + * i_flags helper functions
>> + */
>> +static inline void
>> +__xfs_iflags_set(xfs_inode_t *ip, unsigned short flags)
>> +{
>> +	ip->i_flags |= flags;
>> +}
>> +
>> +static inline void
>> +xfs_iflags_set(xfs_inode_t *ip, unsigned short flags)
>> +{
>> +	spin_lock(&ip->i_flags_lock);
>> +	__xfs_iflags_set(ip, flags);
>> +	spin_unlock(&ip->i_flags_lock);
>> +}
>>     
>
> This is not actually 
>
>   
>> +
>> +static inline void
>> +xfs_iflags_clear(xfs_inode_t *ip, unsigned short flags)
>> +{
>> +	spin_lock(&ip->i_flags_lock);
>> +	ip->i_flags &= ~flags;
>> +	spin_unlock(&ip->i_flags_lock);
>> +}
>> +
>> +static inline int
>> +__xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
>> +{
>> +	return (ip->i_flags & flags);
>> +}
>> +
>> +static inline int
>> +xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
>> +{
>> +	int ret;
>> +	spin_lock(&ip->i_flags_lock);
>> +	ret = __xfs_iflags_test(ip, flags);
>> +	spin_unlock(&ip->i_flags_lock);
>> +	return ret;
>>     
>
> This is not actually guaranteed to work on machiens with very weak
> memory ordering.  Please use the *_bit routines from bitops.h instead.
>
>   
Isn't true that UNLOCK and LOCK in the given order imply full barrier 
Chris ?
As the flag is modified only within the lock/unlock pair, if one tries 
to access the field (test it), it should be like
LOCK IP
modify ...
UNLOCK IP  -----|
                           |  --->  This pair should act as a full 
barrier. 
LOCK IP       -----|
read ...           
UNLOCK IP

-shailendra

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

* Re: [REVIEW 1 of 4] Clean up i_flags handling
  2006-10-24 21:38 ` Christoph Hellwig
  2006-10-24 22:15   ` Shailendra Tripathi
@ 2006-10-26  9:46   ` David Chinner
  1 sibling, 0 replies; 4+ messages in thread
From: David Chinner @ 2006-10-26  9:46 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: David Chinner, xfs, t-nagano, xfs-dev

On Tue, Oct 24, 2006 at 10:38:22PM +0100, Christoph Hellwig wrote:
> > +static inline int
> > +__xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
> > +{
> > +	return (ip->i_flags & flags);
> > +}
> > +
> > +static inline int
> > +xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
> > +{
> > +	int ret;
> > +	spin_lock(&ip->i_flags_lock);
> > +	ret = __xfs_iflags_test(ip, flags);
> > +	spin_unlock(&ip->i_flags_lock);
> > +	return ret;
> 
> This is not actually guaranteed to work on machiens with very weak
> memory ordering.  Please use the *_bit routines from bitops.h instead.

Hmm - don't you have that the wrong way around?

Documentation/memory-barriers.txt:

...
Therefore, from (1), (2) and (4) an UNLOCK followed by an unconditional LOCK is
equivalent to a full barrier, but a LOCK followed by an UNLOCK is not.
....

But the bitops don't guarantee ordering or barriers e.g. from
include/asm-i386/bitops.h:

/**
 * set_bit - Atomically set a bit in memory
 * @nr: the bit to set
 * @addr: the address to start counting from
 *
 * This function is atomic and may not be reordered.  See __set_bit()
 * if you do not require the atomic guarantees.
 *
 * Note: there are no guarantees that this function will not be reordered
 * on non x86 architectures, so if you are writting portable code,
 * make sure not to rely on its reordering guarantees.
 *
 * Note that @nr may be almost arbitrarily large; this function is not
 * restricted to acting on a single-word quantity.
 */

So I think the code is fine as it stands.

Cheers,

Dave.
-- 
Dave Chinner
Principal Engineer
SGI Australian Software Group

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

end of thread, other threads:[~2006-10-26  9:47 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-24  7:17 [REVIEW 1 of 4] Clean up i_flags handling David Chinner
2006-10-24 21:38 ` Christoph Hellwig
2006-10-24 22:15   ` Shailendra Tripathi
2006-10-26  9:46   ` David Chinner

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