Commit 4699d442 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs

* '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
parents 375ac3e0 4a338212
...@@ -489,6 +489,13 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) ...@@ -489,6 +489,13 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
args.total = 0; args.total = 0;
args.whichfork = XFS_ATTR_FORK; 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. * Attach the dquots to the inode.
*/ */
......
...@@ -253,16 +253,21 @@ xfs_iget_cache_hit( ...@@ -253,16 +253,21 @@ xfs_iget_cache_hit(
rcu_read_lock(); rcu_read_lock();
spin_lock(&ip->i_flags_lock); spin_lock(&ip->i_flags_lock);
ip->i_flags &= ~XFS_INEW; ip->i_flags &= ~(XFS_INEW | XFS_IRECLAIM);
ip->i_flags |= XFS_IRECLAIMABLE; ASSERT(ip->i_flags & XFS_IRECLAIMABLE);
__xfs_inode_set_reclaim_tag(pag, ip);
trace_xfs_iget_reclaim_fail(ip); trace_xfs_iget_reclaim_fail(ip);
goto out_error; goto out_error;
} }
spin_lock(&pag->pag_ici_lock); spin_lock(&pag->pag_ici_lock);
spin_lock(&ip->i_flags_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; ip->i_flags |= XFS_INEW;
__xfs_inode_clear_reclaim_tag(mp, pag, ip); __xfs_inode_clear_reclaim_tag(mp, pag, ip);
inode->i_state = I_NEW; inode->i_state = I_NEW;
......
...@@ -383,6 +383,16 @@ static inline void xfs_ifunlock(xfs_inode_t *ip) ...@@ -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_ITRUNCATED 0x0020 /* truncated down so flush-on-close */
#define XFS_IDIRTY_RELEASE 0x0040 /* dirty release already seen */ #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. * Flags for inode locking.
* Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield) * Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield)
......
...@@ -960,9 +960,12 @@ xfs_release( ...@@ -960,9 +960,12 @@ xfs_release(
* be exposed to that problem. * be exposed to that problem.
*/ */
truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED); truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED);
if (truncated && VN_DIRTY(VFS_I(ip)) && ip->i_delayed_blks > 0) 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); xfs_flush_pages(ip, 0, -1, XBF_ASYNC, FI_NONE);
} }
}
if (ip->i_d.di_nlink == 0) if (ip->i_d.di_nlink == 0)
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment