@@ -1340,6 +1340,37 @@ static bool fuse_dio_wr_exclusive_lock(struct kiocb *iocb, struct iov_iter *from
13401340 return false;
13411341}
13421342
1343+ static void fuse_dio_lock (struct kiocb * iocb , struct iov_iter * from ,
1344+ bool * exclusive )
1345+ {
1346+ struct inode * inode = file_inode (iocb -> ki_filp );
1347+
1348+ * exclusive = fuse_dio_wr_exclusive_lock (iocb , from );
1349+ if (* exclusive ) {
1350+ inode_lock (inode );
1351+ } else {
1352+ inode_lock_shared (inode );
1353+ /*
1354+ * Previous check was without inode lock and might have raced,
1355+ * check again.
1356+ */
1357+ if (fuse_io_past_eof (iocb , from )) {
1358+ inode_unlock_shared (inode );
1359+ inode_lock (inode );
1360+ * exclusive = true;
1361+ }
1362+ }
1363+ }
1364+
1365+ static void fuse_dio_unlock (struct inode * inode , bool exclusive )
1366+ {
1367+ if (exclusive ) {
1368+ inode_unlock (inode );
1369+ } else {
1370+ inode_unlock_shared (inode );
1371+ }
1372+ }
1373+
13431374static ssize_t fuse_cache_write_iter (struct kiocb * iocb , struct iov_iter * from )
13441375{
13451376 struct file * file = iocb -> ki_filp ;
@@ -1604,30 +1635,9 @@ static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from)
16041635 struct inode * inode = file_inode (iocb -> ki_filp );
16051636 struct fuse_io_priv io = FUSE_IO_PRIV_SYNC (iocb );
16061637 ssize_t res ;
1607- bool exclusive_lock = fuse_dio_wr_exclusive_lock (iocb , from );
1608-
1609- /*
1610- * Take exclusive lock if
1611- * - Parallel direct writes are disabled - a user space decision
1612- * - Parallel direct writes are enabled and i_size is being extended.
1613- * - Shared mmap on direct_io file is supported (FUSE_DIRECT_IO_ALLOW_MMAP).
1614- * This might not be needed at all, but needs further investigation.
1615- */
1616- if (exclusive_lock )
1617- inode_lock (inode );
1618- else {
1619- inode_lock_shared (inode );
1620-
1621- /*
1622- * Previous check was without any lock and might have raced.
1623- */
1624- if (fuse_io_past_eof (iocb , from )) {
1625- inode_unlock_shared (inode );
1626- inode_lock (inode );
1627- exclusive_lock = true;
1628- }
1629- }
1638+ bool exclusive ;
16301639
1640+ fuse_dio_lock (iocb , from , & exclusive );
16311641 res = generic_write_checks (iocb , from );
16321642 if (res > 0 ) {
16331643 if (!is_sync_kiocb (iocb ) && iocb -> ki_flags & IOCB_DIRECT ) {
@@ -1638,10 +1648,7 @@ static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from)
16381648 fuse_write_update_attr (inode , iocb -> ki_pos , res );
16391649 }
16401650 }
1641- if (exclusive_lock )
1642- inode_unlock (inode );
1643- else
1644- inode_unlock_shared (inode );
1651+ fuse_dio_unlock (inode , exclusive );
16451652
16461653 return res ;
16471654}
0 commit comments