The EXT{3,4}_IOC_SETVERSION ioctl() updates i_ctime and i_generation
without i_mutex. This can lead to a race with the other operations that
update i_ctime. This is not a big issue but let's make the ioctl consistent
with how we handle e.g. other timestamp updates and use i_mutex to protect
inode changes.
Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
Signed-off-by: Jan Kara <jack@suse.cz>
                        goto setversion_out;
                }
 
+               mutex_lock(&inode->i_mutex);
                handle = ext3_journal_start(inode, 1);
                if (IS_ERR(handle)) {
                        err = PTR_ERR(handle);
-                       goto setversion_out;
+                       goto unlock_out;
                }
                err = ext3_reserve_inode_write(handle, inode, &iloc);
                if (err == 0) {
                        err = ext3_mark_iloc_dirty(handle, inode, &iloc);
                }
                ext3_journal_stop(handle);
+
+unlock_out:
+               mutex_unlock(&inode->i_mutex);
 setversion_out:
                mnt_drop_write(filp->f_path.mnt);
                return err;
 
                        goto setversion_out;
                }
 
+               mutex_lock(&inode->i_mutex);
                handle = ext4_journal_start(inode, 1);
                if (IS_ERR(handle)) {
                        err = PTR_ERR(handle);
-                       goto setversion_out;
+                       goto unlock_out;
                }
                err = ext4_reserve_inode_write(handle, inode, &iloc);
                if (err == 0) {
                        err = ext4_mark_iloc_dirty(handle, inode, &iloc);
                }
                ext4_journal_stop(handle);
+
+unlock_out:
+               mutex_unlock(&inode->i_mutex);
 setversion_out:
                mnt_drop_write(filp->f_path.mnt);
                return err;