LCOV - code coverage report
Current view: top level - fs/xfs - xfs_sysfs.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 155 239 64.9 %
Date: 2023-07-31 20:08:12 Functions: 23 34 67.6 %

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

Generated by: LCOV version 1.14