mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-08 04:55:21 +00:00
Compare commits
2 Commits
cw/go_rest
...
zab/read_m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8efb30afbc | ||
|
|
df90b3eb90 |
@@ -29,7 +29,12 @@
|
||||
#include "per_task.h"
|
||||
#include "omap.h"
|
||||
|
||||
/* TODO: Direct I/O, AIO */
|
||||
/*
|
||||
* Start a high level file read. We check for offline extents in the
|
||||
* read region here so that we only check the extents once. We use the
|
||||
* dio count to prevent releasing while we're reading after we've
|
||||
* checked the extents.
|
||||
*/
|
||||
ssize_t scoutfs_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
|
||||
unsigned long nr_segs, loff_t pos)
|
||||
{
|
||||
@@ -43,30 +48,32 @@ ssize_t scoutfs_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
|
||||
int ret;
|
||||
|
||||
retry:
|
||||
/* protect checked extents from release */
|
||||
mutex_lock(&inode->i_mutex);
|
||||
atomic_inc(&inode->i_dio_count);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
ret = scoutfs_lock_inode(sb, SCOUTFS_LOCK_READ,
|
||||
SCOUTFS_LKF_REFRESH_INODE, inode, &inode_lock);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (scoutfs_per_task_add_excl(&si->pt_data_lock, &pt_ent, inode_lock)) {
|
||||
/* protect checked extents from stage/release */
|
||||
mutex_lock(&inode->i_mutex);
|
||||
atomic_inc(&inode->i_dio_count);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
ret = scoutfs_data_wait_check_iov(inode, iov, nr_segs, pos,
|
||||
SEF_OFFLINE,
|
||||
SCOUTFS_IOC_DWO_READ,
|
||||
&dw, inode_lock);
|
||||
if (ret != 0)
|
||||
goto out;
|
||||
} else {
|
||||
WARN_ON_ONCE(true);
|
||||
}
|
||||
|
||||
ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
|
||||
|
||||
out:
|
||||
if (scoutfs_per_task_del(&si->pt_data_lock, &pt_ent))
|
||||
inode_dio_done(inode);
|
||||
inode_dio_done(inode);
|
||||
scoutfs_per_task_del(&si->pt_data_lock, &pt_ent);
|
||||
scoutfs_unlock(sb, inode_lock, SCOUTFS_LOCK_READ);
|
||||
|
||||
if (scoutfs_data_wait_found(&dw)) {
|
||||
|
||||
0
tests/golden/export-lookup-evict-race
Normal file
0
tests/golden/export-lookup-evict-race
Normal file
@@ -13,6 +13,7 @@ lock-refleak.sh
|
||||
lock-shrink-consistency.sh
|
||||
lock-pr-cw-conflict.sh
|
||||
lock-revoke-getcwd.sh
|
||||
export-lookup-evict-race.sh
|
||||
createmany-parallel.sh
|
||||
createmany-large-names.sh
|
||||
createmany-rename-large-dir.sh
|
||||
|
||||
32
tests/tests/export-lookup-evict-race.sh
Normal file
32
tests/tests/export-lookup-evict-race.sh
Normal file
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# test racing fh_to_dentry with evict from lock invalidation. We've
|
||||
# had deadlocks between the ordering of iget and evict when they acquire
|
||||
# cluster locks.
|
||||
#
|
||||
|
||||
t_require_commands touch stat handle_cat
|
||||
t_require_mounts 2
|
||||
|
||||
CPUS=$(getconf _NPROCESSORS_ONLN)
|
||||
NR=$((CPUS * 4))
|
||||
END=$((SECONDS + 30))
|
||||
|
||||
touch "$T_D0/file"
|
||||
ino=$(stat -c "%i" "$T_D0/file")
|
||||
|
||||
while test $SECONDS -lt $END; do
|
||||
for i in $(seq 1 $NR); do
|
||||
fs=$((RANDOM % T_NR_MOUNTS))
|
||||
eval dir="\$T_D${fs}"
|
||||
write=$((RANDOM & 1))
|
||||
|
||||
if [ "$write" == 1 ]; then
|
||||
touch "$dir/file" &
|
||||
else
|
||||
handle_cat "$dir" "$ino" &
|
||||
fi
|
||||
done
|
||||
wait
|
||||
done
|
||||
|
||||
t_pass
|
||||
Reference in New Issue
Block a user