]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.suse/xfs-handle-memory-allocation-failures-during-log-initialisation
Fix oinkmaster patch.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.suse / xfs-handle-memory-allocation-failures-during-log-initialisation
CommitLineData
2cb7cef9
BS
1From: Dave Chinner <david@fromorbit.com>
2Subject: [XFS] handle memory allocation failures during log initialisation
3References: bnc#450658
4Patch-mainline: ?
5
6When there is no memory left in the system, xfs_buf_get_noaddr()
7can fail. If this happens at mount time during xlog_alloc_log()
8we fail to catch the error and oops.
9
10Catch the error from xfs_buf_get_noaddr(), and allow other memory
11allocations to fail and catch those errors too. Report the error
12to the console and fail the mount with ENOMEM.
13
14Tested by manually injecting errors into xfs_buf_get_noaddr() and
15xlog_alloc_log().
16
17Version 2:
18o remove unnecessary casts of the returned pointer from kmem_zalloc()
19
20SGI-PV: 987246
21
22Signed-off-by: Dave Chinner <david@fromorbit.com>
23Reviewed-by: Christoph Hellwig <hch@lst.de>
24Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
25Acked-by: Jan Kara <jack@suse.cz>
26
27diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
28index 5184017..92c20a8 100644
29--- a/fs/xfs/xfs_log.c
30+++ b/fs/xfs/xfs_log.c
31@@ -563,6 +563,11 @@ xfs_log_mount(
32 }
33
34 mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
35+ if (!mp->m_log) {
36+ cmn_err(CE_WARN, "XFS: Log allocation failed: No memory!");
37+ error = ENOMEM;
38+ goto out;
39+ }
40
41 /*
42 * Initialize the AIL now we have a log.
43@@ -601,6 +606,7 @@ xfs_log_mount(
44 return 0;
45 error:
46 xfs_log_unmount_dealloc(mp);
47+out:
48 return error;
49 } /* xfs_log_mount */
50
51@@ -1217,7 +1223,9 @@ xlog_alloc_log(xfs_mount_t *mp,
52 int i;
53 int iclogsize;
54
55- log = (xlog_t *)kmem_zalloc(sizeof(xlog_t), KM_SLEEP);
56+ log = kmem_zalloc(sizeof(xlog_t), KM_MAYFAIL);
57+ if (!log)
58+ return NULL;
59
60 log->l_mp = mp;
61 log->l_targ = log_target;
62@@ -1249,6 +1257,8 @@ xlog_alloc_log(xfs_mount_t *mp,
63 xlog_get_iclog_buffer_size(mp, log);
64
65 bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp);
66+ if (!bp)
67+ goto out_free_log;
68 XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
69 XFS_BUF_SET_BDSTRAT_FUNC(bp, xlog_bdstrat_cb);
70 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
71@@ -1275,13 +1285,17 @@ xlog_alloc_log(xfs_mount_t *mp,
72 iclogsize = log->l_iclog_size;
73 ASSERT(log->l_iclog_size >= 4096);
74 for (i=0; i < log->l_iclog_bufs; i++) {
75- *iclogp = (xlog_in_core_t *)
76- kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP);
77+ *iclogp = kmem_zalloc(sizeof(xlog_in_core_t), KM_MAYFAIL);
78+ if (!*iclogp)
79+ goto out_free_iclog;
80+
81 iclog = *iclogp;
82 iclog->ic_prev = prev_iclog;
83 prev_iclog = iclog;
84
85 bp = xfs_buf_get_noaddr(log->l_iclog_size, mp->m_logdev_targp);
86+ if (!bp)
87+ goto out_free_iclog;
88 if (!XFS_BUF_CPSEMA(bp))
89 ASSERT(0);
90 XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
91@@ -1323,6 +1337,25 @@ xlog_alloc_log(xfs_mount_t *mp,
92 log->l_iclog->ic_prev = prev_iclog; /* re-write 1st prev ptr */
93
94 return log;
95+
96+out_free_iclog:
97+ for (iclog = log->l_iclog; iclog; iclog = prev_iclog) {
98+ prev_iclog = iclog->ic_next;
99+ if (iclog->ic_bp) {
100+ sv_destroy(&iclog->ic_force_wait);
101+ sv_destroy(&iclog->ic_write_wait);
102+ xfs_buf_free(iclog->ic_bp);
103+ xlog_trace_iclog_dealloc(iclog);
104+ }
105+ kmem_free(iclog);
106+ }
107+ spinlock_destroy(&log->l_icloglock);
108+ spinlock_destroy(&log->l_grant_lock);
109+ xlog_trace_loggrant_dealloc(log);
110+ xfs_buf_free(log->l_xbuf);
111+out_free_log:
112+ kmem_free(log);
113+ return NULL;
114 } /* xlog_alloc_log */
115
116