]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/2.6.35.8/xfs-properly-account-for-reclaimed-inodes.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.35.8 / xfs-properly-account-for-reclaimed-inodes.patch
1 From 081003fff467ea0e727f66d5d435b4f473a789b3 Mon Sep 17 00:00:00 2001
2 From: Johannes Weiner <hannes@cmpxchg.org>
3 Date: Fri, 1 Oct 2010 07:43:54 +0000
4 Subject: xfs: properly account for reclaimed inodes
5
6 From: Johannes Weiner <hannes@cmpxchg.org>
7
8 commit 081003fff467ea0e727f66d5d435b4f473a789b3 upstream.
9
10 When marking an inode reclaimable, a per-AG counter is increased, the
11 inode is tagged reclaimable in its per-AG tree, and, when this is the
12 first reclaimable inode in the AG, the AG entry in the per-mount tree
13 is also tagged.
14
15 When an inode is finally reclaimed, however, it is only deleted from
16 the per-AG tree. Neither the counter is decreased, nor is the parent
17 tree's AG entry untagged properly.
18
19 Since the tags in the per-mount tree are not cleared, the inode
20 shrinker iterates over all AGs that have had reclaimable inodes at one
21 point in time.
22
23 The counters on the other hand signal an increasing amount of slab
24 objects to reclaim. Since "70e60ce xfs: convert inode shrinker to
25 per-filesystem context" this is not a real issue anymore because the
26 shrinker bails out after one iteration.
27
28 But the problem was observable on a machine running v2.6.34, where the
29 reclaimable work increased and each process going into direct reclaim
30 eventually got stuck on the xfs inode shrinking path, trying to scan
31 several million objects.
32
33 Fix this by properly unwinding the reclaimable-state tracking of an
34 inode when it is reclaimed.
35
36 Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
37 Reviewed-by: Dave Chinner <dchinner@redhat.com>
38 Signed-off-by: Alex Elder <aelder@sgi.com>
39 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
40
41 ---
42 fs/xfs/linux-2.6/xfs_sync.c | 16 ++++++++++++----
43 fs/xfs/linux-2.6/xfs_sync.h | 1 +
44 fs/xfs/xfs_iget.c | 1 +
45 3 files changed, 14 insertions(+), 4 deletions(-)
46
47 --- a/fs/xfs/linux-2.6/xfs_sync.c
48 +++ b/fs/xfs/linux-2.6/xfs_sync.c
49 @@ -711,13 +711,10 @@ xfs_inode_set_reclaim_tag(
50 }
51
52 void
53 -__xfs_inode_clear_reclaim_tag(
54 - xfs_mount_t *mp,
55 +__xfs_inode_clear_reclaim(
56 xfs_perag_t *pag,
57 xfs_inode_t *ip)
58 {
59 - radix_tree_tag_clear(&pag->pag_ici_root,
60 - XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG);
61 pag->pag_ici_reclaimable--;
62 if (!pag->pag_ici_reclaimable) {
63 /* clear the reclaim tag from the perag radix tree */
64 @@ -731,6 +728,17 @@ __xfs_inode_clear_reclaim_tag(
65 }
66 }
67
68 +void
69 +__xfs_inode_clear_reclaim_tag(
70 + xfs_mount_t *mp,
71 + xfs_perag_t *pag,
72 + xfs_inode_t *ip)
73 +{
74 + radix_tree_tag_clear(&pag->pag_ici_root,
75 + XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG);
76 + __xfs_inode_clear_reclaim(pag, ip);
77 +}
78 +
79 /*
80 * Inodes in different states need to be treated differently, and the return
81 * value of xfs_iflush is not sufficient to get this right. The following table
82 --- a/fs/xfs/linux-2.6/xfs_sync.h
83 +++ b/fs/xfs/linux-2.6/xfs_sync.h
84 @@ -47,6 +47,7 @@ int xfs_reclaim_inodes(struct xfs_mount
85
86 void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
87 void __xfs_inode_set_reclaim_tag(struct xfs_perag *pag, struct xfs_inode *ip);
88 +void __xfs_inode_clear_reclaim(struct xfs_perag *pag, struct xfs_inode *ip);
89 void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag,
90 struct xfs_inode *ip);
91
92 --- a/fs/xfs/xfs_iget.c
93 +++ b/fs/xfs/xfs_iget.c
94 @@ -492,6 +492,7 @@ xfs_ireclaim(
95 write_lock(&pag->pag_ici_lock);
96 if (!radix_tree_delete(&pag->pag_ici_root, agino))
97 ASSERT(0);
98 + __xfs_inode_clear_reclaim(pag, ip);
99 write_unlock(&pag->pag_ici_lock);
100 xfs_perag_put(pag);
101