1 /* 2 * Copyright (c) 2014 Red Hat, Inc. 3 * All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 #include "xfs.h" 20 #include "xfs_sysfs.h" 21 #include "xfs_log_format.h" 22 #include "xfs_log.h" 23 #include "xfs_log_priv.h" 24 #include "xfs_stats.h" 25 26 struct xfs_sysfs_attr { 27 struct attribute attr; 28 ssize_t (*show)(struct kobject *kobject, char *buf); 29 ssize_t (*store)(struct kobject *kobject, const char *buf, 30 size_t count); 31 }; 32 33 static inline struct xfs_sysfs_attr * 34 to_attr(struct attribute *attr) 35 { 36 return container_of(attr, struct xfs_sysfs_attr, attr); 37 } 38 39 #define XFS_SYSFS_ATTR_RW(name) \ 40 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RW(name) 41 #define XFS_SYSFS_ATTR_RO(name) \ 42 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name) 43 #define XFS_SYSFS_ATTR_WO(name) \ 44 static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_WO(name) 45 46 #define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr 47 48 /* 49 * xfs_mount kobject. This currently has no attributes and thus no need for show 50 * and store helpers. The mp kobject serves as the per-mount parent object that 51 * is identified by the fsname under sysfs. 52 */ 53 54 struct kobj_type xfs_mp_ktype = { 55 .release = xfs_sysfs_release, 56 }; 57 58 STATIC ssize_t 59 xfs_sysfs_object_show( 60 struct kobject *kobject, 61 struct attribute *attr, 62 char *buf) 63 { 64 struct xfs_sysfs_attr *xfs_attr = to_attr(attr); 65 66 return xfs_attr->show ? xfs_attr->show(kobject, buf) : 0; 67 } 68 69 STATIC ssize_t 70 xfs_sysfs_object_store( 71 struct kobject *kobject, 72 struct attribute *attr, 73 const char *buf, 74 size_t count) 75 { 76 struct xfs_sysfs_attr *xfs_attr = to_attr(attr); 77 78 return xfs_attr->store ? xfs_attr->store(kobject, buf, count) : 0; 79 } 80 81 static const struct sysfs_ops xfs_sysfs_ops = { 82 .show = xfs_sysfs_object_show, 83 .store = xfs_sysfs_object_store, 84 }; 85 86 #ifdef DEBUG 87 /* debug */ 88 89 STATIC ssize_t 90 log_recovery_delay_store( 91 struct kobject *kobject, 92 const char *buf, 93 size_t count) 94 { 95 int ret; 96 int val; 97 98 ret = kstrtoint(buf, 0, &val); 99 if (ret) 100 return ret; 101 102 if (val < 0 || val > 60) 103 return -EINVAL; 104 105 xfs_globals.log_recovery_delay = val; 106 107 return count; 108 } 109 110 STATIC ssize_t 111 log_recovery_delay_show( 112 struct kobject *kobject, 113 char *buf) 114 { 115 return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.log_recovery_delay); 116 } 117 XFS_SYSFS_ATTR_RW(log_recovery_delay); 118 119 static struct attribute *xfs_dbg_attrs[] = { 120 ATTR_LIST(log_recovery_delay), 121 NULL, 122 }; 123 124 struct kobj_type xfs_dbg_ktype = { 125 .release = xfs_sysfs_release, 126 .sysfs_ops = &xfs_sysfs_ops, 127 .default_attrs = xfs_dbg_attrs, 128 }; 129 130 #endif /* DEBUG */ 131 132 /* stats */ 133 134 static inline struct xstats * 135 to_xstats(struct kobject *kobject) 136 { 137 struct xfs_kobj *kobj = to_kobj(kobject); 138 139 return container_of(kobj, struct xstats, xs_kobj); 140 } 141 142 STATIC ssize_t 143 stats_show( 144 struct kobject *kobject, 145 char *buf) 146 { 147 struct xstats *stats = to_xstats(kobject); 148 149 return xfs_stats_format(stats->xs_stats, buf); 150 } 151 XFS_SYSFS_ATTR_RO(stats); 152 153 STATIC ssize_t 154 stats_clear_store( 155 struct kobject *kobject, 156 const char *buf, 157 size_t count) 158 { 159 int ret; 160 int val; 161 struct xstats *stats = to_xstats(kobject); 162 163 ret = kstrtoint(buf, 0, &val); 164 if (ret) 165 return ret; 166 167 if (val != 1) 168 return -EINVAL; 169 170 xfs_stats_clearall(stats->xs_stats); 171 return count; 172 } 173 XFS_SYSFS_ATTR_WO(stats_clear); 174 175 static struct attribute *xfs_stats_attrs[] = { 176 ATTR_LIST(stats), 177 ATTR_LIST(stats_clear), 178 NULL, 179 }; 180 181 struct kobj_type xfs_stats_ktype = { 182 .release = xfs_sysfs_release, 183 .sysfs_ops = &xfs_sysfs_ops, 184 .default_attrs = xfs_stats_attrs, 185 }; 186 187 /* xlog */ 188 189 static inline struct xlog * 190 to_xlog(struct kobject *kobject) 191 { 192 struct xfs_kobj *kobj = to_kobj(kobject); 193 194 return container_of(kobj, struct xlog, l_kobj); 195 } 196 197 STATIC ssize_t 198 log_head_lsn_show( 199 struct kobject *kobject, 200 char *buf) 201 { 202 int cycle; 203 int block; 204 struct xlog *log = to_xlog(kobject); 205 206 spin_lock(&log->l_icloglock); 207 cycle = log->l_curr_cycle; 208 block = log->l_curr_block; 209 spin_unlock(&log->l_icloglock); 210 211 return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block); 212 } 213 XFS_SYSFS_ATTR_RO(log_head_lsn); 214 215 STATIC ssize_t 216 log_tail_lsn_show( 217 struct kobject *kobject, 218 char *buf) 219 { 220 int cycle; 221 int block; 222 struct xlog *log = to_xlog(kobject); 223 224 xlog_crack_atomic_lsn(&log->l_tail_lsn, &cycle, &block); 225 return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block); 226 } 227 XFS_SYSFS_ATTR_RO(log_tail_lsn); 228 229 STATIC ssize_t 230 reserve_grant_head_show( 231 struct kobject *kobject, 232 char *buf) 233 234 { 235 int cycle; 236 int bytes; 237 struct xlog *log = to_xlog(kobject); 238 239 xlog_crack_grant_head(&log->l_reserve_head.grant, &cycle, &bytes); 240 return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes); 241 } 242 XFS_SYSFS_ATTR_RO(reserve_grant_head); 243 244 STATIC ssize_t 245 write_grant_head_show( 246 struct kobject *kobject, 247 char *buf) 248 { 249 int cycle; 250 int bytes; 251 struct xlog *log = to_xlog(kobject); 252 253 xlog_crack_grant_head(&log->l_write_head.grant, &cycle, &bytes); 254 return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes); 255 } 256 XFS_SYSFS_ATTR_RO(write_grant_head); 257 258 static struct attribute *xfs_log_attrs[] = { 259 ATTR_LIST(log_head_lsn), 260 ATTR_LIST(log_tail_lsn), 261 ATTR_LIST(reserve_grant_head), 262 ATTR_LIST(write_grant_head), 263 NULL, 264 }; 265 266 struct kobj_type xfs_log_ktype = { 267 .release = xfs_sysfs_release, 268 .sysfs_ops = &xfs_sysfs_ops, 269 .default_attrs = xfs_log_attrs, 270 }; 271