^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2014 Red Hat, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "xfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "xfs_shared.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "xfs_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "xfs_log_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "xfs_trans_resv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "xfs_sysfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "xfs_log_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "xfs_mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) struct xfs_sysfs_attr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct attribute attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) ssize_t (*show)(struct kobject *kobject, char *buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) ssize_t (*store)(struct kobject *kobject, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) size_t count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static inline struct xfs_sysfs_attr *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) to_attr(struct attribute *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) return container_of(attr, struct xfs_sysfs_attr, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define XFS_SYSFS_ATTR_RW(name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RW(name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define XFS_SYSFS_ATTR_RO(name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define XFS_SYSFS_ATTR_WO(name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_WO(name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) xfs_sysfs_object_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return xfs_attr->show ? xfs_attr->show(kobject, buf) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) xfs_sysfs_object_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return xfs_attr->store ? xfs_attr->store(kobject, buf, count) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static const struct sysfs_ops xfs_sysfs_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .show = xfs_sysfs_object_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .store = xfs_sysfs_object_store,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static struct attribute *xfs_mp_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct kobj_type xfs_mp_ktype = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .release = xfs_sysfs_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .sysfs_ops = &xfs_sysfs_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .default_attrs = xfs_mp_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* debug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) bug_on_assert_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ret = kstrtoint(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (val == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) xfs_globals.bug_on_assert = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) else if (val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) xfs_globals.bug_on_assert = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) bug_on_assert_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.bug_on_assert ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) XFS_SYSFS_ATTR_RW(bug_on_assert);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) log_recovery_delay_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ret = kstrtoint(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (val < 0 || val > 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) xfs_globals.log_recovery_delay = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) log_recovery_delay_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.log_recovery_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) XFS_SYSFS_ATTR_RW(log_recovery_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) mount_delay_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ret = kstrtoint(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (val < 0 || val > 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) xfs_globals.mount_delay = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) mount_delay_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.mount_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) XFS_SYSFS_ATTR_RW(mount_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) always_cow_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ret = kstrtobool(buf, &xfs_globals.always_cow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) always_cow_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.always_cow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) XFS_SYSFS_ATTR_RW(always_cow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * Override how many threads the parallel work queue is allowed to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * This has to be a debug-only global (instead of an errortag) because one of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * the main users of parallel workqueues is mount time quotacheck.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) pwork_threads_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ret = kstrtoint(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (val < -1 || val > num_possible_cpus())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) xfs_globals.pwork_threads = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) pwork_threads_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.pwork_threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) XFS_SYSFS_ATTR_RW(pwork_threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #endif /* DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static struct attribute *xfs_dbg_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) ATTR_LIST(bug_on_assert),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) ATTR_LIST(log_recovery_delay),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) ATTR_LIST(mount_delay),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ATTR_LIST(always_cow),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ATTR_LIST(pwork_threads),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct kobj_type xfs_dbg_ktype = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) .release = xfs_sysfs_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .sysfs_ops = &xfs_sysfs_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .default_attrs = xfs_dbg_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #endif /* DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* stats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static inline struct xstats *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) to_xstats(struct kobject *kobject)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct xfs_kobj *kobj = to_kobj(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return container_of(kobj, struct xstats, xs_kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) stats_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct xstats *stats = to_xstats(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return xfs_stats_format(stats->xs_stats, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) XFS_SYSFS_ATTR_RO(stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) stats_clear_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct xstats *stats = to_xstats(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) ret = kstrtoint(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (val != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) xfs_stats_clearall(stats->xs_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) XFS_SYSFS_ATTR_WO(stats_clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static struct attribute *xfs_stats_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ATTR_LIST(stats),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) ATTR_LIST(stats_clear),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct kobj_type xfs_stats_ktype = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .release = xfs_sysfs_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .sysfs_ops = &xfs_sysfs_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .default_attrs = xfs_stats_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* xlog */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static inline struct xlog *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) to_xlog(struct kobject *kobject)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct xfs_kobj *kobj = to_kobj(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return container_of(kobj, struct xlog, l_kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) log_head_lsn_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int cycle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct xlog *log = to_xlog(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) spin_lock(&log->l_icloglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) cycle = log->l_curr_cycle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) block = log->l_curr_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) spin_unlock(&log->l_icloglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) XFS_SYSFS_ATTR_RO(log_head_lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) log_tail_lsn_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) int cycle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) int block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct xlog *log = to_xlog(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) xlog_crack_atomic_lsn(&log->l_tail_lsn, &cycle, &block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) XFS_SYSFS_ATTR_RO(log_tail_lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) reserve_grant_head_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int cycle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct xlog *log = to_xlog(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) xlog_crack_grant_head(&log->l_reserve_head.grant, &cycle, &bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) XFS_SYSFS_ATTR_RO(reserve_grant_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) STATIC ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) write_grant_head_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) int cycle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) int bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct xlog *log = to_xlog(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) xlog_crack_grant_head(&log->l_write_head.grant, &cycle, &bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) XFS_SYSFS_ATTR_RO(write_grant_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static struct attribute *xfs_log_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ATTR_LIST(log_head_lsn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) ATTR_LIST(log_tail_lsn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ATTR_LIST(reserve_grant_head),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ATTR_LIST(write_grant_head),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct kobj_type xfs_log_ktype = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .release = xfs_sysfs_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) .sysfs_ops = &xfs_sysfs_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .default_attrs = xfs_log_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * Metadata IO error configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * The sysfs structure here is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * ...xfs/<dev>/error/<class>/<errno>/<error_attrs>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * where <class> allows us to discriminate between data IO and metadata IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * and any other future type of IO (e.g. special inode or directory error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * handling) we care to support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static inline struct xfs_error_cfg *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) to_error_cfg(struct kobject *kobject)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct xfs_kobj *kobj = to_kobj(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return container_of(kobj, struct xfs_error_cfg, kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static inline struct xfs_mount *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) err_to_mp(struct kobject *kobject)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct xfs_kobj *kobj = to_kobj(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return container_of(kobj, struct xfs_mount, m_error_kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) max_retries_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) int retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct xfs_error_cfg *cfg = to_error_cfg(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (cfg->max_retries == XFS_ERR_RETRY_FOREVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) retries = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) retries = cfg->max_retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return snprintf(buf, PAGE_SIZE, "%d\n", retries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) max_retries_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct xfs_error_cfg *cfg = to_error_cfg(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret = kstrtoint(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (val < -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (val == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) cfg->max_retries = XFS_ERR_RETRY_FOREVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) cfg->max_retries = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) XFS_SYSFS_ATTR_RW(max_retries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) retry_timeout_seconds_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct xfs_error_cfg *cfg = to_error_cfg(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (cfg->retry_timeout == XFS_ERR_RETRY_FOREVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) timeout = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) timeout = jiffies_to_msecs(cfg->retry_timeout) / MSEC_PER_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return snprintf(buf, PAGE_SIZE, "%d\n", timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) retry_timeout_seconds_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct xfs_error_cfg *cfg = to_error_cfg(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) ret = kstrtoint(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* 1 day timeout maximum, -1 means infinite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (val < -1 || val > 86400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (val == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) cfg->retry_timeout = XFS_ERR_RETRY_FOREVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) cfg->retry_timeout = msecs_to_jiffies(val * MSEC_PER_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ASSERT(msecs_to_jiffies(val * MSEC_PER_SEC) < LONG_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) XFS_SYSFS_ATTR_RW(retry_timeout_seconds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) fail_at_unmount_show(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct xfs_mount *mp = err_to_mp(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return snprintf(buf, PAGE_SIZE, "%d\n", mp->m_fail_unmount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) fail_at_unmount_store(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct kobject *kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct xfs_mount *mp = err_to_mp(kobject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) ret = kstrtoint(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (val < 0 || val > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) mp->m_fail_unmount = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) XFS_SYSFS_ATTR_RW(fail_at_unmount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static struct attribute *xfs_error_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ATTR_LIST(max_retries),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ATTR_LIST(retry_timeout_seconds),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static struct kobj_type xfs_error_cfg_ktype = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) .release = xfs_sysfs_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) .sysfs_ops = &xfs_sysfs_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .default_attrs = xfs_error_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) static struct kobj_type xfs_error_ktype = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .release = xfs_sysfs_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .sysfs_ops = &xfs_sysfs_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * Error initialization tables. These need to be ordered in the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * order as the enums used to index the array. All class init tables need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * define a "default" behaviour as the first entry, all other entries can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) struct xfs_error_init {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) int max_retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) int retry_timeout; /* in seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static const struct xfs_error_init xfs_error_meta_init[XFS_ERR_ERRNO_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) { .name = "default",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .max_retries = XFS_ERR_RETRY_FOREVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .retry_timeout = XFS_ERR_RETRY_FOREVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) { .name = "EIO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) .max_retries = XFS_ERR_RETRY_FOREVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .retry_timeout = XFS_ERR_RETRY_FOREVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) { .name = "ENOSPC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) .max_retries = XFS_ERR_RETRY_FOREVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .retry_timeout = XFS_ERR_RETRY_FOREVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) { .name = "ENODEV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) .max_retries = 0, /* We can't recover from devices disappearing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) .retry_timeout = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) xfs_error_sysfs_init_class(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) int class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) const char *parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct xfs_kobj *parent_kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) const struct xfs_error_init init[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct xfs_error_cfg *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) ASSERT(class < XFS_ERR_CLASS_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) error = xfs_sysfs_init(parent_kobj, &xfs_error_ktype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) &mp->m_error_kobj, parent_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) for (i = 0; i < XFS_ERR_ERRNO_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) cfg = &mp->m_error_cfg[class][i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) error = xfs_sysfs_init(&cfg->kobj, &xfs_error_cfg_ktype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) parent_kobj, init[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) goto out_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) cfg->max_retries = init[i].max_retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (init[i].retry_timeout == XFS_ERR_RETRY_FOREVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) cfg->retry_timeout = XFS_ERR_RETRY_FOREVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) cfg->retry_timeout = msecs_to_jiffies(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) init[i].retry_timeout * MSEC_PER_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) out_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /* unwind the entries that succeeded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) for (i--; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) cfg = &mp->m_error_cfg[class][i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) xfs_sysfs_del(&cfg->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) xfs_sysfs_del(parent_kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) xfs_error_sysfs_init(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct xfs_mount *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /* .../xfs/<dev>/error/ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) error = xfs_sysfs_init(&mp->m_error_kobj, &xfs_error_ktype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) &mp->m_kobj, "error");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) error = sysfs_create_file(&mp->m_error_kobj.kobject,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) ATTR_LIST(fail_at_unmount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) goto out_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /* .../xfs/<dev>/error/metadata/ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) error = xfs_error_sysfs_init_class(mp, XFS_ERR_METADATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) "metadata", &mp->m_error_meta_kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) xfs_error_meta_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) goto out_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) out_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) xfs_sysfs_del(&mp->m_error_kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) xfs_error_sysfs_del(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct xfs_mount *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct xfs_error_cfg *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) for (i = 0; i < XFS_ERR_CLASS_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) for (j = 0; j < XFS_ERR_ERRNO_MAX; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) cfg = &mp->m_error_cfg[i][j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) xfs_sysfs_del(&cfg->kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) xfs_sysfs_del(&mp->m_error_meta_kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) xfs_sysfs_del(&mp->m_error_kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct xfs_error_cfg *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) xfs_error_get_cfg(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) int error_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) int error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct xfs_error_cfg *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) error = -error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) switch (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) case EIO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) cfg = &mp->m_error_cfg[error_class][XFS_ERR_EIO];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) case ENOSPC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENOSPC];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) case ENODEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENODEV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) cfg = &mp->m_error_cfg[error_class][XFS_ERR_DEFAULT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }