aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c77
1 files changed, 25 insertions, 52 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 365040f61d8..1252a844342 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -313,81 +313,54 @@ xfs_map_blocks(
313 struct xfs_mount *mp = ip->i_mount; 313 struct xfs_mount *mp = ip->i_mount;
314 xfs_fileoff_t offset_fsb, end_fsb; 314 xfs_fileoff_t offset_fsb, end_fsb;
315 int error = 0; 315 int error = 0;
316 int lockmode = 0;
317 int bmapi_flags = XFS_BMAPI_ENTIRE; 316 int bmapi_flags = XFS_BMAPI_ENTIRE;
318 int nimaps = 1; 317 int nimaps = 1;
319 318
320 if (XFS_FORCED_SHUTDOWN(mp)) 319 if (XFS_FORCED_SHUTDOWN(mp))
321 return -XFS_ERROR(EIO); 320 return -XFS_ERROR(EIO);
322 321
323 switch (type) { 322 if (type == IO_UNWRITTEN)
324 case IO_OVERWRITE:
325 lockmode = xfs_ilock_map_shared(ip);
326 break;
327 case IO_UNWRITTEN:
328 lockmode = XFS_ILOCK_EXCL;
329 bmapi_flags |= XFS_BMAPI_IGSTATE; 323 bmapi_flags |= XFS_BMAPI_IGSTATE;
330 xfs_ilock(ip, lockmode); 324
331 break; 325 if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
332 case IO_DELALLOC: 326 if (nonblocking)
333 lockmode = XFS_ILOCK_SHARED; 327 return -XFS_ERROR(EAGAIN);
334 328 xfs_ilock(ip, XFS_ILOCK_SHARED);
335 if (!xfs_ilock_nowait(ip, lockmode)) {
336 if (nonblocking)
337 return -XFS_ERROR(EAGAIN);
338 xfs_ilock(ip, lockmode);
339 }
340 break;
341 } 329 }
342 330
331 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
332 (ip->i_df.if_flags & XFS_IFEXTENTS));
343 ASSERT(offset <= mp->m_maxioffset); 333 ASSERT(offset <= mp->m_maxioffset);
334
344 if (offset + count > mp->m_maxioffset) 335 if (offset + count > mp->m_maxioffset)
345 count = mp->m_maxioffset - offset; 336 count = mp->m_maxioffset - offset;
346 end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); 337 end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
347 offset_fsb = XFS_B_TO_FSBT(mp, offset); 338 offset_fsb = XFS_B_TO_FSBT(mp, offset);
348
349 error = xfs_bmapi(NULL, ip, offset_fsb, end_fsb - offset_fsb, 339 error = xfs_bmapi(NULL, ip, offset_fsb, end_fsb - offset_fsb,
350 bmapi_flags, NULL, 0, imap, &nimaps, NULL); 340 bmapi_flags, NULL, 0, imap, &nimaps, NULL);
351 if (error) 341 xfs_iunlock(ip, XFS_ILOCK_SHARED);
352 goto out;
353
354 switch (type) {
355 case IO_UNWRITTEN:
356 /* If we found an extent, return it */
357 if (nimaps &&
358 (imap->br_startblock != HOLESTARTBLOCK) &&
359 (imap->br_startblock != DELAYSTARTBLOCK)) {
360 trace_xfs_map_blocks_found(ip, offset, count, type, imap);
361 break;
362 }
363 342
364 error = xfs_iomap_write_delay(ip, offset, count, imap); 343 if (error)
365 if (!error) 344 return -XFS_ERROR(error);
366 trace_xfs_map_blocks_alloc(ip, offset, count, type, imap);
367 break;
368 case IO_DELALLOC:
369 /* If we found an extent, return it */
370 xfs_iunlock(ip, lockmode);
371 lockmode = 0;
372
373 if (nimaps && !isnullstartblock(imap->br_startblock)) {
374 trace_xfs_map_blocks_found(ip, offset, count, type, imap);
375 break;
376 }
377 345
346 if (type == IO_DELALLOC &&
347 (!nimaps || isnullstartblock(imap->br_startblock))) {
378 error = xfs_iomap_write_allocate(ip, offset, count, imap); 348 error = xfs_iomap_write_allocate(ip, offset, count, imap);
379 if (!error) 349 if (!error)
380 trace_xfs_map_blocks_alloc(ip, offset, count, type, imap); 350 trace_xfs_map_blocks_alloc(ip, offset, count, type, imap);
381 break; 351 return -XFS_ERROR(error);
382 default:
383 if (nimaps)
384 trace_xfs_map_blocks_found(ip, offset, count, type, imap);
385 } 352 }
386 353
387out: 354#ifdef DEBUG
388 if (lockmode) 355 if (type == IO_UNWRITTEN) {
389 xfs_iunlock(ip, lockmode); 356 ASSERT(nimaps);
390 return -XFS_ERROR(error); 357 ASSERT(imap->br_startblock != HOLESTARTBLOCK);
358 ASSERT(imap->br_startblock != DELAYSTARTBLOCK);
359 }
360#endif
361 if (nimaps)
362 trace_xfs_map_blocks_found(ip, offset, count, type, imap);
363 return 0;
391} 364}
392 365
393STATIC int 366STATIC int