Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

orangefs: fix deadlock; do not write i_size in read_iter

After do_readv_writev, the inode cache is invalidated anyway, so i_size
will never be read. It will be fetched from the server which will also
know about updates from other machines.

Fixes deadlock on 32-bit SMP.

See https://marc.info/?l=linux-fsdevel&m=151268557427760&w=2

Signed-off-by: Martin Brandenburg <martin@omnibond.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Mike Marshall <hubcap@omnibond.com>
Cc: stable@vger.kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Martin Brandenburg and committed by
Linus Torvalds
6793f1c4 6e20630e

+2 -16
+2 -5
fs/orangefs/file.c
··· 452 452 static ssize_t orangefs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) 453 453 { 454 454 struct file *file = iocb->ki_filp; 455 - loff_t pos = *(&iocb->ki_pos); 455 + loff_t pos = iocb->ki_pos; 456 456 ssize_t rc = 0; 457 457 458 458 BUG_ON(iocb->private); ··· 492 492 } 493 493 } 494 494 495 - if (file->f_pos > i_size_read(file->f_mapping->host)) 496 - orangefs_i_size_write(file->f_mapping->host, file->f_pos); 497 - 498 495 rc = generic_write_checks(iocb, iter); 499 496 500 497 if (rc <= 0) { ··· 505 508 * pos to the end of the file, so we will wait till now to set 506 509 * pos... 507 510 */ 508 - pos = *(&iocb->ki_pos); 511 + pos = iocb->ki_pos; 509 512 510 513 rc = do_readv_writev(ORANGEFS_IO_WRITE, 511 514 file,
-11
fs/orangefs/orangefs-kernel.h
··· 533 533 sys_attr.mask = ORANGEFS_ATTR_SYS_ALL_SETABLE; \ 534 534 } while (0) 535 535 536 - static inline void orangefs_i_size_write(struct inode *inode, loff_t i_size) 537 - { 538 - #if BITS_PER_LONG == 32 && defined(CONFIG_SMP) 539 - inode_lock(inode); 540 - #endif 541 - i_size_write(inode, i_size); 542 - #if BITS_PER_LONG == 32 && defined(CONFIG_SMP) 543 - inode_unlock(inode); 544 - #endif 545 - } 546 - 547 536 static inline void orangefs_set_timeout(struct dentry *dentry) 548 537 { 549 538 unsigned long time = jiffies + orangefs_dcache_timeout_msecs*HZ/1000;