android_kernel_oneplus_msm8998/fs/gfs2
Bob Peterson ab9b3db408 GFS2: Take inode off order_write list when setting jdata flag
[ Upstream commit cc555b09d8c3817aeebda43a14ab67049a5653f7 ]

This patch fixes a deadlock caused when the jdata flag is set for
inodes that are already on the ordered write list. Since it is
on the ordered write list, log_flush calls gfs2_ordered_write which
calls filemap_fdatawrite. But since the inode had the jdata flag
set, that calls gfs2_jdata_writepages, which tries to start a new
transaction. A new transaction cannot be started because it tries
to acquire the log_flush rwsem which is already locked by the log
flush operation.

The bottom line is: We cannot switch an inode from ordered to jdata
until we eliminate any ordered data pages (via log flush) or any
log_flush operation afterward will create the circular dependency
above. So we need to flush the log before setting the diskflags to
switch the file mode, then we need to remove the inode from the
ordered writes list.

Before this patch, the log flush was done for jdata->ordered, but
that's wrong. If we're going from jdata to ordered, we don't need
to call gfs2_log_flush because the call to filemap_fdatawrite will
do it for us:

   filemap_fdatawrite() -> __filemap_fdatawrite_range()
      __filemap_fdatawrite_range() -> do_writepages()
         do_writepages() -> gfs2_jdata_writepages()
            gfs2_jdata_writepages() -> gfs2_log_flush()

This patch modifies function do_gfs2_set_flags so that if a file
has its jdata flag set, and it's already on the ordered write list,
the log will be flushed and it will be removed from the list
before setting the flag.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Acked-by: Abhijith Das <adas@redhat.com>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-12-20 10:04:59 +01:00
..
acl.c posix_acl: Clear SGID bit when setting file permissions 2016-10-31 04:13:58 -06:00
acl.h
aops.c GFS2: merge window 2015-06-27 09:47:46 -07:00
bmap.c
bmap.h
dentry.c
dir.c gfs2: avoid uninitialized variable warning 2017-04-30 05:49:28 +02:00
dir.h
export.c
file.c GFS2: Take inode off order_write list when setting jdata flag 2017-12-20 10:04:59 +01:00
gfs2.h
glock.c GFS2: Fix reference to ERR_PTR in gfs2_glock_iter_next 2017-10-08 10:14:16 +02:00
glock.h gfs2: Remove gl_spin define 2015-10-29 12:57:48 -05:00
glops.c gfs2: Remove gl_spin define 2015-10-29 12:57:48 -05:00
glops.h
incore.h gfs2: Fix glock rhashtable rcu bug 2017-07-15 11:57:46 +02:00
inode.c GFS2: merge window 2015-06-27 09:47:46 -07:00
inode.h
Kconfig
lock_dlm.c remove abs64() 2015-11-09 15:11:24 -08:00
log.c
log.h
lops.c GFS2: merge window 2015-09-11 12:23:51 -07:00
lops.h
main.c gfs2: Remove gl_spin define 2015-10-29 12:57:48 -05:00
Makefile
meta_io.c GFS2: Move glock superblock pointer to field gl_name 2015-09-03 13:33:09 -05:00
meta_io.h GFS2: Move glock superblock pointer to field gl_name 2015-09-03 13:33:09 -05:00
ops_fstype.c GFS2: Set s_mode before parsing mount options 2015-09-23 08:45:43 -05:00
quota.c GFS2: Move glock superblock pointer to field gl_name 2015-09-03 13:33:09 -05:00
quota.h
recovery.c
recovery.h
rgrp.c GFS2: Fix rgrp end rounding problem for bsize < page size 2015-11-09 09:38:02 -06:00
rgrp.h GFS2: Don't brelse rgrp buffer_heads every allocation 2015-06-19 07:40:22 -05:00
super.c fs: create and use seq_show_option for escaping 2015-09-04 16:54:41 -07:00
super.h
sys.c
sys.h
trace_gfs2.h gfs2: Make statistics unsigned, suitable for use with do_div() 2015-09-03 13:33:32 -05:00
trans.c gfs2: Add missing else in trans_add_meta/data 2015-10-01 12:00:59 -05:00
trans.h
util.c
util.h
xattr.c xattr handlers: Pass handler to operations instead of flags 2015-11-13 20:34:32 -05:00
xattr.h