aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-04-13 17:35:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-13 17:35:13 -0400
commit3c1795cc4bd9d57281bebc314315b8afa217b9c7 (patch)
tree97972fe4970e5074ec3944c7cd5179fb2bfe5b36 /fs/xfs
parent80a04d3f2f94fb68b5df05e3ac6697130bc3467a (diff)
parentdc2a5536d633dd2318f82f3d5ad3c9e43cfc21d7 (diff)
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
* 'for-linus' of git://oss.sgi.com/xfs/xfs: xfs: remove xfs_flush_space xfs: flush delayed allcoation blocks on ENOSPC in create xfs: block callers of xfs_flush_inodes() correctly xfs: make inode flush at ENOSPC synchronous xfs: use xfs_sync_inodes() for device flushing xfs: inform the xfsaild of the push target before sleeping xfs: prevent unwritten extent conversion from blocking I/O completion xfs: fix double free of inode xfs: validate log feature fields correctly
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c38
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c9
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.c14
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c18
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c78
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.h9
-rw-r--r--fs/xfs/xfs_iget.c23
-rw-r--r--fs/xfs/xfs_iomap.c61
-rw-r--r--fs/xfs/xfs_iomap.h3
-rw-r--r--fs/xfs/xfs_log.c78
-rw-r--r--fs/xfs/xfs_mount.h2
-rw-r--r--fs/xfs/xfs_vnodeops.c7
13 files changed, 180 insertions, 161 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index c13f67300fe7..7ec89fc05b2b 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -153,23 +153,6 @@ xfs_find_bdev_for_inode(
153} 153}
154 154
155/* 155/*
156 * Schedule IO completion handling on a xfsdatad if this was
157 * the final hold on this ioend. If we are asked to wait,
158 * flush the workqueue.
159 */
160STATIC void
161xfs_finish_ioend(
162 xfs_ioend_t *ioend,
163 int wait)
164{
165 if (atomic_dec_and_test(&ioend->io_remaining)) {
166 queue_work(xfsdatad_workqueue, &ioend->io_work);
167 if (wait)
168 flush_workqueue(xfsdatad_workqueue);
169 }
170}
171
172/*
173 * We're now finished for good with this ioend structure. 156 * We're now finished for good with this ioend structure.
174 * Update the page state via the associated buffer_heads, 157 * Update the page state via the associated buffer_heads,
175 * release holds on the inode and bio, and finally free 158 * release holds on the inode and bio, and finally free
@@ -310,6 +293,27 @@ xfs_end_bio_read(
310} 293}
311 294
312/* 295/*
296 * Schedule IO completion handling on a xfsdatad if this was
297 * the final hold on this ioend. If we are asked to wait,
298 * flush the workqueue.
299 */
300STATIC void
301xfs_finish_ioend(
302 xfs_ioend_t *ioend,
303 int wait)
304{
305 if (atomic_dec_and_test(&ioend->io_remaining)) {
306 struct workqueue_struct *wq = xfsdatad_workqueue;
307 if (ioend->io_work.func == xfs_end_bio_unwritten)
308 wq = xfsconvertd_workqueue;
309
310 queue_work(wq, &ioend->io_work);
311 if (wait)
312 flush_workqueue(wq);
313 }
314}
315
316/*
313 * Allocate and initialise an IO completion structure. 317 * Allocate and initialise an IO completion structure.
314 * We need to track unwritten extent write completion here initially. 318 * We need to track unwritten extent write completion here initially.
315 * We'll need to extend this for updating the ondisk inode size later 319 * We'll need to extend this for updating the ondisk inode size later
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index 1dd528849755..221b3e66ceef 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -19,6 +19,7 @@
19#define __XFS_AOPS_H__ 19#define __XFS_AOPS_H__
20 20
21extern struct workqueue_struct *xfsdatad_workqueue; 21extern struct workqueue_struct *xfsdatad_workqueue;
22extern struct workqueue_struct *xfsconvertd_workqueue;
22extern mempool_t *xfs_ioend_pool; 23extern mempool_t *xfs_ioend_pool;
23 24
24/* 25/*
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index aa1016bb9134..e28800a9f2b5 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -51,6 +51,7 @@ static struct shrinker xfs_buf_shake = {
51 51
52static struct workqueue_struct *xfslogd_workqueue; 52static struct workqueue_struct *xfslogd_workqueue;
53struct workqueue_struct *xfsdatad_workqueue; 53struct workqueue_struct *xfsdatad_workqueue;
54struct workqueue_struct *xfsconvertd_workqueue;
54 55
55#ifdef XFS_BUF_TRACE 56#ifdef XFS_BUF_TRACE
56void 57void
@@ -1775,6 +1776,7 @@ xfs_flush_buftarg(
1775 xfs_buf_t *bp, *n; 1776 xfs_buf_t *bp, *n;
1776 int pincount = 0; 1777 int pincount = 0;
1777 1778
1779 xfs_buf_runall_queues(xfsconvertd_workqueue);
1778 xfs_buf_runall_queues(xfsdatad_workqueue); 1780 xfs_buf_runall_queues(xfsdatad_workqueue);
1779 xfs_buf_runall_queues(xfslogd_workqueue); 1781 xfs_buf_runall_queues(xfslogd_workqueue);
1780 1782
@@ -1831,9 +1833,15 @@ xfs_buf_init(void)
1831 if (!xfsdatad_workqueue) 1833 if (!xfsdatad_workqueue)
1832 goto out_destroy_xfslogd_workqueue; 1834 goto out_destroy_xfslogd_workqueue;
1833 1835
1836 xfsconvertd_workqueue = create_workqueue("xfsconvertd");
1837 if (!xfsconvertd_workqueue)
1838 goto out_destroy_xfsdatad_workqueue;
1839
1834 register_shrinker(&xfs_buf_shake); 1840 register_shrinker(&xfs_buf_shake);
1835 return 0; 1841 return 0;
1836 1842
1843 out_destroy_xfsdatad_workqueue:
1844 destroy_workqueue(xfsdatad_workqueue);
1837 out_destroy_xfslogd_workqueue: 1845 out_destroy_xfslogd_workqueue:
1838 destroy_workqueue(xfslogd_workqueue); 1846 destroy_workqueue(xfslogd_workqueue);
1839 out_free_buf_zone: 1847 out_free_buf_zone:
@@ -1849,6 +1857,7 @@ void
1849xfs_buf_terminate(void) 1857xfs_buf_terminate(void)
1850{ 1858{
1851 unregister_shrinker(&xfs_buf_shake); 1859 unregister_shrinker(&xfs_buf_shake);
1860 destroy_workqueue(xfsconvertd_workqueue);
1852 destroy_workqueue(xfsdatad_workqueue); 1861 destroy_workqueue(xfsdatad_workqueue);
1853 destroy_workqueue(xfslogd_workqueue); 1862 destroy_workqueue(xfslogd_workqueue);
1854 kmem_zone_destroy(xfs_buf_zone); 1863 kmem_zone_destroy(xfs_buf_zone);
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c
index 5aeb77776961..08be36d7326c 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.c
@@ -74,14 +74,14 @@ xfs_flush_pages(
74 74
75 if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) { 75 if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
76 xfs_iflags_clear(ip, XFS_ITRUNCATED); 76 xfs_iflags_clear(ip, XFS_ITRUNCATED);
77 ret = filemap_fdatawrite(mapping); 77 ret = -filemap_fdatawrite(mapping);
78 if (flags & XFS_B_ASYNC)
79 return -ret;
80 ret2 = filemap_fdatawait(mapping);
81 if (!ret)
82 ret = ret2;
83 } 78 }
84 return -ret; 79 if (flags & XFS_B_ASYNC)
80 return ret;
81 ret2 = xfs_wait_on_pages(ip, first, last);
82 if (!ret)
83 ret = ret2;
84 return ret;
85} 85}
86 86
87int 87int
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 7e90daa0d1d1..9142192ccbe6 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -751,10 +751,26 @@ start:
751 goto relock; 751 goto relock;
752 } 752 }
753 } else { 753 } else {
754 int enospc = 0;
755 ssize_t ret2 = 0;
756
757write_retry:
754 xfs_rw_enter_trace(XFS_WRITE_ENTER, xip, (void *)iovp, segs, 758 xfs_rw_enter_trace(XFS_WRITE_ENTER, xip, (void *)iovp, segs,
755 *offset, ioflags); 759 *offset, ioflags);
756 ret = generic_file_buffered_write(iocb, iovp, segs, 760 ret2 = generic_file_buffered_write(iocb, iovp, segs,
757 pos, offset, count, ret); 761 pos, offset, count, ret);
762 /*
763 * if we just got an ENOSPC, flush the inode now we
764 * aren't holding any page locks and retry *once*
765 */
766 if (ret2 == -ENOSPC && !enospc) {
767 error = xfs_flush_pages(xip, 0, -1, 0, FI_NONE);
768 if (error)
769 goto out_unlock_internal;
770 enospc = 1;
771 goto write_retry;
772 }
773 ret = ret2;
758 } 774 }
759 775
760 current->backing_dev_info = NULL; 776 current->backing_dev_info = NULL;
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index a608e72fa405..f7ba76633c29 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -62,12 +62,6 @@ xfs_sync_inodes_ag(
62 uint32_t first_index = 0; 62 uint32_t first_index = 0;
63 int error = 0; 63 int error = 0;
64 int last_error = 0; 64 int last_error = 0;
65 int fflag = XFS_B_ASYNC;
66
67 if (flags & SYNC_DELWRI)
68 fflag = XFS_B_DELWRI;
69 if (flags & SYNC_WAIT)
70 fflag = 0; /* synchronous overrides all */
71 65
72 do { 66 do {
73 struct inode *inode; 67 struct inode *inode;
@@ -128,11 +122,23 @@ xfs_sync_inodes_ag(
128 * If we have to flush data or wait for I/O completion 122 * If we have to flush data or wait for I/O completion
129 * we need to hold the iolock. 123 * we need to hold the iolock.
130 */ 124 */
131 if ((flags & SYNC_DELWRI) && VN_DIRTY(inode)) { 125 if (flags & SYNC_DELWRI) {
132 xfs_ilock(ip, XFS_IOLOCK_SHARED); 126 if (VN_DIRTY(inode)) {
133 lock_flags |= XFS_IOLOCK_SHARED; 127 if (flags & SYNC_TRYLOCK) {
134 error = xfs_flush_pages(ip, 0, -1, fflag, FI_NONE); 128 if (xfs_ilock_nowait(ip, XFS_IOLOCK_SHARED))
135 if (flags & SYNC_IOWAIT) 129 lock_flags |= XFS_IOLOCK_SHARED;
130 } else {
131 xfs_ilock(ip, XFS_IOLOCK_SHARED);
132 lock_flags |= XFS_IOLOCK_SHARED;
133 }
134 if (lock_flags & XFS_IOLOCK_SHARED) {
135 error = xfs_flush_pages(ip, 0, -1,
136 (flags & SYNC_WAIT) ? 0
137 : XFS_B_ASYNC,
138 FI_NONE);
139 }
140 }
141 if (VN_CACHED(inode) && (flags & SYNC_IOWAIT))
136 xfs_ioend_wait(ip); 142 xfs_ioend_wait(ip);
137 } 143 }
138 xfs_ilock(ip, XFS_ILOCK_SHARED); 144 xfs_ilock(ip, XFS_ILOCK_SHARED);
@@ -398,15 +404,17 @@ STATIC void
398xfs_syncd_queue_work( 404xfs_syncd_queue_work(
399 struct xfs_mount *mp, 405 struct xfs_mount *mp,
400 void *data, 406 void *data,
401 void (*syncer)(struct xfs_mount *, void *)) 407 void (*syncer)(struct xfs_mount *, void *),
408 struct completion *completion)
402{ 409{
403 struct bhv_vfs_sync_work *work; 410 struct xfs_sync_work *work;
404 411
405 work = kmem_alloc(sizeof(struct bhv_vfs_sync_work), KM_SLEEP); 412 work = kmem_alloc(sizeof(struct xfs_sync_work), KM_SLEEP);
406 INIT_LIST_HEAD(&work->w_list); 413 INIT_LIST_HEAD(&work->w_list);
407 work->w_syncer = syncer; 414 work->w_syncer = syncer;
408 work->w_data = data; 415 work->w_data = data;
409 work->w_mount = mp; 416 work->w_mount = mp;
417 work->w_completion = completion;
410 spin_lock(&mp->m_sync_lock); 418 spin_lock(&mp->m_sync_lock);
411 list_add_tail(&work->w_list, &mp->m_sync_list); 419 list_add_tail(&work->w_list, &mp->m_sync_list);
412 spin_unlock(&mp->m_sync_lock); 420 spin_unlock(&mp->m_sync_lock);
@@ -420,49 +428,26 @@ xfs_syncd_queue_work(
420 * heads, looking about for more room... 428 * heads, looking about for more room...
421 */ 429 */
422STATIC void 430STATIC void
423xfs_flush_inode_work( 431xfs_flush_inodes_work(
424 struct xfs_mount *mp,
425 void *arg)
426{
427 struct inode *inode = arg;
428 filemap_flush(inode->i_mapping);
429 iput(inode);
430}
431
432void
433xfs_flush_inode(
434 xfs_inode_t *ip)
435{
436 struct inode *inode = VFS_I(ip);
437
438 igrab(inode);
439 xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_inode_work);
440 delay(msecs_to_jiffies(500));
441}
442
443/*
444 * This is the "bigger hammer" version of xfs_flush_inode_work...
445 * (IOW, "If at first you don't succeed, use a Bigger Hammer").
446 */
447STATIC void
448xfs_flush_device_work(
449 struct xfs_mount *mp, 432 struct xfs_mount *mp,
450 void *arg) 433 void *arg)
451{ 434{
452 struct inode *inode = arg; 435 struct inode *inode = arg;
453 sync_blockdev(mp->m_super->s_bdev); 436 xfs_sync_inodes(mp, SYNC_DELWRI | SYNC_TRYLOCK);
437 xfs_sync_inodes(mp, SYNC_DELWRI | SYNC_TRYLOCK | SYNC_IOWAIT);
454 iput(inode); 438 iput(inode);
455} 439}
456 440
457void 441void
458xfs_flush_device( 442xfs_flush_inodes(
459 xfs_inode_t *ip) 443 xfs_inode_t *ip)
460{ 444{
461 struct inode *inode = VFS_I(ip); 445 struct inode *inode = VFS_I(ip);
446 DECLARE_COMPLETION_ONSTACK(completion);
462 447
463 igrab(inode); 448 igrab(inode);
464 xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_device_work); 449 xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_inodes_work, &completion);
465 delay(msecs_to_jiffies(500)); 450 wait_for_completion(&completion);
466 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC); 451 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
467} 452}
468 453
@@ -497,7 +482,7 @@ xfssyncd(
497{ 482{
498 struct xfs_mount *mp = arg; 483 struct xfs_mount *mp = arg;
499 long timeleft; 484 long timeleft;
500 bhv_vfs_sync_work_t *work, *n; 485 xfs_sync_work_t *work, *n;
501 LIST_HEAD (tmp); 486 LIST_HEAD (tmp);
502 487
503 set_freezable(); 488 set_freezable();
@@ -532,6 +517,8 @@ xfssyncd(
532 list_del(&work->w_list); 517 list_del(&work->w_list);
533 if (work == &mp->m_sync_work) 518 if (work == &mp->m_sync_work)
534 continue; 519 continue;
520 if (work->w_completion)
521 complete(work->w_completion);
535 kmem_free(work); 522 kmem_free(work);
536 } 523 }
537 } 524 }
@@ -545,6 +532,7 @@ xfs_syncd_init(
545{ 532{
546 mp->m_sync_work.w_syncer = xfs_sync_worker; 533 mp->m_sync_work.w_syncer = xfs_sync_worker;
547 mp->m_sync_work.w_mount = mp; 534 mp->m_sync_work.w_mount = mp;
535 mp->m_sync_work.w_completion = NULL;
548 mp->m_sync_task = kthread_run(xfssyncd, mp, "xfssyncd"); 536 mp->m_sync_task = kthread_run(xfssyncd, mp, "xfssyncd");
549 if (IS_ERR(mp->m_sync_task)) 537 if (IS_ERR(mp->m_sync_task))
550 return -PTR_ERR(mp->m_sync_task); 538 return -PTR_ERR(mp->m_sync_task);
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h
index 04f058c848ae..308d5bf6dfbd 100644
--- a/fs/xfs/linux-2.6/xfs_sync.h
+++ b/fs/xfs/linux-2.6/xfs_sync.h
@@ -21,18 +21,20 @@
21struct xfs_mount; 21struct xfs_mount;
22struct xfs_perag; 22struct xfs_perag;
23 23
24typedef struct bhv_vfs_sync_work { 24typedef struct xfs_sync_work {
25 struct list_head w_list; 25 struct list_head w_list;
26 struct xfs_mount *w_mount; 26 struct xfs_mount *w_mount;
27 void *w_data; /* syncer routine argument */ 27 void *w_data; /* syncer routine argument */
28 void (*w_syncer)(struct xfs_mount *, void *); 28 void (*w_syncer)(struct xfs_mount *, void *);
29} bhv_vfs_sync_work_t; 29 struct completion *w_completion;
30} xfs_sync_work_t;
30 31
31#define SYNC_ATTR 0x0001 /* sync attributes */ 32#define SYNC_ATTR 0x0001 /* sync attributes */
32#define SYNC_DELWRI 0x0002 /* look at delayed writes */ 33#define SYNC_DELWRI 0x0002 /* look at delayed writes */
33#define SYNC_WAIT 0x0004 /* wait for i/o to complete */ 34#define SYNC_WAIT 0x0004 /* wait for i/o to complete */
34#define SYNC_BDFLUSH 0x0008 /* BDFLUSH is calling -- don't block */ 35#define SYNC_BDFLUSH 0x0008 /* BDFLUSH is calling -- don't block */
35#define SYNC_IOWAIT 0x0010 /* wait for all I/O to complete */ 36#define SYNC_IOWAIT 0x0010 /* wait for all I/O to complete */
37#define SYNC_TRYLOCK 0x0020 /* only try to lock inodes */
36 38
37int xfs_syncd_init(struct xfs_mount *mp); 39int xfs_syncd_init(struct xfs_mount *mp);
38void xfs_syncd_stop(struct xfs_mount *mp); 40void xfs_syncd_stop(struct xfs_mount *mp);
@@ -43,8 +45,7 @@ int xfs_sync_fsdata(struct xfs_mount *mp, int flags);
43int xfs_quiesce_data(struct xfs_mount *mp); 45int xfs_quiesce_data(struct xfs_mount *mp);
44void xfs_quiesce_attr(struct xfs_mount *mp); 46void xfs_quiesce_attr(struct xfs_mount *mp);
45 47
46void xfs_flush_inode(struct xfs_inode *ip); 48void xfs_flush_inodes(struct xfs_inode *ip);
47void xfs_flush_device(struct xfs_inode *ip);
48 49
49int xfs_reclaim_inode(struct xfs_inode *ip, int locked, int sync_mode); 50int xfs_reclaim_inode(struct xfs_inode *ip, int locked, int sync_mode);
50int xfs_reclaim_inodes(struct xfs_mount *mp, int noblock, int mode); 51int xfs_reclaim_inodes(struct xfs_mount *mp, int noblock, int mode);
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 478e587087fe..89b81eedce6a 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -69,15 +69,6 @@ xfs_inode_alloc(
69 ASSERT(!spin_is_locked(&ip->i_flags_lock)); 69 ASSERT(!spin_is_locked(&ip->i_flags_lock));
70 ASSERT(completion_done(&ip->i_flush)); 70 ASSERT(completion_done(&ip->i_flush));
71 71
72 /*
73 * initialise the VFS inode here to get failures
74 * out of the way early.
75 */
76 if (!inode_init_always(mp->m_super, VFS_I(ip))) {
77 kmem_zone_free(xfs_inode_zone, ip);
78 return NULL;
79 }
80
81 /* initialise the xfs inode */ 72 /* initialise the xfs inode */
82 ip->i_ino = ino; 73 ip->i_ino = ino;
83 ip->i_mount = mp; 74 ip->i_mount = mp;
@@ -113,6 +104,20 @@ xfs_inode_alloc(
113#ifdef XFS_DIR2_TRACE 104#ifdef XFS_DIR2_TRACE
114 ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS); 105 ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS);
115#endif 106#endif
107 /*
108 * Now initialise the VFS inode. We do this after the xfs_inode
109 * initialisation as internal failures will result in ->destroy_inode
110 * being called and that will pass down through the reclaim path and
111 * free the XFS inode. This path requires the XFS inode to already be
112 * initialised. Hence if this call fails, the xfs_inode has already
113 * been freed and we should not reference it at all in the error
114 * handling.
115 */
116 if (!inode_init_always(mp->m_super, VFS_I(ip)))
117 return NULL;
118
119 /* prevent anyone from using this yet */
120 VFS_I(ip)->i_state = I_NEW|I_LOCK;
116 121
117 return ip; 122 return ip;
118} 123}
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 08ce72316bfe..5aaa2d7ec155 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -338,38 +338,6 @@ xfs_iomap_eof_align_last_fsb(
338} 338}
339 339
340STATIC int 340STATIC int
341xfs_flush_space(
342 xfs_inode_t *ip,
343 int *fsynced,
344 int *ioflags)
345{
346 switch (*fsynced) {
347 case 0:
348 if (ip->i_delayed_blks) {
349 xfs_iunlock(ip, XFS_ILOCK_EXCL);
350 xfs_flush_inode(ip);
351 xfs_ilock(ip, XFS_ILOCK_EXCL);
352 *fsynced = 1;
353 } else {
354 *ioflags |= BMAPI_SYNC;
355 *fsynced = 2;
356 }
357 return 0;
358 case 1:
359 *fsynced = 2;
360 *ioflags |= BMAPI_SYNC;
361 return 0;
362 case 2:
363 xfs_iunlock(ip, XFS_ILOCK_EXCL);
364 xfs_flush_device(ip);
365 xfs_ilock(ip, XFS_ILOCK_EXCL);
366 *fsynced = 3;
367 return 0;
368 }
369 return 1;
370}
371
372STATIC int
373xfs_cmn_err_fsblock_zero( 341xfs_cmn_err_fsblock_zero(
374 xfs_inode_t *ip, 342 xfs_inode_t *ip,
375 xfs_bmbt_irec_t *imap) 343 xfs_bmbt_irec_t *imap)
@@ -538,15 +506,9 @@ error_out:
538} 506}
539 507
540/* 508/*
541 * If the caller is doing a write at the end of the file, 509 * If the caller is doing a write at the end of the file, then extend the
542 * then extend the allocation out to the file system's write 510 * allocation out to the file system's write iosize. We clean up any extra
543 * iosize. We clean up any extra space left over when the 511 * space left over when the file is closed in xfs_inactive().
544 * file is closed in xfs_inactive().
545 *
546 * For sync writes, we are flushing delayed allocate space to
547 * try to make additional space available for allocation near
548 * the filesystem full boundary - preallocation hurts in that
549 * situation, of course.
550 */ 512 */
551STATIC int 513STATIC int
552xfs_iomap_eof_want_preallocate( 514xfs_iomap_eof_want_preallocate(
@@ -565,7 +527,7 @@ xfs_iomap_eof_want_preallocate(
565 int n, error, imaps; 527 int n, error, imaps;
566 528
567 *prealloc = 0; 529 *prealloc = 0;
568 if ((ioflag & BMAPI_SYNC) || (offset + count) <= ip->i_size) 530 if ((offset + count) <= ip->i_size)
569 return 0; 531 return 0;
570 532
571 /* 533 /*
@@ -611,7 +573,7 @@ xfs_iomap_write_delay(
611 xfs_extlen_t extsz; 573 xfs_extlen_t extsz;
612 int nimaps; 574 int nimaps;
613 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS]; 575 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS];
614 int prealloc, fsynced = 0; 576 int prealloc, flushed = 0;
615 int error; 577 int error;
616 578
617 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 579 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
@@ -627,12 +589,12 @@ xfs_iomap_write_delay(
627 extsz = xfs_get_extsz_hint(ip); 589 extsz = xfs_get_extsz_hint(ip);
628 offset_fsb = XFS_B_TO_FSBT(mp, offset); 590 offset_fsb = XFS_B_TO_FSBT(mp, offset);
629 591
630retry:
631 error = xfs_iomap_eof_want_preallocate(mp, ip, offset, count, 592 error = xfs_iomap_eof_want_preallocate(mp, ip, offset, count,
632 ioflag, imap, XFS_WRITE_IMAPS, &prealloc); 593 ioflag, imap, XFS_WRITE_IMAPS, &prealloc);
633 if (error) 594 if (error)
634 return error; 595 return error;
635 596
597retry:
636 if (prealloc) { 598 if (prealloc) {
637 aligned_offset = XFS_WRITEIO_ALIGN(mp, (offset + count - 1)); 599 aligned_offset = XFS_WRITEIO_ALIGN(mp, (offset + count - 1));
638 ioalign = XFS_B_TO_FSBT(mp, aligned_offset); 600 ioalign = XFS_B_TO_FSBT(mp, aligned_offset);
@@ -659,15 +621,22 @@ retry:
659 621
660 /* 622 /*
661 * If bmapi returned us nothing, and if we didn't get back EDQUOT, 623 * If bmapi returned us nothing, and if we didn't get back EDQUOT,
662 * then we must have run out of space - flush delalloc, and retry.. 624 * then we must have run out of space - flush all other inodes with
625 * delalloc blocks and retry without EOF preallocation.
663 */ 626 */
664 if (nimaps == 0) { 627 if (nimaps == 0) {
665 xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE, 628 xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE,
666 ip, offset, count); 629 ip, offset, count);
667 if (xfs_flush_space(ip, &fsynced, &ioflag)) 630 if (flushed)
668 return XFS_ERROR(ENOSPC); 631 return XFS_ERROR(ENOSPC);
669 632
633 xfs_iunlock(ip, XFS_ILOCK_EXCL);
634 xfs_flush_inodes(ip);
635 xfs_ilock(ip, XFS_ILOCK_EXCL);
636
637 flushed = 1;
670 error = 0; 638 error = 0;
639 prealloc = 0;
671 goto retry; 640 goto retry;
672 } 641 }
673 642
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index a1cc1322fc0f..fdcf7b82747f 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -40,8 +40,7 @@ typedef enum {
40 BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */ 40 BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */
41 BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */ 41 BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */
42 BMAPI_MMAP = (1 << 6), /* allocate for mmap write */ 42 BMAPI_MMAP = (1 << 6), /* allocate for mmap write */
43 BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */ 43 BMAPI_TRYLOCK = (1 << 7), /* non-blocking request */
44 BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */
45} bmapi_flags_t; 44} bmapi_flags_t;
46 45
47 46
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index f76c6d7cea21..3750f04ede0b 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -562,9 +562,8 @@ xfs_log_mount(
562 } 562 }
563 563
564 mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks); 564 mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
565 if (!mp->m_log) { 565 if (IS_ERR(mp->m_log)) {
566 cmn_err(CE_WARN, "XFS: Log allocation failed: No memory!"); 566 error = -PTR_ERR(mp->m_log);
567 error = ENOMEM;
568 goto out; 567 goto out;
569 } 568 }
570 569
@@ -1180,10 +1179,13 @@ xlog_alloc_log(xfs_mount_t *mp,
1180 xfs_buf_t *bp; 1179 xfs_buf_t *bp;
1181 int i; 1180 int i;
1182 int iclogsize; 1181 int iclogsize;
1182 int error = ENOMEM;
1183 1183
1184 log = kmem_zalloc(sizeof(xlog_t), KM_MAYFAIL); 1184 log = kmem_zalloc(sizeof(xlog_t), KM_MAYFAIL);
1185 if (!log) 1185 if (!log) {
1186 return NULL; 1186 xlog_warn("XFS: Log allocation failed: No memory!");
1187 goto out;
1188 }
1187 1189
1188 log->l_mp = mp; 1190 log->l_mp = mp;
1189 log->l_targ = log_target; 1191 log->l_targ = log_target;
@@ -1201,19 +1203,35 @@ xlog_alloc_log(xfs_mount_t *mp,
1201 log->l_grant_reserve_cycle = 1; 1203 log->l_grant_reserve_cycle = 1;
1202 log->l_grant_write_cycle = 1; 1204 log->l_grant_write_cycle = 1;
1203 1205
1206 error = EFSCORRUPTED;
1204 if (xfs_sb_version_hassector(&mp->m_sb)) { 1207 if (xfs_sb_version_hassector(&mp->m_sb)) {
1205 log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; 1208 log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT;
1206 ASSERT(log->l_sectbb_log <= mp->m_sectbb_log); 1209 if (log->l_sectbb_log < 0 ||
1210 log->l_sectbb_log > mp->m_sectbb_log) {
1211 xlog_warn("XFS: Log sector size (0x%x) out of range.",
1212 log->l_sectbb_log);
1213 goto out_free_log;
1214 }
1215
1207 /* for larger sector sizes, must have v2 or external log */ 1216 /* for larger sector sizes, must have v2 or external log */
1208 ASSERT(log->l_sectbb_log == 0 || 1217 if (log->l_sectbb_log != 0 &&
1209 log->l_logBBstart == 0 || 1218 (log->l_logBBstart != 0 &&
1210 xfs_sb_version_haslogv2(&mp->m_sb)); 1219 !xfs_sb_version_haslogv2(&mp->m_sb))) {
1211 ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT); 1220 xlog_warn("XFS: log sector size (0x%x) invalid "
1221 "for configuration.", log->l_sectbb_log);
1222 goto out_free_log;
1223 }
1224 if (mp->m_sb.sb_logsectlog < BBSHIFT) {
1225 xlog_warn("XFS: Log sector log (0x%x) too small.",
1226 mp->m_sb.sb_logsectlog);
1227 goto out_free_log;
1228 }
1212 } 1229 }
1213 log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1; 1230 log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1;
1214 1231
1215 xlog_get_iclog_buffer_size(mp, log); 1232 xlog_get_iclog_buffer_size(mp, log);
1216 1233
1234 error = ENOMEM;
1217 bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp); 1235 bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp);
1218 if (!bp) 1236 if (!bp)
1219 goto out_free_log; 1237 goto out_free_log;
@@ -1313,7 +1331,8 @@ out_free_iclog:
1313 xfs_buf_free(log->l_xbuf); 1331 xfs_buf_free(log->l_xbuf);
1314out_free_log: 1332out_free_log:
1315 kmem_free(log); 1333 kmem_free(log);
1316 return NULL; 1334out:
1335 return ERR_PTR(-error);
1317} /* xlog_alloc_log */ 1336} /* xlog_alloc_log */
1318 1337
1319 1338
@@ -2541,18 +2560,19 @@ redo:
2541 xlog_ins_ticketq(&log->l_reserve_headq, tic); 2560 xlog_ins_ticketq(&log->l_reserve_headq, tic);
2542 xlog_trace_loggrant(log, tic, 2561 xlog_trace_loggrant(log, tic,
2543 "xlog_grant_log_space: sleep 2"); 2562 "xlog_grant_log_space: sleep 2");
2563 spin_unlock(&log->l_grant_lock);
2564 xlog_grant_push_ail(log->l_mp, need_bytes);
2565 spin_lock(&log->l_grant_lock);
2566
2544 XFS_STATS_INC(xs_sleep_logspace); 2567 XFS_STATS_INC(xs_sleep_logspace);
2545 sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s); 2568 sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s);
2546 2569
2547 if (XLOG_FORCED_SHUTDOWN(log)) { 2570 spin_lock(&log->l_grant_lock);
2548 spin_lock(&log->l_grant_lock); 2571 if (XLOG_FORCED_SHUTDOWN(log))
2549 goto error_return; 2572 goto error_return;
2550 }
2551 2573
2552 xlog_trace_loggrant(log, tic, 2574 xlog_trace_loggrant(log, tic,
2553 "xlog_grant_log_space: wake 2"); 2575 "xlog_grant_log_space: wake 2");
2554 xlog_grant_push_ail(log->l_mp, need_bytes);
2555 spin_lock(&log->l_grant_lock);
2556 goto redo; 2576 goto redo;
2557 } else if (tic->t_flags & XLOG_TIC_IN_Q) 2577 } else if (tic->t_flags & XLOG_TIC_IN_Q)
2558 xlog_del_ticketq(&log->l_reserve_headq, tic); 2578 xlog_del_ticketq(&log->l_reserve_headq, tic);
@@ -2631,7 +2651,7 @@ xlog_regrant_write_log_space(xlog_t *log,
2631 * for more free space, otherwise try to get some space for 2651 * for more free space, otherwise try to get some space for
2632 * this transaction. 2652 * this transaction.
2633 */ 2653 */
2634 2654 need_bytes = tic->t_unit_res;
2635 if ((ntic = log->l_write_headq)) { 2655 if ((ntic = log->l_write_headq)) {
2636 free_bytes = xlog_space_left(log, log->l_grant_write_cycle, 2656 free_bytes = xlog_space_left(log, log->l_grant_write_cycle,
2637 log->l_grant_write_bytes); 2657 log->l_grant_write_bytes);
@@ -2651,26 +2671,25 @@ xlog_regrant_write_log_space(xlog_t *log,
2651 2671
2652 xlog_trace_loggrant(log, tic, 2672 xlog_trace_loggrant(log, tic,
2653 "xlog_regrant_write_log_space: sleep 1"); 2673 "xlog_regrant_write_log_space: sleep 1");
2674 spin_unlock(&log->l_grant_lock);
2675 xlog_grant_push_ail(log->l_mp, need_bytes);
2676 spin_lock(&log->l_grant_lock);
2677
2654 XFS_STATS_INC(xs_sleep_logspace); 2678 XFS_STATS_INC(xs_sleep_logspace);
2655 sv_wait(&tic->t_wait, PINOD|PLTWAIT, 2679 sv_wait(&tic->t_wait, PINOD|PLTWAIT,
2656 &log->l_grant_lock, s); 2680 &log->l_grant_lock, s);
2657 2681
2658 /* If we're shutting down, this tic is already 2682 /* If we're shutting down, this tic is already
2659 * off the queue */ 2683 * off the queue */
2660 if (XLOG_FORCED_SHUTDOWN(log)) { 2684 spin_lock(&log->l_grant_lock);
2661 spin_lock(&log->l_grant_lock); 2685 if (XLOG_FORCED_SHUTDOWN(log))
2662 goto error_return; 2686 goto error_return;
2663 }
2664 2687
2665 xlog_trace_loggrant(log, tic, 2688 xlog_trace_loggrant(log, tic,
2666 "xlog_regrant_write_log_space: wake 1"); 2689 "xlog_regrant_write_log_space: wake 1");
2667 xlog_grant_push_ail(log->l_mp, tic->t_unit_res);
2668 spin_lock(&log->l_grant_lock);
2669 } 2690 }
2670 } 2691 }
2671 2692
2672 need_bytes = tic->t_unit_res;
2673
2674redo: 2693redo:
2675 if (XLOG_FORCED_SHUTDOWN(log)) 2694 if (XLOG_FORCED_SHUTDOWN(log))
2676 goto error_return; 2695 goto error_return;
@@ -2680,19 +2699,20 @@ redo:
2680 if (free_bytes < need_bytes) { 2699 if (free_bytes < need_bytes) {
2681 if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) 2700 if ((tic->t_flags & XLOG_TIC_IN_Q) == 0)
2682 xlog_ins_ticketq(&log->l_write_headq, tic); 2701 xlog_ins_ticketq(&log->l_write_headq, tic);
2702 spin_unlock(&log->l_grant_lock);
2703 xlog_grant_push_ail(log->l_mp, need_bytes);
2704 spin_lock(&log->l_grant_lock);
2705
2683 XFS_STATS_INC(xs_sleep_logspace); 2706 XFS_STATS_INC(xs_sleep_logspace);
2684 sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s); 2707 sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s);
2685 2708
2686 /* If we're shutting down, this tic is already off the queue */ 2709 /* If we're shutting down, this tic is already off the queue */
2687 if (XLOG_FORCED_SHUTDOWN(log)) { 2710 spin_lock(&log->l_grant_lock);
2688 spin_lock(&log->l_grant_lock); 2711 if (XLOG_FORCED_SHUTDOWN(log))
2689 goto error_return; 2712 goto error_return;
2690 }
2691 2713
2692 xlog_trace_loggrant(log, tic, 2714 xlog_trace_loggrant(log, tic,
2693 "xlog_regrant_write_log_space: wake 2"); 2715 "xlog_regrant_write_log_space: wake 2");
2694 xlog_grant_push_ail(log->l_mp, need_bytes);
2695 spin_lock(&log->l_grant_lock);
2696 goto redo; 2716 goto redo;
2697 } else if (tic->t_flags & XLOG_TIC_IN_Q) 2717 } else if (tic->t_flags & XLOG_TIC_IN_Q)
2698 xlog_del_ticketq(&log->l_write_headq, tic); 2718 xlog_del_ticketq(&log->l_write_headq, tic);
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 7af44adffc8f..d6a64392f983 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -313,7 +313,7 @@ typedef struct xfs_mount {
313#endif 313#endif
314 struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ 314 struct xfs_mru_cache *m_filestream; /* per-mount filestream data */
315 struct task_struct *m_sync_task; /* generalised sync thread */ 315 struct task_struct *m_sync_task; /* generalised sync thread */
316 bhv_vfs_sync_work_t m_sync_work; /* work item for VFS_SYNC */ 316 xfs_sync_work_t m_sync_work; /* work item for VFS_SYNC */
317 struct list_head m_sync_list; /* sync thread work item list */ 317 struct list_head m_sync_list; /* sync thread work item list */
318 spinlock_t m_sync_lock; /* work item list lock */ 318 spinlock_t m_sync_lock; /* work item list lock */
319 int m_sync_seq; /* sync thread generation no. */ 319 int m_sync_seq; /* sync thread generation no. */
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 7394c7af5de5..19cf90a9c762 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1457,6 +1457,13 @@ xfs_create(
1457 error = xfs_trans_reserve(tp, resblks, log_res, 0, 1457 error = xfs_trans_reserve(tp, resblks, log_res, 0,
1458 XFS_TRANS_PERM_LOG_RES, log_count); 1458 XFS_TRANS_PERM_LOG_RES, log_count);
1459 if (error == ENOSPC) { 1459 if (error == ENOSPC) {
1460 /* flush outstanding delalloc blocks and retry */
1461 xfs_flush_inodes(dp);
1462 error = xfs_trans_reserve(tp, resblks, XFS_CREATE_LOG_RES(mp), 0,
1463 XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT);
1464 }
1465 if (error == ENOSPC) {
1466 /* No space at all so try a "no-allocation" reservation */
1460 resblks = 0; 1467 resblks = 0;
1461 error = xfs_trans_reserve(tp, 0, log_res, 0, 1468 error = xfs_trans_reserve(tp, 0, log_res, 0,
1462 XFS_TRANS_PERM_LOG_RES, log_count); 1469 XFS_TRANS_PERM_LOG_RES, log_count);