* [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