Commit fa67ac18eff4b59b7937c59e821f8b4be812113c
Committed by
Greg Kroah-Hartman
1 parent
9ebfb4fa3a
Exists in
smarct4x-processor-sdk-04.01.00.06
and in
1 other branch
udf: Fix deadlock between writeback and udf_setsize()
commit f2e95355891153f66d4156bf3a142c6489cd78c6 upstream. udf_setsize() called truncate_setsize() with i_data_sem held. Thus truncate_pagecache() called from truncate_setsize() could lock a page under i_data_sem which can deadlock as page lock ranks below i_data_sem - e. g. writeback can hold page lock and try to acquire i_data_sem to map a block. Fix the problem by moving truncate_setsize() calls from under i_data_sem. It is safe for us to change i_size without holding i_data_sem as all the places that depend on i_size being stable already hold inode_lock. Fixes: 7e49b6f2480cb9a9e7322a91592e56a5c85361f5 Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 1 changed file with 2 additions and 2 deletions Side-by-side Diff
fs/udf/inode.c
... | ... | @@ -1243,8 +1243,8 @@ |
1243 | 1243 | return err; |
1244 | 1244 | } |
1245 | 1245 | set_size: |
1246 | - truncate_setsize(inode, newsize); | |
1247 | 1246 | up_write(&iinfo->i_data_sem); |
1247 | + truncate_setsize(inode, newsize); | |
1248 | 1248 | } else { |
1249 | 1249 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
1250 | 1250 | down_write(&iinfo->i_data_sem); |
1251 | 1251 | |
... | ... | @@ -1261,9 +1261,9 @@ |
1261 | 1261 | udf_get_block); |
1262 | 1262 | if (err) |
1263 | 1263 | return err; |
1264 | + truncate_setsize(inode, newsize); | |
1264 | 1265 | down_write(&iinfo->i_data_sem); |
1265 | 1266 | udf_clear_extent_cache(inode); |
1266 | - truncate_setsize(inode, newsize); | |
1267 | 1267 | udf_truncate_extents(inode); |
1268 | 1268 | up_write(&iinfo->i_data_sem); |
1269 | 1269 | } |