Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2014 Red Hat, Inc.
0004  * All Rights Reserved.
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 /* debug */
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  * Override how many threads the parallel work queue is allowed to create.
0199  * This has to be a debug-only global (instead of an errortag) because one of
0200  * the main users of parallel workqueues is mount time quotacheck.
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 /* DEBUG */
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 /* DEBUG */
0276 
0277 /* stats */
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 /* xlog */
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  * Metadata IO error configuration
0421  *
0422  * The sysfs structure here is:
0423  *  ...xfs/<dev>/error/<class>/<errno>/<error_attrs>
0424  *
0425  * where <class> allows us to discriminate between data IO and metadata IO,
0426  * and any other future type of IO (e.g. special inode or directory error
0427  * handling) we care to support.
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     /* 1 day timeout maximum, -1 means infinite */
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  * Error initialization tables. These need to be ordered in the same
0580  * order as the enums used to index the array. All class init tables need to
0581  * define a "default" behaviour as the first entry, all other entries can be
0582  * empty.
0583  */
0584 struct xfs_error_init {
0585     char        *name;
0586     int     max_retries;
0587     int     retry_timeout;  /* in seconds */
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, /* We can't recover from devices disappearing */
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     /* unwind the entries that succeeded */
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     /* .../xfs/<dev>/error/ */
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     /* .../xfs/<dev>/error/metadata/ */
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 }