Skip to content

Commit 9bbb671

Browse files
bsberndMiklos Szeredi
authored andcommitted
fuse: add fuse_dio_lock/unlock helper functions
So far this is just a helper to remove complex locking logic out of fuse_direct_write_iter. Especially needed by the next patch in the series to that adds the fuse inode cache IO mode and adds in even more locking complexity. Signed-off-by: Bernd Schubert <[email protected]> Signed-off-by: Miklos Szeredi <[email protected]>
1 parent 699cf82 commit 9bbb671

File tree

1 file changed

+34
-27
lines changed

1 file changed

+34
-27
lines changed

fs/fuse/file.c

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
13431374
static 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

Comments
 (0)