Whamcloud - gitweb
LU-18748 class: print statfs_state for OBD devices 59/58259/21
authorAndreas Dilger <adilger@whamcloud.com>
Thu, 27 Feb 2025 02:36:01 +0000 (19:36 -0700)
committerOleg Drokin <green@whamcloud.com>
Wed, 26 Mar 2025 04:00:56 +0000 (04:00 +0000)
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>
lustre/include/dt_object.h
lustre/include/lprocfs_status.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/llite/lproc_llite.c
lustre/obdclass/dt_object.c
lustre/obdclass/lprocfs_status.c
lustre/tests/sanity.sh
lustre/utils/lfs.c

index 13262ef..a5228ce 100644 (file)
@@ -3087,13 +3087,4 @@ int dt_tunables_init(struct dt_device *dt, struct obd_type *type,
                     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 */
index 13696b9..54fc627 100644 (file)
@@ -937,6 +937,7 @@ int lprocfs_wr_root_squash(const char __user *buffer, unsigned long count,
                           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 */
 
@@ -1155,43 +1156,6 @@ lprocfs_import_seq_write(struct file *file, const char __user *buffer,
        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)
 {
index 7721903..09de932 100644 (file)
@@ -274,6 +274,49 @@ enum obd_statfs_state {
        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
index 4979091..9ca56ff 100644 (file)
@@ -127,7 +127,7 @@ static ssize_t blocksize_show(struct kobject *kobj, struct attribute *attr,
        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);
 
@@ -137,7 +137,7 @@ static ssize_t stat_blocksize_show(struct kobject *kobj, struct attribute *attr,
        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,
@@ -183,7 +183,7 @@ static ssize_t kbytestotal_show(struct kobject *kobj, struct attribute *attr,
        while (blk_size >>= 1)
                result <<= 1;
 
-       return sprintf(buf, "%llu\n", result);
+       return scnprintf(buf, PAGE_SIZE, "%llu\n", result);
 }
 LUSTRE_RO_ATTR(kbytestotal);
 
@@ -207,7 +207,7 @@ static ssize_t kbytesfree_show(struct kobject *kobj, struct attribute *attr,
        while (blk_size >>= 1)
                result <<= 1;
 
-       return sprintf(buf, "%llu\n", result);
+       return scnprintf(buf, PAGE_SIZE, "%llu\n", result);
 }
 LUSTRE_RO_ATTR(kbytesfree);
 
@@ -231,7 +231,7 @@ static ssize_t kbytesavail_show(struct kobject *kobj, struct attribute *attr,
        while (blk_size >>= 1)
                result <<= 1;
 
-       return sprintf(buf, "%llu\n", result);
+       return scnprintf(buf, PAGE_SIZE, "%llu\n", result);
 }
 LUSTRE_RO_ATTR(kbytesavail);
 
@@ -247,7 +247,7 @@ static ssize_t filestotal_show(struct kobject *kobj, struct attribute *attr,
        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);
 
@@ -263,10 +263,26 @@ static ssize_t filesfree_show(struct kobject *kobj, struct attribute *attr,
        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)
 {
@@ -2438,12 +2454,11 @@ struct ldebugfs_vars lprocfs_llite_obd_vars[] = {
 
 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,
@@ -2459,6 +2474,7 @@ static struct attribute *llite_attrs[] = {
        &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,
@@ -2474,6 +2490,7 @@ static struct attribute *llite_attrs[] = {
        &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,
index 8816cce..e9dc2fc 100644 (file)
@@ -1057,102 +1057,6 @@ void dt_index_page_adjust(struct page **pages, const u32 npages,
 #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)
 {
@@ -1287,14 +1191,31 @@ static ssize_t filesfree_show(struct kobject *kobj, struct attribute *attr,
 }
 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,
 };
 
index 68d1f0a..5e29a0e 100644 (file)
@@ -344,6 +344,54 @@ static ssize_t filesfree_show(struct kobject *kobj, struct attribute *attr,
 }
 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,
@@ -1063,11 +1111,12 @@ static const struct attribute *obd_def_uuid_attrs[] = {
 
 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,
 };
index 78daede..7c90f65 100755 (executable)
@@ -6846,46 +6846,75 @@ test_56c() {
        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"
 
@@ -12042,36 +12071,28 @@ test_78() { # bug 10901
 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"
@@ -26701,14 +26722,15 @@ get_mdc_stats() {
 }
 
 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))
index 7ecd998..4974b4f 100755 (executable)
@@ -1462,10 +1462,10 @@ static int lfs_component_create(char *fname, int open_flags, mode_t open_mode,
 
        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;
 }
@@ -7335,28 +7335,6 @@ static inline int obd_statfs_ratio(const struct obd_statfs *st, bool inodes)
        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)
@@ -7431,14 +7409,25 @@ static int showdf(char *mntdir, struct obd_statfs *stat,
                        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;
                        }
                }