1 From 492c93e8097f0bf58b2884064af85242fabe5d71 Mon Sep 17 00:00:00 2001
2 From: Dmitry Monakhov <dmonakhov@openvz.org>
3 Date: Sun, 30 May 2010 22:49:31 -0400
4 Subject: ext4: fix error handling in migrate
6 commit f39490bcd1691d65dc33689222a12e1fc13dd824 upstream (as of v2.6.33-git11)
8 Set i_nlink to zero for temporary inode from very beginning.
9 otherwise we may fail to start new journal handle and this
10 inode will be unreferenced but with i_nlink == 1
11 Since we hold inode reference it can not be pruned.
13 Also add missed journal_start retval check.
15 Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
16 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
17 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
19 fs/ext4/migrate.c | 29 ++++++++++++++---------------
20 1 file changed, 14 insertions(+), 15 deletions(-)
22 --- a/fs/ext4/migrate.c
23 +++ b/fs/ext4/migrate.c
24 @@ -494,14 +494,10 @@ int ext4_ext_migrate(struct inode *inode
26 i_size_write(tmp_inode, i_size_read(inode));
28 - * We don't want the inode to be reclaimed
29 - * if we got interrupted in between. We have
30 - * this tmp inode carrying reference to the
31 - * data blocks of the original file. We set
32 - * the i_nlink to zero at the last stage after
33 - * switching the original file to extent format
34 + * Set the i_nlink to zero so it will be deleted later
35 + * when we drop inode reference.
37 - tmp_inode->i_nlink = 1;
38 + tmp_inode->i_nlink = 0;
40 ext4_ext_tree_init(handle, tmp_inode);
41 ext4_orphan_add(handle, tmp_inode);
42 @@ -528,6 +524,16 @@ int ext4_ext_migrate(struct inode *inode
43 up_read((&EXT4_I(inode)->i_data_sem));
45 handle = ext4_journal_start(inode, 1);
46 + if (IS_ERR(handle)) {
48 + * It is impossible to update on-disk structures without
49 + * a handle, so just rollback in-core changes and live other
50 + * work to orphan_list_cleanup()
52 + ext4_orphan_del(NULL, tmp_inode);
53 + retval = PTR_ERR(handle);
59 @@ -609,15 +615,8 @@ err_out:
61 /* Reset the extent details */
62 ext4_ext_tree_init(handle, tmp_inode);
65 - * Set the i_nlink to zero so that
66 - * generic_drop_inode really deletes the
69 - tmp_inode->i_nlink = 0;
71 ext4_journal_stop(handle);
73 unlock_new_inode(tmp_inode);