aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iomap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_iomap.c')
-rw-r--r--fs/xfs/xfs_iomap.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 7f537663365b..add06b4e9a63 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -41,6 +41,7 @@
41#include "xfs_utils.h" 41#include "xfs_utils.h"
42#include "xfs_iomap.h" 42#include "xfs_iomap.h"
43#include "xfs_trace.h" 43#include "xfs_trace.h"
44#include "xfs_icache.h"
44 45
45 46
46#define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \ 47#define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \
@@ -373,7 +374,7 @@ xfs_iomap_write_delay(
373 xfs_extlen_t extsz; 374 xfs_extlen_t extsz;
374 int nimaps; 375 int nimaps;
375 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS]; 376 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS];
376 int prealloc, flushed = 0; 377 int prealloc;
377 int error; 378 int error;
378 379
379 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 380 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
@@ -434,31 +435,29 @@ retry:
434 } 435 }
435 436
436 /* 437 /*
437 * If bmapi returned us nothing, we got either ENOSPC or EDQUOT. For 438 * If bmapi returned us nothing, we got either ENOSPC or EDQUOT. Retry
438 * ENOSPC, * flush all other inodes with delalloc blocks to free up
439 * some of the excess reserved metadata space. For both cases, retry
440 * without EOF preallocation. 439 * without EOF preallocation.
441 */ 440 */
442 if (nimaps == 0) { 441 if (nimaps == 0) {
443 trace_xfs_delalloc_enospc(ip, offset, count); 442 trace_xfs_delalloc_enospc(ip, offset, count);
444 if (flushed) 443 if (prealloc) {
445 return XFS_ERROR(error ? error : ENOSPC); 444 prealloc = 0;
446 445 error = 0;
447 if (error == ENOSPC) { 446 goto retry;
448 xfs_iunlock(ip, XFS_ILOCK_EXCL);
449 xfs_flush_inodes(ip);
450 xfs_ilock(ip, XFS_ILOCK_EXCL);
451 } 447 }
452 448 return XFS_ERROR(error ? error : ENOSPC);
453 flushed = 1;
454 error = 0;
455 prealloc = 0;
456 goto retry;
457 } 449 }
458 450
459 if (!(imap[0].br_startblock || XFS_IS_REALTIME_INODE(ip))) 451 if (!(imap[0].br_startblock || XFS_IS_REALTIME_INODE(ip)))
460 return xfs_alert_fsblock_zero(ip, &imap[0]); 452 return xfs_alert_fsblock_zero(ip, &imap[0]);
461 453
454 /*
455 * Tag the inode as speculatively preallocated so we can reclaim this
456 * space on demand, if necessary.
457 */
458 if (prealloc)
459 xfs_inode_set_eofblocks_tag(ip);
460
462 *ret_imap = imap[0]; 461 *ret_imap = imap[0];
463 return 0; 462 return 0;
464} 463}