mirror of
https://github.com/versity/scoutfs.git
synced 2026-06-09 21:22:36 +00:00
Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bcf559818b | |||
| 36ee4d946b | |||
| dc57b34b8d | |||
| 779b96df81 | |||
| 1ee0331b8b | |||
| 42acf01dce | |||
| ca4d463c75 | |||
| e7dadd09ae | |||
| 954843d2ab | |||
| 5968265aad | |||
| f30c095e8e | |||
| 1578ded917 | |||
| 2c21f88f24 | |||
| 57356b57aa | |||
| b81e3bf421 | |||
| 5d1742a954 | |||
| 22bd4c4493 | |||
| 371bff49af | |||
| 3d43fdfeaa | |||
| 6563f70a90 | |||
| a14da52cbb | |||
| f367e485a6 | |||
| 8a7bc0cdfa | |||
| e81d16f8db | |||
| bad0455e28 | |||
| 0a30c0b926 | |||
| 84a4000c85 | |||
| 859f63e49b | |||
| 588bdb7969 | |||
| b894f6b04c | |||
| e26573ae8e | |||
| 3f6b98496f | |||
| b8a378ede7 | |||
| 4b08e79988 | |||
| 2ac28c4969 | |||
| 3608d1aae1 | |||
| f13757f0af | |||
| 34e6efd39c | |||
| b452ca3d23 | |||
| 090c795b7e | |||
| d9394cb084 | |||
| 67ae352618 | |||
| 38bb5a8254 | |||
| 2510688a36 | |||
| 15a5dca8c6 | |||
| c3996cb021 |
@@ -1,22 +1,6 @@
|
||||
Versity ScoutFS Release Notes
|
||||
=============================
|
||||
|
||||
---
|
||||
v1.17
|
||||
\
|
||||
*Oct 23, 2023*
|
||||
|
||||
Add support for EL8 generation kernels.
|
||||
|
||||
---
|
||||
v1.16
|
||||
\
|
||||
*Oct 4, 2023*
|
||||
|
||||
Fix an issue where the server could hang on startup if its persistent
|
||||
allocator structures were left in a specific degraded state by the
|
||||
previously active server.
|
||||
|
||||
---
|
||||
v1.15
|
||||
\
|
||||
|
||||
+1
-1
@@ -1078,7 +1078,7 @@ static unsigned long block_count_objects(struct shrinker *shrink, struct shrink_
|
||||
|
||||
scoutfs_inc_counter(sb, block_cache_count_objects);
|
||||
|
||||
return shrinker_min_long(atomic_read(&binf->total_inserted));
|
||||
return shrinker_min_t_long((u64)atomic_read(&binf->total_inserted));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+65
-19
@@ -1058,15 +1058,16 @@ static int symlink_item_ops(struct super_block *sb, enum symlink_ops op, u64 ino
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef KC_LINUX_HAVE_RHEL_IOPS_WRAPPER
|
||||
/*
|
||||
* Fill a buffer with the null terminated symlink, and return it
|
||||
* so callers can free it once the vfs is done.
|
||||
* Full a buffer with the null terminated symlink, point nd at it, and
|
||||
* return it so put_link can free it once the vfs is done.
|
||||
*
|
||||
* We chose to pay the runtime cost of per-call allocation and copy
|
||||
* overhead instead of wiring up symlinks to the page cache, storing
|
||||
* each small link in a full page, and later having to reclaim them.
|
||||
*/
|
||||
static void *scoutfs_get_link_target(struct dentry *dentry)
|
||||
static void *scoutfs_follow_link(struct dentry *dentry, struct nameidata *nd)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
@@ -1125,20 +1126,10 @@ out:
|
||||
if (ret < 0) {
|
||||
kfree(path);
|
||||
path = ERR_PTR(ret);
|
||||
}
|
||||
|
||||
scoutfs_unlock(sb, inode_lock, SCOUTFS_LOCK_READ);
|
||||
return path;
|
||||
}
|
||||
|
||||
#ifdef KC_LINUX_HAVE_RHEL_IOPS_WRAPPER
|
||||
static void *scoutfs_follow_link(struct dentry *dentry, struct nameidata *nd)
|
||||
{
|
||||
char *path;
|
||||
|
||||
path = scoutfs_get_link_target(dentry);
|
||||
if (!IS_ERR_OR_NULL(path))
|
||||
} else {
|
||||
nd_set_link(nd, path);
|
||||
}
|
||||
scoutfs_unlock(sb, inode_lock, SCOUTFS_LOCK_READ);
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -1151,12 +1142,67 @@ static void scoutfs_put_link(struct dentry *dentry, struct nameidata *nd,
|
||||
#else
|
||||
static const char *scoutfs_get_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done)
|
||||
{
|
||||
char *path;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
struct scoutfs_lock *inode_lock = NULL;
|
||||
char *path = NULL;
|
||||
loff_t size;
|
||||
int ret;
|
||||
|
||||
path = scoutfs_get_link_target(dentry);
|
||||
if (!IS_ERR_OR_NULL(path))
|
||||
ret = scoutfs_lock_inode(sb, SCOUTFS_LOCK_READ,
|
||||
SCOUTFS_LKF_REFRESH_INODE, inode, &inode_lock);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
size = i_size_read(inode);
|
||||
|
||||
if (size == 0 || size > SCOUTFS_SYMLINK_MAX_SIZE) {
|
||||
scoutfs_corruption(sb, SC_SYMLINK_INODE_SIZE,
|
||||
corrupt_symlink_inode_size,
|
||||
"ino %llu size %llu",
|
||||
scoutfs_ino(inode), (u64)size);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* unlikely, but possible I suppose */
|
||||
if (size > PATH_MAX) {
|
||||
ret = -ENAMETOOLONG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
path = kmalloc(size, GFP_NOFS);
|
||||
if (!path) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = symlink_item_ops(sb, SYM_LOOKUP, scoutfs_ino(inode), inode_lock,
|
||||
path, size);
|
||||
|
||||
if (ret == -ENOENT) {
|
||||
scoutfs_corruption(sb, SC_SYMLINK_MISSING_ITEM,
|
||||
corrupt_symlink_missing_item,
|
||||
"ino %llu size %llu", scoutfs_ino(inode),
|
||||
size);
|
||||
ret = -EIO;
|
||||
|
||||
} else if (ret == 0 && path[size - 1]) {
|
||||
scoutfs_corruption(sb, SC_SYMLINK_NOT_NULL_TERM,
|
||||
corrupt_symlink_not_null_term,
|
||||
"ino %llu last %u",
|
||||
scoutfs_ino(inode), path[size - 1]);
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
if (ret != -EIO)
|
||||
set_delayed_call(done, kfree_link, path);
|
||||
|
||||
out:
|
||||
if (ret < 0) {
|
||||
kfree(path);
|
||||
path = ERR_PTR(ret);
|
||||
}
|
||||
scoutfs_unlock(sb, inode_lock, SCOUTFS_LOCK_READ);
|
||||
return path;
|
||||
}
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -2541,7 +2541,7 @@ static unsigned long item_cache_count_objects(struct shrinker *shrink,
|
||||
|
||||
scoutfs_inc_counter(sb, item_cache_count_objects);
|
||||
|
||||
return shrinker_min_long(cinf->lru_pages);
|
||||
return shrinker_min_t_long((u64)(cinf->lru_pages));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -1409,7 +1409,7 @@ static unsigned long lock_count_objects(struct shrinker *shrink,
|
||||
|
||||
scoutfs_inc_counter(sb, lock_count_objects);
|
||||
|
||||
return shrinker_min_long(linfo->lru_nr);
|
||||
return shrinker_min_t_long((u64)(linfo->lru_nr));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+12
-16
@@ -1896,9 +1896,8 @@ DEFINE_EVENT(scoutfs_server_client_count_class, scoutfs_server_client_down,
|
||||
|
||||
DECLARE_EVENT_CLASS(scoutfs_server_commit_users_class,
|
||||
TP_PROTO(struct super_block *sb, int holding, int applying, int nr_holders,
|
||||
u32 avail_before, u32 freed_before, int committing, int exceeded),
|
||||
TP_ARGS(sb, holding, applying, nr_holders, avail_before, freed_before, committing,
|
||||
exceeded),
|
||||
u32 avail_before, u32 freed_before, int exceeded),
|
||||
TP_ARGS(sb, holding, applying, nr_holders, avail_before, freed_before, exceeded),
|
||||
TP_STRUCT__entry(
|
||||
SCSB_TRACE_FIELDS
|
||||
__field(int, holding)
|
||||
@@ -1906,7 +1905,6 @@ DECLARE_EVENT_CLASS(scoutfs_server_commit_users_class,
|
||||
__field(int, nr_holders)
|
||||
__field(__u32, avail_before)
|
||||
__field(__u32, freed_before)
|
||||
__field(int, committing)
|
||||
__field(int, exceeded)
|
||||
),
|
||||
TP_fast_assign(
|
||||
@@ -1916,33 +1914,31 @@ DECLARE_EVENT_CLASS(scoutfs_server_commit_users_class,
|
||||
__entry->nr_holders = nr_holders;
|
||||
__entry->avail_before = avail_before;
|
||||
__entry->freed_before = freed_before;
|
||||
__entry->committing = !!committing;
|
||||
__entry->exceeded = !!exceeded;
|
||||
),
|
||||
TP_printk(SCSBF" holding %u applying %u nr %u avail_before %u freed_before %u committing %u exceeded %u",
|
||||
TP_printk(SCSBF" holding %u applying %u nr %u avail_before %u freed_before %u exceeded %u",
|
||||
SCSB_TRACE_ARGS, __entry->holding, __entry->applying, __entry->nr_holders,
|
||||
__entry->avail_before, __entry->freed_before, __entry->committing,
|
||||
__entry->exceeded)
|
||||
__entry->avail_before, __entry->freed_before, __entry->exceeded)
|
||||
);
|
||||
DEFINE_EVENT(scoutfs_server_commit_users_class, scoutfs_server_commit_hold,
|
||||
TP_PROTO(struct super_block *sb, int holding, int applying, int nr_holders,
|
||||
u32 avail_before, u32 freed_before, int committing, int exceeded),
|
||||
TP_ARGS(sb, holding, applying, nr_holders, avail_before, freed_before, committing, exceeded)
|
||||
u32 avail_before, u32 freed_before, int exceeded),
|
||||
TP_ARGS(sb, holding, applying, nr_holders, avail_before, freed_before, exceeded)
|
||||
);
|
||||
DEFINE_EVENT(scoutfs_server_commit_users_class, scoutfs_server_commit_apply,
|
||||
TP_PROTO(struct super_block *sb, int holding, int applying, int nr_holders,
|
||||
u32 avail_before, u32 freed_before, int committing, int exceeded),
|
||||
TP_ARGS(sb, holding, applying, nr_holders, avail_before, freed_before, committing, exceeded)
|
||||
u32 avail_before, u32 freed_before, int exceeded),
|
||||
TP_ARGS(sb, holding, applying, nr_holders, avail_before, freed_before, exceeded)
|
||||
);
|
||||
DEFINE_EVENT(scoutfs_server_commit_users_class, scoutfs_server_commit_start,
|
||||
TP_PROTO(struct super_block *sb, int holding, int applying, int nr_holders,
|
||||
u32 avail_before, u32 freed_before, int committing, int exceeded),
|
||||
TP_ARGS(sb, holding, applying, nr_holders, avail_before, freed_before, committing, exceeded)
|
||||
u32 avail_before, u32 freed_before, int exceeded),
|
||||
TP_ARGS(sb, holding, applying, nr_holders, avail_before, freed_before, exceeded)
|
||||
);
|
||||
DEFINE_EVENT(scoutfs_server_commit_users_class, scoutfs_server_commit_end,
|
||||
TP_PROTO(struct super_block *sb, int holding, int applying, int nr_holders,
|
||||
u32 avail_before, u32 freed_before, int committing, int exceeded),
|
||||
TP_ARGS(sb, holding, applying, nr_holders, avail_before, freed_before, committing, exceeded)
|
||||
u32 avail_before, u32 freed_before, int exceeded),
|
||||
TP_ARGS(sb, holding, applying, nr_holders, avail_before, freed_before, exceeded)
|
||||
);
|
||||
|
||||
#define slt_symbolic(mode) \
|
||||
|
||||
+37
-60
@@ -67,7 +67,6 @@ struct commit_users {
|
||||
unsigned int nr_holders;
|
||||
u32 avail_before;
|
||||
u32 freed_before;
|
||||
bool committing;
|
||||
bool exceeded;
|
||||
};
|
||||
|
||||
@@ -85,7 +84,7 @@ do { \
|
||||
__typeof__(cusers) _cusers = (cusers); \
|
||||
trace_scoutfs_server_commit_##which(sb, !list_empty(&_cusers->holding), \
|
||||
!list_empty(&_cusers->applying), _cusers->nr_holders, _cusers->avail_before, \
|
||||
_cusers->freed_before, _cusers->committing, _cusers->exceeded); \
|
||||
_cusers->freed_before, _cusers->exceeded); \
|
||||
} while (0)
|
||||
|
||||
struct server_info {
|
||||
@@ -283,14 +282,6 @@ struct commit_hold {
|
||||
* per-holder allocation consumption tracking. The best we can do is
|
||||
* flag all the current holders so that as they release we can see
|
||||
* everyone involved in crossing the limit.
|
||||
*
|
||||
* The consumption of space to record freed blocks is tricky. The
|
||||
* freed_before value was the space available as the holder started.
|
||||
* But that happens before we actually dirty the first block in the
|
||||
* freed list. If that block is too full then we just allocate a new
|
||||
* empty first block. In that case the current remaining here can be a
|
||||
* lot more than the initial freed_before. We account for that and
|
||||
* treat freed_before as the maximum capacity.
|
||||
*/
|
||||
static void check_holder_budget(struct super_block *sb, struct server_info *server,
|
||||
struct commit_users *cusers)
|
||||
@@ -310,13 +301,8 @@ static void check_holder_budget(struct super_block *sb, struct server_info *serv
|
||||
return;
|
||||
|
||||
scoutfs_alloc_meta_remaining(&server->alloc, &avail_now, &freed_now);
|
||||
|
||||
avail_used = cusers->avail_before - avail_now;
|
||||
if (freed_now < cusers->freed_before)
|
||||
freed_used = cusers->freed_before - freed_now;
|
||||
else
|
||||
freed_used = SCOUTFS_ALLOC_LIST_MAX_BLOCKS - freed_now;
|
||||
|
||||
freed_used = cusers->freed_before - freed_now;
|
||||
budget = cusers->nr_holders * COMMIT_HOLD_ALLOC_BUDGET;
|
||||
if (avail_used <= budget && freed_used <= budget)
|
||||
return;
|
||||
@@ -339,18 +325,31 @@ static void check_holder_budget(struct super_block *sb, struct server_info *serv
|
||||
/*
|
||||
* We don't have per-holder consumption. We allow commit holders as
|
||||
* long as the total budget of all the holders doesn't exceed the alloc
|
||||
* resources that were available. If a hold is waiting for budget
|
||||
* availability in the allocators then we try and kick off a commit to
|
||||
* fill and use the next allocators after the current transaction.
|
||||
* resources that were available
|
||||
*/
|
||||
static bool commit_alloc_has_room(struct server_info *server, struct commit_users *cusers,
|
||||
unsigned int more_holders)
|
||||
{
|
||||
u32 avail_before;
|
||||
u32 freed_before;
|
||||
u32 budget;
|
||||
|
||||
if (cusers->nr_holders > 0) {
|
||||
avail_before = cusers->avail_before;
|
||||
freed_before = cusers->freed_before;
|
||||
} else {
|
||||
scoutfs_alloc_meta_remaining(&server->alloc, &avail_before, &freed_before);
|
||||
}
|
||||
|
||||
budget = (cusers->nr_holders + more_holders) * COMMIT_HOLD_ALLOC_BUDGET;
|
||||
|
||||
return avail_before >= budget && freed_before >= budget;
|
||||
}
|
||||
|
||||
static bool hold_commit(struct super_block *sb, struct server_info *server,
|
||||
struct commit_users *cusers, struct commit_hold *hold)
|
||||
{
|
||||
bool has_room;
|
||||
bool held;
|
||||
u32 budget;
|
||||
u32 av;
|
||||
u32 fr;
|
||||
bool held = false;
|
||||
|
||||
spin_lock(&cusers->lock);
|
||||
|
||||
@@ -358,39 +357,19 @@ static bool hold_commit(struct super_block *sb, struct server_info *server,
|
||||
|
||||
check_holder_budget(sb, server, cusers);
|
||||
|
||||
if (cusers->nr_holders == 0) {
|
||||
scoutfs_alloc_meta_remaining(&server->alloc, &av, &fr);
|
||||
} else {
|
||||
av = cusers->avail_before;
|
||||
fr = cusers->freed_before;
|
||||
}
|
||||
|
||||
/* +2 for our additional hold and then for the final commit work the server does */
|
||||
budget = (cusers->nr_holders + 2) * COMMIT_HOLD_ALLOC_BUDGET;
|
||||
has_room = av >= budget && fr >= budget;
|
||||
/* checking applying so holders drain once an apply caller starts waiting */
|
||||
held = !cusers->committing && has_room && list_empty(&cusers->applying);
|
||||
|
||||
if (held) {
|
||||
if (list_empty(&cusers->applying) && commit_alloc_has_room(server, cusers, 2)) {
|
||||
scoutfs_alloc_meta_remaining(&server->alloc, &hold->avail, &hold->freed);
|
||||
if (cusers->nr_holders == 0) {
|
||||
cusers->avail_before = av;
|
||||
cusers->freed_before = fr;
|
||||
hold->avail = av;
|
||||
hold->freed = fr;
|
||||
cusers->avail_before = hold->avail;
|
||||
cusers->freed_before = hold->freed;
|
||||
cusers->exceeded = false;
|
||||
} else {
|
||||
scoutfs_alloc_meta_remaining(&server->alloc, &hold->avail, &hold->freed);
|
||||
}
|
||||
|
||||
hold->exceeded = false;
|
||||
hold->start = ktime_get();
|
||||
list_add_tail(&hold->entry, &cusers->holding);
|
||||
|
||||
cusers->nr_holders++;
|
||||
|
||||
} else if (!has_room && cusers->nr_holders == 0 && !cusers->committing) {
|
||||
cusers->committing = true;
|
||||
queue_work(server->wq, &server->commit_work);
|
||||
held = true;
|
||||
}
|
||||
|
||||
spin_unlock(&cusers->lock);
|
||||
@@ -424,6 +403,7 @@ static int server_apply_commit(struct super_block *sb, struct commit_hold *hold,
|
||||
DECLARE_SERVER_INFO(sb, server);
|
||||
struct commit_users *cusers = &server->cusers;
|
||||
struct timespec ts;
|
||||
bool start_commit;
|
||||
|
||||
spin_lock(&cusers->lock);
|
||||
|
||||
@@ -444,15 +424,13 @@ static int server_apply_commit(struct super_block *sb, struct commit_hold *hold,
|
||||
list_del_init(&hold->entry);
|
||||
hold->ret = err;
|
||||
}
|
||||
|
||||
cusers->nr_holders--;
|
||||
if (cusers->nr_holders == 0 && !cusers->committing && !list_empty(&cusers->applying)) {
|
||||
cusers->committing = true;
|
||||
queue_work(server->wq, &server->commit_work);
|
||||
}
|
||||
|
||||
start_commit = cusers->nr_holders == 0 && !list_empty(&cusers->applying);
|
||||
spin_unlock(&cusers->lock);
|
||||
|
||||
if (start_commit)
|
||||
queue_work(server->wq, &server->commit_work);
|
||||
|
||||
wait_event(cusers->waitq, list_empty_careful(&hold->entry));
|
||||
smp_rmb(); /* entry load before ret */
|
||||
return hold->ret;
|
||||
@@ -460,8 +438,8 @@ static int server_apply_commit(struct super_block *sb, struct commit_hold *hold,
|
||||
|
||||
/*
|
||||
* Start a commit from the commit work. We should only have been queued
|
||||
* while there are no active holders and someone started the commit.
|
||||
* There may or may not be blocked apply callers waiting for the result.
|
||||
* while a holder is waiting to apply after all active holders have
|
||||
* finished.
|
||||
*/
|
||||
static int commit_start(struct super_block *sb, struct commit_users *cusers)
|
||||
{
|
||||
@@ -470,7 +448,7 @@ static int commit_start(struct super_block *sb, struct commit_users *cusers)
|
||||
/* make sure holders held off once commit started */
|
||||
spin_lock(&cusers->lock);
|
||||
TRACE_COMMIT_USERS(sb, cusers, start);
|
||||
if (WARN_ON_ONCE(!cusers->committing || cusers->nr_holders != 0))
|
||||
if (WARN_ON_ONCE(list_empty(&cusers->applying) || cusers->nr_holders != 0))
|
||||
ret = -EINVAL;
|
||||
spin_unlock(&cusers->lock);
|
||||
|
||||
@@ -493,7 +471,6 @@ static void commit_end(struct super_block *sb, struct commit_users *cusers, int
|
||||
smp_wmb(); /* ret stores before list updates */
|
||||
list_for_each_entry_safe(hold, tmp, &cusers->applying, entry)
|
||||
list_del_init(&hold->entry);
|
||||
cusers->committing = false;
|
||||
spin_unlock(&cusers->lock);
|
||||
|
||||
wake_up(&cusers->waitq);
|
||||
@@ -566,7 +543,7 @@ static void set_stable_super(struct server_info *server, struct scoutfs_super_bl
|
||||
* implement commits with a single pending work func.
|
||||
*
|
||||
* Processing paths hold the commit while they're making multiple
|
||||
* dependent changes. When they're done and want it persistent they
|
||||
* dependent changes. When they're done and want it persistent they add
|
||||
* queue the commit work. This work runs, performs the commit, and
|
||||
* wakes all the applying waiters with the result. Readers can run
|
||||
* concurrently with these commits.
|
||||
|
||||
+2
-2
@@ -23,9 +23,9 @@ static inline void down_write_two(struct rw_semaphore *a,
|
||||
* ~0UL values. Hence, we cap count to ~0L, which is arbitarily high
|
||||
* enough to avoid it.
|
||||
*/
|
||||
static inline long shrinker_min_long(long count)
|
||||
static inline unsigned long shrinker_min_t_long(unsigned long count)
|
||||
{
|
||||
return min(count, LONG_MAX);
|
||||
return min_t(u64, count, LONG_MAX);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ t_fail()
|
||||
t_quiet()
|
||||
{
|
||||
echo "# $*" >> "$T_TMPDIR/quiet.log"
|
||||
"$@" >> "$T_TMPDIR/quiet.log" 2>&1 || \
|
||||
"$@" > "$T_TMPDIR/quiet.log" 2>&1 || \
|
||||
t_fail "quiet command failed"
|
||||
}
|
||||
|
||||
|
||||
@@ -88,8 +88,5 @@ t_filter_dmesg()
|
||||
# change-devices causes loop device resizing
|
||||
re="$re|loop[0-9].* detected capacity change from.*"
|
||||
|
||||
# ignore systemd-journal rotating
|
||||
re="$re|systemd-journald.*"
|
||||
|
||||
egrep -v "($re)"
|
||||
}
|
||||
|
||||
@@ -7,11 +7,14 @@ t_require_mounts 2
|
||||
|
||||
#
|
||||
# Make sure that all mounts can read the results of a write from each
|
||||
# mount.
|
||||
# mount. And make sure that the greatest of all the written seqs is
|
||||
# visible after the writes were commited by remote reads.
|
||||
#
|
||||
check_read_write()
|
||||
{
|
||||
local expected
|
||||
local greatest=0
|
||||
local seq
|
||||
local path
|
||||
local saw
|
||||
local w
|
||||
@@ -22,6 +25,11 @@ check_read_write()
|
||||
eval path="\$T_D${w}/written"
|
||||
echo "$expected" > "$path"
|
||||
|
||||
seq=$(scoutfs stat -s meta_seq $path)
|
||||
if [ "$seq" -gt "$greatest" ]; then
|
||||
greatest=$seq
|
||||
fi
|
||||
|
||||
for r in $(t_fs_nrs); do
|
||||
eval path="\$T_D${r}/written"
|
||||
saw=$(cat "$path")
|
||||
@@ -30,6 +38,11 @@ check_read_write()
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
seq=$(scoutfs statfs -s committed_seq -p $T_D0)
|
||||
if [ "$seq" -lt "$greatest" ]; then
|
||||
echo "committed_seq $seq less than greatest $greatest"
|
||||
fi
|
||||
}
|
||||
|
||||
# verify that fenced ran our testing fence script
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
# Some basic tests of online resizing metadata and data devices.
|
||||
#
|
||||
|
||||
t_require_commands bc
|
||||
|
||||
statfs_total() {
|
||||
local single="total_$1_blocks"
|
||||
local mnt="$2"
|
||||
|
||||
Reference in New Issue
Block a user