aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_sync.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_sync.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c75
1 files changed, 18 insertions, 57 deletions
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index ee1648b179f7..fb5cca3df840 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -63,25 +63,16 @@ xfs_sync_inodes_ag(
63 int error = 0; 63 int error = 0;
64 int last_error = 0; 64 int last_error = 0;
65 int fflag = XFS_B_ASYNC; 65 int fflag = XFS_B_ASYNC;
66 int lock_flags = XFS_ILOCK_SHARED;
67 66
68 if (flags & SYNC_DELWRI) 67 if (flags & SYNC_DELWRI)
69 fflag = XFS_B_DELWRI; 68 fflag = XFS_B_DELWRI;
70 if (flags & SYNC_WAIT) 69 if (flags & SYNC_WAIT)
71 fflag = 0; /* synchronous overrides all */ 70 fflag = 0; /* synchronous overrides all */
72 71
73 if (flags & SYNC_DELWRI) {
74 /*
75 * We need the I/O lock if we're going to call any of
76 * the flush/inval routines.
77 */
78 lock_flags |= XFS_IOLOCK_SHARED;
79 }
80
81 do { 72 do {
82 struct inode *inode; 73 struct inode *inode;
83 boolean_t inode_refed;
84 xfs_inode_t *ip = NULL; 74 xfs_inode_t *ip = NULL;
75 int lock_flags = XFS_ILOCK_SHARED;
85 76
86 /* 77 /*
87 * use a gang lookup to find the next inode in the tree 78 * use a gang lookup to find the next inode in the tree
@@ -109,22 +100,6 @@ xfs_sync_inodes_ag(
109 break; 100 break;
110 } 101 }
111 102
112 /*
113 * skip inodes in reclaim. Let xfs_syncsub do that for
114 * us so we don't need to worry.
115 */
116 if (xfs_iflags_test(ip, (XFS_IRECLAIM|XFS_IRECLAIMABLE))) {
117 read_unlock(&pag->pag_ici_lock);
118 continue;
119 }
120
121 /* bad inodes are dealt with elsewhere */
122 inode = VFS_I(ip);
123 if (is_bad_inode(inode)) {
124 read_unlock(&pag->pag_ici_lock);
125 continue;
126 }
127
128 /* nothing to sync during shutdown */ 103 /* nothing to sync during shutdown */
129 if (XFS_FORCED_SHUTDOWN(mp)) { 104 if (XFS_FORCED_SHUTDOWN(mp)) {
130 read_unlock(&pag->pag_ici_lock); 105 read_unlock(&pag->pag_ici_lock);
@@ -132,42 +107,34 @@ xfs_sync_inodes_ag(
132 } 107 }
133 108
134 /* 109 /*
135 * If we can't get a reference on the VFS_I, the inode must be 110 * If we can't get a reference on the inode, it must be
136 * in reclaim. If we can get the inode lock without blocking, 111 * in reclaim. Leave it for the reclaim code to flush.
137 * it is safe to flush the inode because we hold the tree lock
138 * and xfs_iextract will block right now. Hence if we lock the
139 * inode while holding the tree lock, xfs_ireclaim() is
140 * guaranteed to block on the inode lock we now hold and hence
141 * it is safe to reference the inode until we drop the inode
142 * locks completely.
143 */ 112 */
144 inode_refed = B_FALSE; 113 inode = VFS_I(ip);
145 if (igrab(inode)) { 114 if (!igrab(inode)) {
146 read_unlock(&pag->pag_ici_lock);
147 xfs_ilock(ip, lock_flags);
148 inode_refed = B_TRUE;
149 } else {
150 if (!xfs_ilock_nowait(ip, lock_flags)) {
151 /* leave it to reclaim */
152 read_unlock(&pag->pag_ici_lock);
153 continue;
154 }
155 read_unlock(&pag->pag_ici_lock); 115 read_unlock(&pag->pag_ici_lock);
116 continue;
117 }
118 read_unlock(&pag->pag_ici_lock);
119
120 /* bad inodes are dealt with elsewhere */
121 if (is_bad_inode(inode)) {
122 IRELE(ip);
123 continue;
156 } 124 }
157 125
158 /* 126 /*
159 * If we have to flush data or wait for I/O completion 127 * If we have to flush data or wait for I/O completion
160 * we need to drop the ilock that we currently hold. 128 * we need to hold the iolock.
161 * If we need to drop the lock, insert a marker if we
162 * have not already done so.
163 */ 129 */
164 if ((flags & SYNC_DELWRI) && VN_DIRTY(inode)) { 130 if ((flags & SYNC_DELWRI) && VN_DIRTY(inode)) {
165 xfs_iunlock(ip, XFS_ILOCK_SHARED); 131 xfs_ilock(ip, XFS_IOLOCK_SHARED);
132 lock_flags |= XFS_IOLOCK_SHARED;
166 error = xfs_flush_pages(ip, 0, -1, fflag, FI_NONE); 133 error = xfs_flush_pages(ip, 0, -1, fflag, FI_NONE);
167 if (flags & SYNC_IOWAIT) 134 if (flags & SYNC_IOWAIT)
168 vn_iowait(ip); 135 vn_iowait(ip);
169 xfs_ilock(ip, XFS_ILOCK_SHARED);
170 } 136 }
137 xfs_ilock(ip, XFS_ILOCK_SHARED);
171 138
172 if ((flags & SYNC_ATTR) && !xfs_inode_clean(ip)) { 139 if ((flags & SYNC_ATTR) && !xfs_inode_clean(ip)) {
173 if (flags & SYNC_WAIT) { 140 if (flags & SYNC_WAIT) {
@@ -183,13 +150,7 @@ xfs_sync_inodes_ag(
183 xfs_ifunlock(ip); 150 xfs_ifunlock(ip);
184 } 151 }
185 } 152 }
186 153 xfs_iput(ip, lock_flags);
187 if (lock_flags)
188 xfs_iunlock(ip, lock_flags);
189
190 if (inode_refed) {
191 IRELE(ip);
192 }
193 154
194 if (error) 155 if (error)
195 last_error = error; 156 last_error = error;