@@ -1340,6 +1340,37 @@ static bool fuse_dio_wr_exclusive_lock(struct kiocb *iocb, struct iov_iter *from
1340
1340
return false;
1341
1341
}
1342
1342
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
+
1343
1374
static ssize_t fuse_cache_write_iter (struct kiocb * iocb , struct iov_iter * from )
1344
1375
{
1345
1376
struct file * file = iocb -> ki_filp ;
@@ -1604,30 +1635,9 @@ static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from)
1604
1635
struct inode * inode = file_inode (iocb -> ki_filp );
1605
1636
struct fuse_io_priv io = FUSE_IO_PRIV_SYNC (iocb );
1606
1637
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 ;
1630
1639
1640
+ fuse_dio_lock (iocb , from , & exclusive );
1631
1641
res = generic_write_checks (iocb , from );
1632
1642
if (res > 0 ) {
1633
1643
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)
1638
1648
fuse_write_update_attr (inode , iocb -> ki_pos , res );
1639
1649
}
1640
1650
}
1641
- if (exclusive_lock )
1642
- inode_unlock (inode );
1643
- else
1644
- inode_unlock_shared (inode );
1651
+ fuse_dio_unlock (inode , exclusive );
1645
1652
1646
1653
return res ;
1647
1654
}
0 commit comments