]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.32.1/0001-ext4-fix-potential-buffer-head-leak-when-add_dirent_.patch
drop queue-4.14/mips-make-sure-dt-memory-regions-are-valid.patch
[thirdparty/kernel/stable-queue.git] / releases / 2.6.32.1 / 0001-ext4-fix-potential-buffer-head-leak-when-add_dirent_.patch
CommitLineData
e46fb18b
GKH
1From 4df5b14f4bea734ff3d9c721eb331540ad142de3 Mon Sep 17 00:00:00 2001
2From: Theodore Ts'o <tytso@mit.edu>
3Date: Mon, 23 Nov 2009 07:25:49 -0500
4Subject: [PATCH 01/30] ext4: fix potential buffer head leak when add_dirent_to_buf() returns ENOSPC
5
6(cherry picked from commit 2de770a406b06dfc619faabbf5d85c835ed3f2e1)
7
8Previously add_dirent_to_buf() did not free its passed-in buffer head
9in the case of ENOSPC, since in some cases the caller still needed it.
10However, this led to potential buffer head leaks since not all callers
11dealt with this correctly. Fix this by making simplifying the freeing
12convention; now add_dirent_to_buf() *never* frees the passed-in buffer
13head, and leaves that to the responsibility of its caller. This makes
14things cleaner and easier to prove that the code is neither leaking
15buffer heads or calling brelse() one time too many.
16
17Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
18Cc: Curt Wohlgemuth <curtw@google.com>
19Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
20---
21 fs/ext4/namei.c | 30 ++++++++++++------------------
22 1 file changed, 12 insertions(+), 18 deletions(-)
23
24--- a/fs/ext4/namei.c
25+++ b/fs/ext4/namei.c
26@@ -1292,9 +1292,6 @@ errout:
27 * add_dirent_to_buf will attempt search the directory block for
28 * space. It will return -ENOSPC if no space is available, and -EIO
29 * and -EEXIST if directory entry already exists.
30- *
31- * NOTE! bh is NOT released in the case where ENOSPC is returned. In
32- * all other cases bh is released.
33 */
34 static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
35 struct inode *inode, struct ext4_dir_entry_2 *de,
36@@ -1315,14 +1312,10 @@ static int add_dirent_to_buf(handle_t *h
37 top = bh->b_data + blocksize - reclen;
38 while ((char *) de <= top) {
39 if (!ext4_check_dir_entry("ext4_add_entry", dir, de,
40- bh, offset)) {
41- brelse(bh);
42+ bh, offset))
43 return -EIO;
44- }
45- if (ext4_match(namelen, name, de)) {
46- brelse(bh);
47+ if (ext4_match(namelen, name, de))
48 return -EEXIST;
49- }
50 nlen = EXT4_DIR_REC_LEN(de->name_len);
51 rlen = ext4_rec_len_from_disk(de->rec_len, blocksize);
52 if ((de->inode? rlen - nlen: rlen) >= reclen)
53@@ -1337,7 +1330,6 @@ static int add_dirent_to_buf(handle_t *h
54 err = ext4_journal_get_write_access(handle, bh);
55 if (err) {
56 ext4_std_error(dir->i_sb, err);
57- brelse(bh);
58 return err;
59 }
60
61@@ -1377,7 +1369,6 @@ static int add_dirent_to_buf(handle_t *h
62 err = ext4_handle_dirty_metadata(handle, dir, bh);
63 if (err)
64 ext4_std_error(dir->i_sb, err);
65- brelse(bh);
66 return 0;
67 }
68
69@@ -1471,7 +1462,9 @@ static int make_indexed_dir(handle_t *ha
70 if (!(de))
71 return retval;
72
73- return add_dirent_to_buf(handle, dentry, inode, de, bh);
74+ retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
75+ brelse(bh);
76+ return retval;
77 }
78
79 /*
80@@ -1514,8 +1507,10 @@ static int ext4_add_entry(handle_t *hand
81 if(!bh)
82 return retval;
83 retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
84- if (retval != -ENOSPC)
85+ if (retval != -ENOSPC) {
86+ brelse(bh);
87 return retval;
88+ }
89
90 if (blocks == 1 && !dx_fallback &&
91 EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX))
92@@ -1528,7 +1523,9 @@ static int ext4_add_entry(handle_t *hand
93 de = (struct ext4_dir_entry_2 *) bh->b_data;
94 de->inode = 0;
95 de->rec_len = ext4_rec_len_to_disk(blocksize, blocksize);
96- return add_dirent_to_buf(handle, dentry, inode, de, bh);
97+ retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
98+ brelse(bh);
99+ return retval;
100 }
101
102 /*
103@@ -1561,10 +1558,8 @@ static int ext4_dx_add_entry(handle_t *h
104 goto journal_error;
105
106 err = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
107- if (err != -ENOSPC) {
108- bh = NULL;
109+ if (err != -ENOSPC)
110 goto cleanup;
111- }
112
113 /* Block full, should compress but for now just split */
114 dxtrace(printk(KERN_DEBUG "using %u of %u node entries\n",
115@@ -1657,7 +1652,6 @@ static int ext4_dx_add_entry(handle_t *h
116 if (!de)
117 goto cleanup;
118 err = add_dirent_to_buf(handle, dentry, inode, de, bh);
119- bh = NULL;
120 goto cleanup;
121
122 journal_error: