add patch create-function-to-read-journal-inode
[ext4-patch-queue.git] / reinforce-check-of-i_dtime-when-clearing-high-uid-gid-fields
blob08284139e2fac96da94c57c332b99687ae759647
1 ext4: reinforce check of i_dtime when clearing high fields of uid and gid
3 From: Daeho Jeong <daeho.jeong@samsung.com>
5 Now, ext4_do_update_inode() clears high 16-bit fields of uid/gid
6 of deleted and evicted inode to fix up interoperability with old
7 kernels. However, it checks only i_dtime of an inode to determine
8 whether the inode was deleted and evicted, and this is very risky,
9 because i_dtime can be used for the pointer maintaining orphan inode
10 list, too. We need to further check whether the i_dtime is being
11 used for the orphan inode list even if the i_dtime is not NULL.
13 We found that high 16-bit fields of uid/gid of inode are unintentionally
14 and permanently cleared when the inode truncation is just triggered,
15 but not finished, and the inode metadata, whose high uid/gid bits are
16 cleared, is written on disk, and the sudden power-off follows that
17 in order.
19 Signed-off-by: Daeho Jeong <daeho.jeong@samsung.com>
20 Signed-off-by: Hobin Woo <hobin.woo@samsung.com>
21 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
22 ---
23  fs/ext4/inode.c |    8 ++++----
24  1 file changed, 4 insertions(+), 4 deletions(-)
26 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
27 index f7140ca..bb5aede 100644
28 --- a/fs/ext4/inode.c
29 +++ b/fs/ext4/inode.c
30 @@ -4785,14 +4785,14 @@ static int ext4_do_update_inode(handle_t *handle,
31   * Fix up interoperability with old kernels. Otherwise, old inodes get
32   * re-used with the upper 16 bits of the uid/gid intact
33   */
34 -               if (!ei->i_dtime) {
35 +               if (ei->i_dtime && list_empty(&ei->i_orphan)) {
36 +                       raw_inode->i_uid_high = 0;
37 +                       raw_inode->i_gid_high = 0;
38 +               } else {
39                         raw_inode->i_uid_high =
40                                 cpu_to_le16(high_16_bits(i_uid));
41                         raw_inode->i_gid_high =
42                                 cpu_to_le16(high_16_bits(i_gid));
43 -               } else {
44 -                       raw_inode->i_uid_high = 0;
45 -                       raw_inode->i_gid_high = 0;
46                 }
47         } else {
48                 raw_inode->i_uid_low = cpu_to_le16(fs_high2lowuid(i_uid));
49 -- 
50 1.7.9.5