mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-07 20:45:18 +00:00
Compare commits
24 Commits
zab/server
...
auke/hole_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3879728cf3 | ||
|
|
f7f7980da7 | ||
|
|
6a1c6e3808 | ||
|
|
3848c16a3e | ||
|
|
1c7678b6f5 | ||
|
|
22b5e79bbd | ||
|
|
259e639271 | ||
|
|
4d66c38c71 | ||
|
|
7ef62894bd | ||
|
|
1f363a1ead | ||
|
|
8ddf9b8c8c | ||
|
|
fd80c17ab6 | ||
|
|
991e2cbdf8 | ||
|
|
92ac132873 | ||
|
|
ad078cd93c | ||
|
|
90cb458cd5 | ||
|
|
1ab798e7eb | ||
|
|
e182914e51 | ||
|
|
8484a58dd6 | ||
|
|
a077104531 | ||
|
|
23aaa994df | ||
|
|
7d14b57b2d | ||
|
|
3f252be4be | ||
|
|
a4d25d9b55 |
@@ -1,6 +1,41 @@
|
||||
Versity ScoutFS Release Notes
|
||||
=============================
|
||||
|
||||
---
|
||||
v1.26
|
||||
\
|
||||
*Nov 17, 2025*
|
||||
|
||||
Add the ino\_alloc\_per\_lock mount option. This changes the number of
|
||||
inode numbers allocated under each cluster lock and can alleviate lock
|
||||
contention for some patterns of larger file creation.
|
||||
|
||||
Add the tcp\_keepalive\_timeout\_ms mount option. This can enable the
|
||||
system to survive longer periods of networking outages.
|
||||
|
||||
Fix a rare double free of internal btree metadata blocks when merging
|
||||
log trees. The duplicated freed metadata block numbers would cause
|
||||
persistent errors in the server, preventing the server from starting and
|
||||
hanging the system.
|
||||
|
||||
Fix the data\_wait interface to not require the correct data\_version of
|
||||
the inode when raising an error. This lets callers raise errors when
|
||||
they're unable to recall the details of the inode to discover its
|
||||
data\_version.
|
||||
|
||||
Change scoutfs to more aggressively reclaim cached memory when under
|
||||
memory pressure. This makes scoutfs behave more like other kernel
|
||||
components and it integrates better with the reclaim policy heuristics
|
||||
in the VM core of the kernel.
|
||||
|
||||
Change scoutfs to more efficiently transmit and receive socket messages.
|
||||
Under heavy load this can process messages sufficiently more quickly to
|
||||
avoid hung task messages for tasks that were waiting for cluster lock
|
||||
messages to be processed.
|
||||
|
||||
Fix faulty server block commit budget calculations that were generating
|
||||
spurious "holders exceeded alloc budget" console messages.
|
||||
|
||||
---
|
||||
v1.25
|
||||
\
|
||||
|
||||
@@ -1515,6 +1515,93 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Punch holes in offline extents. This is a very specific tool that
|
||||
* only does one job: it converts extents from offline to sparse. It
|
||||
* returns an error if it encounters an extent that isn't offline or has
|
||||
* a block mapping. It ignores i_size completely; it does not test it,
|
||||
* and does not update it.
|
||||
*
|
||||
* The caller has the inode locked in the vfs and performed basic sanity
|
||||
* checks. We manage transactions and the extent_sem which is ordered
|
||||
* inside the transaction.
|
||||
*/
|
||||
int scoutfs_data_punch_offline(struct inode *inode, u64 iblock, u64 last, u64 data_version,
|
||||
struct scoutfs_lock *lock)
|
||||
{
|
||||
struct scoutfs_inode_info *si = SCOUTFS_I(inode);
|
||||
struct super_block *sb = inode->i_sb;
|
||||
struct data_ext_args args = {
|
||||
.ino = scoutfs_ino(inode),
|
||||
.inode = inode,
|
||||
.lock = lock,
|
||||
};
|
||||
struct scoutfs_extent ext;
|
||||
LIST_HEAD(ind_locks);
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (WARN_ON_ONCE(iblock > last)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* idiomatic to call start,last with 0,~0, clamp last to last possible */
|
||||
last = min(last, SCOUTFS_BLOCK_SM_MAX);
|
||||
|
||||
ret = 0;
|
||||
while (iblock <= last) {
|
||||
ret = scoutfs_inode_index_lock_hold(inode, &ind_locks, true, false) ?:
|
||||
scoutfs_dirty_inode_item(inode, lock);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
down_write(&si->extent_sem);
|
||||
|
||||
for (i = 0; i < 32 && (iblock <= last); i++) {
|
||||
ret = scoutfs_ext_next(sb, &data_ext_ops, &args, iblock, 1, &ext);
|
||||
if (ret == -ENOENT || ext.start > last) {
|
||||
iblock = last + 1;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ext.map) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ext.flags & SEF_OFFLINE) {
|
||||
if (iblock > ext.start) {
|
||||
ext.len -= iblock - ext.start;
|
||||
ext.start = iblock;
|
||||
}
|
||||
ext.len = min(ext.len, last - ext.start + 1);
|
||||
ext.flags &= ~SEF_OFFLINE;
|
||||
|
||||
ret = scoutfs_ext_set(sb, &data_ext_ops, &args,
|
||||
ext.start, ext.len, ext.map, ext.flags);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
iblock = ext.start + ext.len;
|
||||
}
|
||||
|
||||
up_write(&si->extent_sem);
|
||||
|
||||
scoutfs_update_inode_item(inode, lock, &ind_locks);
|
||||
scoutfs_release_trans(sb);
|
||||
scoutfs_inode_index_unlock(sb, &ind_locks);
|
||||
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This copies to userspace :/
|
||||
*/
|
||||
|
||||
@@ -57,6 +57,8 @@ int scoutfs_data_init_offline_extent(struct inode *inode, u64 size,
|
||||
int scoutfs_data_move_blocks(struct inode *from, u64 from_off,
|
||||
u64 byte_len, struct inode *to, u64 to_off, bool to_stage,
|
||||
u64 data_version);
|
||||
int scoutfs_data_punch_offline(struct inode *inode, u64 iblock, u64 last, u64 data_version,
|
||||
struct scoutfs_lock *lock);
|
||||
|
||||
int scoutfs_data_wait_check(struct inode *inode, loff_t pos, loff_t len,
|
||||
u8 sef, u8 op, struct scoutfs_data_wait *ow,
|
||||
|
||||
@@ -1482,12 +1482,6 @@ static int remove_index_items(struct super_block *sb, u64 ino,
|
||||
* Return an allocated and unused inode number. Returns -ENOSPC if
|
||||
* we're out of inode.
|
||||
*
|
||||
* Each parent directory has its own pool of free inode numbers. Items
|
||||
* are sorted by their inode numbers as they're stored in segments.
|
||||
* This will tend to group together files that are created in a
|
||||
* directory at the same time in segments. Concurrent creation across
|
||||
* different directories will be stored in their own regions.
|
||||
*
|
||||
* Inode numbers are never reclaimed. If the inode is evicted or we're
|
||||
* unmounted the pending inode numbers will be lost. Asking for a
|
||||
* relatively small number from the server each time will tend to
|
||||
@@ -1497,12 +1491,18 @@ static int remove_index_items(struct super_block *sb, u64 ino,
|
||||
int scoutfs_alloc_ino(struct super_block *sb, bool is_dir, u64 *ino_ret)
|
||||
{
|
||||
DECLARE_INODE_SB_INFO(sb, inf);
|
||||
struct scoutfs_mount_options opts;
|
||||
struct inode_allocator *ia;
|
||||
u64 ino;
|
||||
u64 nr;
|
||||
int ret;
|
||||
|
||||
ia = is_dir ? &inf->dir_ino_alloc : &inf->ino_alloc;
|
||||
scoutfs_options_read(sb, &opts);
|
||||
|
||||
if (is_dir && opts.ino_alloc_per_lock == SCOUTFS_LOCK_INODE_GROUP_NR)
|
||||
ia = &inf->dir_ino_alloc;
|
||||
else
|
||||
ia = &inf->ino_alloc;
|
||||
|
||||
spin_lock(&ia->lock);
|
||||
|
||||
@@ -1523,6 +1523,17 @@ int scoutfs_alloc_ino(struct super_block *sb, bool is_dir, u64 *ino_ret)
|
||||
*ino_ret = ia->ino++;
|
||||
ia->nr--;
|
||||
|
||||
if (opts.ino_alloc_per_lock != SCOUTFS_LOCK_INODE_GROUP_NR) {
|
||||
nr = ia->ino & SCOUTFS_LOCK_INODE_GROUP_MASK;
|
||||
if (nr >= opts.ino_alloc_per_lock) {
|
||||
nr = SCOUTFS_LOCK_INODE_GROUP_NR - nr;
|
||||
if (nr > ia->nr)
|
||||
nr = ia->nr;
|
||||
ia->ino += nr;
|
||||
ia->nr -= nr;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&ia->lock);
|
||||
ret = 0;
|
||||
out:
|
||||
|
||||
@@ -441,8 +441,6 @@ static long scoutfs_ioc_data_wait_err(struct file *file, unsigned long arg)
|
||||
|
||||
if (!S_ISREG(inode->i_mode)) {
|
||||
ret = -EINVAL;
|
||||
} else if (scoutfs_inode_data_version(inode) != args.data_version) {
|
||||
ret = -ESTALE;
|
||||
} else {
|
||||
ret = scoutfs_data_wait_err(inode, sblock, eblock, args.op,
|
||||
args.err);
|
||||
@@ -1671,6 +1669,78 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long scoutfs_ioc_punch_offline(struct file *file, unsigned long arg)
|
||||
{
|
||||
struct inode *inode = file_inode(file);
|
||||
struct super_block *sb = inode->i_sb;
|
||||
struct scoutfs_ioctl_punch_offline __user *upo = (void __user *)arg;
|
||||
struct scoutfs_ioctl_punch_offline po;
|
||||
struct scoutfs_lock *lock = NULL;
|
||||
u64 iblock;
|
||||
u64 last;
|
||||
u64 tmp;
|
||||
int ret;
|
||||
|
||||
if (copy_from_user(&po, upo, sizeof(po)))
|
||||
return -EFAULT;
|
||||
|
||||
if (po.len == 0)
|
||||
return 0;
|
||||
|
||||
if (check_add_overflow(po.offset, po.len - 1, &tmp) ||
|
||||
(po.offset & SCOUTFS_BLOCK_SM_MASK) ||
|
||||
(po.len & SCOUTFS_BLOCK_SM_MASK))
|
||||
return -EOVERFLOW;
|
||||
|
||||
if (po.flags)
|
||||
return -EINVAL;
|
||||
|
||||
ret = mnt_want_write_file(file);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
inode_lock(inode);
|
||||
|
||||
ret = scoutfs_lock_inode(sb, SCOUTFS_LOCK_WRITE,
|
||||
SCOUTFS_LKF_REFRESH_INODE, inode, &lock);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (!S_ISREG(inode->i_mode)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(file->f_mode & FMODE_WRITE)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = inode_permission(KC_VFS_INIT_NS inode, MAY_WRITE);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
if (scoutfs_inode_data_version(inode) != po.data_version) {
|
||||
ret = -ESTALE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((ret = scoutfs_inode_check_retention(inode)))
|
||||
goto out;
|
||||
|
||||
iblock = po.offset >> SCOUTFS_BLOCK_SM_SHIFT;
|
||||
last = (po.offset + po.len - 1) >> SCOUTFS_BLOCK_SM_SHIFT;
|
||||
|
||||
ret = scoutfs_data_punch_offline(inode, iblock, last, po.data_version, lock);
|
||||
|
||||
out:
|
||||
scoutfs_unlock(sb, lock, SCOUTFS_LOCK_WRITE);
|
||||
inode_unlock(inode);
|
||||
mnt_drop_write_file(file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
long scoutfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
@@ -1720,6 +1790,8 @@ long scoutfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
return scoutfs_ioc_mod_quota_rule(file, arg, false);
|
||||
case SCOUTFS_IOC_READ_XATTR_INDEX:
|
||||
return scoutfs_ioc_read_xattr_index(file, arg);
|
||||
case SCOUTFS_IOC_PUNCH_OFFLINE:
|
||||
return scoutfs_ioc_punch_offline(file, arg);
|
||||
}
|
||||
|
||||
return -ENOTTY;
|
||||
|
||||
@@ -366,10 +366,15 @@ struct scoutfs_ioctl_statfs_more {
|
||||
*
|
||||
* Find current waiters that match the inode, op, and block range to wake
|
||||
* up and return an error.
|
||||
*
|
||||
* (*) ca. v1.25 and earlier required that the data_version passed match
|
||||
* that of the waiter, but this check is removed. It was never needed
|
||||
* because no data is modified during this ioctl. Any data_version value
|
||||
* here is thus since then ignored.
|
||||
*/
|
||||
struct scoutfs_ioctl_data_wait_err {
|
||||
__u64 ino;
|
||||
__u64 data_version;
|
||||
__u64 data_version; /* Ignored, see above (*) */
|
||||
__u64 offset;
|
||||
__u64 count;
|
||||
__u64 op;
|
||||
@@ -843,4 +848,32 @@ struct scoutfs_ioctl_read_xattr_index {
|
||||
#define SCOUTFS_IOC_READ_XATTR_INDEX \
|
||||
_IOR(SCOUTFS_IOCTL_MAGIC, 23, struct scoutfs_ioctl_read_xattr_index)
|
||||
|
||||
/*
|
||||
* This is a limited and specific version of hole punching. It's an
|
||||
* archive layer operation that only converts unmapped offline extents
|
||||
* into sparse extents. It is intended to be used when restoring sparse
|
||||
* files after the initial creation set the entire file size offline.
|
||||
*
|
||||
* The offset and len fields are in units of bytes and must be aligned
|
||||
* to the small (4KiB) block size. All regions of offline extents
|
||||
* covered by the region will be converted into sparse online extents,
|
||||
* including regions that straddle the boundaries of the region. Any
|
||||
* existing sparse extents in the region are ignored.
|
||||
*
|
||||
* The data_version must match the inode or EINVAL is returned. The
|
||||
* data_version is not modified by this operation.
|
||||
*
|
||||
* EINVAL is returned if any mapped extents are found in the region. If
|
||||
* an error is returned then partial progress may have been made.
|
||||
*/
|
||||
struct scoutfs_ioctl_punch_offline {
|
||||
__u64 offset;
|
||||
__u64 len;
|
||||
__u64 data_version;
|
||||
__u64 flags;
|
||||
};
|
||||
|
||||
#define SCOUTFS_IOC_PUNCH_OFFLINE \
|
||||
_IOW(SCOUTFS_IOCTL_MAGIC, 24, struct scoutfs_ioctl_punch_offline)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,6 +35,12 @@ do { \
|
||||
} \
|
||||
} while (0) \
|
||||
|
||||
#define scoutfs_bug_on_err(sb, err, fmt, args...) \
|
||||
do { \
|
||||
__typeof__(err) _err = (err); \
|
||||
scoutfs_bug_on(sb, _err < 0 && _err != -ENOLINK, fmt, ##args); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Each message is only generated once per volume. Remounting resets
|
||||
* the messages.
|
||||
|
||||
@@ -33,6 +33,7 @@ enum {
|
||||
Opt_acl,
|
||||
Opt_data_prealloc_blocks,
|
||||
Opt_data_prealloc_contig_only,
|
||||
Opt_ino_alloc_per_lock,
|
||||
Opt_log_merge_wait_timeout_ms,
|
||||
Opt_metadev_path,
|
||||
Opt_noacl,
|
||||
@@ -47,6 +48,7 @@ static const match_table_t tokens = {
|
||||
{Opt_acl, "acl"},
|
||||
{Opt_data_prealloc_blocks, "data_prealloc_blocks=%s"},
|
||||
{Opt_data_prealloc_contig_only, "data_prealloc_contig_only=%s"},
|
||||
{Opt_ino_alloc_per_lock, "ino_alloc_per_lock=%s"},
|
||||
{Opt_log_merge_wait_timeout_ms, "log_merge_wait_timeout_ms=%s"},
|
||||
{Opt_metadev_path, "metadev_path=%s"},
|
||||
{Opt_noacl, "noacl"},
|
||||
@@ -136,6 +138,7 @@ static void init_default_options(struct scoutfs_mount_options *opts)
|
||||
|
||||
opts->data_prealloc_blocks = SCOUTFS_DATA_PREALLOC_DEFAULT_BLOCKS;
|
||||
opts->data_prealloc_contig_only = 1;
|
||||
opts->ino_alloc_per_lock = SCOUTFS_LOCK_INODE_GROUP_NR;
|
||||
opts->log_merge_wait_timeout_ms = DEFAULT_LOG_MERGE_WAIT_TIMEOUT_MS;
|
||||
opts->orphan_scan_delay_ms = -1;
|
||||
opts->quorum_heartbeat_timeout_ms = SCOUTFS_QUORUM_DEF_HB_TIMEO_MS;
|
||||
@@ -238,6 +241,18 @@ static int parse_options(struct super_block *sb, char *options, struct scoutfs_m
|
||||
opts->data_prealloc_contig_only = nr;
|
||||
break;
|
||||
|
||||
case Opt_ino_alloc_per_lock:
|
||||
ret = match_int(args, &nr);
|
||||
if (ret < 0 || nr < 1 || nr > SCOUTFS_LOCK_INODE_GROUP_NR) {
|
||||
scoutfs_err(sb, "invalid ino_alloc_per_lock option, must be between 1 and %u",
|
||||
SCOUTFS_LOCK_INODE_GROUP_NR);
|
||||
if (ret == 0)
|
||||
ret = -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
opts->ino_alloc_per_lock = nr;
|
||||
break;
|
||||
|
||||
case Opt_tcp_keepalive_timeout_ms:
|
||||
ret = match_int(args, &nr);
|
||||
ret = verify_tcp_keepalive_timeout_ms(sb, ret, nr);
|
||||
@@ -393,6 +408,7 @@ int scoutfs_options_show(struct seq_file *seq, struct dentry *root)
|
||||
seq_puts(seq, ",acl");
|
||||
seq_printf(seq, ",data_prealloc_blocks=%llu", opts.data_prealloc_blocks);
|
||||
seq_printf(seq, ",data_prealloc_contig_only=%u", opts.data_prealloc_contig_only);
|
||||
seq_printf(seq, ",ino_alloc_per_lock=%u", opts.ino_alloc_per_lock);
|
||||
seq_printf(seq, ",metadev_path=%s", opts.metadev_path);
|
||||
if (!is_acl)
|
||||
seq_puts(seq, ",noacl");
|
||||
@@ -481,6 +497,45 @@ static ssize_t data_prealloc_contig_only_store(struct kobject *kobj, struct kobj
|
||||
}
|
||||
SCOUTFS_ATTR_RW(data_prealloc_contig_only);
|
||||
|
||||
static ssize_t ino_alloc_per_lock_show(struct kobject *kobj, struct kobj_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct super_block *sb = SCOUTFS_SYSFS_ATTRS_SB(kobj);
|
||||
struct scoutfs_mount_options opts;
|
||||
|
||||
scoutfs_options_read(sb, &opts);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%u", opts.ino_alloc_per_lock);
|
||||
}
|
||||
static ssize_t ino_alloc_per_lock_store(struct kobject *kobj, struct kobj_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct super_block *sb = SCOUTFS_SYSFS_ATTRS_SB(kobj);
|
||||
DECLARE_OPTIONS_INFO(sb, optinf);
|
||||
char nullterm[20]; /* more than enough for octal -U32_MAX */
|
||||
long val;
|
||||
int len;
|
||||
int ret;
|
||||
|
||||
len = min(count, sizeof(nullterm) - 1);
|
||||
memcpy(nullterm, buf, len);
|
||||
nullterm[len] = '\0';
|
||||
|
||||
ret = kstrtol(nullterm, 0, &val);
|
||||
if (ret < 0 || val < 1 || val > SCOUTFS_LOCK_INODE_GROUP_NR) {
|
||||
scoutfs_err(sb, "invalid ino_alloc_per_lock option, must be between 1 and %u",
|
||||
SCOUTFS_LOCK_INODE_GROUP_NR);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
write_seqlock(&optinf->seqlock);
|
||||
optinf->opts.ino_alloc_per_lock = val;
|
||||
write_sequnlock(&optinf->seqlock);
|
||||
|
||||
return count;
|
||||
}
|
||||
SCOUTFS_ATTR_RW(ino_alloc_per_lock);
|
||||
|
||||
static ssize_t log_merge_wait_timeout_ms_show(struct kobject *kobj, struct kobj_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
@@ -621,6 +676,7 @@ SCOUTFS_ATTR_RO(quorum_slot_nr);
|
||||
static struct attribute *options_attrs[] = {
|
||||
SCOUTFS_ATTR_PTR(data_prealloc_blocks),
|
||||
SCOUTFS_ATTR_PTR(data_prealloc_contig_only),
|
||||
SCOUTFS_ATTR_PTR(ino_alloc_per_lock),
|
||||
SCOUTFS_ATTR_PTR(log_merge_wait_timeout_ms),
|
||||
SCOUTFS_ATTR_PTR(metadev_path),
|
||||
SCOUTFS_ATTR_PTR(orphan_scan_delay_ms),
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
struct scoutfs_mount_options {
|
||||
u64 data_prealloc_blocks;
|
||||
bool data_prealloc_contig_only;
|
||||
unsigned int ino_alloc_per_lock;
|
||||
unsigned int log_merge_wait_timeout_ms;
|
||||
char *metadev_path;
|
||||
unsigned int orphan_scan_delay_ms;
|
||||
|
||||
@@ -994,10 +994,11 @@ static int for_each_rid_last_lt(struct super_block *sb, struct scoutfs_btree_roo
|
||||
}
|
||||
|
||||
/*
|
||||
* Log merge range items are stored at the starting fs key of the range.
|
||||
* The only fs key field that doesn't hold information is the zone, so
|
||||
* we use the zone to differentiate all types that we store in the log
|
||||
* merge tree.
|
||||
* Log merge range items are stored at the starting fs key of the range
|
||||
* with the zone overwritten to indicate the log merge item type. This
|
||||
* day0 mistake loses sorting information for items in the different
|
||||
* zones in the fs root, so the range items aren't strictly sorted by
|
||||
* the starting key of their range.
|
||||
*/
|
||||
static void init_log_merge_key(struct scoutfs_key *key, u8 zone, u64 first,
|
||||
u64 second)
|
||||
@@ -1029,6 +1030,51 @@ static int next_log_merge_item_key(struct super_block *sb, struct scoutfs_btree_
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The range items aren't sorted by their range.start because
|
||||
* _RANGE_ZONE clobbers the range's zone. We sweep all the items and
|
||||
* find the range with the next least starting key that's greater than
|
||||
* the caller's starting key. We have to be careful to iterate over the
|
||||
* log_merge tree keys because the ranges can overlap as they're mapped
|
||||
* to the log_merge keys by clobbering their zone.
|
||||
*/
|
||||
static int next_log_merge_range(struct super_block *sb, struct scoutfs_btree_root *root,
|
||||
struct scoutfs_key *start, struct scoutfs_log_merge_range *rng)
|
||||
{
|
||||
struct scoutfs_log_merge_range *next;
|
||||
SCOUTFS_BTREE_ITEM_REF(iref);
|
||||
struct scoutfs_key key;
|
||||
int ret;
|
||||
|
||||
key = *start;
|
||||
key.sk_zone = SCOUTFS_LOG_MERGE_RANGE_ZONE;
|
||||
scoutfs_key_set_ones(&rng->start);
|
||||
|
||||
do {
|
||||
ret = scoutfs_btree_next(sb, root, &key, &iref);
|
||||
if (ret == 0) {
|
||||
if (iref.key->sk_zone != SCOUTFS_LOG_MERGE_RANGE_ZONE) {
|
||||
ret = -ENOENT;
|
||||
} else if (iref.val_len != sizeof(struct scoutfs_log_merge_range)) {
|
||||
ret = -EIO;
|
||||
} else {
|
||||
next = iref.val;
|
||||
if (scoutfs_key_compare(&next->start, &rng->start) < 0 &&
|
||||
scoutfs_key_compare(&next->start, start) >= 0)
|
||||
*rng = *next;
|
||||
key = *iref.key;
|
||||
scoutfs_key_inc(&key);
|
||||
}
|
||||
scoutfs_btree_put_iref(&iref);
|
||||
}
|
||||
} while (ret == 0);
|
||||
|
||||
if (ret == -ENOENT && !scoutfs_key_is_ones(&rng->start))
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int next_log_merge_item(struct super_block *sb,
|
||||
struct scoutfs_btree_root *root,
|
||||
u8 zone, u64 first, u64 second,
|
||||
@@ -1682,6 +1728,7 @@ static int server_commit_log_trees(struct super_block *sb,
|
||||
int ret;
|
||||
|
||||
if (arg_len != sizeof(struct scoutfs_log_trees)) {
|
||||
err_str = "invalid message log_trees size";
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -1745,7 +1792,7 @@ static int server_commit_log_trees(struct super_block *sb,
|
||||
|
||||
ret = scoutfs_btree_update(sb, &server->alloc, &server->wri,
|
||||
&super->logs_root, &key, <, sizeof(lt));
|
||||
BUG_ON(ret < 0); /* dirtying should have guaranteed success */
|
||||
BUG_ON(ret < 0); /* dirtying should have guaranteed success, srch item inconsistent */
|
||||
if (ret < 0)
|
||||
err_str = "updating log trees item";
|
||||
|
||||
@@ -1753,11 +1800,10 @@ unlock:
|
||||
mutex_unlock(&server->logs_mutex);
|
||||
|
||||
ret = server_apply_commit(sb, &hold, ret);
|
||||
out:
|
||||
if (ret < 0)
|
||||
scoutfs_err(sb, "server error %d committing client logs for rid %016llx, nr %llu: %s",
|
||||
ret, rid, le64_to_cpu(lt.nr), err_str);
|
||||
out:
|
||||
WARN_ON_ONCE(ret < 0);
|
||||
return scoutfs_net_response(sb, conn, cmd, id, ret, NULL, 0);
|
||||
}
|
||||
|
||||
@@ -2094,7 +2140,7 @@ static int server_srch_get_compact(struct super_block *sb,
|
||||
|
||||
apply:
|
||||
ret = server_apply_commit(sb, &hold, ret);
|
||||
WARN_ON_ONCE(ret < 0 && ret != -ENOENT); /* XXX leaked busy item */
|
||||
WARN_ON_ONCE(ret < 0 && ret != -ENOENT && ret != -ENOLINK); /* XXX leaked busy item */
|
||||
out:
|
||||
ret = scoutfs_net_response(sb, conn, cmd, id, ret,
|
||||
sc, sizeof(struct scoutfs_srch_compact));
|
||||
@@ -2472,10 +2518,9 @@ out:
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
scoutfs_err(sb, "server error %d splicing log merge completion: %s", ret, err_str);
|
||||
|
||||
BUG_ON(ret); /* inconsistent */
|
||||
/* inconsistent */
|
||||
scoutfs_bug_on_err(sb, ret,
|
||||
"server error %d splicing log merge completion: %s", ret, err_str);
|
||||
|
||||
return ret ?: einprogress;
|
||||
}
|
||||
@@ -2720,10 +2765,7 @@ restart:
|
||||
|
||||
/* find the next range, always checking for splicing */
|
||||
for (;;) {
|
||||
key = stat.next_range_key;
|
||||
key.sk_zone = SCOUTFS_LOG_MERGE_RANGE_ZONE;
|
||||
ret = next_log_merge_item_key(sb, &super->log_merge, SCOUTFS_LOG_MERGE_RANGE_ZONE,
|
||||
&key, &rng, sizeof(rng));
|
||||
ret = next_log_merge_range(sb, &super->log_merge, &stat.next_range_key, &rng);
|
||||
if (ret < 0 && ret != -ENOENT) {
|
||||
err_str = "finding merge range item";
|
||||
goto out;
|
||||
|
||||
@@ -117,6 +117,7 @@ used during the test.
|
||||
| T\_NR\_MOUNTS | number of mounts | -n | 3 |
|
||||
| T\_O[0-9] | mount options | created per run | -o server\_addr= |
|
||||
| T\_QUORUM | quorum count | -q | 2 |
|
||||
| T\_EXTRA | per-test file dir | revision ctled | tests/extra/t |
|
||||
| T\_TMP | per-test tmp prefix | made for test | results/tmp/t/tmp |
|
||||
| T\_TMPDIR | per-test tmp dir dir | made for test | results/tmp/t |
|
||||
|
||||
|
||||
882
tests/extra/xfstests/expected-results
Normal file
882
tests/extra/xfstests/expected-results
Normal file
@@ -0,0 +1,882 @@
|
||||
Ran:
|
||||
generic/001
|
||||
generic/002
|
||||
generic/004
|
||||
generic/005
|
||||
generic/006
|
||||
generic/007
|
||||
generic/008
|
||||
generic/009
|
||||
generic/011
|
||||
generic/012
|
||||
generic/013
|
||||
generic/014
|
||||
generic/015
|
||||
generic/016
|
||||
generic/018
|
||||
generic/020
|
||||
generic/021
|
||||
generic/022
|
||||
generic/023
|
||||
generic/024
|
||||
generic/025
|
||||
generic/026
|
||||
generic/028
|
||||
generic/029
|
||||
generic/030
|
||||
generic/031
|
||||
generic/032
|
||||
generic/033
|
||||
generic/034
|
||||
generic/035
|
||||
generic/037
|
||||
generic/039
|
||||
generic/040
|
||||
generic/041
|
||||
generic/050
|
||||
generic/052
|
||||
generic/053
|
||||
generic/056
|
||||
generic/057
|
||||
generic/058
|
||||
generic/059
|
||||
generic/060
|
||||
generic/061
|
||||
generic/062
|
||||
generic/063
|
||||
generic/064
|
||||
generic/065
|
||||
generic/066
|
||||
generic/067
|
||||
generic/069
|
||||
generic/070
|
||||
generic/071
|
||||
generic/073
|
||||
generic/076
|
||||
generic/078
|
||||
generic/079
|
||||
generic/080
|
||||
generic/081
|
||||
generic/082
|
||||
generic/084
|
||||
generic/086
|
||||
generic/087
|
||||
generic/088
|
||||
generic/090
|
||||
generic/091
|
||||
generic/092
|
||||
generic/094
|
||||
generic/096
|
||||
generic/097
|
||||
generic/098
|
||||
generic/099
|
||||
generic/101
|
||||
generic/104
|
||||
generic/105
|
||||
generic/106
|
||||
generic/107
|
||||
generic/110
|
||||
generic/111
|
||||
generic/113
|
||||
generic/114
|
||||
generic/115
|
||||
generic/116
|
||||
generic/117
|
||||
generic/118
|
||||
generic/119
|
||||
generic/120
|
||||
generic/121
|
||||
generic/122
|
||||
generic/123
|
||||
generic/124
|
||||
generic/126
|
||||
generic/128
|
||||
generic/129
|
||||
generic/130
|
||||
generic/131
|
||||
generic/134
|
||||
generic/135
|
||||
generic/136
|
||||
generic/138
|
||||
generic/139
|
||||
generic/140
|
||||
generic/141
|
||||
generic/142
|
||||
generic/143
|
||||
generic/144
|
||||
generic/145
|
||||
generic/146
|
||||
generic/147
|
||||
generic/148
|
||||
generic/149
|
||||
generic/150
|
||||
generic/151
|
||||
generic/152
|
||||
generic/153
|
||||
generic/154
|
||||
generic/155
|
||||
generic/156
|
||||
generic/157
|
||||
generic/158
|
||||
generic/159
|
||||
generic/160
|
||||
generic/161
|
||||
generic/162
|
||||
generic/163
|
||||
generic/169
|
||||
generic/171
|
||||
generic/172
|
||||
generic/173
|
||||
generic/174
|
||||
generic/177
|
||||
generic/178
|
||||
generic/179
|
||||
generic/180
|
||||
generic/181
|
||||
generic/182
|
||||
generic/183
|
||||
generic/184
|
||||
generic/185
|
||||
generic/188
|
||||
generic/189
|
||||
generic/190
|
||||
generic/191
|
||||
generic/193
|
||||
generic/194
|
||||
generic/195
|
||||
generic/196
|
||||
generic/197
|
||||
generic/198
|
||||
generic/199
|
||||
generic/200
|
||||
generic/201
|
||||
generic/202
|
||||
generic/203
|
||||
generic/205
|
||||
generic/206
|
||||
generic/207
|
||||
generic/210
|
||||
generic/211
|
||||
generic/212
|
||||
generic/214
|
||||
generic/215
|
||||
generic/216
|
||||
generic/217
|
||||
generic/218
|
||||
generic/219
|
||||
generic/220
|
||||
generic/221
|
||||
generic/222
|
||||
generic/223
|
||||
generic/225
|
||||
generic/227
|
||||
generic/228
|
||||
generic/229
|
||||
generic/230
|
||||
generic/235
|
||||
generic/236
|
||||
generic/237
|
||||
generic/238
|
||||
generic/240
|
||||
generic/244
|
||||
generic/245
|
||||
generic/246
|
||||
generic/247
|
||||
generic/248
|
||||
generic/249
|
||||
generic/250
|
||||
generic/252
|
||||
generic/253
|
||||
generic/254
|
||||
generic/255
|
||||
generic/256
|
||||
generic/257
|
||||
generic/258
|
||||
generic/259
|
||||
generic/260
|
||||
generic/261
|
||||
generic/262
|
||||
generic/263
|
||||
generic/264
|
||||
generic/265
|
||||
generic/266
|
||||
generic/267
|
||||
generic/268
|
||||
generic/271
|
||||
generic/272
|
||||
generic/276
|
||||
generic/277
|
||||
generic/278
|
||||
generic/279
|
||||
generic/281
|
||||
generic/282
|
||||
generic/283
|
||||
generic/284
|
||||
generic/286
|
||||
generic/287
|
||||
generic/288
|
||||
generic/289
|
||||
generic/290
|
||||
generic/291
|
||||
generic/292
|
||||
generic/293
|
||||
generic/294
|
||||
generic/295
|
||||
generic/296
|
||||
generic/301
|
||||
generic/302
|
||||
generic/303
|
||||
generic/304
|
||||
generic/305
|
||||
generic/306
|
||||
generic/307
|
||||
generic/308
|
||||
generic/309
|
||||
generic/312
|
||||
generic/313
|
||||
generic/314
|
||||
generic/315
|
||||
generic/316
|
||||
generic/317
|
||||
generic/319
|
||||
generic/322
|
||||
generic/324
|
||||
generic/325
|
||||
generic/326
|
||||
generic/327
|
||||
generic/328
|
||||
generic/329
|
||||
generic/330
|
||||
generic/331
|
||||
generic/332
|
||||
generic/335
|
||||
generic/336
|
||||
generic/337
|
||||
generic/341
|
||||
generic/342
|
||||
generic/343
|
||||
generic/346
|
||||
generic/348
|
||||
generic/353
|
||||
generic/355
|
||||
generic/358
|
||||
generic/359
|
||||
generic/360
|
||||
generic/361
|
||||
generic/362
|
||||
generic/363
|
||||
generic/364
|
||||
generic/365
|
||||
generic/366
|
||||
generic/367
|
||||
generic/368
|
||||
generic/369
|
||||
generic/370
|
||||
generic/371
|
||||
generic/372
|
||||
generic/373
|
||||
generic/374
|
||||
generic/375
|
||||
generic/376
|
||||
generic/377
|
||||
generic/378
|
||||
generic/379
|
||||
generic/380
|
||||
generic/381
|
||||
generic/382
|
||||
generic/383
|
||||
generic/384
|
||||
generic/385
|
||||
generic/386
|
||||
generic/389
|
||||
generic/391
|
||||
generic/392
|
||||
generic/393
|
||||
generic/394
|
||||
generic/395
|
||||
generic/396
|
||||
generic/397
|
||||
generic/398
|
||||
generic/400
|
||||
generic/401
|
||||
generic/402
|
||||
generic/403
|
||||
generic/404
|
||||
generic/406
|
||||
generic/407
|
||||
generic/408
|
||||
generic/412
|
||||
generic/413
|
||||
generic/414
|
||||
generic/417
|
||||
generic/419
|
||||
generic/420
|
||||
generic/421
|
||||
generic/422
|
||||
generic/424
|
||||
generic/425
|
||||
generic/426
|
||||
generic/427
|
||||
generic/428
|
||||
generic/436
|
||||
generic/437
|
||||
generic/439
|
||||
generic/440
|
||||
generic/443
|
||||
generic/445
|
||||
generic/446
|
||||
generic/448
|
||||
generic/449
|
||||
generic/450
|
||||
generic/451
|
||||
generic/452
|
||||
generic/453
|
||||
generic/454
|
||||
generic/456
|
||||
generic/458
|
||||
generic/460
|
||||
generic/462
|
||||
generic/463
|
||||
generic/465
|
||||
generic/466
|
||||
generic/468
|
||||
generic/469
|
||||
generic/470
|
||||
generic/471
|
||||
generic/474
|
||||
generic/477
|
||||
generic/478
|
||||
generic/479
|
||||
generic/480
|
||||
generic/481
|
||||
generic/483
|
||||
generic/485
|
||||
generic/486
|
||||
generic/487
|
||||
generic/488
|
||||
generic/489
|
||||
generic/490
|
||||
generic/491
|
||||
generic/492
|
||||
generic/498
|
||||
generic/499
|
||||
generic/501
|
||||
generic/502
|
||||
generic/503
|
||||
generic/504
|
||||
generic/505
|
||||
generic/506
|
||||
generic/507
|
||||
generic/508
|
||||
generic/509
|
||||
generic/510
|
||||
generic/511
|
||||
generic/512
|
||||
generic/513
|
||||
generic/514
|
||||
generic/515
|
||||
generic/516
|
||||
generic/517
|
||||
generic/518
|
||||
generic/519
|
||||
generic/520
|
||||
generic/523
|
||||
generic/524
|
||||
generic/525
|
||||
generic/526
|
||||
generic/527
|
||||
generic/528
|
||||
generic/529
|
||||
generic/530
|
||||
generic/531
|
||||
generic/533
|
||||
generic/534
|
||||
generic/535
|
||||
generic/536
|
||||
generic/537
|
||||
generic/538
|
||||
generic/539
|
||||
generic/540
|
||||
generic/541
|
||||
generic/542
|
||||
generic/543
|
||||
generic/544
|
||||
generic/545
|
||||
generic/546
|
||||
generic/547
|
||||
generic/548
|
||||
generic/549
|
||||
generic/550
|
||||
generic/552
|
||||
generic/553
|
||||
generic/555
|
||||
generic/556
|
||||
generic/557
|
||||
generic/566
|
||||
generic/567
|
||||
generic/571
|
||||
generic/572
|
||||
generic/573
|
||||
generic/574
|
||||
generic/575
|
||||
generic/576
|
||||
generic/577
|
||||
generic/578
|
||||
generic/580
|
||||
generic/581
|
||||
generic/582
|
||||
generic/583
|
||||
generic/584
|
||||
generic/586
|
||||
generic/587
|
||||
generic/588
|
||||
generic/591
|
||||
generic/592
|
||||
generic/593
|
||||
generic/594
|
||||
generic/595
|
||||
generic/596
|
||||
generic/597
|
||||
generic/598
|
||||
generic/599
|
||||
generic/600
|
||||
generic/601
|
||||
generic/602
|
||||
generic/603
|
||||
generic/604
|
||||
generic/605
|
||||
generic/606
|
||||
generic/607
|
||||
generic/608
|
||||
generic/609
|
||||
generic/610
|
||||
generic/611
|
||||
generic/612
|
||||
generic/613
|
||||
generic/614
|
||||
generic/618
|
||||
generic/621
|
||||
generic/623
|
||||
generic/624
|
||||
generic/625
|
||||
generic/626
|
||||
generic/628
|
||||
generic/629
|
||||
generic/630
|
||||
generic/632
|
||||
generic/634
|
||||
generic/635
|
||||
generic/637
|
||||
generic/638
|
||||
generic/639
|
||||
generic/640
|
||||
generic/644
|
||||
generic/645
|
||||
generic/646
|
||||
generic/647
|
||||
generic/651
|
||||
generic/652
|
||||
generic/653
|
||||
generic/654
|
||||
generic/655
|
||||
generic/657
|
||||
generic/658
|
||||
generic/659
|
||||
generic/660
|
||||
generic/661
|
||||
generic/662
|
||||
generic/663
|
||||
generic/664
|
||||
generic/665
|
||||
generic/666
|
||||
generic/667
|
||||
generic/668
|
||||
generic/669
|
||||
generic/673
|
||||
generic/674
|
||||
generic/675
|
||||
generic/676
|
||||
generic/677
|
||||
generic/678
|
||||
generic/679
|
||||
generic/680
|
||||
generic/681
|
||||
generic/682
|
||||
generic/683
|
||||
generic/684
|
||||
generic/685
|
||||
generic/686
|
||||
generic/687
|
||||
generic/688
|
||||
generic/689
|
||||
shared/002
|
||||
shared/032
|
||||
Not
|
||||
run:
|
||||
generic/008
|
||||
generic/009
|
||||
generic/012
|
||||
generic/015
|
||||
generic/016
|
||||
generic/018
|
||||
generic/021
|
||||
generic/022
|
||||
generic/025
|
||||
generic/026
|
||||
generic/031
|
||||
generic/033
|
||||
generic/050
|
||||
generic/052
|
||||
generic/058
|
||||
generic/059
|
||||
generic/060
|
||||
generic/061
|
||||
generic/063
|
||||
generic/064
|
||||
generic/078
|
||||
generic/079
|
||||
generic/081
|
||||
generic/082
|
||||
generic/091
|
||||
generic/094
|
||||
generic/096
|
||||
generic/110
|
||||
generic/111
|
||||
generic/113
|
||||
generic/114
|
||||
generic/115
|
||||
generic/116
|
||||
generic/118
|
||||
generic/119
|
||||
generic/121
|
||||
generic/122
|
||||
generic/123
|
||||
generic/128
|
||||
generic/130
|
||||
generic/134
|
||||
generic/135
|
||||
generic/136
|
||||
generic/138
|
||||
generic/139
|
||||
generic/140
|
||||
generic/142
|
||||
generic/143
|
||||
generic/144
|
||||
generic/145
|
||||
generic/146
|
||||
generic/147
|
||||
generic/148
|
||||
generic/149
|
||||
generic/150
|
||||
generic/151
|
||||
generic/152
|
||||
generic/153
|
||||
generic/154
|
||||
generic/155
|
||||
generic/156
|
||||
generic/157
|
||||
generic/158
|
||||
generic/159
|
||||
generic/160
|
||||
generic/161
|
||||
generic/162
|
||||
generic/163
|
||||
generic/171
|
||||
generic/172
|
||||
generic/173
|
||||
generic/174
|
||||
generic/177
|
||||
generic/178
|
||||
generic/179
|
||||
generic/180
|
||||
generic/181
|
||||
generic/182
|
||||
generic/183
|
||||
generic/185
|
||||
generic/188
|
||||
generic/189
|
||||
generic/190
|
||||
generic/191
|
||||
generic/193
|
||||
generic/194
|
||||
generic/195
|
||||
generic/196
|
||||
generic/197
|
||||
generic/198
|
||||
generic/199
|
||||
generic/200
|
||||
generic/201
|
||||
generic/202
|
||||
generic/203
|
||||
generic/205
|
||||
generic/206
|
||||
generic/207
|
||||
generic/210
|
||||
generic/211
|
||||
generic/212
|
||||
generic/214
|
||||
generic/216
|
||||
generic/217
|
||||
generic/218
|
||||
generic/219
|
||||
generic/220
|
||||
generic/222
|
||||
generic/223
|
||||
generic/225
|
||||
generic/227
|
||||
generic/229
|
||||
generic/230
|
||||
generic/235
|
||||
generic/238
|
||||
generic/240
|
||||
generic/244
|
||||
generic/250
|
||||
generic/252
|
||||
generic/253
|
||||
generic/254
|
||||
generic/255
|
||||
generic/256
|
||||
generic/259
|
||||
generic/260
|
||||
generic/261
|
||||
generic/262
|
||||
generic/263
|
||||
generic/264
|
||||
generic/265
|
||||
generic/266
|
||||
generic/267
|
||||
generic/268
|
||||
generic/271
|
||||
generic/272
|
||||
generic/276
|
||||
generic/277
|
||||
generic/278
|
||||
generic/279
|
||||
generic/281
|
||||
generic/282
|
||||
generic/283
|
||||
generic/284
|
||||
generic/287
|
||||
generic/288
|
||||
generic/289
|
||||
generic/290
|
||||
generic/291
|
||||
generic/292
|
||||
generic/293
|
||||
generic/295
|
||||
generic/296
|
||||
generic/301
|
||||
generic/302
|
||||
generic/303
|
||||
generic/304
|
||||
generic/305
|
||||
generic/312
|
||||
generic/314
|
||||
generic/316
|
||||
generic/317
|
||||
generic/324
|
||||
generic/326
|
||||
generic/327
|
||||
generic/328
|
||||
generic/329
|
||||
generic/330
|
||||
generic/331
|
||||
generic/332
|
||||
generic/353
|
||||
generic/355
|
||||
generic/358
|
||||
generic/359
|
||||
generic/361
|
||||
generic/362
|
||||
generic/363
|
||||
generic/364
|
||||
generic/365
|
||||
generic/366
|
||||
generic/367
|
||||
generic/368
|
||||
generic/369
|
||||
generic/370
|
||||
generic/371
|
||||
generic/372
|
||||
generic/373
|
||||
generic/374
|
||||
generic/378
|
||||
generic/379
|
||||
generic/380
|
||||
generic/381
|
||||
generic/382
|
||||
generic/383
|
||||
generic/384
|
||||
generic/385
|
||||
generic/386
|
||||
generic/391
|
||||
generic/392
|
||||
generic/395
|
||||
generic/396
|
||||
generic/397
|
||||
generic/398
|
||||
generic/400
|
||||
generic/402
|
||||
generic/404
|
||||
generic/406
|
||||
generic/407
|
||||
generic/408
|
||||
generic/412
|
||||
generic/413
|
||||
generic/414
|
||||
generic/417
|
||||
generic/419
|
||||
generic/420
|
||||
generic/421
|
||||
generic/422
|
||||
generic/424
|
||||
generic/425
|
||||
generic/427
|
||||
generic/439
|
||||
generic/440
|
||||
generic/446
|
||||
generic/449
|
||||
generic/450
|
||||
generic/451
|
||||
generic/453
|
||||
generic/454
|
||||
generic/456
|
||||
generic/458
|
||||
generic/462
|
||||
generic/463
|
||||
generic/465
|
||||
generic/466
|
||||
generic/468
|
||||
generic/469
|
||||
generic/470
|
||||
generic/471
|
||||
generic/474
|
||||
generic/485
|
||||
generic/487
|
||||
generic/488
|
||||
generic/491
|
||||
generic/492
|
||||
generic/499
|
||||
generic/501
|
||||
generic/503
|
||||
generic/505
|
||||
generic/506
|
||||
generic/507
|
||||
generic/508
|
||||
generic/511
|
||||
generic/513
|
||||
generic/514
|
||||
generic/515
|
||||
generic/516
|
||||
generic/517
|
||||
generic/518
|
||||
generic/519
|
||||
generic/520
|
||||
generic/528
|
||||
generic/530
|
||||
generic/536
|
||||
generic/537
|
||||
generic/538
|
||||
generic/539
|
||||
generic/540
|
||||
generic/541
|
||||
generic/542
|
||||
generic/543
|
||||
generic/544
|
||||
generic/545
|
||||
generic/546
|
||||
generic/548
|
||||
generic/549
|
||||
generic/550
|
||||
generic/552
|
||||
generic/553
|
||||
generic/555
|
||||
generic/556
|
||||
generic/566
|
||||
generic/567
|
||||
generic/572
|
||||
generic/573
|
||||
generic/574
|
||||
generic/575
|
||||
generic/576
|
||||
generic/577
|
||||
generic/578
|
||||
generic/580
|
||||
generic/581
|
||||
generic/582
|
||||
generic/583
|
||||
generic/584
|
||||
generic/586
|
||||
generic/587
|
||||
generic/588
|
||||
generic/591
|
||||
generic/592
|
||||
generic/593
|
||||
generic/594
|
||||
generic/595
|
||||
generic/596
|
||||
generic/597
|
||||
generic/598
|
||||
generic/599
|
||||
generic/600
|
||||
generic/601
|
||||
generic/602
|
||||
generic/603
|
||||
generic/605
|
||||
generic/606
|
||||
generic/607
|
||||
generic/608
|
||||
generic/609
|
||||
generic/610
|
||||
generic/612
|
||||
generic/613
|
||||
generic/621
|
||||
generic/623
|
||||
generic/624
|
||||
generic/625
|
||||
generic/626
|
||||
generic/628
|
||||
generic/629
|
||||
generic/630
|
||||
generic/635
|
||||
generic/644
|
||||
generic/645
|
||||
generic/646
|
||||
generic/647
|
||||
generic/651
|
||||
generic/652
|
||||
generic/653
|
||||
generic/654
|
||||
generic/655
|
||||
generic/657
|
||||
generic/658
|
||||
generic/659
|
||||
generic/660
|
||||
generic/661
|
||||
generic/662
|
||||
generic/663
|
||||
generic/664
|
||||
generic/665
|
||||
generic/666
|
||||
generic/667
|
||||
generic/668
|
||||
generic/669
|
||||
generic/673
|
||||
generic/674
|
||||
generic/675
|
||||
generic/677
|
||||
generic/678
|
||||
generic/679
|
||||
generic/680
|
||||
generic/681
|
||||
generic/682
|
||||
generic/683
|
||||
generic/684
|
||||
generic/685
|
||||
generic/686
|
||||
generic/687
|
||||
generic/688
|
||||
generic/689
|
||||
shared/002
|
||||
shared/032
|
||||
Passed all 512 tests
|
||||
44
tests/extra/xfstests/local.exclude
Normal file
44
tests/extra/xfstests/local.exclude
Normal file
@@ -0,0 +1,44 @@
|
||||
generic/003 # missing atime update in buffered read
|
||||
generic/075 # file content mismatch failures (fds, etc)
|
||||
generic/103 # enospc causes trans commit failures
|
||||
generic/108 # mount fails on failing device?
|
||||
generic/112 # file content mismatch failures (fds, etc)
|
||||
generic/213 # enospc causes trans commit failures
|
||||
generic/318 # can't support user namespaces until v5.11
|
||||
generic/321 # requires selinux enabled for '+' in ls?
|
||||
generic/338 # BUG_ON update inode error handling
|
||||
generic/347 # _dmthin_mount doesn't work?
|
||||
generic/356 # swap
|
||||
generic/357 # swap
|
||||
generic/409 # bind mounts not scripted yet
|
||||
generic/410 # bind mounts not scripted yet
|
||||
generic/411 # bind mounts not scripted yet
|
||||
generic/423 # symlink inode size is strlen() + 1 on scoutfs
|
||||
generic/430 # xfs_io copy_range missing in el7
|
||||
generic/431 # xfs_io copy_range missing in el7
|
||||
generic/432 # xfs_io copy_range missing in el7
|
||||
generic/433 # xfs_io copy_range missing in el7
|
||||
generic/434 # xfs_io copy_range missing in el7
|
||||
generic/441 # dm-mapper
|
||||
generic/444 # el9's posix_acl_update_mode is buggy ?
|
||||
generic/467 # open_by_handle ESTALE
|
||||
generic/472 # swap
|
||||
generic/484 # dm-mapper
|
||||
generic/493 # swap
|
||||
generic/494 # swap
|
||||
generic/495 # swap
|
||||
generic/496 # swap
|
||||
generic/497 # swap
|
||||
generic/532 # xfs_io statx attrib_mask missing in el7
|
||||
generic/554 # swap
|
||||
generic/563 # cgroup+loopdev
|
||||
generic/564 # xfs_io copy_range missing in el7
|
||||
generic/565 # xfs_io copy_range missing in el7
|
||||
generic/568 # falloc not resulting in block count increase
|
||||
generic/569 # swap
|
||||
generic/570 # swap
|
||||
generic/620 # dm-hugedisk
|
||||
generic/633 # id-mapped mounts missing in el7
|
||||
generic/636 # swap
|
||||
generic/641 # swap
|
||||
generic/643 # swap
|
||||
@@ -8,36 +8,34 @@
|
||||
|
||||
echo "$0 running rid '$SCOUTFS_FENCED_REQ_RID' ip '$SCOUTFS_FENCED_REQ_IP' args '$@'"
|
||||
|
||||
log() {
|
||||
echo "$@" > /dev/stderr
|
||||
echo_fail() {
|
||||
echo "$@" >> /dev/stderr
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo_fail() {
|
||||
echo "$@" > /dev/stderr
|
||||
exit 1
|
||||
# silence error messages
|
||||
quiet_cat()
|
||||
{
|
||||
cat "$@" 2>/dev/null
|
||||
}
|
||||
|
||||
rid="$SCOUTFS_FENCED_REQ_RID"
|
||||
|
||||
shopt -s nullglob
|
||||
for fs in /sys/fs/scoutfs/*; do
|
||||
[ ! -d "$fs" ] && continue
|
||||
fs_rid="$(quiet_cat $fs/rid)"
|
||||
nr="$(quiet_cat $fs/data_device_maj_min)"
|
||||
[ ! -d "$fs" -o "$fs_rid" != "$rid" ] && continue
|
||||
|
||||
fs_rid="$(cat $fs/rid)" || \
|
||||
echo_fail "failed to get rid in $fs"
|
||||
if [ "$fs_rid" != "$rid" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
nr="$(cat $fs/data_device_maj_min)" || \
|
||||
echo_fail "failed to get data device major:minor in $fs"
|
||||
|
||||
mnts=$(findmnt -l -n -t scoutfs -o TARGET -S $nr) || \
|
||||
mnt=$(findmnt -l -n -t scoutfs -o TARGET -S $nr) || \
|
||||
echo_fail "findmnt -t scoutfs -S $nr failed"
|
||||
for mnt in $mnts; do
|
||||
umount -f "$mnt" || \
|
||||
echo_fail "umout -f $mnt failed"
|
||||
done
|
||||
[ -z "$mnt" ] && continue
|
||||
|
||||
if ! umount -qf "$mnt"; then
|
||||
if [ -d "$fs" ]; then
|
||||
echo_fail "umount -qf $mnt failed"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -64,21 +64,27 @@ t_rc()
|
||||
}
|
||||
|
||||
#
|
||||
# redirect test output back to the output of the invoking script intead
|
||||
# of the compared output.
|
||||
# As run, stdout/err are redirected to a file that will be compared with
|
||||
# the stored expected golden output of the test. This redirects
|
||||
# stdout/err in the script to stdout of the invoking run-test. It's
|
||||
# intended to give visible output of tests without being included in the
|
||||
# golden output.
|
||||
#
|
||||
t_restore_output()
|
||||
# (see the goofy "exec" fd manipulation in the main run-tests as it runs
|
||||
# each test)
|
||||
#
|
||||
t_stdout_invoked()
|
||||
{
|
||||
exec >&6 2>&1
|
||||
}
|
||||
|
||||
#
|
||||
# redirect a command's output back to the compared output after the
|
||||
# test has restored its output
|
||||
# This undoes t_stdout_invokved, returning the test's stdout/err to the
|
||||
# output file as it was when it was launched.
|
||||
#
|
||||
t_compare_output()
|
||||
t_stdout_compare()
|
||||
{
|
||||
"$@" >&7 2>&1
|
||||
exec >&7 2>&1
|
||||
}
|
||||
|
||||
#
|
||||
|
||||
@@ -121,6 +121,7 @@ t_filter_dmesg()
|
||||
|
||||
# in debugging kernels we can slow things down a bit
|
||||
re="$re|hrtimer: interrupt took .*"
|
||||
re="$re|clocksource: Long readout interval"
|
||||
|
||||
# fencing tests force unmounts and trigger timeouts
|
||||
re="$re|scoutfs .* forcing unmount"
|
||||
@@ -166,6 +167,9 @@ t_filter_dmesg()
|
||||
# perf warning that it adjusted sample rate
|
||||
re="$re|perf: interrupt took too long.*lowering kernel.perf_event_max_sample_rate.*"
|
||||
|
||||
# some ci test guests are unresponsive
|
||||
re="$re|longest quorum heartbeat .* delay"
|
||||
|
||||
egrep -v "($re)" | \
|
||||
ignore_harmless_unwind_kasan_stack_oob
|
||||
}
|
||||
|
||||
453
tests/golden/punch-offline
Normal file
453
tests/golden/punch-offline
Normal file
@@ -0,0 +1,453 @@
|
||||
== can't hole punch dir or special ==
|
||||
failed to open '/mnt/test.0/test/punch-offline/dir': Is a directory (21)
|
||||
scoutfs: punch-offline failed: Is a directory (21)
|
||||
== punching an empty file does nothing ==
|
||||
== punch outside of i_size does nothing ==
|
||||
== can't hole punch online extent ==
|
||||
0: offset: 0 length: 4096 flags: ..L
|
||||
extents: 1
|
||||
punch_offline ioctl failed: Invalid argument (22)
|
||||
scoutfs: punch-offline failed: Invalid argument (22)
|
||||
0: offset: 0 length: 4096 flags: ..L
|
||||
extents: 1
|
||||
== can't hole punch unwritten extent ==
|
||||
0: offset: 0 length: 12288 flags: .UL
|
||||
extents: 1
|
||||
punch_offline ioctl failed: Invalid argument (22)
|
||||
scoutfs: punch-offline failed: Invalid argument (22)
|
||||
0: offset: 0 length: 12288 flags: .UL
|
||||
extents: 1
|
||||
== hole punch offline extent ==
|
||||
0: offset: 0 length: 12288 flags: O.L
|
||||
extents: 1
|
||||
0: offset: 0 length: 4096 flags: O..
|
||||
1: offset: 8192 length: 4096 flags: O.L
|
||||
extents: 2
|
||||
== can't hole punch non-aligned bsz offset or len ==
|
||||
0: offset: 0 length: 12288 flags: O.L
|
||||
extents: 1
|
||||
punch_offline ioctl failed: Value too large for defined data type (75)
|
||||
scoutfs: punch-offline failed: Value too large for defined data type (75)
|
||||
punch_offline ioctl failed: Value too large for defined data type (75)
|
||||
scoutfs: punch-offline failed: Value too large for defined data type (75)
|
||||
punch_offline ioctl failed: Value too large for defined data type (75)
|
||||
scoutfs: punch-offline failed: Value too large for defined data type (75)
|
||||
punch_offline ioctl failed: Value too large for defined data type (75)
|
||||
scoutfs: punch-offline failed: Value too large for defined data type (75)
|
||||
punch_offline ioctl failed: Value too large for defined data type (75)
|
||||
scoutfs: punch-offline failed: Value too large for defined data type (75)
|
||||
punch_offline ioctl failed: Value too large for defined data type (75)
|
||||
scoutfs: punch-offline failed: Value too large for defined data type (75)
|
||||
0: offset: 0 length: 12288 flags: O.L
|
||||
extents: 1
|
||||
== can't hole punch mismatched data_version ==
|
||||
0: offset: 0 length: 12288 flags: O.L
|
||||
extents: 1
|
||||
punch_offline ioctl failed: Stale file handle (116)
|
||||
scoutfs: punch-offline failed: Stale file handle (116)
|
||||
punch_offline ioctl failed: Stale file handle (116)
|
||||
scoutfs: punch-offline failed: Stale file handle (116)
|
||||
punch_offline ioctl failed: Stale file handle (116)
|
||||
scoutfs: punch-offline failed: Stale file handle (116)
|
||||
0: offset: 0 length: 12288 flags: O.L
|
||||
extents: 1
|
||||
== Punch hole crossing multiple extents ==
|
||||
0: offset: 0 length: 7 flags: O.L
|
||||
extents: 1
|
||||
0: offset: 0 length: 1 flags: O..
|
||||
1: offset: 2 length: 1 flags: O..
|
||||
2: offset: 4 length: 1 flags: O..
|
||||
3: offset: 6 length: 1 flags: O.L
|
||||
extents: 4
|
||||
0: offset: 0 length: 1 flags: O..
|
||||
1: offset: 6 length: 1 flags: O.L
|
||||
extents: 2
|
||||
== punch hole starting at a hole ==
|
||||
0: offset: 0 length: 7 flags: O.L
|
||||
extents: 1
|
||||
0: offset: 0 length: 1 flags: O..
|
||||
1: offset: 2 length: 1 flags: O..
|
||||
2: offset: 4 length: 1 flags: O..
|
||||
3: offset: 6 length: 1 flags: O.L
|
||||
extents: 4
|
||||
0: offset: 0 length: 1 flags: O..
|
||||
1: offset: 6 length: 1 flags: O.L
|
||||
extents: 2
|
||||
== large punch ==
|
||||
0: offset: 0 length: 1572864 flags: O.L
|
||||
extents: 1
|
||||
0: offset: 0 length: 134123 flags: O..
|
||||
1: offset: 202466 length: 264807 flags: O..
|
||||
2: offset: 535616 length: 199007 flags: O..
|
||||
3: offset: 802966 length: 769898 flags: O.L
|
||||
extents: 4
|
||||
== overlapping punches with lots of extents ==
|
||||
0: offset: 0 length: 4194304 flags: O.L
|
||||
extents: 1
|
||||
extents: 512
|
||||
extents: 505
|
||||
extents: 378
|
||||
extents: 252
|
||||
0: offset: 0 length: 4096 flags: O..
|
||||
1: offset: 8192 length: 4096 flags: O..
|
||||
2: offset: 32768 length: 4096 flags: O..
|
||||
3: offset: 40960 length: 4096 flags: O..
|
||||
4: offset: 65536 length: 4096 flags: O..
|
||||
5: offset: 73728 length: 4096 flags: O..
|
||||
6: offset: 98304 length: 4096 flags: O..
|
||||
7: offset: 106496 length: 4096 flags: O..
|
||||
8: offset: 196608 length: 4096 flags: O..
|
||||
9: offset: 204800 length: 4096 flags: O..
|
||||
10: offset: 229376 length: 4096 flags: O..
|
||||
11: offset: 237568 length: 4096 flags: O..
|
||||
12: offset: 262144 length: 4096 flags: O..
|
||||
13: offset: 270336 length: 4096 flags: O..
|
||||
14: offset: 294912 length: 4096 flags: O..
|
||||
15: offset: 303104 length: 4096 flags: O..
|
||||
16: offset: 327680 length: 4096 flags: O..
|
||||
17: offset: 335872 length: 4096 flags: O..
|
||||
18: offset: 360448 length: 4096 flags: O..
|
||||
19: offset: 368640 length: 4096 flags: O..
|
||||
20: offset: 393216 length: 4096 flags: O..
|
||||
21: offset: 401408 length: 4096 flags: O..
|
||||
22: offset: 425984 length: 4096 flags: O..
|
||||
23: offset: 434176 length: 4096 flags: O..
|
||||
24: offset: 458752 length: 4096 flags: O..
|
||||
25: offset: 466944 length: 4096 flags: O..
|
||||
26: offset: 491520 length: 4096 flags: O..
|
||||
27: offset: 499712 length: 4096 flags: O..
|
||||
28: offset: 720896 length: 4096 flags: O..
|
||||
29: offset: 729088 length: 4096 flags: O..
|
||||
30: offset: 753664 length: 4096 flags: O..
|
||||
31: offset: 761856 length: 4096 flags: O..
|
||||
32: offset: 786432 length: 4096 flags: O..
|
||||
33: offset: 794624 length: 4096 flags: O..
|
||||
34: offset: 819200 length: 4096 flags: O..
|
||||
35: offset: 827392 length: 4096 flags: O..
|
||||
36: offset: 851968 length: 4096 flags: O..
|
||||
37: offset: 860160 length: 4096 flags: O..
|
||||
38: offset: 884736 length: 4096 flags: O..
|
||||
39: offset: 892928 length: 4096 flags: O..
|
||||
40: offset: 917504 length: 4096 flags: O..
|
||||
41: offset: 925696 length: 4096 flags: O..
|
||||
42: offset: 950272 length: 4096 flags: O..
|
||||
43: offset: 958464 length: 4096 flags: O..
|
||||
44: offset: 983040 length: 4096 flags: O..
|
||||
45: offset: 991232 length: 4096 flags: O..
|
||||
46: offset: 1015808 length: 4096 flags: O..
|
||||
47: offset: 1024000 length: 4096 flags: O..
|
||||
48: offset: 1048576 length: 4096 flags: O..
|
||||
49: offset: 1056768 length: 4096 flags: O..
|
||||
50: offset: 1081344 length: 4096 flags: O..
|
||||
51: offset: 1089536 length: 4096 flags: O..
|
||||
52: offset: 1114112 length: 4096 flags: O..
|
||||
53: offset: 1122304 length: 4096 flags: O..
|
||||
54: offset: 1146880 length: 4096 flags: O..
|
||||
55: offset: 1155072 length: 4096 flags: O..
|
||||
56: offset: 1179648 length: 4096 flags: O..
|
||||
57: offset: 1187840 length: 4096 flags: O..
|
||||
58: offset: 1212416 length: 4096 flags: O..
|
||||
59: offset: 1220608 length: 4096 flags: O..
|
||||
60: offset: 1245184 length: 4096 flags: O..
|
||||
61: offset: 1253376 length: 4096 flags: O..
|
||||
62: offset: 1277952 length: 4096 flags: O..
|
||||
63: offset: 1286144 length: 4096 flags: O..
|
||||
64: offset: 1310720 length: 4096 flags: O..
|
||||
65: offset: 1318912 length: 4096 flags: O..
|
||||
66: offset: 1343488 length: 4096 flags: O..
|
||||
67: offset: 1351680 length: 4096 flags: O..
|
||||
68: offset: 1376256 length: 4096 flags: O..
|
||||
69: offset: 1384448 length: 4096 flags: O..
|
||||
70: offset: 1409024 length: 4096 flags: O..
|
||||
71: offset: 1417216 length: 4096 flags: O..
|
||||
72: offset: 1441792 length: 4096 flags: O..
|
||||
73: offset: 1449984 length: 4096 flags: O..
|
||||
74: offset: 1474560 length: 4096 flags: O..
|
||||
75: offset: 1482752 length: 4096 flags: O..
|
||||
76: offset: 1507328 length: 4096 flags: O..
|
||||
77: offset: 1515520 length: 4096 flags: O..
|
||||
78: offset: 1540096 length: 4096 flags: O..
|
||||
79: offset: 1548288 length: 4096 flags: O..
|
||||
80: offset: 1572864 length: 4096 flags: O..
|
||||
81: offset: 1581056 length: 4096 flags: O..
|
||||
82: offset: 1605632 length: 4096 flags: O..
|
||||
83: offset: 1613824 length: 4096 flags: O..
|
||||
84: offset: 1638400 length: 4096 flags: O..
|
||||
85: offset: 1646592 length: 4096 flags: O..
|
||||
86: offset: 1671168 length: 4096 flags: O..
|
||||
87: offset: 1679360 length: 4096 flags: O..
|
||||
88: offset: 1703936 length: 4096 flags: O..
|
||||
89: offset: 1712128 length: 4096 flags: O..
|
||||
90: offset: 1736704 length: 4096 flags: O..
|
||||
91: offset: 1744896 length: 4096 flags: O..
|
||||
92: offset: 1769472 length: 4096 flags: O..
|
||||
93: offset: 1777664 length: 4096 flags: O..
|
||||
94: offset: 1802240 length: 4096 flags: O..
|
||||
95: offset: 1810432 length: 4096 flags: O..
|
||||
96: offset: 1835008 length: 4096 flags: O..
|
||||
97: offset: 1843200 length: 4096 flags: O..
|
||||
98: offset: 1867776 length: 4096 flags: O..
|
||||
99: offset: 1875968 length: 4096 flags: O..
|
||||
100: offset: 1900544 length: 4096 flags: O..
|
||||
101: offset: 1908736 length: 4096 flags: O..
|
||||
102: offset: 1933312 length: 4096 flags: O..
|
||||
103: offset: 1941504 length: 4096 flags: O..
|
||||
104: offset: 1966080 length: 4096 flags: O..
|
||||
105: offset: 1974272 length: 4096 flags: O..
|
||||
106: offset: 1998848 length: 4096 flags: O..
|
||||
107: offset: 2007040 length: 4096 flags: O..
|
||||
108: offset: 2031616 length: 4096 flags: O..
|
||||
109: offset: 2039808 length: 4096 flags: O..
|
||||
110: offset: 2064384 length: 4096 flags: O..
|
||||
111: offset: 2072576 length: 4096 flags: O..
|
||||
112: offset: 2097152 length: 4096 flags: O..
|
||||
113: offset: 2105344 length: 4096 flags: O..
|
||||
114: offset: 2129920 length: 4096 flags: O..
|
||||
115: offset: 2138112 length: 4096 flags: O..
|
||||
116: offset: 2162688 length: 4096 flags: O..
|
||||
117: offset: 2170880 length: 4096 flags: O..
|
||||
118: offset: 2195456 length: 4096 flags: O..
|
||||
119: offset: 2203648 length: 4096 flags: O..
|
||||
120: offset: 2228224 length: 4096 flags: O..
|
||||
121: offset: 2236416 length: 4096 flags: O..
|
||||
122: offset: 2260992 length: 4096 flags: O..
|
||||
123: offset: 2269184 length: 4096 flags: O..
|
||||
124: offset: 2293760 length: 4096 flags: O..
|
||||
125: offset: 2301952 length: 4096 flags: O..
|
||||
126: offset: 2326528 length: 4096 flags: O..
|
||||
127: offset: 2334720 length: 4096 flags: O..
|
||||
128: offset: 2359296 length: 4096 flags: O..
|
||||
129: offset: 2367488 length: 4096 flags: O..
|
||||
130: offset: 2392064 length: 4096 flags: O..
|
||||
131: offset: 2400256 length: 4096 flags: O..
|
||||
132: offset: 2424832 length: 4096 flags: O..
|
||||
133: offset: 2433024 length: 4096 flags: O..
|
||||
134: offset: 2457600 length: 4096 flags: O..
|
||||
135: offset: 2465792 length: 4096 flags: O..
|
||||
136: offset: 2490368 length: 4096 flags: O..
|
||||
137: offset: 2498560 length: 4096 flags: O..
|
||||
138: offset: 2523136 length: 4096 flags: O..
|
||||
139: offset: 2531328 length: 4096 flags: O..
|
||||
140: offset: 2555904 length: 4096 flags: O..
|
||||
141: offset: 2564096 length: 4096 flags: O..
|
||||
142: offset: 2588672 length: 4096 flags: O..
|
||||
143: offset: 2596864 length: 4096 flags: O..
|
||||
144: offset: 2621440 length: 4096 flags: O..
|
||||
145: offset: 2629632 length: 4096 flags: O..
|
||||
146: offset: 2654208 length: 4096 flags: O..
|
||||
147: offset: 2662400 length: 4096 flags: O..
|
||||
148: offset: 2686976 length: 4096 flags: O..
|
||||
149: offset: 2695168 length: 4096 flags: O..
|
||||
150: offset: 2719744 length: 4096 flags: O..
|
||||
151: offset: 2727936 length: 4096 flags: O..
|
||||
152: offset: 2752512 length: 4096 flags: O..
|
||||
153: offset: 2760704 length: 4096 flags: O..
|
||||
154: offset: 2785280 length: 4096 flags: O..
|
||||
155: offset: 2793472 length: 4096 flags: O..
|
||||
156: offset: 2818048 length: 4096 flags: O..
|
||||
157: offset: 2826240 length: 4096 flags: O..
|
||||
158: offset: 2850816 length: 4096 flags: O..
|
||||
159: offset: 2859008 length: 4096 flags: O..
|
||||
160: offset: 2883584 length: 4096 flags: O..
|
||||
161: offset: 2891776 length: 4096 flags: O..
|
||||
162: offset: 2916352 length: 4096 flags: O..
|
||||
163: offset: 2924544 length: 4096 flags: O..
|
||||
164: offset: 2949120 length: 4096 flags: O..
|
||||
165: offset: 2957312 length: 4096 flags: O..
|
||||
166: offset: 2981888 length: 4096 flags: O..
|
||||
167: offset: 2990080 length: 4096 flags: O..
|
||||
168: offset: 3014656 length: 4096 flags: O..
|
||||
169: offset: 3022848 length: 4096 flags: O..
|
||||
170: offset: 3047424 length: 4096 flags: O..
|
||||
171: offset: 3055616 length: 4096 flags: O..
|
||||
172: offset: 3080192 length: 4096 flags: O..
|
||||
173: offset: 3088384 length: 4096 flags: O..
|
||||
174: offset: 3112960 length: 4096 flags: O..
|
||||
175: offset: 3121152 length: 4096 flags: O..
|
||||
176: offset: 3145728 length: 4096 flags: O..
|
||||
177: offset: 3153920 length: 4096 flags: O..
|
||||
178: offset: 3178496 length: 4096 flags: O..
|
||||
179: offset: 3186688 length: 4096 flags: O..
|
||||
180: offset: 3211264 length: 4096 flags: O..
|
||||
181: offset: 3219456 length: 4096 flags: O..
|
||||
182: offset: 3244032 length: 4096 flags: O..
|
||||
183: offset: 3252224 length: 4096 flags: O..
|
||||
184: offset: 3276800 length: 4096 flags: O..
|
||||
185: offset: 3284992 length: 4096 flags: O..
|
||||
186: offset: 3309568 length: 4096 flags: O..
|
||||
187: offset: 3317760 length: 4096 flags: O..
|
||||
188: offset: 3342336 length: 4096 flags: O..
|
||||
189: offset: 3350528 length: 4096 flags: O..
|
||||
190: offset: 3375104 length: 4096 flags: O..
|
||||
191: offset: 3383296 length: 4096 flags: O..
|
||||
192: offset: 3407872 length: 4096 flags: O..
|
||||
193: offset: 3416064 length: 4096 flags: O..
|
||||
194: offset: 3440640 length: 4096 flags: O..
|
||||
195: offset: 3448832 length: 4096 flags: O..
|
||||
196: offset: 3473408 length: 4096 flags: O..
|
||||
197: offset: 3481600 length: 4096 flags: O..
|
||||
198: offset: 3506176 length: 4096 flags: O..
|
||||
199: offset: 3514368 length: 4096 flags: O..
|
||||
200: offset: 3538944 length: 4096 flags: O..
|
||||
201: offset: 3547136 length: 4096 flags: O..
|
||||
202: offset: 3571712 length: 4096 flags: O..
|
||||
203: offset: 3579904 length: 4096 flags: O..
|
||||
204: offset: 3604480 length: 4096 flags: O..
|
||||
205: offset: 3612672 length: 4096 flags: O..
|
||||
206: offset: 3637248 length: 4096 flags: O..
|
||||
207: offset: 3645440 length: 4096 flags: O..
|
||||
208: offset: 3670016 length: 4096 flags: O..
|
||||
209: offset: 3678208 length: 4096 flags: O..
|
||||
210: offset: 3702784 length: 4096 flags: O..
|
||||
211: offset: 3710976 length: 4096 flags: O..
|
||||
212: offset: 3735552 length: 4096 flags: O..
|
||||
213: offset: 3743744 length: 4096 flags: O..
|
||||
214: offset: 3768320 length: 4096 flags: O..
|
||||
215: offset: 3776512 length: 4096 flags: O..
|
||||
216: offset: 3801088 length: 4096 flags: O..
|
||||
217: offset: 3809280 length: 4096 flags: O..
|
||||
218: offset: 3833856 length: 4096 flags: O..
|
||||
219: offset: 3842048 length: 4096 flags: O..
|
||||
220: offset: 3866624 length: 4096 flags: O..
|
||||
221: offset: 3874816 length: 4096 flags: O..
|
||||
222: offset: 3899392 length: 4096 flags: O..
|
||||
223: offset: 3907584 length: 4096 flags: O..
|
||||
224: offset: 3932160 length: 4096 flags: O..
|
||||
225: offset: 3940352 length: 4096 flags: O..
|
||||
226: offset: 3964928 length: 4096 flags: O..
|
||||
227: offset: 3973120 length: 4096 flags: O..
|
||||
228: offset: 3997696 length: 4096 flags: O..
|
||||
229: offset: 4005888 length: 4096 flags: O..
|
||||
230: offset: 4030464 length: 4096 flags: O..
|
||||
231: offset: 4038656 length: 4096 flags: O..
|
||||
232: offset: 4063232 length: 4096 flags: O..
|
||||
233: offset: 4071424 length: 4096 flags: O..
|
||||
234: offset: 4096000 length: 4096 flags: O..
|
||||
235: offset: 4104192 length: 4096 flags: O..
|
||||
236: offset: 4128768 length: 4096 flags: O..
|
||||
237: offset: 4136960 length: 4096 flags: O..
|
||||
238: offset: 4161536 length: 4096 flags: O..
|
||||
239: offset: 4169728 length: 4096 flags: O.L
|
||||
extents: 240
|
||||
0: offset: 0 length: 1 flags: O..
|
||||
1: offset: 8 length: 1 flags: O..
|
||||
2: offset: 16 length: 1 flags: O..
|
||||
3: offset: 24 length: 1 flags: O..
|
||||
4: offset: 48 length: 1 flags: O..
|
||||
5: offset: 56 length: 1 flags: O..
|
||||
6: offset: 64 length: 1 flags: O..
|
||||
7: offset: 72 length: 1 flags: O..
|
||||
8: offset: 80 length: 1 flags: O..
|
||||
9: offset: 88 length: 1 flags: O..
|
||||
10: offset: 96 length: 1 flags: O..
|
||||
11: offset: 104 length: 1 flags: O..
|
||||
12: offset: 112 length: 1 flags: O..
|
||||
13: offset: 120 length: 1 flags: O..
|
||||
14: offset: 176 length: 1 flags: O..
|
||||
15: offset: 184 length: 1 flags: O..
|
||||
16: offset: 192 length: 1 flags: O..
|
||||
17: offset: 200 length: 1 flags: O..
|
||||
18: offset: 208 length: 1 flags: O..
|
||||
19: offset: 216 length: 1 flags: O..
|
||||
20: offset: 224 length: 1 flags: O..
|
||||
21: offset: 232 length: 1 flags: O..
|
||||
22: offset: 240 length: 1 flags: O..
|
||||
23: offset: 248 length: 1 flags: O..
|
||||
24: offset: 256 length: 1 flags: O..
|
||||
25: offset: 264 length: 1 flags: O..
|
||||
26: offset: 272 length: 1 flags: O..
|
||||
27: offset: 280 length: 1 flags: O..
|
||||
28: offset: 288 length: 1 flags: O..
|
||||
29: offset: 296 length: 1 flags: O..
|
||||
30: offset: 304 length: 1 flags: O..
|
||||
31: offset: 312 length: 1 flags: O..
|
||||
32: offset: 320 length: 1 flags: O..
|
||||
33: offset: 328 length: 1 flags: O..
|
||||
34: offset: 336 length: 1 flags: O..
|
||||
35: offset: 344 length: 1 flags: O..
|
||||
36: offset: 352 length: 1 flags: O..
|
||||
37: offset: 360 length: 1 flags: O..
|
||||
38: offset: 368 length: 1 flags: O..
|
||||
39: offset: 376 length: 1 flags: O..
|
||||
40: offset: 384 length: 1 flags: O..
|
||||
41: offset: 392 length: 1 flags: O..
|
||||
42: offset: 400 length: 1 flags: O..
|
||||
43: offset: 408 length: 1 flags: O..
|
||||
44: offset: 416 length: 1 flags: O..
|
||||
45: offset: 424 length: 1 flags: O..
|
||||
46: offset: 432 length: 1 flags: O..
|
||||
47: offset: 440 length: 1 flags: O..
|
||||
48: offset: 448 length: 1 flags: O..
|
||||
49: offset: 456 length: 1 flags: O..
|
||||
50: offset: 464 length: 1 flags: O..
|
||||
51: offset: 472 length: 1 flags: O..
|
||||
52: offset: 480 length: 1 flags: O..
|
||||
53: offset: 488 length: 1 flags: O..
|
||||
54: offset: 496 length: 1 flags: O..
|
||||
55: offset: 504 length: 1 flags: O..
|
||||
56: offset: 512 length: 1 flags: O..
|
||||
57: offset: 520 length: 1 flags: O..
|
||||
58: offset: 528 length: 1 flags: O..
|
||||
59: offset: 536 length: 1 flags: O..
|
||||
60: offset: 544 length: 1 flags: O..
|
||||
61: offset: 552 length: 1 flags: O..
|
||||
62: offset: 560 length: 1 flags: O..
|
||||
63: offset: 568 length: 1 flags: O..
|
||||
64: offset: 576 length: 1 flags: O..
|
||||
65: offset: 584 length: 1 flags: O..
|
||||
66: offset: 592 length: 1 flags: O..
|
||||
67: offset: 600 length: 1 flags: O..
|
||||
68: offset: 608 length: 1 flags: O..
|
||||
69: offset: 616 length: 1 flags: O..
|
||||
70: offset: 624 length: 1 flags: O..
|
||||
71: offset: 632 length: 1 flags: O..
|
||||
72: offset: 640 length: 1 flags: O..
|
||||
73: offset: 648 length: 1 flags: O..
|
||||
74: offset: 656 length: 1 flags: O..
|
||||
75: offset: 664 length: 1 flags: O..
|
||||
76: offset: 672 length: 1 flags: O..
|
||||
77: offset: 680 length: 1 flags: O..
|
||||
78: offset: 688 length: 1 flags: O..
|
||||
79: offset: 696 length: 1 flags: O..
|
||||
80: offset: 704 length: 1 flags: O..
|
||||
81: offset: 712 length: 1 flags: O..
|
||||
82: offset: 720 length: 1 flags: O..
|
||||
83: offset: 728 length: 1 flags: O..
|
||||
84: offset: 736 length: 1 flags: O..
|
||||
85: offset: 744 length: 1 flags: O..
|
||||
86: offset: 752 length: 1 flags: O..
|
||||
87: offset: 760 length: 1 flags: O..
|
||||
88: offset: 768 length: 1 flags: O..
|
||||
89: offset: 776 length: 1 flags: O..
|
||||
90: offset: 784 length: 1 flags: O..
|
||||
91: offset: 792 length: 1 flags: O..
|
||||
92: offset: 800 length: 1 flags: O..
|
||||
93: offset: 808 length: 1 flags: O..
|
||||
94: offset: 816 length: 1 flags: O..
|
||||
95: offset: 824 length: 1 flags: O..
|
||||
96: offset: 832 length: 1 flags: O..
|
||||
97: offset: 840 length: 1 flags: O..
|
||||
98: offset: 848 length: 1 flags: O..
|
||||
99: offset: 856 length: 1 flags: O..
|
||||
100: offset: 864 length: 1 flags: O..
|
||||
101: offset: 872 length: 1 flags: O..
|
||||
102: offset: 880 length: 1 flags: O..
|
||||
103: offset: 888 length: 1 flags: O..
|
||||
104: offset: 896 length: 1 flags: O..
|
||||
105: offset: 904 length: 1 flags: O..
|
||||
106: offset: 912 length: 1 flags: O..
|
||||
107: offset: 920 length: 1 flags: O..
|
||||
108: offset: 928 length: 1 flags: O..
|
||||
109: offset: 936 length: 1 flags: O..
|
||||
110: offset: 944 length: 1 flags: O..
|
||||
111: offset: 952 length: 1 flags: O..
|
||||
112: offset: 960 length: 1 flags: O..
|
||||
113: offset: 968 length: 1 flags: O..
|
||||
114: offset: 976 length: 1 flags: O..
|
||||
115: offset: 984 length: 1 flags: O..
|
||||
116: offset: 992 length: 1 flags: O..
|
||||
117: offset: 1000 length: 1 flags: O..
|
||||
118: offset: 1008 length: 1 flags: O..
|
||||
119: offset: 1016 length: 1 flags: O.L
|
||||
extents: 120
|
||||
extents: 0
|
||||
@@ -1,882 +0,0 @@
|
||||
Ran:
|
||||
generic/001
|
||||
generic/002
|
||||
generic/004
|
||||
generic/005
|
||||
generic/006
|
||||
generic/007
|
||||
generic/008
|
||||
generic/009
|
||||
generic/011
|
||||
generic/012
|
||||
generic/013
|
||||
generic/014
|
||||
generic/015
|
||||
generic/016
|
||||
generic/018
|
||||
generic/020
|
||||
generic/021
|
||||
generic/022
|
||||
generic/023
|
||||
generic/024
|
||||
generic/025
|
||||
generic/026
|
||||
generic/028
|
||||
generic/029
|
||||
generic/030
|
||||
generic/031
|
||||
generic/032
|
||||
generic/033
|
||||
generic/034
|
||||
generic/035
|
||||
generic/037
|
||||
generic/039
|
||||
generic/040
|
||||
generic/041
|
||||
generic/050
|
||||
generic/052
|
||||
generic/053
|
||||
generic/056
|
||||
generic/057
|
||||
generic/058
|
||||
generic/059
|
||||
generic/060
|
||||
generic/061
|
||||
generic/062
|
||||
generic/063
|
||||
generic/064
|
||||
generic/065
|
||||
generic/066
|
||||
generic/067
|
||||
generic/069
|
||||
generic/070
|
||||
generic/071
|
||||
generic/073
|
||||
generic/076
|
||||
generic/078
|
||||
generic/079
|
||||
generic/080
|
||||
generic/081
|
||||
generic/082
|
||||
generic/084
|
||||
generic/086
|
||||
generic/087
|
||||
generic/088
|
||||
generic/090
|
||||
generic/091
|
||||
generic/092
|
||||
generic/094
|
||||
generic/096
|
||||
generic/097
|
||||
generic/098
|
||||
generic/099
|
||||
generic/101
|
||||
generic/104
|
||||
generic/105
|
||||
generic/106
|
||||
generic/107
|
||||
generic/110
|
||||
generic/111
|
||||
generic/113
|
||||
generic/114
|
||||
generic/115
|
||||
generic/116
|
||||
generic/117
|
||||
generic/118
|
||||
generic/119
|
||||
generic/120
|
||||
generic/121
|
||||
generic/122
|
||||
generic/123
|
||||
generic/124
|
||||
generic/126
|
||||
generic/128
|
||||
generic/129
|
||||
generic/130
|
||||
generic/131
|
||||
generic/134
|
||||
generic/135
|
||||
generic/136
|
||||
generic/138
|
||||
generic/139
|
||||
generic/140
|
||||
generic/141
|
||||
generic/142
|
||||
generic/143
|
||||
generic/144
|
||||
generic/145
|
||||
generic/146
|
||||
generic/147
|
||||
generic/148
|
||||
generic/149
|
||||
generic/150
|
||||
generic/151
|
||||
generic/152
|
||||
generic/153
|
||||
generic/154
|
||||
generic/155
|
||||
generic/156
|
||||
generic/157
|
||||
generic/158
|
||||
generic/159
|
||||
generic/160
|
||||
generic/161
|
||||
generic/162
|
||||
generic/163
|
||||
generic/169
|
||||
generic/171
|
||||
generic/172
|
||||
generic/173
|
||||
generic/174
|
||||
generic/177
|
||||
generic/178
|
||||
generic/179
|
||||
generic/180
|
||||
generic/181
|
||||
generic/182
|
||||
generic/183
|
||||
generic/184
|
||||
generic/185
|
||||
generic/188
|
||||
generic/189
|
||||
generic/190
|
||||
generic/191
|
||||
generic/193
|
||||
generic/194
|
||||
generic/195
|
||||
generic/196
|
||||
generic/197
|
||||
generic/198
|
||||
generic/199
|
||||
generic/200
|
||||
generic/201
|
||||
generic/202
|
||||
generic/203
|
||||
generic/205
|
||||
generic/206
|
||||
generic/207
|
||||
generic/210
|
||||
generic/211
|
||||
generic/212
|
||||
generic/214
|
||||
generic/215
|
||||
generic/216
|
||||
generic/217
|
||||
generic/218
|
||||
generic/219
|
||||
generic/220
|
||||
generic/221
|
||||
generic/222
|
||||
generic/223
|
||||
generic/225
|
||||
generic/227
|
||||
generic/228
|
||||
generic/229
|
||||
generic/230
|
||||
generic/235
|
||||
generic/236
|
||||
generic/237
|
||||
generic/238
|
||||
generic/240
|
||||
generic/244
|
||||
generic/245
|
||||
generic/246
|
||||
generic/247
|
||||
generic/248
|
||||
generic/249
|
||||
generic/250
|
||||
generic/252
|
||||
generic/253
|
||||
generic/254
|
||||
generic/255
|
||||
generic/256
|
||||
generic/257
|
||||
generic/258
|
||||
generic/259
|
||||
generic/260
|
||||
generic/261
|
||||
generic/262
|
||||
generic/263
|
||||
generic/264
|
||||
generic/265
|
||||
generic/266
|
||||
generic/267
|
||||
generic/268
|
||||
generic/271
|
||||
generic/272
|
||||
generic/276
|
||||
generic/277
|
||||
generic/278
|
||||
generic/279
|
||||
generic/281
|
||||
generic/282
|
||||
generic/283
|
||||
generic/284
|
||||
generic/286
|
||||
generic/287
|
||||
generic/288
|
||||
generic/289
|
||||
generic/290
|
||||
generic/291
|
||||
generic/292
|
||||
generic/293
|
||||
generic/294
|
||||
generic/295
|
||||
generic/296
|
||||
generic/301
|
||||
generic/302
|
||||
generic/303
|
||||
generic/304
|
||||
generic/305
|
||||
generic/306
|
||||
generic/307
|
||||
generic/308
|
||||
generic/309
|
||||
generic/312
|
||||
generic/313
|
||||
generic/314
|
||||
generic/315
|
||||
generic/316
|
||||
generic/317
|
||||
generic/319
|
||||
generic/322
|
||||
generic/324
|
||||
generic/325
|
||||
generic/326
|
||||
generic/327
|
||||
generic/328
|
||||
generic/329
|
||||
generic/330
|
||||
generic/331
|
||||
generic/332
|
||||
generic/335
|
||||
generic/336
|
||||
generic/337
|
||||
generic/341
|
||||
generic/342
|
||||
generic/343
|
||||
generic/346
|
||||
generic/348
|
||||
generic/353
|
||||
generic/355
|
||||
generic/358
|
||||
generic/359
|
||||
generic/360
|
||||
generic/361
|
||||
generic/362
|
||||
generic/363
|
||||
generic/364
|
||||
generic/365
|
||||
generic/366
|
||||
generic/367
|
||||
generic/368
|
||||
generic/369
|
||||
generic/370
|
||||
generic/371
|
||||
generic/372
|
||||
generic/373
|
||||
generic/374
|
||||
generic/375
|
||||
generic/376
|
||||
generic/377
|
||||
generic/378
|
||||
generic/379
|
||||
generic/380
|
||||
generic/381
|
||||
generic/382
|
||||
generic/383
|
||||
generic/384
|
||||
generic/385
|
||||
generic/386
|
||||
generic/389
|
||||
generic/391
|
||||
generic/392
|
||||
generic/393
|
||||
generic/394
|
||||
generic/395
|
||||
generic/396
|
||||
generic/397
|
||||
generic/398
|
||||
generic/400
|
||||
generic/401
|
||||
generic/402
|
||||
generic/403
|
||||
generic/404
|
||||
generic/406
|
||||
generic/407
|
||||
generic/408
|
||||
generic/412
|
||||
generic/413
|
||||
generic/414
|
||||
generic/417
|
||||
generic/419
|
||||
generic/420
|
||||
generic/421
|
||||
generic/422
|
||||
generic/424
|
||||
generic/425
|
||||
generic/426
|
||||
generic/427
|
||||
generic/428
|
||||
generic/436
|
||||
generic/437
|
||||
generic/439
|
||||
generic/440
|
||||
generic/443
|
||||
generic/445
|
||||
generic/446
|
||||
generic/448
|
||||
generic/449
|
||||
generic/450
|
||||
generic/451
|
||||
generic/452
|
||||
generic/453
|
||||
generic/454
|
||||
generic/456
|
||||
generic/458
|
||||
generic/460
|
||||
generic/462
|
||||
generic/463
|
||||
generic/465
|
||||
generic/466
|
||||
generic/468
|
||||
generic/469
|
||||
generic/470
|
||||
generic/471
|
||||
generic/474
|
||||
generic/477
|
||||
generic/478
|
||||
generic/479
|
||||
generic/480
|
||||
generic/481
|
||||
generic/483
|
||||
generic/485
|
||||
generic/486
|
||||
generic/487
|
||||
generic/488
|
||||
generic/489
|
||||
generic/490
|
||||
generic/491
|
||||
generic/492
|
||||
generic/498
|
||||
generic/499
|
||||
generic/501
|
||||
generic/502
|
||||
generic/503
|
||||
generic/504
|
||||
generic/505
|
||||
generic/506
|
||||
generic/507
|
||||
generic/508
|
||||
generic/509
|
||||
generic/510
|
||||
generic/511
|
||||
generic/512
|
||||
generic/513
|
||||
generic/514
|
||||
generic/515
|
||||
generic/516
|
||||
generic/517
|
||||
generic/518
|
||||
generic/519
|
||||
generic/520
|
||||
generic/523
|
||||
generic/524
|
||||
generic/525
|
||||
generic/526
|
||||
generic/527
|
||||
generic/528
|
||||
generic/529
|
||||
generic/530
|
||||
generic/531
|
||||
generic/533
|
||||
generic/534
|
||||
generic/535
|
||||
generic/536
|
||||
generic/537
|
||||
generic/538
|
||||
generic/539
|
||||
generic/540
|
||||
generic/541
|
||||
generic/542
|
||||
generic/543
|
||||
generic/544
|
||||
generic/545
|
||||
generic/546
|
||||
generic/547
|
||||
generic/548
|
||||
generic/549
|
||||
generic/550
|
||||
generic/552
|
||||
generic/553
|
||||
generic/555
|
||||
generic/556
|
||||
generic/557
|
||||
generic/566
|
||||
generic/567
|
||||
generic/571
|
||||
generic/572
|
||||
generic/573
|
||||
generic/574
|
||||
generic/575
|
||||
generic/576
|
||||
generic/577
|
||||
generic/578
|
||||
generic/580
|
||||
generic/581
|
||||
generic/582
|
||||
generic/583
|
||||
generic/584
|
||||
generic/586
|
||||
generic/587
|
||||
generic/588
|
||||
generic/591
|
||||
generic/592
|
||||
generic/593
|
||||
generic/594
|
||||
generic/595
|
||||
generic/596
|
||||
generic/597
|
||||
generic/598
|
||||
generic/599
|
||||
generic/600
|
||||
generic/601
|
||||
generic/602
|
||||
generic/603
|
||||
generic/604
|
||||
generic/605
|
||||
generic/606
|
||||
generic/607
|
||||
generic/608
|
||||
generic/609
|
||||
generic/610
|
||||
generic/611
|
||||
generic/612
|
||||
generic/613
|
||||
generic/614
|
||||
generic/618
|
||||
generic/621
|
||||
generic/623
|
||||
generic/624
|
||||
generic/625
|
||||
generic/626
|
||||
generic/628
|
||||
generic/629
|
||||
generic/630
|
||||
generic/632
|
||||
generic/634
|
||||
generic/635
|
||||
generic/637
|
||||
generic/638
|
||||
generic/639
|
||||
generic/640
|
||||
generic/644
|
||||
generic/645
|
||||
generic/646
|
||||
generic/647
|
||||
generic/651
|
||||
generic/652
|
||||
generic/653
|
||||
generic/654
|
||||
generic/655
|
||||
generic/657
|
||||
generic/658
|
||||
generic/659
|
||||
generic/660
|
||||
generic/661
|
||||
generic/662
|
||||
generic/663
|
||||
generic/664
|
||||
generic/665
|
||||
generic/666
|
||||
generic/667
|
||||
generic/668
|
||||
generic/669
|
||||
generic/673
|
||||
generic/674
|
||||
generic/675
|
||||
generic/676
|
||||
generic/677
|
||||
generic/678
|
||||
generic/679
|
||||
generic/680
|
||||
generic/681
|
||||
generic/682
|
||||
generic/683
|
||||
generic/684
|
||||
generic/685
|
||||
generic/686
|
||||
generic/687
|
||||
generic/688
|
||||
generic/689
|
||||
shared/002
|
||||
shared/032
|
||||
Not
|
||||
run:
|
||||
generic/008
|
||||
generic/009
|
||||
generic/012
|
||||
generic/015
|
||||
generic/016
|
||||
generic/018
|
||||
generic/021
|
||||
generic/022
|
||||
generic/025
|
||||
generic/026
|
||||
generic/031
|
||||
generic/033
|
||||
generic/050
|
||||
generic/052
|
||||
generic/058
|
||||
generic/059
|
||||
generic/060
|
||||
generic/061
|
||||
generic/063
|
||||
generic/064
|
||||
generic/078
|
||||
generic/079
|
||||
generic/081
|
||||
generic/082
|
||||
generic/091
|
||||
generic/094
|
||||
generic/096
|
||||
generic/110
|
||||
generic/111
|
||||
generic/113
|
||||
generic/114
|
||||
generic/115
|
||||
generic/116
|
||||
generic/118
|
||||
generic/119
|
||||
generic/121
|
||||
generic/122
|
||||
generic/123
|
||||
generic/128
|
||||
generic/130
|
||||
generic/134
|
||||
generic/135
|
||||
generic/136
|
||||
generic/138
|
||||
generic/139
|
||||
generic/140
|
||||
generic/142
|
||||
generic/143
|
||||
generic/144
|
||||
generic/145
|
||||
generic/146
|
||||
generic/147
|
||||
generic/148
|
||||
generic/149
|
||||
generic/150
|
||||
generic/151
|
||||
generic/152
|
||||
generic/153
|
||||
generic/154
|
||||
generic/155
|
||||
generic/156
|
||||
generic/157
|
||||
generic/158
|
||||
generic/159
|
||||
generic/160
|
||||
generic/161
|
||||
generic/162
|
||||
generic/163
|
||||
generic/171
|
||||
generic/172
|
||||
generic/173
|
||||
generic/174
|
||||
generic/177
|
||||
generic/178
|
||||
generic/179
|
||||
generic/180
|
||||
generic/181
|
||||
generic/182
|
||||
generic/183
|
||||
generic/185
|
||||
generic/188
|
||||
generic/189
|
||||
generic/190
|
||||
generic/191
|
||||
generic/193
|
||||
generic/194
|
||||
generic/195
|
||||
generic/196
|
||||
generic/197
|
||||
generic/198
|
||||
generic/199
|
||||
generic/200
|
||||
generic/201
|
||||
generic/202
|
||||
generic/203
|
||||
generic/205
|
||||
generic/206
|
||||
generic/207
|
||||
generic/210
|
||||
generic/211
|
||||
generic/212
|
||||
generic/214
|
||||
generic/216
|
||||
generic/217
|
||||
generic/218
|
||||
generic/219
|
||||
generic/220
|
||||
generic/222
|
||||
generic/223
|
||||
generic/225
|
||||
generic/227
|
||||
generic/229
|
||||
generic/230
|
||||
generic/235
|
||||
generic/238
|
||||
generic/240
|
||||
generic/244
|
||||
generic/250
|
||||
generic/252
|
||||
generic/253
|
||||
generic/254
|
||||
generic/255
|
||||
generic/256
|
||||
generic/259
|
||||
generic/260
|
||||
generic/261
|
||||
generic/262
|
||||
generic/263
|
||||
generic/264
|
||||
generic/265
|
||||
generic/266
|
||||
generic/267
|
||||
generic/268
|
||||
generic/271
|
||||
generic/272
|
||||
generic/276
|
||||
generic/277
|
||||
generic/278
|
||||
generic/279
|
||||
generic/281
|
||||
generic/282
|
||||
generic/283
|
||||
generic/284
|
||||
generic/287
|
||||
generic/288
|
||||
generic/289
|
||||
generic/290
|
||||
generic/291
|
||||
generic/292
|
||||
generic/293
|
||||
generic/295
|
||||
generic/296
|
||||
generic/301
|
||||
generic/302
|
||||
generic/303
|
||||
generic/304
|
||||
generic/305
|
||||
generic/312
|
||||
generic/314
|
||||
generic/316
|
||||
generic/317
|
||||
generic/324
|
||||
generic/326
|
||||
generic/327
|
||||
generic/328
|
||||
generic/329
|
||||
generic/330
|
||||
generic/331
|
||||
generic/332
|
||||
generic/353
|
||||
generic/355
|
||||
generic/358
|
||||
generic/359
|
||||
generic/361
|
||||
generic/362
|
||||
generic/363
|
||||
generic/364
|
||||
generic/365
|
||||
generic/366
|
||||
generic/367
|
||||
generic/368
|
||||
generic/369
|
||||
generic/370
|
||||
generic/371
|
||||
generic/372
|
||||
generic/373
|
||||
generic/374
|
||||
generic/378
|
||||
generic/379
|
||||
generic/380
|
||||
generic/381
|
||||
generic/382
|
||||
generic/383
|
||||
generic/384
|
||||
generic/385
|
||||
generic/386
|
||||
generic/391
|
||||
generic/392
|
||||
generic/395
|
||||
generic/396
|
||||
generic/397
|
||||
generic/398
|
||||
generic/400
|
||||
generic/402
|
||||
generic/404
|
||||
generic/406
|
||||
generic/407
|
||||
generic/408
|
||||
generic/412
|
||||
generic/413
|
||||
generic/414
|
||||
generic/417
|
||||
generic/419
|
||||
generic/420
|
||||
generic/421
|
||||
generic/422
|
||||
generic/424
|
||||
generic/425
|
||||
generic/427
|
||||
generic/439
|
||||
generic/440
|
||||
generic/446
|
||||
generic/449
|
||||
generic/450
|
||||
generic/451
|
||||
generic/453
|
||||
generic/454
|
||||
generic/456
|
||||
generic/458
|
||||
generic/462
|
||||
generic/463
|
||||
generic/465
|
||||
generic/466
|
||||
generic/468
|
||||
generic/469
|
||||
generic/470
|
||||
generic/471
|
||||
generic/474
|
||||
generic/485
|
||||
generic/487
|
||||
generic/488
|
||||
generic/491
|
||||
generic/492
|
||||
generic/499
|
||||
generic/501
|
||||
generic/503
|
||||
generic/505
|
||||
generic/506
|
||||
generic/507
|
||||
generic/508
|
||||
generic/511
|
||||
generic/513
|
||||
generic/514
|
||||
generic/515
|
||||
generic/516
|
||||
generic/517
|
||||
generic/518
|
||||
generic/519
|
||||
generic/520
|
||||
generic/528
|
||||
generic/530
|
||||
generic/536
|
||||
generic/537
|
||||
generic/538
|
||||
generic/539
|
||||
generic/540
|
||||
generic/541
|
||||
generic/542
|
||||
generic/543
|
||||
generic/544
|
||||
generic/545
|
||||
generic/546
|
||||
generic/548
|
||||
generic/549
|
||||
generic/550
|
||||
generic/552
|
||||
generic/553
|
||||
generic/555
|
||||
generic/556
|
||||
generic/566
|
||||
generic/567
|
||||
generic/572
|
||||
generic/573
|
||||
generic/574
|
||||
generic/575
|
||||
generic/576
|
||||
generic/577
|
||||
generic/578
|
||||
generic/580
|
||||
generic/581
|
||||
generic/582
|
||||
generic/583
|
||||
generic/584
|
||||
generic/586
|
||||
generic/587
|
||||
generic/588
|
||||
generic/591
|
||||
generic/592
|
||||
generic/593
|
||||
generic/594
|
||||
generic/595
|
||||
generic/596
|
||||
generic/597
|
||||
generic/598
|
||||
generic/599
|
||||
generic/600
|
||||
generic/601
|
||||
generic/602
|
||||
generic/603
|
||||
generic/605
|
||||
generic/606
|
||||
generic/607
|
||||
generic/608
|
||||
generic/609
|
||||
generic/610
|
||||
generic/612
|
||||
generic/613
|
||||
generic/621
|
||||
generic/623
|
||||
generic/624
|
||||
generic/625
|
||||
generic/626
|
||||
generic/628
|
||||
generic/629
|
||||
generic/630
|
||||
generic/635
|
||||
generic/644
|
||||
generic/645
|
||||
generic/646
|
||||
generic/647
|
||||
generic/651
|
||||
generic/652
|
||||
generic/653
|
||||
generic/654
|
||||
generic/655
|
||||
generic/657
|
||||
generic/658
|
||||
generic/659
|
||||
generic/660
|
||||
generic/661
|
||||
generic/662
|
||||
generic/663
|
||||
generic/664
|
||||
generic/665
|
||||
generic/666
|
||||
generic/667
|
||||
generic/668
|
||||
generic/669
|
||||
generic/673
|
||||
generic/674
|
||||
generic/675
|
||||
generic/677
|
||||
generic/678
|
||||
generic/679
|
||||
generic/680
|
||||
generic/681
|
||||
generic/682
|
||||
generic/683
|
||||
generic/684
|
||||
generic/685
|
||||
generic/686
|
||||
generic/687
|
||||
generic/688
|
||||
generic/689
|
||||
shared/002
|
||||
shared/032
|
||||
Passed all 512 tests
|
||||
|
||||
@@ -56,6 +56,7 @@ $(basename $0) options:
|
||||
| only tests matching will be run. Can be provided multiple
|
||||
| times
|
||||
-i | Force removing and inserting the built scoutfs.ko module.
|
||||
-l <nr> | Loop each test <nr> times while passing, last run counts.
|
||||
-M <file> | Specify the filesystem's meta data device path that contains
|
||||
| the file system to be tested. Will be clobbered by -m mkfs.
|
||||
-m | Run mkfs on the device before mounting and running
|
||||
@@ -91,6 +92,7 @@ done
|
||||
T_TRACE_DUMP="0"
|
||||
T_TRACE_PRINTK="0"
|
||||
T_PORT_START="19700"
|
||||
T_LOOP_ITER="1"
|
||||
|
||||
# array declarations to be able to use array ops
|
||||
declare -a T_TRACE_GLOB
|
||||
@@ -131,6 +133,12 @@ while true; do
|
||||
-i)
|
||||
T_INSMOD="1"
|
||||
;;
|
||||
-l)
|
||||
test -n "$2" || die "-l must have a nr iterations argument"
|
||||
test "$2" -eq "$2" 2>/dev/null || die "-l <nr> argument must be an integer"
|
||||
T_LOOP_ITER="$2"
|
||||
shift
|
||||
;;
|
||||
-M)
|
||||
test -n "$2" || die "-z must have meta device file argument"
|
||||
T_META_DEVICE="$2"
|
||||
@@ -430,6 +438,30 @@ cmd grep . /sys/kernel/debug/tracing/options/trace_printk \
|
||||
/sys/kernel/debug/tracing/buffer_size_kb \
|
||||
/proc/sys/kernel/ftrace_dump_on_oops
|
||||
|
||||
# we can record pids to kill as we exit, we kill in reverse added order
|
||||
atexit_kill_pids=""
|
||||
add_atexit_kill_pid()
|
||||
{
|
||||
atexit_kill_pids="$1 $atexit_kill_pids"
|
||||
}
|
||||
atexit_kill()
|
||||
{
|
||||
local pid
|
||||
|
||||
# suppress bg function exited messages
|
||||
exec {ERR}>&2 2>/dev/null
|
||||
|
||||
for pid in $atexit_kill_pids; do
|
||||
if test -e "/proc/$pid/status" ; then
|
||||
kill "$pid"
|
||||
wait "$pid"
|
||||
fi
|
||||
done
|
||||
|
||||
exec 2>&$ERR {ERR}>&-
|
||||
}
|
||||
trap atexit_kill EXIT
|
||||
|
||||
#
|
||||
# Build a fenced config that runs scripts out of the repository rather
|
||||
# than the default system directory
|
||||
@@ -443,26 +475,43 @@ EOF
|
||||
export SCOUTFS_FENCED_CONFIG_FILE="$conf"
|
||||
T_FENCED_LOG="$T_RESULTS/fenced.log"
|
||||
|
||||
#
|
||||
# Run the agent in the background, log its output, an kill it if we
|
||||
# exit
|
||||
#
|
||||
fenced_log()
|
||||
{
|
||||
echo "[$(timestamp)] $*" >> "$T_FENCED_LOG"
|
||||
}
|
||||
fenced_pid=""
|
||||
kill_fenced()
|
||||
{
|
||||
if test -n "$fenced_pid" -a -d "/proc/$fenced_pid" ; then
|
||||
fenced_log "killing fenced pid $fenced_pid"
|
||||
kill "$fenced_pid"
|
||||
fi
|
||||
}
|
||||
trap kill_fenced EXIT
|
||||
$T_UTILS/fenced/scoutfs-fenced > "$T_FENCED_LOG" 2>&1 &
|
||||
fenced_pid=$!
|
||||
fenced_log "started fenced pid $fenced_pid in the background"
|
||||
add_atexit_kill_pid $fenced_pid
|
||||
|
||||
#
|
||||
# some critical failures will cause fs operations to hang. We can watch
|
||||
# for evidence of them and cause the system to crash, at least.
|
||||
#
|
||||
crash_monitor()
|
||||
{
|
||||
local bad=0
|
||||
|
||||
while sleep 1; do
|
||||
if dmesg | grep -q "inserting extent.*overlaps existing"; then
|
||||
echo "run-tests monitor saw overlapping extent message"
|
||||
bad=1
|
||||
fi
|
||||
|
||||
if dmesg | grep -q "error indicated by fence action" ; then
|
||||
echo "run-tests monitor saw fence agent error message"
|
||||
bad=1
|
||||
fi
|
||||
|
||||
if [ ! -e "/proc/${fenced_pid}/status" ]; then
|
||||
echo "run-tests monitor didn't see fenced pid $fenced_pid /proc dir"
|
||||
bad=1
|
||||
fi
|
||||
|
||||
if [ "$bad" != 0 ]; then
|
||||
echo "run-tests monitor triggering crash"
|
||||
echo c > /proc/sysrq-trigger
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
crash_monitor &
|
||||
add_atexit_kill_pid $!
|
||||
|
||||
# setup dm tables
|
||||
echo "0 $(blockdev --getsz $T_META_DEVICE) linear $T_META_DEVICE 0" > \
|
||||
@@ -535,7 +584,7 @@ fi
|
||||
. funcs/filter.sh
|
||||
|
||||
# give tests access to built binaries in src/, prefer over installed
|
||||
PATH="$PWD/src:$PATH"
|
||||
export PATH="$PWD/src:$PATH"
|
||||
|
||||
msg "running tests"
|
||||
> "$T_RESULTS/skip.log"
|
||||
@@ -555,101 +604,110 @@ for t in $tests; do
|
||||
t="tests/$t"
|
||||
test_name=$(basename "$t" | sed -e 's/.sh$//')
|
||||
|
||||
# create a temporary dir and file path for the test
|
||||
T_TMPDIR="$T_RESULTS/tmp/$test_name"
|
||||
T_TMP="$T_TMPDIR/tmp"
|
||||
cmd rm -rf "$T_TMPDIR"
|
||||
cmd mkdir -p "$T_TMPDIR"
|
||||
|
||||
# create a test name dir in the fs, clean up old data as needed
|
||||
T_DS=""
|
||||
for i in $(seq 0 $((T_NR_MOUNTS - 1))); do
|
||||
dir="${T_M[$i]}/test/$test_name"
|
||||
|
||||
test $i == 0 && (
|
||||
test -d "$dir" && cmd rm -rf "$dir"
|
||||
cmd mkdir -p "$dir"
|
||||
)
|
||||
|
||||
eval T_D$i=$dir
|
||||
T_D[$i]=$dir
|
||||
T_DS+="$dir "
|
||||
done
|
||||
|
||||
# export all our T_ variables
|
||||
for v in ${!T_*}; do
|
||||
eval export $v
|
||||
done
|
||||
export PATH # give test access to scoutfs binary
|
||||
|
||||
# prepare to compare output to golden output
|
||||
test -e "$T_RESULTS/output" || cmd mkdir -p "$T_RESULTS/output"
|
||||
out="$T_RESULTS/output/$test_name"
|
||||
> "$T_TMPDIR/status.msg"
|
||||
golden="golden/$test_name"
|
||||
|
||||
# get stats from previous pass
|
||||
last="$T_RESULTS/last-passed-test-stats"
|
||||
stats=$(grep -s "^$test_name " "$last" | cut -d " " -f 2-)
|
||||
test -n "$stats" && stats="last: $stats"
|
||||
|
||||
printf " %-30s $stats" "$test_name"
|
||||
|
||||
# mark in dmesg as to what test we are running
|
||||
echo "run scoutfs test $test_name" > /dev/kmsg
|
||||
|
||||
# record dmesg before
|
||||
dmesg | t_filter_dmesg > "$T_TMPDIR/dmesg.before"
|
||||
# let the test get at its extra files
|
||||
T_EXTRA="$T_TESTS/extra/$test_name"
|
||||
|
||||
# give tests stdout and compared output on specific fds
|
||||
exec 6>&1
|
||||
exec 7>$out
|
||||
for iter in $(seq 1 $T_LOOP_ITER); do
|
||||
|
||||
# run the test with access to our functions
|
||||
start_secs=$SECONDS
|
||||
bash -c "for f in funcs/*.sh; do . \$f; done; . $t" >&7 2>&1
|
||||
sts="$?"
|
||||
log "test $t exited with status $sts"
|
||||
stats="$((SECONDS - start_secs))s"
|
||||
# create a temporary dir and file path for the test
|
||||
T_TMPDIR="$T_RESULTS/tmp/$test_name"
|
||||
T_TMP="$T_TMPDIR/tmp"
|
||||
cmd rm -rf "$T_TMPDIR"
|
||||
cmd mkdir -p "$T_TMPDIR"
|
||||
|
||||
# close our weird descriptors
|
||||
exec 6>&-
|
||||
exec 7>&-
|
||||
# create a test name dir in the fs, clean up old data as needed
|
||||
T_DS=""
|
||||
for i in $(seq 0 $((T_NR_MOUNTS - 1))); do
|
||||
dir="${T_M[$i]}/test/$test_name"
|
||||
|
||||
# compare output if the test returned passed status
|
||||
if [ "$sts" == "$T_PASS_STATUS" ]; then
|
||||
if [ ! -e "$golden" ]; then
|
||||
message="no golden output"
|
||||
sts=$T_FAIL_STATUS
|
||||
elif ! cmp -s "$golden" "$out"; then
|
||||
message="output differs"
|
||||
sts=$T_FAIL_STATUS
|
||||
diff -u "$golden" "$out" >> "$T_RESULTS/fail.log"
|
||||
test $i == 0 && (
|
||||
test -d "$dir" && cmd rm -rf "$dir"
|
||||
cmd mkdir -p "$dir"
|
||||
)
|
||||
|
||||
eval T_D$i=$dir
|
||||
T_D[$i]=$dir
|
||||
T_DS+="$dir "
|
||||
done
|
||||
|
||||
# export all our T_ variables
|
||||
for v in ${!T_*}; do
|
||||
eval export $v
|
||||
done
|
||||
|
||||
# prepare to compare output to golden output
|
||||
test -e "$T_RESULTS/output" || cmd mkdir -p "$T_RESULTS/output"
|
||||
out="$T_RESULTS/output/$test_name"
|
||||
> "$T_TMPDIR/status.msg"
|
||||
golden="golden/$test_name"
|
||||
|
||||
# record dmesg before
|
||||
dmesg | t_filter_dmesg > "$T_TMPDIR/dmesg.before"
|
||||
|
||||
# give tests stdout and compared output on specific fds
|
||||
exec 6>&1
|
||||
exec 7>$out
|
||||
|
||||
# run the test with access to our functions
|
||||
start_secs=$SECONDS
|
||||
bash -c "for f in funcs/*.sh; do . \$f; done; . $t" >&7 2>&1
|
||||
sts="$?"
|
||||
log "test $t exited with status $sts"
|
||||
stats="$((SECONDS - start_secs))s"
|
||||
|
||||
# close our weird descriptors
|
||||
exec 6>&-
|
||||
exec 7>&-
|
||||
|
||||
# compare output if the test returned passed status
|
||||
if [ "$sts" == "$T_PASS_STATUS" ]; then
|
||||
if [ ! -e "$golden" ]; then
|
||||
message="no golden output"
|
||||
sts=$T_FAIL_STATUS
|
||||
elif ! cmp -s "$golden" "$out"; then
|
||||
message="output differs"
|
||||
sts=$T_FAIL_STATUS
|
||||
diff -u "$golden" "$out" >> "$T_RESULTS/fail.log"
|
||||
fi
|
||||
else
|
||||
# get message from t_*() functions
|
||||
message=$(cat "$T_TMPDIR/status.msg")
|
||||
fi
|
||||
else
|
||||
# get message from t_*() functions
|
||||
message=$(cat "$T_TMPDIR/status.msg")
|
||||
fi
|
||||
|
||||
# see if anything unexpected was added to dmesg
|
||||
if [ "$sts" == "$T_PASS_STATUS" ]; then
|
||||
dmesg | t_filter_dmesg > "$T_TMPDIR/dmesg.after"
|
||||
diff --old-line-format="" --unchanged-line-format="" \
|
||||
"$T_TMPDIR/dmesg.before" "$T_TMPDIR/dmesg.after" > \
|
||||
"$T_TMPDIR/dmesg.new"
|
||||
# see if anything unexpected was added to dmesg
|
||||
if [ "$sts" == "$T_PASS_STATUS" ]; then
|
||||
dmesg | t_filter_dmesg > "$T_TMPDIR/dmesg.after"
|
||||
diff --old-line-format="" --unchanged-line-format="" \
|
||||
"$T_TMPDIR/dmesg.before" "$T_TMPDIR/dmesg.after" > \
|
||||
"$T_TMPDIR/dmesg.new"
|
||||
|
||||
if [ -s "$T_TMPDIR/dmesg.new" ]; then
|
||||
message="unexpected messages in dmesg"
|
||||
sts=$T_FAIL_STATUS
|
||||
cat "$T_TMPDIR/dmesg.new" >> "$T_RESULTS/fail.log"
|
||||
if [ -s "$T_TMPDIR/dmesg.new" ]; then
|
||||
message="unexpected messages in dmesg"
|
||||
sts=$T_FAIL_STATUS
|
||||
cat "$T_TMPDIR/dmesg.new" >> "$T_RESULTS/fail.log"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# record unknown exit status
|
||||
if [ "$sts" -lt "$T_FIRST_STATUS" -o "$sts" -gt "$T_LAST_STATUS" ]; then
|
||||
message="unknown status: $sts"
|
||||
sts=$T_FAIL_STATUS
|
||||
fi
|
||||
# record unknown exit status
|
||||
if [ "$sts" -lt "$T_FIRST_STATUS" -o "$sts" -gt "$T_LAST_STATUS" ]; then
|
||||
message="unknown status: $sts"
|
||||
sts=$T_FAIL_STATUS
|
||||
fi
|
||||
|
||||
# stop looping if we didn't pass
|
||||
if [ "$sts" != "$T_PASS_STATUS" ]; then
|
||||
break;
|
||||
fi
|
||||
done
|
||||
|
||||
# show and record the result of the test
|
||||
if [ "$sts" == "$T_PASS_STATUS" ]; then
|
||||
|
||||
@@ -10,6 +10,7 @@ simple-readdir.sh
|
||||
get-referring-entries.sh
|
||||
fallocate.sh
|
||||
basic-truncate.sh
|
||||
punch-offline.sh
|
||||
data-prealloc.sh
|
||||
setattr_more.sh
|
||||
offline-extent-waiting.sh
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <inttypes.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
@@ -29,7 +30,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
static int size = 0;
|
||||
static int count = 0; /* XXX make this duration instead */
|
||||
static int duration = 0;
|
||||
|
||||
struct thread_info {
|
||||
int nr;
|
||||
@@ -41,6 +42,8 @@ static void *run_test_func(void *ptr)
|
||||
void *buf = NULL;
|
||||
char *addr = NULL;
|
||||
struct thread_info *tinfo = ptr;
|
||||
uint64_t seconds = 0;
|
||||
struct timespec ts;
|
||||
int c = 0;
|
||||
int fd;
|
||||
ssize_t read, written, ret;
|
||||
@@ -61,9 +64,15 @@ static void *run_test_func(void *ptr)
|
||||
|
||||
usleep(100000); /* 0.1sec to allow all threads to start roughly at the same time */
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &ts); /* record start time */
|
||||
seconds = ts.tv_sec + duration;
|
||||
|
||||
for (;;) {
|
||||
if (++c > count)
|
||||
break;
|
||||
if (++c % 16 == 0) {
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
if (ts.tv_sec >= seconds)
|
||||
break;
|
||||
}
|
||||
|
||||
switch (rand() % 4) {
|
||||
case 0: /* pread */
|
||||
@@ -99,6 +108,8 @@ static void *run_test_func(void *ptr)
|
||||
memcpy(addr, buf, size); /* noerr */
|
||||
break;
|
||||
}
|
||||
|
||||
usleep(10000);
|
||||
}
|
||||
|
||||
munmap(addr, size);
|
||||
@@ -120,7 +131,7 @@ int main(int argc, char **argv)
|
||||
int i;
|
||||
|
||||
if (argc != 8) {
|
||||
fprintf(stderr, "%s requires 7 arguments - size count file1 file2 file3 file4 file5\n", argv[0]);
|
||||
fprintf(stderr, "%s requires 7 arguments - size duration file1 file2 file3 file4 file5\n", argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@@ -130,9 +141,9 @@ int main(int argc, char **argv)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
count = atoi(argv[2]);
|
||||
if (count < 0) {
|
||||
fprintf(stderr, "invalid count, must be greater than 0\n");
|
||||
duration = atoi(argv[2]);
|
||||
if (duration < 0) {
|
||||
fprintf(stderr, "invalid duration, must be greater than or equal to 0\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
t_require_commands mmap_stress mmap_validate scoutfs xfs_io
|
||||
|
||||
echo "== mmap_stress"
|
||||
mmap_stress 8192 2000 "$T_D0/mmap_stress" "$T_D1/mmap_stress" "$T_D2/mmap_stress" "$T_D3/mmap_stress" "$T_D4/mmap_stress" | sed 's/:.*//g' | sort
|
||||
mmap_stress 8192 30 "$T_D0/mmap_stress" "$T_D0/mmap_stress" "$T_D0/mmap_stress" "$T_D3/mmap_stress" "$T_D3/mmap_stress" | sed 's/:.*//g' | sort
|
||||
|
||||
echo "== basic mmap/read/write consistency checks"
|
||||
mmap_validate 256 1000 "$T_D0/mmap_val1" "$T_D1/mmap_val1"
|
||||
|
||||
146
tests/tests/punch-offline.sh
Normal file
146
tests/tests/punch-offline.sh
Normal file
@@ -0,0 +1,146 @@
|
||||
|
||||
t_require_commands scoutfs dd fallocate
|
||||
|
||||
FILE="$T_D0/file"
|
||||
DIR="$T_D0/dir"
|
||||
|
||||
echo "== can't hole punch dir or special =="
|
||||
rm -rf $DIR && mkdir -p $DIR
|
||||
scoutfs punch-offline $DIR -o 0 -l 4096 -V 0
|
||||
|
||||
echo "== punching an empty file does nothing =="
|
||||
rm -f $FILE && touch $FILE
|
||||
scoutfs punch-offline $FILE -o 0 -l 4096 -V 0
|
||||
|
||||
echo "== punch outside of i_size does nothing =="
|
||||
dd if=/dev/zero of=$FILE bs=4096 count=1 status=none
|
||||
scoutfs punch-offline $FILE -o 4096 -l 4096 -V 1
|
||||
|
||||
echo "== can't hole punch online extent =="
|
||||
scoutfs get-fiemap -Lb $FILE
|
||||
scoutfs punch-offline $FILE -o 0 -l 4096 -V 1
|
||||
scoutfs get-fiemap -Lb $FILE
|
||||
|
||||
echo "== can't hole punch unwritten extent =="
|
||||
rm -rf $FILE && touch $FILE
|
||||
fallocate -l $((4096 * 3)) $FILE
|
||||
vers=$(scoutfs stat -s data_version "$FILE")
|
||||
scoutfs get-fiemap -Lb $FILE
|
||||
scoutfs punch-offline $FILE -o 4096 -l 4096 -V $vers
|
||||
scoutfs get-fiemap -Lb $FILE
|
||||
|
||||
echo "== hole punch offline extent =="
|
||||
rm -rf $FILE && touch $FILE
|
||||
fallocate -l $((4096 * 3)) $FILE
|
||||
vers=$(scoutfs stat -s data_version "$FILE")
|
||||
scoutfs release $FILE --data-version $vers
|
||||
scoutfs get-fiemap -Lb $FILE
|
||||
scoutfs punch-offline $FILE -o 4096 -l 4096 -V $vers
|
||||
scoutfs get-fiemap -Lb $FILE
|
||||
|
||||
echo "== can't hole punch non-aligned bsz offset or len =="
|
||||
rm -rf $FILE && touch $FILE
|
||||
fallocate -l $((4096 * 3)) $FILE
|
||||
vers=$(scoutfs stat -s data_version "$FILE")
|
||||
scoutfs release $FILE --data-version $vers
|
||||
scoutfs get-fiemap -Lb $FILE
|
||||
scoutfs punch-offline $FILE -o 4095 -l 4096 -V $vers
|
||||
scoutfs punch-offline $FILE -o 1 -l 4096 -V $vers
|
||||
scoutfs punch-offline $FILE -o 4096 -l 409700 -V $vers
|
||||
scoutfs punch-offline $FILE -o 4096 -l 4097 -V $vers
|
||||
scoutfs punch-offline $FILE -o 4096 -l 4095 -V $vers
|
||||
scoutfs punch-offline $FILE -o 4096 -l 1 -V $vers
|
||||
scoutfs punch-offline $FILE -o 4096 -l 0 -V $vers
|
||||
scoutfs get-fiemap -Lb $FILE
|
||||
|
||||
echo "== can't hole punch mismatched data_version =="
|
||||
rm -rf $FILE && touch $FILE
|
||||
fallocate -l $((4096 * 3)) $FILE
|
||||
vers=$(scoutfs stat -s data_version "$FILE")
|
||||
scoutfs release $FILE --data-version $vers
|
||||
scoutfs get-fiemap -Lb $FILE
|
||||
scoutfs punch-offline $FILE -o 4096 -l 4096 -V 0
|
||||
scoutfs punch-offline $FILE -o 4096 -l 4096 -V 2
|
||||
scoutfs punch-offline $FILE -o 4096 -l 4096 -V 9999
|
||||
scoutfs get-fiemap -Lb $FILE
|
||||
|
||||
echo "== Punch hole crossing multiple extents =="
|
||||
rm -rf $FILE && touch $FILE
|
||||
fallocate -l $((7 * 4096)) $FILE
|
||||
vers=$(scoutfs stat -s data_version "$FILE")
|
||||
scoutfs release $FILE --data-version $vers
|
||||
scoutfs get-fiemap -L $FILE
|
||||
scoutfs punch-offline $FILE -o $((1 * 4096)) -l 4096 -V $vers
|
||||
scoutfs punch-offline $FILE -o $((3 * 4096)) -l 4096 -V $vers
|
||||
scoutfs punch-offline $FILE -o $((5 * 4096)) -l 4096 -V $vers
|
||||
# 0.1.2.3
|
||||
scoutfs get-fiemap -L $FILE
|
||||
scoutfs punch-offline $FILE -o $((2 * 4096)) -l $((3 * 4096)) -V $vers
|
||||
# 0.....1
|
||||
scoutfs get-fiemap -L $FILE
|
||||
|
||||
echo "== punch hole starting at a hole =="
|
||||
rm -rf $FILE && touch $FILE
|
||||
fallocate -l $((7 * 4096)) $FILE
|
||||
vers=$(scoutfs stat -s data_version "$FILE")
|
||||
scoutfs release $FILE --data-version $vers
|
||||
scoutfs get-fiemap -L $FILE
|
||||
scoutfs punch-offline $FILE -o $((1 * 4096)) -l 4096 -V $vers
|
||||
scoutfs punch-offline $FILE -o $((3 * 4096)) -l 4096 -V $vers
|
||||
scoutfs punch-offline $FILE -o $((5 * 4096)) -l 4096 -V $vers
|
||||
# 0.1.2.3
|
||||
scoutfs get-fiemap -L $FILE
|
||||
scoutfs punch-offline $FILE -o $((1 * 4096)) -l $((5 * 4096)) -V $vers
|
||||
# 0.....1
|
||||
scoutfs get-fiemap -L $FILE
|
||||
|
||||
echo "== large punch =="
|
||||
rm -rf $FILE && touch $FILE
|
||||
fallocate -l $((6 * 1024 * 1024 * 1024)) $FILE
|
||||
vers=$(scoutfs stat -s data_version "$FILE")
|
||||
scoutfs release $FILE --data-version $vers
|
||||
scoutfs get-fiemap -L $FILE
|
||||
scoutfs punch-offline $FILE -o $((134123 * 4096)) -l $((68343 * 4096)) -V $vers
|
||||
scoutfs punch-offline $FILE -o $((467273 * 4096)) -l $((68343 * 4096)) -V $vers
|
||||
scoutfs punch-offline $FILE -o $((734623 * 4096)) -l $((68343 * 4096)) -V $vers
|
||||
scoutfs get-fiemap -L $FILE
|
||||
|
||||
echo "== overlapping punches with lots of extents =="
|
||||
rm -rf $FILE && touch $FILE
|
||||
fallocate -l $((4096 * 1024)) $FILE
|
||||
vers=$(scoutfs stat -s data_version "$FILE")
|
||||
scoutfs release $FILE --data-version 1
|
||||
scoutfs get-fiemap -Lb $FILE
|
||||
# punch odd ones away
|
||||
for h in $(seq 1 2 1023); do
|
||||
scoutfs punch-offline $FILE -o $((h * 4096)) -l 4096 -V $vers
|
||||
done
|
||||
scoutfs get-fiemap -Lb $FILE | tail -n 1
|
||||
# punch a large hole from 32 to 55, removing 7 extents
|
||||
scoutfs punch-offline $FILE -o $((32 * 4096)) -l $((13 * 4096)) -V $vers
|
||||
scoutfs get-fiemap -Lb $FILE | tail -n 1
|
||||
# punch every 8th @6
|
||||
for h in $(seq 6 8 1024); do
|
||||
scoutfs punch-offline $FILE -o $((h * 4096)) -l 4096 -V $vers
|
||||
done
|
||||
# again @4
|
||||
scoutfs get-fiemap -Lb $FILE | tail -n 1
|
||||
for h in $(seq 4 8 1024); do
|
||||
scoutfs punch-offline $FILE -o $((h * 4096)) -l 4096 -V $vers
|
||||
done
|
||||
scoutfs get-fiemap -Lb $FILE | tail -n 1
|
||||
# punching a large hole from 127 to 175, removing 12 extents
|
||||
scoutfs punch-offline $FILE -o $((127 * 4096)) -l $((48 * 4096)) -V $vers
|
||||
scoutfs get-fiemap -Lb $FILE
|
||||
# again @2
|
||||
for h in $(seq 2 8 1024); do
|
||||
scoutfs punch-offline $FILE -o $((h * 4096)) -l 4096 -V $vers
|
||||
done
|
||||
scoutfs get-fiemap -L $FILE
|
||||
# and again @0, punching away everything remaining extent
|
||||
for h in $(seq 0 8 1024); do
|
||||
scoutfs punch-offline $FILE -o $((h * 4096)) -l 4096 -V $vers
|
||||
done
|
||||
scoutfs get-fiemap -Lb $FILE
|
||||
|
||||
t_pass
|
||||
@@ -63,73 +63,47 @@ export MOUNT_OPTIONS="-o quorum_slot_nr=0,metadev_path=$T_MB0"
|
||||
export TEST_FS_MOUNT_OPTS="-o quorum_slot_nr=0,metadev_path=$T_MB0"
|
||||
EOF
|
||||
|
||||
cat << EOF > local.exclude
|
||||
generic/003 # missing atime update in buffered read
|
||||
generic/075 # file content mismatch failures (fds, etc)
|
||||
generic/103 # enospc causes trans commit failures
|
||||
generic/108 # mount fails on failing device?
|
||||
generic/112 # file content mismatch failures (fds, etc)
|
||||
generic/213 # enospc causes trans commit failures
|
||||
generic/318 # can't support user namespaces until v5.11
|
||||
generic/321 # requires selinux enabled for '+' in ls?
|
||||
generic/338 # BUG_ON update inode error handling
|
||||
generic/347 # _dmthin_mount doesn't work?
|
||||
generic/356 # swap
|
||||
generic/357 # swap
|
||||
generic/409 # bind mounts not scripted yet
|
||||
generic/410 # bind mounts not scripted yet
|
||||
generic/411 # bind mounts not scripted yet
|
||||
generic/423 # symlink inode size is strlen() + 1 on scoutfs
|
||||
generic/430 # xfs_io copy_range missing in el7
|
||||
generic/431 # xfs_io copy_range missing in el7
|
||||
generic/432 # xfs_io copy_range missing in el7
|
||||
generic/433 # xfs_io copy_range missing in el7
|
||||
generic/434 # xfs_io copy_range missing in el7
|
||||
generic/441 # dm-mapper
|
||||
generic/444 # el9's posix_acl_update_mode is buggy ?
|
||||
generic/467 # open_by_handle ESTALE
|
||||
generic/472 # swap
|
||||
generic/484 # dm-mapper
|
||||
generic/493 # swap
|
||||
generic/494 # swap
|
||||
generic/495 # swap
|
||||
generic/496 # swap
|
||||
generic/497 # swap
|
||||
generic/532 # xfs_io statx attrib_mask missing in el7
|
||||
generic/554 # swap
|
||||
generic/563 # cgroup+loopdev
|
||||
generic/564 # xfs_io copy_range missing in el7
|
||||
generic/565 # xfs_io copy_range missing in el7
|
||||
generic/568 # falloc not resulting in block count increase
|
||||
generic/569 # swap
|
||||
generic/570 # swap
|
||||
generic/620 # dm-hugedisk
|
||||
generic/633 # id-mapped mounts missing in el7
|
||||
generic/636 # swap
|
||||
generic/641 # swap
|
||||
generic/643 # swap
|
||||
EOF
|
||||
cp "$T_EXTRA/local.exclude" local.exclude
|
||||
|
||||
t_restore_output
|
||||
t_stdout_invoked
|
||||
echo " (showing output of xfstests)"
|
||||
|
||||
args="-E local.exclude ${T_XFSTESTS_ARGS:--g quick}"
|
||||
./check $args
|
||||
# the fs is unmounted when check finishes
|
||||
|
||||
t_stdout_compare
|
||||
|
||||
#
|
||||
# ./check writes the results of the run to check.log. It lists
|
||||
# the tests it ran, skipped, or failed. Then it writes a line saying
|
||||
# everything passed or some failed. We scrape the most recent run and
|
||||
# use it as the output to compare to make sure that we run the right
|
||||
# tests and get the right results.
|
||||
# ./check writes the results of the run to check.log. It lists the
|
||||
# tests it ran, skipped, or failed. Then it writes a line saying
|
||||
# everything passed or some failed.
|
||||
#
|
||||
|
||||
#
|
||||
# If XFSTESTS_ARGS were specified then we just pass/fail to match the
|
||||
# check run.
|
||||
#
|
||||
if [ -n "$T_XFSTESTS_ARGS" ]; then
|
||||
if tail -1 results/check.log | grep -q "Failed"; then
|
||||
t_fail
|
||||
else
|
||||
t_pass
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Otherwise, typically, when there were no args then we scrape the most
|
||||
# recent run and use it as the output to compare to make sure that we
|
||||
# run the right tests and get the right results.
|
||||
#
|
||||
awk '
|
||||
/^(Ran|Not run|Failures):.*/ {
|
||||
if (pf) {
|
||||
res=""
|
||||
pf=""
|
||||
} res = res "\n" $0
|
||||
}
|
||||
res = res "\n" $0
|
||||
}
|
||||
/^(Passed|Failed).*tests$/ {
|
||||
pf=$0
|
||||
@@ -139,10 +113,14 @@ awk '
|
||||
}' < results/check.log > "$T_TMPDIR/results"
|
||||
|
||||
# put a test per line so diff shows tests that differ
|
||||
egrep "^(Ran|Not run|Failures):" "$T_TMPDIR/results" | \
|
||||
fmt -w 1 > "$T_TMPDIR/results.fmt"
|
||||
egrep "^(Passed|Failed).*tests$" "$T_TMPDIR/results" >> "$T_TMPDIR/results.fmt"
|
||||
grep -E "^(Ran|Not run|Failures):" "$T_TMPDIR/results" | fmt -w 1 > "$T_TMPDIR/results.fmt"
|
||||
grep -E "^(Passed|Failed).*tests$" "$T_TMPDIR/results" >> "$T_TMPDIR/results.fmt"
|
||||
|
||||
t_compare_output cat "$T_TMPDIR/results.fmt"
|
||||
diff -u "$T_EXTRA/expected-results" "$T_TMPDIR/results.fmt" > "$T_TMPDIR/results.diff"
|
||||
if [ -s "$T_TMPDIR/results.diff" ]; then
|
||||
echo "tests that were skipped/run differed from expected:"
|
||||
cat "$T_TMPDIR/results.diff"
|
||||
t_fail
|
||||
fi
|
||||
|
||||
t_pass
|
||||
|
||||
@@ -7,7 +7,7 @@ message_output()
|
||||
|
||||
error_message()
|
||||
{
|
||||
message_output "$@" >&2
|
||||
message_output "$@" >> /dev/stderr
|
||||
}
|
||||
|
||||
error_exit()
|
||||
@@ -62,31 +62,27 @@ test -x "$SCOUTFS_FENCED_RUN" || \
|
||||
# files disappear.
|
||||
#
|
||||
|
||||
# generate failure messages to stderr while still echoing 0 for the caller
|
||||
careful_cat()
|
||||
# silence error messages
|
||||
quiet_cat()
|
||||
{
|
||||
local path="$@"
|
||||
|
||||
cat "$@" || echo 0
|
||||
cat "$@" 2>/dev/null
|
||||
}
|
||||
|
||||
while sleep $SCOUTFS_FENCED_DELAY; do
|
||||
shopt -s nullglob
|
||||
for fence in /sys/fs/scoutfs/*/fence/*; do
|
||||
# catches unmatched regex when no dirs
|
||||
if [ ! -d "$fence" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# skip requests that have been handled
|
||||
if [ "$(careful_cat $fence/fenced)" == 1 -o \
|
||||
"$(careful_cat $fence/error)" == 1 ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
srv=$(basename $(dirname $(dirname $fence)))
|
||||
rid="$(cat $fence/rid)"
|
||||
ip="$(cat $fence/ipv4_addr)"
|
||||
reason="$(cat $fence/reason)"
|
||||
fenced="$(quiet_cat $fence/fenced)"
|
||||
error="$(quiet_cat $fence/error)"
|
||||
rid="$(quiet_cat $fence/rid)"
|
||||
ip="$(quiet_cat $fence/ipv4_addr)"
|
||||
reason="$(quiet_cat $fence/reason)"
|
||||
|
||||
# request dirs can linger then disappear after fenced/error is set
|
||||
if [ ! -d "$fence" -o "$fenced" == "1" -o "$error" == "1" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
log_message "server $srv fencing rid $rid at IP $ip for $reason"
|
||||
|
||||
|
||||
@@ -55,6 +55,14 @@ with initial sparse regions (perhaps by multiple threads writing to
|
||||
different regions) and wasted space isn't an issue (perhaps because the
|
||||
file population contains few small files).
|
||||
.TP
|
||||
.B ino_alloc_per_lock=<number>
|
||||
This option determines how many inode numbers are allocated in the same
|
||||
cluster lock. The default, and maximum, is 1024. The minimum is 1.
|
||||
Allocating fewer inodes per lock can allow more parallelism between
|
||||
mounts because there are more locks that cover the same number of
|
||||
created files. This can be helpful when working with smaller numbers of
|
||||
large files.
|
||||
.TP
|
||||
.B log_merge_wait_timeout_ms=<number>
|
||||
This option sets the amount of time, in milliseconds, that log merge
|
||||
creation can wait before timing out. This setting is per-mount, only
|
||||
|
||||
120
utils/src/punch_offline.c
Normal file
120
utils/src/punch_offline.c
Normal file
@@ -0,0 +1,120 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <argp.h>
|
||||
|
||||
#include "sparse.h"
|
||||
#include "parse.h"
|
||||
#include "util.h"
|
||||
#include "ioctl.h"
|
||||
#include "cmd.h"
|
||||
|
||||
struct po_args {
|
||||
char *path;
|
||||
u64 offset;
|
||||
u64 length;
|
||||
u64 data_version;
|
||||
};
|
||||
|
||||
static int do_punch_offline(struct po_args *args)
|
||||
{
|
||||
struct scoutfs_ioctl_punch_offline ioctl_args;
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
fd = get_path(args->path, O_RDWR);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
ioctl_args.offset = args->offset;
|
||||
ioctl_args.len = args->length;
|
||||
ioctl_args.data_version = args->data_version;
|
||||
ioctl_args.flags = 0;
|
||||
|
||||
ret = ioctl(fd, SCOUTFS_IOC_PUNCH_OFFLINE, &ioctl_args);
|
||||
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
fprintf(stderr, "punch_offline ioctl failed: %s (%d)\n",
|
||||
strerror(errno), errno);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return ret;
|
||||
};
|
||||
|
||||
static int parse_opt(int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
struct po_args *args = state->input;
|
||||
int ret = 0;
|
||||
|
||||
switch (key) {
|
||||
case 'V':
|
||||
ret = parse_u64(arg, &args->data_version);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
case 'o': /* offset */
|
||||
ret = parse_human(arg, &args->offset);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
case 'l': /* length */
|
||||
ret = parse_human(arg, &args->length);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (!args->path)
|
||||
args->path = strdup_or_error(state, arg);
|
||||
else
|
||||
argp_error(state, "unknown extra argument given");
|
||||
break;
|
||||
case ARGP_KEY_FINI:
|
||||
if (!args->path)
|
||||
argp_error(state, "must provide path to file");
|
||||
if (args->offset < 0)
|
||||
argp_error(state, "must provide offset");
|
||||
if (args->length < 0)
|
||||
argp_error(state, "must provide length");
|
||||
if (args->data_version < 0)
|
||||
argp_error(state, "must provide data_version");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct argp_option options[] = {
|
||||
{ "data-version", 'V', "VERSION", 0, "Data version of the file [Required]"},
|
||||
{ "offset", 'o', "OFFSET", 0, "Offset (bytes or KMGTP units) in file to stage (default: 0)"},
|
||||
{ "length", 'l', "LENGTH", 0, "Length of range (bytes or KMGTP units) of file to stage. (default: size of ARCHIVE-FILE)"},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static struct argp argp = {
|
||||
options,
|
||||
parse_opt,
|
||||
"PATH",
|
||||
"Make a (sparse) hole in the file at offset and with length"
|
||||
};
|
||||
|
||||
static int punch_offline_cmd(int argc, char **argv)
|
||||
{
|
||||
struct po_args po_args = {NULL};
|
||||
int ret;
|
||||
|
||||
ret = argp_parse(&argp, argc, argv, 0, NULL, &po_args);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return do_punch_offline(&po_args);
|
||||
}
|
||||
|
||||
static void __attribute__((constructor)) punch_offline_ctor(void)
|
||||
{
|
||||
cmd_register_argp("punch-offline", &argp, GROUP_AGENT, punch_offline_cmd);
|
||||
}
|
||||
Reference in New Issue
Block a user