Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
Browse files Browse the repository at this point in the history
* 'for-linus' of git://oss.sgi.com/xfs/xfs:
  xfs: prevent bogus assert when trying to remove non-existent attribute
  xfs: clear XFS_IDIRTY_RELEASE on truncate down
  xfs: reset inode per-lifetime state when recycling it
  • Loading branch information
Linus Torvalds committed Jun 27, 2011
2 parents 375ac3e + 4a33821 commit 4699d44
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 6 deletions.
7 changes: 7 additions & 0 deletions fs/xfs/xfs_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,13 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
args.total = 0;
args.whichfork = XFS_ATTR_FORK;

/*
* we have no control over the attribute names that userspace passes us
* to remove, so we have to allow the name lookup prior to attribute
* removal to fail.
*/
args.op_flags = XFS_DA_OP_OKNOENT;

/*
* Attach the dquots to the inode.
*/
Expand Down
13 changes: 9 additions & 4 deletions fs/xfs/xfs_iget.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,16 +253,21 @@ xfs_iget_cache_hit(
rcu_read_lock();
spin_lock(&ip->i_flags_lock);

ip->i_flags &= ~XFS_INEW;
ip->i_flags |= XFS_IRECLAIMABLE;
__xfs_inode_set_reclaim_tag(pag, ip);
ip->i_flags &= ~(XFS_INEW | XFS_IRECLAIM);
ASSERT(ip->i_flags & XFS_IRECLAIMABLE);
trace_xfs_iget_reclaim_fail(ip);
goto out_error;
}

spin_lock(&pag->pag_ici_lock);
spin_lock(&ip->i_flags_lock);
ip->i_flags &= ~(XFS_IRECLAIMABLE | XFS_IRECLAIM);

/*
* Clear the per-lifetime state in the inode as we are now
* effectively a new inode and need to return to the initial
* state before reuse occurs.
*/
ip->i_flags &= ~XFS_IRECLAIM_RESET_FLAGS;
ip->i_flags |= XFS_INEW;
__xfs_inode_clear_reclaim_tag(mp, pag, ip);
inode->i_state = I_NEW;
Expand Down
10 changes: 10 additions & 0 deletions fs/xfs/xfs_inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,16 @@ static inline void xfs_ifunlock(xfs_inode_t *ip)
#define XFS_ITRUNCATED 0x0020 /* truncated down so flush-on-close */
#define XFS_IDIRTY_RELEASE 0x0040 /* dirty release already seen */

/*
* Per-lifetime flags need to be reset when re-using a reclaimable inode during
* inode lookup. Thi prevents unintended behaviour on the new inode from
* ocurring.
*/
#define XFS_IRECLAIM_RESET_FLAGS \
(XFS_IRECLAIMABLE | XFS_IRECLAIM | \
XFS_IDIRTY_RELEASE | XFS_ITRUNCATED | \
XFS_IFILESTREAM);

/*
* Flags for inode locking.
* Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield)
Expand Down
7 changes: 5 additions & 2 deletions fs/xfs/xfs_vnodeops.c
Original file line number Diff line number Diff line change
Expand Up @@ -960,8 +960,11 @@ xfs_release(
* be exposed to that problem.
*/
truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED);
if (truncated && VN_DIRTY(VFS_I(ip)) && ip->i_delayed_blks > 0)
xfs_flush_pages(ip, 0, -1, XBF_ASYNC, FI_NONE);
if (truncated) {
xfs_iflags_clear(ip, XFS_IDIRTY_RELEASE);
if (VN_DIRTY(VFS_I(ip)) && ip->i_delayed_blks > 0)
xfs_flush_pages(ip, 0, -1, XBF_ASYNC, FI_NONE);
}
}

if (ip->i_d.di_nlink == 0)
Expand Down

0 comments on commit 4699d44

Please sign in to comment.