aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-06-27 02:04:50 -0400
committerBen Myers <bpm@sgi.com>2013-06-27 14:31:04 -0400
commit1baaed8fa955ab0d23aab24477dae566ed6a105b (patch)
treecbd1ce98e6779a70e8d289dc0266f183f31ff7da /fs/xfs
parentcca9f93a52d2ead50b5da59ca83d5f469ee4be5f (diff)
xfs: xfs_ifree doesn't need to modify the inode buffer
Long ago, bulkstat used to read inodes directly from the backing buffer for speed. This had the unfortunate problem of being cache incoherent with unlinks, and so xfs_ifree() had to mark the inode as free directly in the backing buffer. bulkstat was changed some time ago to use inode cache coherent lookups, and so will never see unlinked inodes in it's lookups. Hence xfs_ifree() does not need to touch the inode backing buffer anymore. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_inode.c32
1 files changed, 4 insertions, 28 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index d1f76da6f8bf..9ecfe1e559fc 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2048,8 +2048,6 @@ xfs_ifree(
2048 int error; 2048 int error;
2049 int delete; 2049 int delete;
2050 xfs_ino_t first_ino; 2050 xfs_ino_t first_ino;
2051 xfs_dinode_t *dip;
2052 xfs_buf_t *ibp;
2053 2051
2054 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 2052 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
2055 ASSERT(ip->i_d.di_nlink == 0); 2053 ASSERT(ip->i_d.di_nlink == 0);
@@ -2062,14 +2060,13 @@ xfs_ifree(
2062 * Pull the on-disk inode from the AGI unlinked list. 2060 * Pull the on-disk inode from the AGI unlinked list.
2063 */ 2061 */
2064 error = xfs_iunlink_remove(tp, ip); 2062 error = xfs_iunlink_remove(tp, ip);
2065 if (error != 0) { 2063 if (error)
2066 return error; 2064 return error;
2067 }
2068 2065
2069 error = xfs_difree(tp, ip->i_ino, flist, &delete, &first_ino); 2066 error = xfs_difree(tp, ip->i_ino, flist, &delete, &first_ino);
2070 if (error != 0) { 2067 if (error)
2071 return error; 2068 return error;
2072 } 2069
2073 ip->i_d.di_mode = 0; /* mark incore inode as free */ 2070 ip->i_d.di_mode = 0; /* mark incore inode as free */
2074 ip->i_d.di_flags = 0; 2071 ip->i_d.di_flags = 0;
2075 ip->i_d.di_dmevmask = 0; 2072 ip->i_d.di_dmevmask = 0;
@@ -2081,31 +2078,10 @@ xfs_ifree(
2081 * by reincarnations of this inode. 2078 * by reincarnations of this inode.
2082 */ 2079 */
2083 ip->i_d.di_gen++; 2080 ip->i_d.di_gen++;
2084
2085 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 2081 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
2086 2082
2087 error = xfs_imap_to_bp(ip->i_mount, tp, &ip->i_imap, &dip, &ibp, 2083 if (delete)
2088 0, 0);
2089 if (error)
2090 return error;
2091
2092 /*
2093 * Clear the on-disk di_mode. This is to prevent xfs_bulkstat
2094 * from picking up this inode when it is reclaimed (its incore state
2095 * initialzed but not flushed to disk yet). The in-core di_mode is
2096 * already cleared and a corresponding transaction logged.
2097 * The hack here just synchronizes the in-core to on-disk
2098 * di_mode value in advance before the actual inode sync to disk.
2099 * This is OK because the inode is already unlinked and would never
2100 * change its di_mode again for this inode generation.
2101 * This is a temporary hack that would require a proper fix
2102 * in the future.
2103 */
2104 dip->di_mode = 0;
2105
2106 if (delete) {
2107 error = xfs_ifree_cluster(ip, tp, first_ino); 2084 error = xfs_ifree_cluster(ip, tp, first_ino);
2108 }
2109 2085
2110 return error; 2086 return error;
2111} 2087}