In addition to the regular os_filesfree, os_kbytesfree, etc.
parameters available for each OBD device, add os_state as
a "statfs_state" parameter that contain a single character
fir each of the OS_STATE_* flags that indicate an uncommon
aspec of the target, so that it can be checked.
This allows checking if an OST is read-only ('R' character),
out of blocks ('B'), or inodes ('I'), degraded ('D'),
or is flash-based (non-rotational) storage decoce ('f').
Remove old procfs wrappers for printing statfs data, since
they are no longer used in any parts of the code.
Modify sanity test_56c() to verify that the new statfs_state
is matching the state printed by "lfs df -v". Allow this
subtest to be run on flash devices that already have 'f' set.
Remove hard-coded waits. Clean up properly in case of errors.
Fix up the code style of sanity test_79 to match current rules.
Allow restore_lustre_params() to accept a filename argument, and
remove it after restore, rather than needing this in all callers.
Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Change-Id: I0462acdb7b9b7ec76792c9ff50206af2ae2540e5
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/58259
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Artem Blagodarenko <ablagodarenko@ddn.com>
Reviewed-by: Arshad Hussain <arshad.hussain@aeoncomputing.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
const char *name, struct ldebugfs_vars *list);
int dt_tunables_fini(struct dt_device *dt);
-#ifdef CONFIG_PROC_FS
-int lprocfs_dt_blksize_seq_show(struct seq_file *m, void *v);
-int lprocfs_dt_kbytestotal_seq_show(struct seq_file *m, void *v);
-int lprocfs_dt_kbytesfree_seq_show(struct seq_file *m, void *v);
-int lprocfs_dt_kbytesavail_seq_show(struct seq_file *m, void *v);
-int lprocfs_dt_filestotal_seq_show(struct seq_file *m, void *v);
-int lprocfs_dt_filesfree_seq_show(struct seq_file *m, void *v);
-#endif /* CONFIG_PROC_FS */
-
#endif /* __LUSTRE_DT_OBJECT_H */
struct root_squash_info *squash, char *name);
int lprocfs_wr_nosquash_nids(const char __user *buffer, unsigned long count,
struct root_squash_info *squash, char *name);
+ssize_t lprocfs_statfs_state(char *buf, size_t buflen, __u32 state);
#else /* !CONFIG_PROC_FS */
return 0;
}
-/* Statfs helpers */
-static inline
-int lprocfs_blksize_seq_show(struct seq_file *m, void *data)
-{
- return 0;
-}
-
-static inline
-int lprocfs_kbytestotal_seq_show(struct seq_file *m, void *data)
-{
- return 0;
-}
-
-static inline
-int lprocfs_kbytesfree_seq_show(struct seq_file *m, void *data)
-{
- return 0;
-}
-
-static inline
-int lprocfs_kbytesavail_seq_show(struct seq_file *m, void *data)
-{
- return 0;
-}
-
-static inline
-int lprocfs_filestotal_seq_show(struct seq_file *m, void *data)
-{
- return 0;
-}
-
-static inline
-int lprocfs_filesfree_seq_show(struct seq_file *m, void *data)
-{
- return 0;
-}
-
static inline
void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value)
{
OS_STATFS_SUM = 0x00000100, /**< aggregated for all tagrets */
OS_STATFS_NONROT = 0x00000200, /**< non-rotational device */
};
+
+struct obd_statfs_state_name {
+ enum obd_statfs_state osn_state;
+ const char osn_name;
+ bool osn_err;
+};
+
+/*
+ * Return the obd_statfs state info that matches the first set bit in @state.
+ *
+ * This is to identify various states returned by the OST_STATFS RPC.
+ *
+ * If .osn_err = true, then this is an error state indicating the target
+ * is degraded, read-only, full, or should otherwise not be used.
+ * If .osn_err = false, then this is an informational state and uses a
+ * lower-case name to distinguish it from error conditions.
+ *
+ * The UNUSED[12] bits were part of os_state=EROFS=30=0x1e until Lustre 1.6.
+ */
+static inline const
+struct obd_statfs_state_name *obd_statfs_state_name_find(__u32 state)
+{
+ static struct obd_statfs_state_name oss_names[] = {
+ { .osn_state = OS_STATFS_DEGRADED, .osn_name = 'D', .osn_err = true },
+ { .osn_state = OS_STATFS_READONLY, .osn_name = 'R', .osn_err = true },
+ { .osn_state = OS_STATFS_NOCREATE, .osn_name = 'N', .osn_err = true },
+ { .osn_state = OS_STATFS_UNUSED1, .osn_name = '?', .osn_err = true },
+ { .osn_state = OS_STATFS_UNUSED2, .osn_name = '?', .osn_err = true },
+ { .osn_state = OS_STATFS_ENOSPC, .osn_name = 'S', .osn_err = true },
+ { .osn_state = OS_STATFS_ENOINO, .osn_name = 'I', .osn_err = true },
+ { .osn_state = OS_STATFS_SUM, .osn_name = 'a', /* aggregate */ },
+ { .osn_state = OS_STATFS_NONROT, .osn_name = 'f', /* flash */ },
+ { .osn_state = 0, }
+ };
+ int i;
+
+ for (i = 0; oss_names[i].osn_state; i++) {
+ if (state & oss_names[i].osn_state)
+ return &oss_names[i];
+ }
+
+ return NULL;
+};
#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 20, 53, 0)
#define OS_STATFS_NOPRECREATE OS_STATFS_NOCREATE
#endif
if (rc)
return rc;
- return sprintf(buf, "%u\n", osfs.os_bsize);
+ return scnprintf(buf, PAGE_SIZE, "%u\n", osfs.os_bsize);
}
LUSTRE_RO_ATTR(blocksize);
struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
ll_kset.kobj);
- return sprintf(buf, "%u\n", sbi->ll_stat_blksize);
+ return scnprintf(buf, PAGE_SIZE, "%u\n", sbi->ll_stat_blksize);
}
static ssize_t stat_blocksize_store(struct kobject *kobj,
while (blk_size >>= 1)
result <<= 1;
- return sprintf(buf, "%llu\n", result);
+ return scnprintf(buf, PAGE_SIZE, "%llu\n", result);
}
LUSTRE_RO_ATTR(kbytestotal);
while (blk_size >>= 1)
result <<= 1;
- return sprintf(buf, "%llu\n", result);
+ return scnprintf(buf, PAGE_SIZE, "%llu\n", result);
}
LUSTRE_RO_ATTR(kbytesfree);
while (blk_size >>= 1)
result <<= 1;
- return sprintf(buf, "%llu\n", result);
+ return scnprintf(buf, PAGE_SIZE, "%llu\n", result);
}
LUSTRE_RO_ATTR(kbytesavail);
if (rc)
return rc;
- return sprintf(buf, "%llu\n", osfs.os_files);
+ return scnprintf(buf, PAGE_SIZE, "%llu\n", osfs.os_files);
}
LUSTRE_RO_ATTR(filestotal);
if (rc)
return rc;
- return sprintf(buf, "%llu\n", osfs.os_ffree);
+ return scnprintf(buf, PAGE_SIZE, "%llu\n", osfs.os_ffree);
}
LUSTRE_RO_ATTR(filesfree);
+static ssize_t statfs_state_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kset.kobj);
+ struct obd_statfs osfs;
+ int rc;
+
+ rc = ll_statfs_internal(sbi, &osfs, OBD_STATFS_NODELAY);
+ if (rc)
+ return rc;
+
+ return lprocfs_statfs_state(buf, PAGE_SIZE, osfs.os_state);
+}
+LUSTRE_RO_ATTR(statfs_state);
+
static ssize_t client_type_show(struct kobject *kobj, struct attribute *attr,
char *buf)
{
static struct attribute *llite_attrs[] = {
&lustre_attr_blocksize.attr,
- &lustre_attr_stat_blocksize.attr,
+ &lustre_attr_filestotal.attr,
+ &lustre_attr_filesfree.attr,
&lustre_attr_kbytestotal.attr,
&lustre_attr_kbytesfree.attr,
&lustre_attr_kbytesavail.attr,
- &lustre_attr_filestotal.attr,
- &lustre_attr_filesfree.attr,
&lustre_attr_client_type.attr,
&lustre_attr_foreign_symlink_enable.attr,
&lustre_attr_foreign_symlink_prefix.attr,
&lustre_attr_max_read_ahead_async_active.attr,
&lustre_attr_read_ahead_async_file_threshold_mb.attr,
&lustre_attr_read_ahead_range_kb.attr,
+ &lustre_attr_stat_blocksize.attr,
&lustre_attr_stats_track_pid.attr,
&lustre_attr_stats_track_ppid.attr,
&lustre_attr_stats_track_gid.attr,
&lustre_attr_lazystatfs.attr,
&lustre_attr_statfs_max_age.attr,
&lustre_attr_statfs_project.attr,
+ &lustre_attr_statfs_state.attr,
&lustre_attr_max_easize.attr,
&lustre_attr_default_easize.attr,
&lustre_attr_xattr_cache.attr,
#endif
EXPORT_SYMBOL(dt_index_page_adjust);
-#ifdef CONFIG_PROC_FS
-int lprocfs_dt_blksize_seq_show(struct seq_file *m, void *v)
-{
- struct dt_device *dt = m->private;
- struct obd_statfs osfs;
-
- int rc = dt_statfs(NULL, dt, &osfs);
- if (rc == 0)
- seq_printf(m, "%u\n", (unsigned) osfs.os_bsize);
- return rc;
-}
-EXPORT_SYMBOL(lprocfs_dt_blksize_seq_show);
-
-int lprocfs_dt_kbytestotal_seq_show(struct seq_file *m, void *v)
-{
- struct dt_device *dt = m->private;
- struct obd_statfs osfs;
-
- int rc = dt_statfs(NULL, dt, &osfs);
- if (rc == 0) {
- __u32 blk_size = osfs.os_bsize >> 10;
- __u64 result = osfs.os_blocks;
-
- while (blk_size >>= 1)
- result <<= 1;
-
- seq_printf(m, "%llu\n", result);
- }
- return rc;
-}
-EXPORT_SYMBOL(lprocfs_dt_kbytestotal_seq_show);
-
-int lprocfs_dt_kbytesfree_seq_show(struct seq_file *m, void *v)
-{
- struct dt_device *dt = m->private;
- struct obd_statfs osfs;
-
- int rc = dt_statfs(NULL, dt, &osfs);
- if (rc == 0) {
- __u32 blk_size = osfs.os_bsize >> 10;
- __u64 result = osfs.os_bfree;
-
- while (blk_size >>= 1)
- result <<= 1;
-
- seq_printf(m, "%llu\n", result);
- }
- return rc;
-}
-EXPORT_SYMBOL(lprocfs_dt_kbytesfree_seq_show);
-
-int lprocfs_dt_kbytesavail_seq_show(struct seq_file *m, void *v)
-{
- struct dt_device *dt = m->private;
- struct obd_statfs osfs;
-
- int rc = dt_statfs(NULL, dt, &osfs);
- if (rc == 0) {
- __u32 blk_size = osfs.os_bsize >> 10;
- __u64 result = osfs.os_bavail;
-
- while (blk_size >>= 1)
- result <<= 1;
-
- seq_printf(m, "%llu\n", result);
- }
- return rc;
-}
-EXPORT_SYMBOL(lprocfs_dt_kbytesavail_seq_show);
-
-int lprocfs_dt_filestotal_seq_show(struct seq_file *m, void *v)
-{
- struct dt_device *dt = m->private;
- struct obd_statfs osfs;
-
- int rc = dt_statfs(NULL, dt, &osfs);
- if (rc == 0)
- seq_printf(m, "%llu\n", osfs.os_files);
- return rc;
-}
-EXPORT_SYMBOL(lprocfs_dt_filestotal_seq_show);
-
-int lprocfs_dt_filesfree_seq_show(struct seq_file *m, void *v)
-{
- struct dt_device *dt = m->private;
- struct obd_statfs osfs;
-
- int rc = dt_statfs(NULL, dt, &osfs);
- if (rc == 0)
- seq_printf(m, "%llu\n", osfs.os_ffree);
- return rc;
-}
-EXPORT_SYMBOL(lprocfs_dt_filesfree_seq_show);
-
-#endif /* CONFIG_PROC_FS */
-
static ssize_t uuid_show(struct kobject *kobj, struct attribute *attr,
char *buf)
{
}
LUSTRE_RO_ATTR(filesfree);
+static ssize_t statfs_state_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct dt_device *dt = container_of(kobj, struct dt_device,
+ dd_kobj);
+ struct obd_statfs osfs;
+ int rc;
+
+ rc = dt_statfs(NULL, dt, &osfs);
+ if (rc)
+ return rc;
+
+ return lprocfs_statfs_state(buf, PAGE_SIZE, osfs.os_state);
+}
+LUSTRE_RO_ATTR(statfs_state);
+
static const struct attribute *dt_def_attrs[] = {
- &lustre_attr_uuid.attr,
&lustre_attr_blocksize.attr,
&lustre_attr_kbytestotal.attr,
&lustre_attr_kbytesfree.attr,
&lustre_attr_kbytesavail.attr,
&lustre_attr_filestotal.attr,
&lustre_attr_filesfree.attr,
+ &lustre_attr_statfs_state.attr,
+ &lustre_attr_uuid.attr,
NULL,
};
}
LUSTRE_RO_ATTR(filesfree);
+ssize_t lprocfs_statfs_state(char *buf, size_t buflen, __u32 state)
+{
+ size_t off = 0;
+
+ while (state != 0) {
+ const struct obd_statfs_state_name *osn;
+
+ osn = obd_statfs_state_name_find(state);
+ if (!osn) {
+ int len;
+
+ /* Only unknown (future) OS_STATFS flags left.
+ *
+ * Print in octal to avoid confusion with existing
+ * 'a' and 'f' flags if it was printed in hex.
+ */
+ len = scnprintf(buf + off, buflen, "(%#o)", state);
+ off += len;
+ buflen -= len;
+ break;
+ }
+ buf[off++] = osn->osn_name;
+ buflen--;
+ state ^= osn->osn_state;
+ }
+
+ return off + scnprintf(buf + off, buflen, "\n");
+}
+EXPORT_SYMBOL(lprocfs_statfs_state);
+
+static ssize_t statfs_state_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct obd_statfs osfs;
+ int rc;
+
+ rc = obd_statfs(NULL, obd->obd_self_export, &osfs,
+ ktime_get_seconds() - OBD_STATFS_CACHE_SECONDS,
+ OBD_STATFS_NODELAY);
+ if (rc)
+ return rc;
+
+ return lprocfs_statfs_state(buf, PAGE_SIZE, osfs.os_state);
+}
+LUSTRE_RO_ATTR(statfs_state);
+
ssize_t conn_uuid_show(struct kobject *kobj, struct attribute *attr, char *buf)
{
struct obd_device *obd = container_of(kobj, struct obd_device,
static const struct attribute *obd_def_attrs[] = {
&lustre_attr_blocksize.attr,
+ &lustre_attr_filestotal.attr,
+ &lustre_attr_filesfree.attr,
&lustre_attr_kbytestotal.attr,
&lustre_attr_kbytesfree.attr,
&lustre_attr_kbytesavail.attr,
- &lustre_attr_filestotal.attr,
- &lustre_attr_filesfree.attr,
+ &lustre_attr_statfs_state.attr,
&lustre_attr_uuid.attr,
NULL,
};
local ost_idx=0
local ost_name=$(ostname_from_index $ost_idx)
local old_status=$(ost_dev_status $ost_idx)
+ local inst=$(lfs getname -i $DIR)
+ local state="osc.$ost_name-osc-$inst.statfs_state"
+ local old_state=$($LCTL get_param -n $state)
local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
- [[ -z "$old_status" ]] ||
+ [[ "$old_status" == "$old_state" ]] ||
+ error "old status '$old_status' != state '$old_state'"
+
+ [[ -z "$old_status" || "$old_status" == "f" ]] ||
skip_env "OST $ost_name is in $old_status status"
- do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
- [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
- $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
- if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
- save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
- do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
+ local degraded="obdfilter.$ost_name.degraded"
+ save_lustre_params ost1 $degraded > $p
+ do_facet ost1 $LCTL set_param -n $degraded=1
+ stack_trap "restore_lustre_params < $p; rm -f $p"
+
+ if (( $OST1_VERSION >= $(version_code 2.12.55) )); then
+ local no_precreate="obdfilter.$ost_name.no_precreate"
+
+ save_lustre_params ost1 $no_precreate >> $p
+ do_facet ost1 $LCTL set_param -n $no_precreate=1
fi
+ if (( $OST1_VERSION >= $(version_code 2.12.57) )) &&
+ [[ ! "$old_status" =~ "f" ]]; then
+ local nonrotational="osd-*.$ost_name.nonrotational"
- [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
+ save_lustre_params ost1 $nonrotational >> $p
+ do_facet ost1 $LCTL set_param -n $nonrotational=1
+ fi
+
+ [[ ! $($LFS df -v $MOUNT 2>&1) =~ "inactive device" ]] ||
error "$LFS df -v showing inactive devices"
sleep_maxage
+ $LFS df -v $MOUNT
+ $LCTL get_param *.*.statfs_state
+
local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
[[ "$new_status" =~ "D" ]] ||
error "$ost_name status is '$new_status', missing 'D'"
- if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
- [[ "$new_status" =~ "N" ]] ||
- error "$ost_name status is '$new_status', missing 'N'"
+ if (( $OST1_VERSION >= $(version_code 2.12.55) )) &&
+ [[ ! "$new_status" =~ "N" ]]; then
+ error "$ost_name status is '$new_status', missing 'N'"
fi
- if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
- [[ "$new_status" =~ "f" ]] ||
- error "$ost_name status is '$new_status', missing 'f'"
+ if (( $OST1_VERSION >= $(version_code 2.12.57) )) &&
+ [[ ! "$new_status" =~ "f" ]]; then
+ error "$ost_name status is '$new_status', missing 'f'"
fi
- do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
- [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
- $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
- [[ -z "$p" ]] && restore_lustre_params < $p || true
- sleep_maxage
+ wait_update_facet client "$LCTL get_param -n $state" "$new_status" ||
+ error "new state != new_status '$new_status'"
+
+ restore_lustre_params < $p
+
+ wait_update_facet client \
+ "$LFS df -v | awk '/$ost_name/ { print \\\$7 }'" "$old_status" ||
+ {
+ new_status=$(ost_dev_status $ost_idx)
+
+ error "new_status '$new_status' != old_status '$old_status'"
+ }
+
+ wait_update_facet client "$LCTL get_param -n $state" "$old_state" ||
+ {
+ local new_state=$($LCTL get_param -n $state)
- new_status=$(ost_dev_status $ost_idx)
- [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
- error "$ost_name status is '$new_status', has 'D' and/or 'N'"
- # can't check 'f' as devices may actually be on flash
+ error "restored state '$new_state' != old_state '$old_state'"
+ }
}
run_test 56c "check 'lfs df' showing device status"
run_test 78 "handle large O_DIRECT writes correctly ============"
test_79() { # bug 12743
- [ $PARALLEL == "yes" ] && skip "skip parallel run"
+ [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
wait_delete_completed
- BKTOTAL=$(calc_osc_kbytes kbytestotal)
- BKFREE=$(calc_osc_kbytes kbytesfree)
- BKAVAIL=$(calc_osc_kbytes kbytesavail)
-
- STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
- DFTOTAL=`echo $STRING | cut -d, -f1`
- DFUSED=`echo $STRING | cut -d, -f2`
- DFAVAIL=`echo $STRING | cut -d, -f3`
- DFFREE=$(($DFTOTAL - $DFUSED))
-
- ALLOWANCE=$((64 * $OSTCOUNT))
-
- if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
- [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
- error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
- fi
- if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
- [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
- error "df free($DFFREE) mismatch OST free($BKFREE)"
- fi
- if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
- [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
- error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
- fi
-}
-run_test 79 "df report consistency check ======================="
+ local bktotal=$(calc_osc_kbytes kbytestotal)
+ local bkfree=$(calc_osc_kbytes kbytesfree)
+ local bkavail=$(calc_osc_kbytes kbytesavail)
+ local string=($(df -P $MOUNT | tail -n 1))
+ local dftotal=${string[1]}
+ local dfused=${string[2]}
+ local dfavail=${string[3]}
+ local dffree=$(($dftotal - $dfused))
+ local allowance=$((64 * $OSTCOUNT))
+
+ (( dftotal >= bktotal - allowance && dftotal <= bktotal + allowance)) ||
+ error "df total($dftotal) mismatch OST total($bktotal)"
+ (( dffree >= bkfree - allowance && dffree <= bkfree + allowance )) ||
+ error "df free($dffree) mismatch OST free($bkfree)"
+ (( dfavail >= bkavail - allowance && dfavail <= bkavail + allowance)) ||
+ error "df avail($dfavail) mismatch OST avail($bkavail)"
+}
+run_test 79 "df report consistency check"
test_80() { # bug 10718
remote_ost_nodsh && skip "remote OST with nodsh"
}
test_271c() {
- [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
- skip "Need MDS version at least 2.10.55"
+ (( $MDS1_VERSION >= $(version_code v2_10_55_0-74-g2f09984f3f) )) ||
+ skip "Need MDS >= 2.10.55.74 for combined DoM lock bits"
local dom=$DIR/$tdir/dom
mkdir -p $DIR/$tdir
- $LFS setstripe -E 1024K -L mdt $DIR/$tdir
+ $LFS setstripe -E 1024K -L mdt $DIR/$tdir ||
+ error "unable to set DoM layout on $DIR/$tdir"
local mdtidx=$($LFS getstripe -m $DIR/$tdir)
local facet=mds$((mdtidx + 1))
fd = llapi_layout_file_open(fname, open_flags, open_mode, layout);
if (fd < 0)
- fprintf(stderr, "%s: cannot %s '%s': %s\n", progname,
+ fprintf(stderr, "%s: %s '%s': %s\n", progname,
S_ISDIR(st.st_mode) ?
- "set default composite layout for" :
- "create composite file",
+ "cannot set default composite layout for" :
+ "cannot create composite file",
fname, strerror(errno));
return fd;
}
return (ratio - (int)ratio) > 0 ? (int)(ratio + 1) : (int)ratio;
}
-/*
- * This is to identify various problem states for "lfs df" if .osn_err = true,
- * so only show flags reflecting those states by default. Informational states
- * are only shown with "-v" and use lower-case names to distinguish them.
- * UNUSED[12] were for "EROFS = 30" until 1.6 but are now available for use.
- */
-static struct obd_statfs_state_names {
- enum obd_statfs_state osn_state;
- const char osn_name;
- bool osn_err;
-} oss_names[] = {
- { .osn_state = OS_STATFS_DEGRADED, .osn_name = 'D', .osn_err = true },
- { .osn_state = OS_STATFS_READONLY, .osn_name = 'R', .osn_err = true },
- { .osn_state = OS_STATFS_NOCREATE, .osn_name = 'N', .osn_err = true },
- { .osn_state = OS_STATFS_UNUSED1, .osn_name = '?', .osn_err = true },
- { .osn_state = OS_STATFS_UNUSED2, .osn_name = '?', .osn_err = true },
- { .osn_state = OS_STATFS_ENOSPC, .osn_name = 'S', .osn_err = true },
- { .osn_state = OS_STATFS_ENOINO, .osn_name = 'I', .osn_err = true },
- { .osn_state = OS_STATFS_SUM, .osn_name = 'a', /* aggregate */ },
- { .osn_state = OS_STATFS_NONROT, .osn_name = 'f', /* flash */ },
-};
-
static int showdf(char *mntdir, struct obd_statfs *stat,
char *uuid, enum mntdf_flags flags,
char *type, int index, int rc)
printf("[%s:%d]", type, index);
if (stat->os_state) {
- uint32_t i;
+ __u32 state = stat->os_state;
printf(" ");
- for (i = 0; i < ARRAY_SIZE(oss_names); i++) {
- if (oss_names[i].osn_state & stat->os_state &&
- (oss_names[i].osn_err ||
- flags & MNTDF_VERBOSE))
- printf("%c", oss_names[i].osn_name);
+ while (state != 0) {
+ const struct obd_statfs_state_name *osn;
+
+ osn = obd_statfs_state_name_find(state);
+ if (!osn) {
+ /* Unknown flag(s) for remainder.
+ * Print in octal to avoid confusion
+ * with existing 'a' and 'f' flags
+ * if printed in hex.
+ */
+ printf("(%#o)", state);
+ break;
+ }
+ if (osn->osn_err || flags & MNTDF_VERBOSE)
+ printf("%c", osn->osn_name);
+ state ^= osn->osn_state;
}
}