1
0
Fork 0
remarkable-linux/fs/gfs2
Bob Peterson 75f66eeae6 GFS2: Take inode off order_write list when setting jdata flag
[ Upstream commit cc555b09d8 ]

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:07:30 +01:00
..
Kconfig Finally eradicate CONFIG_HOTPLUG 2013-06-03 14:20:18 -07:00
Makefile GFS2: Rename ops_inode.c to inode.c 2011-05-10 13:12:49 +01:00
acl.c posix_acl: Clear SGID bit when setting file permissions 2016-09-22 10:55:32 +02:00
acl.h gfs2: Switch to generic xattr handlers 2016-05-12 22:28:05 -04:00
aops.c gfs2: Remove dirty buffer warning from gfs2_releasepage 2016-08-18 08:57:04 -05:00
bmap.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
bmap.h GFS2: Clean up journal extent mapping 2014-03-03 13:50:12 +00:00
dentry.c gfs2: Lock holder cleanup 2016-06-27 09:47:09 -05:00
dir.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
dir.h GFS2: Make rename not save dirent location 2014-10-01 14:06:15 +01:00
export.c gfs2: Get rid of gfs2_ilookup 2016-06-27 09:47:08 -05:00
file.c GFS2: Take inode off order_write list when setting jdata flag 2017-12-20 10:07:30 +01:00
gfs2.h [GFS2] Remove remote lock dropping code 2008-06-27 09:39:44 +01:00
glock.c GFS2: Fix reference to ERR_PTR in gfs2_glock_iter_next 2017-10-08 10:26:02 +02:00
glock.h gfs2: Lock holder cleanup 2016-06-27 09:47:09 -05:00
glops.c GFS2: Get rid of dead code in inode_go_demote_ok 2016-04-05 11:59:18 -04:00
glops.h GFS2: update freeze code to use freeze/thaw_super on all nodes 2014-11-17 10:36:39 +00:00
incore.h gfs2: Fix glock rhashtable rcu bug 2017-07-12 15:01:06 +02:00
inode.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
inode.h GFS2: use BIT() macro 2016-08-02 12:05:27 -05:00
lock_dlm.c remove abs64() 2015-11-09 15:11:24 -08:00
log.c gfs2: use bio op accessors 2016-06-07 13:41:38 -06:00
log.h GFS2: remove transaction glock 2014-05-14 10:04:34 +01:00
lops.c Merge branch 'for-4.8/core' of git://git.kernel.dk/linux-block 2016-07-26 15:03:07 -07:00
lops.h gfs2: use bio op accessors 2016-06-07 13:41:38 -06:00
main.c gfs2: fix to detect failure of register_shrinker 2016-09-21 12:09:40 -05:00
meta_io.c gfs2: Fix extended attribute readahead optimization 2016-08-18 11:36:41 -05:00
meta_io.h GFS2: Refactor gfs2_remove_from_journal 2016-05-06 11:27:27 -05:00
ops_fstype.c GFS2: use BIT() macro 2016-08-02 12:05:27 -05:00
quota.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2016-10-10 20:16:43 -07:00
quota.h GFS2: Make rgrp reservations part of the gfs2_inode structure 2015-12-14 12:16:38 -06:00
recovery.c GFS2: Fix gfs2_replay_incr_blk for multiple journal sizes 2016-07-21 13:02:44 -05:00
recovery.h GFS2: Fix gfs2_replay_incr_blk for multiple journal sizes 2016-07-21 13:02:44 -05:00
rgrp.c GFS2: Check rs_free with rd_rsspin protection 2016-07-12 11:48:22 -05:00
rgrp.h GFS2: Make rgrp reservations part of the gfs2_inode structure 2015-12-14 12:16:38 -06:00
super.c GFS2: use BIT() macro 2016-08-02 12:05:27 -05:00
super.h GFS2: update freeze code to use freeze/thaw_super on all nodes 2014-11-17 10:36:39 +00:00
sys.c gfs2: convert simple_str to kstr 2015-05-05 13:23:22 -05:00
sys.h GFS2: dlm based recovery coordination 2012-01-11 09:23:05 +00:00
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 GFS2: Split gfs2_trans_add_bh() into two 2013-01-29 10:28:04 +00:00
util.c GFS2: ignore unlock failures after withdraw 2016-03-24 08:28:48 -04:00
util.h GFS2: Make rgrp reservations part of the gfs2_inode structure 2015-12-14 12:16:38 -06:00
xattr.c fs: Replace CURRENT_TIME with current_time() for inode timestamps 2016-09-27 21:06:21 -04:00
xattr.h gfs2: Remove gfs2_xattr_acl_chmod 2015-12-06 21:25:17 -05:00