Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 209977
b: refs/heads/master
c: 5b3eed7
h: refs/heads/master
i:
  209975: c18f793
v: v3
  • Loading branch information
Dave Chinner authored and Dave Chinner committed Aug 24, 2010
1 parent 4eae321 commit 4d3b82b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 24 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d17c701ce6a548a92f7f8a3cec20299465f36ee3
refs/heads/master: 5b3eed756cd37255cad1181bd86bfd0977e97953
49 changes: 26 additions & 23 deletions trunk/fs/xfs/xfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1914,6 +1914,11 @@ xfs_iunlink_remove(
return 0;
}

/*
* A big issue when freeing the inode cluster is is that we _cannot_ skip any
* inodes that are in memory - they all must be marked stale and attached to
* the cluster buffer.
*/
STATIC void
xfs_ifree_cluster(
xfs_inode_t *free_ip,
Expand Down Expand Up @@ -1945,8 +1950,6 @@ xfs_ifree_cluster(
}

for (j = 0; j < nbufs; j++, inum += ninodes) {
int found = 0;

blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum),
XFS_INO_TO_AGBNO(mp, inum));

Expand All @@ -1965,7 +1968,9 @@ xfs_ifree_cluster(
/*
* Walk the inodes already attached to the buffer and mark them
* stale. These will all have the flush locks held, so an
* in-memory inode walk can't lock them.
* in-memory inode walk can't lock them. By marking them all
* stale first, we will not attempt to lock them in the loop
* below as the XFS_ISTALE flag will be set.
*/
lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);
while (lip) {
Expand All @@ -1977,11 +1982,11 @@ xfs_ifree_cluster(
&iip->ili_flush_lsn,
&iip->ili_item.li_lsn);
xfs_iflags_set(iip->ili_inode, XFS_ISTALE);
found++;
}
lip = lip->li_bio_list;
}


/*
* For each inode in memory attempt to add it to the inode
* buffer and set it up for being staled on buffer IO
Expand All @@ -1993,6 +1998,7 @@ xfs_ifree_cluster(
* even trying to lock them.
*/
for (i = 0; i < ninodes; i++) {
retry:
read_lock(&pag->pag_ici_lock);
ip = radix_tree_lookup(&pag->pag_ici_root,
XFS_INO_TO_AGINO(mp, (inum + i)));
Expand All @@ -2003,38 +2009,36 @@ xfs_ifree_cluster(
continue;
}

/* don't try to lock/unlock the current inode */
/*
* Don't try to lock/unlock the current inode, but we
* _cannot_ skip the other inodes that we did not find
* in the list attached to the buffer and are not
* already marked stale. If we can't lock it, back off
* and retry.
*/
if (ip != free_ip &&
!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
read_unlock(&pag->pag_ici_lock);
continue;
delay(1);
goto retry;
}
read_unlock(&pag->pag_ici_lock);

if (!xfs_iflock_nowait(ip)) {
if (ip != free_ip)
xfs_iunlock(ip, XFS_ILOCK_EXCL);
continue;
}

xfs_iflock(ip);
xfs_iflags_set(ip, XFS_ISTALE);
if (xfs_inode_clean(ip)) {
ASSERT(ip != free_ip);
xfs_ifunlock(ip);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
continue;
}

/*
* we don't need to attach clean inodes or those only
* with unlogged changes (which we throw away, anyway).
*/
iip = ip->i_itemp;
if (!iip) {
/* inode with unlogged changes only */
if (!iip || xfs_inode_clean(ip)) {
ASSERT(ip != free_ip);
ip->i_update_core = 0;
xfs_ifunlock(ip);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
continue;
}
found++;

iip->ili_last_fields = iip->ili_format.ilf_fields;
iip->ili_format.ilf_fields = 0;
Expand All @@ -2049,8 +2053,7 @@ xfs_ifree_cluster(
xfs_iunlock(ip, XFS_ILOCK_EXCL);
}

if (found)
xfs_trans_stale_inode_buf(tp, bp);
xfs_trans_stale_inode_buf(tp, bp);
xfs_trans_binval(tp, bp);
}

Expand Down

0 comments on commit 4d3b82b

Please sign in to comment.