View | Details | Raw Unified | Return to bug 568319
Collapse All | Expand All

(-)linux-2.6.31-openSUSE-11.2/fs/xfs/linux-2.6/xfs_aops.c (-31 / +55 lines)
Lines 186-198 xfs_destroy_ioend( Link Here
186
}
186
}
187
187
188
/*
188
/*
189
 * Update on-disk file size now that data has been written to disk.
189
 * Update on-disk file size now that data has been written to disk.  The
190
 * The current in-memory file size is i_size.  If a write is beyond
190
 * current in-memory file size is i_size.  If a write is beyond eof i_new_size
191
 * eof i_new_size will be the intended file size until i_size is
191
 * will be the intended file size until i_size is updated.  If this write does
192
 * updated.  If this write does not extend all the way to the valid
192
 * not extend all the way to the valid file size then restrict this update to
193
 * file size then restrict this update to the end of the write.
193
 * the end of the write.
194
 *
195
 * This function does not block as blocking on the inode lock in IO completion
196
 * can lead to IO completion order dependency deadlocks.. If it can't get the
197
 * inode ilock it will return EAGAIN. Callers must handle this.
194
 */
198
 */
195
STATIC void
199
STATIC int
196
xfs_setfilesize(
200
xfs_setfilesize(
197
	xfs_ioend_t		*ioend)
201
	xfs_ioend_t		*ioend)
198
{
202
{
Lines 204-214 xfs_setfilesize( Link Here
204
	ASSERT(ioend->io_type != IOMAP_READ);
208
	ASSERT(ioend->io_type != IOMAP_READ);
205
209
206
	if (unlikely(ioend->io_error))
210
	if (unlikely(ioend->io_error))
207
		return;
211
		return 0;
208
212
209
	bsize = ioend->io_offset + ioend->io_size;
213
	bsize = ioend->io_offset + ioend->io_size;
210
214
211
	xfs_ilock(ip, XFS_ILOCK_EXCL);
215
	if (!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL))
216
		return EAGAIN;
212
217
213
	isize = MAX(ip->i_size, ip->i_new_size);
218
	isize = MAX(ip->i_size, ip->i_new_size);
214
	isize = MIN(isize, bsize);
219
	isize = MIN(isize, bsize);
Lines 221-226 xfs_setfilesize( Link Here
221
	}
226
	}
222
227
223
	xfs_iunlock(ip, XFS_ILOCK_EXCL);
228
	xfs_iunlock(ip, XFS_ILOCK_EXCL);
229
230
	return 0;
231
}
232
233
234
/*
235
 * Schedule IO completion handling on a xfsdatad if this was
236
 * the final hold on this ioend. If we are asked to wait,
237
 * flush the workqueue.
238
 */
239
STATIC void
240
xfs_finish_ioend(
241
	xfs_ioend_t	*ioend,
242
	int		wait)
243
{
244
	if (atomic_dec_and_test(&ioend->io_remaining)) {
245
		struct workqueue_struct *wq;
246
247
		wq = (ioend->io_type == IOMAP_UNWRITTEN) ?
248
			xfsconvertd_workqueue : xfsdatad_workqueue;
249
		queue_work(wq, &ioend->io_work);
250
		if (wait)
251
			flush_workqueue(wq);
252
	}
224
}
253
}
225
254
226
/*
255
/*
Lines 233-238 xfs_end_io( Link Here
233
	xfs_ioend_t		*ioend =
262
	xfs_ioend_t		*ioend =
234
		container_of(work, xfs_ioend_t, io_work);
263
		container_of(work, xfs_ioend_t, io_work);
235
	struct xfs_inode	*ip = XFS_I(ioend->io_inode);
264
	struct xfs_inode	*ip = XFS_I(ioend->io_inode);
265
	int		error;
266
236
267
237
	/*
268
	/*
238
	 * For unwritten extents we need to issue transactions to convert a
269
	 * For unwritten extents we need to issue transactions to convert a
Lines 240-246 xfs_end_io( Link Here
240
	 */
271
	 */
241
	if (ioend->io_type == IOMAP_UNWRITTEN &&
272
	if (ioend->io_type == IOMAP_UNWRITTEN &&
242
	    likely(!ioend->io_error && !XFS_FORCED_SHUTDOWN(ip->i_mount))) {
273
	    likely(!ioend->io_error && !XFS_FORCED_SHUTDOWN(ip->i_mount))) {
243
		int error;
244
274
245
		error = xfs_iomap_write_unwritten(ip, ioend->io_offset,
275
		error = xfs_iomap_write_unwritten(ip, ioend->io_offset,
246
						 ioend->io_size);
276
						 ioend->io_size);
Lines 252-281 xfs_end_io( Link Here
252
	 * We might have to update the on-disk file size after extending
282
	 * We might have to update the on-disk file size after extending
253
	 * writes.
283
	 * writes.
254
	 */
284
	 */
255
	if (ioend->io_type != IOMAP_READ)
285
	if (ioend->io_type != IOMAP_READ) {
256
		xfs_setfilesize(ioend);
286
		error = xfs_setfilesize(ioend);
257
	xfs_destroy_ioend(ioend);
287
		ASSERT(!error || error == EAGAIN);
258
}
288
 	}
259
289
260
/*
290
	/*
261
 * Schedule IO completion handling on a xfsdatad if this was
291
	 * If we didn't complete processing of the ioend, requeue it to the
262
 * the final hold on this ioend. If we are asked to wait,
292
	 * tail of the workqueue for another attempt later. Otherwise destroy
263
 * flush the workqueue.
293
	 * it.
264
 */
294
	 */
265
STATIC void
295
	if (error == EAGAIN) {
266
xfs_finish_ioend(
296
		atomic_inc(&ioend->io_remaining);
267
	xfs_ioend_t	*ioend,
297
		xfs_finish_ioend(ioend, 0);
268
	int		wait)
298
		/* ensure we don't spin on blocked ioends */
269
{
299
		delay(1);
270
	if (atomic_dec_and_test(&ioend->io_remaining)) {
300
	} else
271
		struct workqueue_struct *wq;
301
		xfs_destroy_ioend(ioend);
272
302
273
		wq = (ioend->io_type == IOMAP_UNWRITTEN) ?
274
			xfsconvertd_workqueue : xfsdatad_workqueue;
275
		queue_work(wq, &ioend->io_work);
276
		if (wait)
277
			flush_workqueue(wq);
278
	}
279
}
303
}
280
304
281
/*
305
/*

Return to bug 568319