0001
0002
0003
0004
0005
0006
0007 #include "xfs.h"
0008 #include "xfs_shared.h"
0009 #include "xfs_format.h"
0010 #include "xfs_log_format.h"
0011 #include "xfs_trans_resv.h"
0012 #include "xfs_sysfs.h"
0013 #include "xfs_log.h"
0014 #include "xfs_log_priv.h"
0015 #include "xfs_mount.h"
0016
0017 struct xfs_sysfs_attr {
0018 struct attribute attr;
0019 ssize_t (*show)(struct kobject *kobject, char *buf);
0020 ssize_t (*store)(struct kobject *kobject, const char *buf,
0021 size_t count);
0022 };
0023
0024 static inline struct xfs_sysfs_attr *
0025 to_attr(struct attribute *attr)
0026 {
0027 return container_of(attr, struct xfs_sysfs_attr, attr);
0028 }
0029
0030 #define XFS_SYSFS_ATTR_RW(name) \
0031 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RW(name)
0032 #define XFS_SYSFS_ATTR_RO(name) \
0033 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name)
0034 #define XFS_SYSFS_ATTR_WO(name) \
0035 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_WO(name)
0036
0037 #define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr
0038
0039 STATIC ssize_t
0040 xfs_sysfs_object_show(
0041 struct kobject *kobject,
0042 struct attribute *attr,
0043 char *buf)
0044 {
0045 struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
0046
0047 return xfs_attr->show ? xfs_attr->show(kobject, buf) : 0;
0048 }
0049
0050 STATIC ssize_t
0051 xfs_sysfs_object_store(
0052 struct kobject *kobject,
0053 struct attribute *attr,
0054 const char *buf,
0055 size_t count)
0056 {
0057 struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
0058
0059 return xfs_attr->store ? xfs_attr->store(kobject, buf, count) : 0;
0060 }
0061
0062 static const struct sysfs_ops xfs_sysfs_ops = {
0063 .show = xfs_sysfs_object_show,
0064 .store = xfs_sysfs_object_store,
0065 };
0066
0067 static struct attribute *xfs_mp_attrs[] = {
0068 NULL,
0069 };
0070 ATTRIBUTE_GROUPS(xfs_mp);
0071
0072 struct kobj_type xfs_mp_ktype = {
0073 .release = xfs_sysfs_release,
0074 .sysfs_ops = &xfs_sysfs_ops,
0075 .default_groups = xfs_mp_groups,
0076 };
0077
0078 #ifdef DEBUG
0079
0080
0081 STATIC ssize_t
0082 bug_on_assert_store(
0083 struct kobject *kobject,
0084 const char *buf,
0085 size_t count)
0086 {
0087 int ret;
0088 int val;
0089
0090 ret = kstrtoint(buf, 0, &val);
0091 if (ret)
0092 return ret;
0093
0094 if (val == 1)
0095 xfs_globals.bug_on_assert = true;
0096 else if (val == 0)
0097 xfs_globals.bug_on_assert = false;
0098 else
0099 return -EINVAL;
0100
0101 return count;
0102 }
0103
0104 STATIC ssize_t
0105 bug_on_assert_show(
0106 struct kobject *kobject,
0107 char *buf)
0108 {
0109 return sysfs_emit(buf, "%d\n", xfs_globals.bug_on_assert);
0110 }
0111 XFS_SYSFS_ATTR_RW(bug_on_assert);
0112
0113 STATIC ssize_t
0114 log_recovery_delay_store(
0115 struct kobject *kobject,
0116 const char *buf,
0117 size_t count)
0118 {
0119 int ret;
0120 int val;
0121
0122 ret = kstrtoint(buf, 0, &val);
0123 if (ret)
0124 return ret;
0125
0126 if (val < 0 || val > 60)
0127 return -EINVAL;
0128
0129 xfs_globals.log_recovery_delay = val;
0130
0131 return count;
0132 }
0133
0134 STATIC ssize_t
0135 log_recovery_delay_show(
0136 struct kobject *kobject,
0137 char *buf)
0138 {
0139 return sysfs_emit(buf, "%d\n", xfs_globals.log_recovery_delay);
0140 }
0141 XFS_SYSFS_ATTR_RW(log_recovery_delay);
0142
0143 STATIC ssize_t
0144 mount_delay_store(
0145 struct kobject *kobject,
0146 const char *buf,
0147 size_t count)
0148 {
0149 int ret;
0150 int val;
0151
0152 ret = kstrtoint(buf, 0, &val);
0153 if (ret)
0154 return ret;
0155
0156 if (val < 0 || val > 60)
0157 return -EINVAL;
0158
0159 xfs_globals.mount_delay = val;
0160
0161 return count;
0162 }
0163
0164 STATIC ssize_t
0165 mount_delay_show(
0166 struct kobject *kobject,
0167 char *buf)
0168 {
0169 return sysfs_emit(buf, "%d\n", xfs_globals.mount_delay);
0170 }
0171 XFS_SYSFS_ATTR_RW(mount_delay);
0172
0173 static ssize_t
0174 always_cow_store(
0175 struct kobject *kobject,
0176 const char *buf,
0177 size_t count)
0178 {
0179 ssize_t ret;
0180
0181 ret = kstrtobool(buf, &xfs_globals.always_cow);
0182 if (ret < 0)
0183 return ret;
0184 return count;
0185 }
0186
0187 static ssize_t
0188 always_cow_show(
0189 struct kobject *kobject,
0190 char *buf)
0191 {
0192 return sysfs_emit(buf, "%d\n", xfs_globals.always_cow);
0193 }
0194 XFS_SYSFS_ATTR_RW(always_cow);
0195
0196 #ifdef DEBUG
0197
0198
0199
0200
0201
0202 STATIC ssize_t
0203 pwork_threads_store(
0204 struct kobject *kobject,
0205 const char *buf,
0206 size_t count)
0207 {
0208 int ret;
0209 int val;
0210
0211 ret = kstrtoint(buf, 0, &val);
0212 if (ret)
0213 return ret;
0214
0215 if (val < -1 || val > num_possible_cpus())
0216 return -EINVAL;
0217
0218 xfs_globals.pwork_threads = val;
0219
0220 return count;
0221 }
0222
0223 STATIC ssize_t
0224 pwork_threads_show(
0225 struct kobject *kobject,
0226 char *buf)
0227 {
0228 return sysfs_emit(buf, "%d\n", xfs_globals.pwork_threads);
0229 }
0230 XFS_SYSFS_ATTR_RW(pwork_threads);
0231
0232 static ssize_t
0233 larp_store(
0234 struct kobject *kobject,
0235 const char *buf,
0236 size_t count)
0237 {
0238 ssize_t ret;
0239
0240 ret = kstrtobool(buf, &xfs_globals.larp);
0241 if (ret < 0)
0242 return ret;
0243 return count;
0244 }
0245
0246 STATIC ssize_t
0247 larp_show(
0248 struct kobject *kobject,
0249 char *buf)
0250 {
0251 return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.larp);
0252 }
0253 XFS_SYSFS_ATTR_RW(larp);
0254 #endif
0255
0256 static struct attribute *xfs_dbg_attrs[] = {
0257 ATTR_LIST(bug_on_assert),
0258 ATTR_LIST(log_recovery_delay),
0259 ATTR_LIST(mount_delay),
0260 ATTR_LIST(always_cow),
0261 #ifdef DEBUG
0262 ATTR_LIST(pwork_threads),
0263 ATTR_LIST(larp),
0264 #endif
0265 NULL,
0266 };
0267 ATTRIBUTE_GROUPS(xfs_dbg);
0268
0269 struct kobj_type xfs_dbg_ktype = {
0270 .release = xfs_sysfs_release,
0271 .sysfs_ops = &xfs_sysfs_ops,
0272 .default_groups = xfs_dbg_groups,
0273 };
0274
0275 #endif
0276
0277
0278
0279 static inline struct xstats *
0280 to_xstats(struct kobject *kobject)
0281 {
0282 struct xfs_kobj *kobj = to_kobj(kobject);
0283
0284 return container_of(kobj, struct xstats, xs_kobj);
0285 }
0286
0287 STATIC ssize_t
0288 stats_show(
0289 struct kobject *kobject,
0290 char *buf)
0291 {
0292 struct xstats *stats = to_xstats(kobject);
0293
0294 return xfs_stats_format(stats->xs_stats, buf);
0295 }
0296 XFS_SYSFS_ATTR_RO(stats);
0297
0298 STATIC ssize_t
0299 stats_clear_store(
0300 struct kobject *kobject,
0301 const char *buf,
0302 size_t count)
0303 {
0304 int ret;
0305 int val;
0306 struct xstats *stats = to_xstats(kobject);
0307
0308 ret = kstrtoint(buf, 0, &val);
0309 if (ret)
0310 return ret;
0311
0312 if (val != 1)
0313 return -EINVAL;
0314
0315 xfs_stats_clearall(stats->xs_stats);
0316 return count;
0317 }
0318 XFS_SYSFS_ATTR_WO(stats_clear);
0319
0320 static struct attribute *xfs_stats_attrs[] = {
0321 ATTR_LIST(stats),
0322 ATTR_LIST(stats_clear),
0323 NULL,
0324 };
0325 ATTRIBUTE_GROUPS(xfs_stats);
0326
0327 struct kobj_type xfs_stats_ktype = {
0328 .release = xfs_sysfs_release,
0329 .sysfs_ops = &xfs_sysfs_ops,
0330 .default_groups = xfs_stats_groups,
0331 };
0332
0333
0334
0335 static inline struct xlog *
0336 to_xlog(struct kobject *kobject)
0337 {
0338 struct xfs_kobj *kobj = to_kobj(kobject);
0339
0340 return container_of(kobj, struct xlog, l_kobj);
0341 }
0342
0343 STATIC ssize_t
0344 log_head_lsn_show(
0345 struct kobject *kobject,
0346 char *buf)
0347 {
0348 int cycle;
0349 int block;
0350 struct xlog *log = to_xlog(kobject);
0351
0352 spin_lock(&log->l_icloglock);
0353 cycle = log->l_curr_cycle;
0354 block = log->l_curr_block;
0355 spin_unlock(&log->l_icloglock);
0356
0357 return sysfs_emit(buf, "%d:%d\n", cycle, block);
0358 }
0359 XFS_SYSFS_ATTR_RO(log_head_lsn);
0360
0361 STATIC ssize_t
0362 log_tail_lsn_show(
0363 struct kobject *kobject,
0364 char *buf)
0365 {
0366 int cycle;
0367 int block;
0368 struct xlog *log = to_xlog(kobject);
0369
0370 xlog_crack_atomic_lsn(&log->l_tail_lsn, &cycle, &block);
0371 return sysfs_emit(buf, "%d:%d\n", cycle, block);
0372 }
0373 XFS_SYSFS_ATTR_RO(log_tail_lsn);
0374
0375 STATIC ssize_t
0376 reserve_grant_head_show(
0377 struct kobject *kobject,
0378 char *buf)
0379
0380 {
0381 int cycle;
0382 int bytes;
0383 struct xlog *log = to_xlog(kobject);
0384
0385 xlog_crack_grant_head(&log->l_reserve_head.grant, &cycle, &bytes);
0386 return sysfs_emit(buf, "%d:%d\n", cycle, bytes);
0387 }
0388 XFS_SYSFS_ATTR_RO(reserve_grant_head);
0389
0390 STATIC ssize_t
0391 write_grant_head_show(
0392 struct kobject *kobject,
0393 char *buf)
0394 {
0395 int cycle;
0396 int bytes;
0397 struct xlog *log = to_xlog(kobject);
0398
0399 xlog_crack_grant_head(&log->l_write_head.grant, &cycle, &bytes);
0400 return sysfs_emit(buf, "%d:%d\n", cycle, bytes);
0401 }
0402 XFS_SYSFS_ATTR_RO(write_grant_head);
0403
0404 static struct attribute *xfs_log_attrs[] = {
0405 ATTR_LIST(log_head_lsn),
0406 ATTR_LIST(log_tail_lsn),
0407 ATTR_LIST(reserve_grant_head),
0408 ATTR_LIST(write_grant_head),
0409 NULL,
0410 };
0411 ATTRIBUTE_GROUPS(xfs_log);
0412
0413 struct kobj_type xfs_log_ktype = {
0414 .release = xfs_sysfs_release,
0415 .sysfs_ops = &xfs_sysfs_ops,
0416 .default_groups = xfs_log_groups,
0417 };
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429 static inline struct xfs_error_cfg *
0430 to_error_cfg(struct kobject *kobject)
0431 {
0432 struct xfs_kobj *kobj = to_kobj(kobject);
0433 return container_of(kobj, struct xfs_error_cfg, kobj);
0434 }
0435
0436 static inline struct xfs_mount *
0437 err_to_mp(struct kobject *kobject)
0438 {
0439 struct xfs_kobj *kobj = to_kobj(kobject);
0440 return container_of(kobj, struct xfs_mount, m_error_kobj);
0441 }
0442
0443 static ssize_t
0444 max_retries_show(
0445 struct kobject *kobject,
0446 char *buf)
0447 {
0448 int retries;
0449 struct xfs_error_cfg *cfg = to_error_cfg(kobject);
0450
0451 if (cfg->max_retries == XFS_ERR_RETRY_FOREVER)
0452 retries = -1;
0453 else
0454 retries = cfg->max_retries;
0455
0456 return sysfs_emit(buf, "%d\n", retries);
0457 }
0458
0459 static ssize_t
0460 max_retries_store(
0461 struct kobject *kobject,
0462 const char *buf,
0463 size_t count)
0464 {
0465 struct xfs_error_cfg *cfg = to_error_cfg(kobject);
0466 int ret;
0467 int val;
0468
0469 ret = kstrtoint(buf, 0, &val);
0470 if (ret)
0471 return ret;
0472
0473 if (val < -1)
0474 return -EINVAL;
0475
0476 if (val == -1)
0477 cfg->max_retries = XFS_ERR_RETRY_FOREVER;
0478 else
0479 cfg->max_retries = val;
0480 return count;
0481 }
0482 XFS_SYSFS_ATTR_RW(max_retries);
0483
0484 static ssize_t
0485 retry_timeout_seconds_show(
0486 struct kobject *kobject,
0487 char *buf)
0488 {
0489 int timeout;
0490 struct xfs_error_cfg *cfg = to_error_cfg(kobject);
0491
0492 if (cfg->retry_timeout == XFS_ERR_RETRY_FOREVER)
0493 timeout = -1;
0494 else
0495 timeout = jiffies_to_msecs(cfg->retry_timeout) / MSEC_PER_SEC;
0496
0497 return sysfs_emit(buf, "%d\n", timeout);
0498 }
0499
0500 static ssize_t
0501 retry_timeout_seconds_store(
0502 struct kobject *kobject,
0503 const char *buf,
0504 size_t count)
0505 {
0506 struct xfs_error_cfg *cfg = to_error_cfg(kobject);
0507 int ret;
0508 int val;
0509
0510 ret = kstrtoint(buf, 0, &val);
0511 if (ret)
0512 return ret;
0513
0514
0515 if (val < -1 || val > 86400)
0516 return -EINVAL;
0517
0518 if (val == -1)
0519 cfg->retry_timeout = XFS_ERR_RETRY_FOREVER;
0520 else {
0521 cfg->retry_timeout = msecs_to_jiffies(val * MSEC_PER_SEC);
0522 ASSERT(msecs_to_jiffies(val * MSEC_PER_SEC) < LONG_MAX);
0523 }
0524 return count;
0525 }
0526 XFS_SYSFS_ATTR_RW(retry_timeout_seconds);
0527
0528 static ssize_t
0529 fail_at_unmount_show(
0530 struct kobject *kobject,
0531 char *buf)
0532 {
0533 struct xfs_mount *mp = err_to_mp(kobject);
0534
0535 return sysfs_emit(buf, "%d\n", mp->m_fail_unmount);
0536 }
0537
0538 static ssize_t
0539 fail_at_unmount_store(
0540 struct kobject *kobject,
0541 const char *buf,
0542 size_t count)
0543 {
0544 struct xfs_mount *mp = err_to_mp(kobject);
0545 int ret;
0546 int val;
0547
0548 ret = kstrtoint(buf, 0, &val);
0549 if (ret)
0550 return ret;
0551
0552 if (val < 0 || val > 1)
0553 return -EINVAL;
0554
0555 mp->m_fail_unmount = val;
0556 return count;
0557 }
0558 XFS_SYSFS_ATTR_RW(fail_at_unmount);
0559
0560 static struct attribute *xfs_error_attrs[] = {
0561 ATTR_LIST(max_retries),
0562 ATTR_LIST(retry_timeout_seconds),
0563 NULL,
0564 };
0565 ATTRIBUTE_GROUPS(xfs_error);
0566
0567 static struct kobj_type xfs_error_cfg_ktype = {
0568 .release = xfs_sysfs_release,
0569 .sysfs_ops = &xfs_sysfs_ops,
0570 .default_groups = xfs_error_groups,
0571 };
0572
0573 static struct kobj_type xfs_error_ktype = {
0574 .release = xfs_sysfs_release,
0575 .sysfs_ops = &xfs_sysfs_ops,
0576 };
0577
0578
0579
0580
0581
0582
0583
0584 struct xfs_error_init {
0585 char *name;
0586 int max_retries;
0587 int retry_timeout;
0588 };
0589
0590 static const struct xfs_error_init xfs_error_meta_init[XFS_ERR_ERRNO_MAX] = {
0591 { .name = "default",
0592 .max_retries = XFS_ERR_RETRY_FOREVER,
0593 .retry_timeout = XFS_ERR_RETRY_FOREVER,
0594 },
0595 { .name = "EIO",
0596 .max_retries = XFS_ERR_RETRY_FOREVER,
0597 .retry_timeout = XFS_ERR_RETRY_FOREVER,
0598 },
0599 { .name = "ENOSPC",
0600 .max_retries = XFS_ERR_RETRY_FOREVER,
0601 .retry_timeout = XFS_ERR_RETRY_FOREVER,
0602 },
0603 { .name = "ENODEV",
0604 .max_retries = 0,
0605 .retry_timeout = 0,
0606 },
0607 };
0608
0609 static int
0610 xfs_error_sysfs_init_class(
0611 struct xfs_mount *mp,
0612 int class,
0613 const char *parent_name,
0614 struct xfs_kobj *parent_kobj,
0615 const struct xfs_error_init init[])
0616 {
0617 struct xfs_error_cfg *cfg;
0618 int error;
0619 int i;
0620
0621 ASSERT(class < XFS_ERR_CLASS_MAX);
0622
0623 error = xfs_sysfs_init(parent_kobj, &xfs_error_ktype,
0624 &mp->m_error_kobj, parent_name);
0625 if (error)
0626 return error;
0627
0628 for (i = 0; i < XFS_ERR_ERRNO_MAX; i++) {
0629 cfg = &mp->m_error_cfg[class][i];
0630 error = xfs_sysfs_init(&cfg->kobj, &xfs_error_cfg_ktype,
0631 parent_kobj, init[i].name);
0632 if (error)
0633 goto out_error;
0634
0635 cfg->max_retries = init[i].max_retries;
0636 if (init[i].retry_timeout == XFS_ERR_RETRY_FOREVER)
0637 cfg->retry_timeout = XFS_ERR_RETRY_FOREVER;
0638 else
0639 cfg->retry_timeout = msecs_to_jiffies(
0640 init[i].retry_timeout * MSEC_PER_SEC);
0641 }
0642 return 0;
0643
0644 out_error:
0645
0646 for (i--; i >= 0; i--) {
0647 cfg = &mp->m_error_cfg[class][i];
0648 xfs_sysfs_del(&cfg->kobj);
0649 }
0650 xfs_sysfs_del(parent_kobj);
0651 return error;
0652 }
0653
0654 int
0655 xfs_error_sysfs_init(
0656 struct xfs_mount *mp)
0657 {
0658 int error;
0659
0660
0661 error = xfs_sysfs_init(&mp->m_error_kobj, &xfs_error_ktype,
0662 &mp->m_kobj, "error");
0663 if (error)
0664 return error;
0665
0666 error = sysfs_create_file(&mp->m_error_kobj.kobject,
0667 ATTR_LIST(fail_at_unmount));
0668
0669 if (error)
0670 goto out_error;
0671
0672
0673 error = xfs_error_sysfs_init_class(mp, XFS_ERR_METADATA,
0674 "metadata", &mp->m_error_meta_kobj,
0675 xfs_error_meta_init);
0676 if (error)
0677 goto out_error;
0678
0679 return 0;
0680
0681 out_error:
0682 xfs_sysfs_del(&mp->m_error_kobj);
0683 return error;
0684 }
0685
0686 void
0687 xfs_error_sysfs_del(
0688 struct xfs_mount *mp)
0689 {
0690 struct xfs_error_cfg *cfg;
0691 int i, j;
0692
0693 for (i = 0; i < XFS_ERR_CLASS_MAX; i++) {
0694 for (j = 0; j < XFS_ERR_ERRNO_MAX; j++) {
0695 cfg = &mp->m_error_cfg[i][j];
0696
0697 xfs_sysfs_del(&cfg->kobj);
0698 }
0699 }
0700 xfs_sysfs_del(&mp->m_error_meta_kobj);
0701 xfs_sysfs_del(&mp->m_error_kobj);
0702 }
0703
0704 struct xfs_error_cfg *
0705 xfs_error_get_cfg(
0706 struct xfs_mount *mp,
0707 int error_class,
0708 int error)
0709 {
0710 struct xfs_error_cfg *cfg;
0711
0712 if (error < 0)
0713 error = -error;
0714
0715 switch (error) {
0716 case EIO:
0717 cfg = &mp->m_error_cfg[error_class][XFS_ERR_EIO];
0718 break;
0719 case ENOSPC:
0720 cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENOSPC];
0721 break;
0722 case ENODEV:
0723 cfg = &mp->m_error_cfg[error_class][XFS_ERR_ENODEV];
0724 break;
0725 default:
0726 cfg = &mp->m_error_cfg[error_class][XFS_ERR_DEFAULT];
0727 break;
0728 }
0729
0730 return cfg;
0731 }