1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
5 * Use is subject to license terms.
7 * Copyright (c) 2012, 2017, Intel Corporation.
11 * This file is part of Lustre, http://www.lustre.org/
13 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
14 * Author: Mike Pershin <tappro@whamcloud.com>
17 #define DEBUG_SUBSYSTEM S_OSD
20 #include <obd_class.h>
21 #include <lprocfs_status.h>
22 #include <lustre_scrub.h>
24 #include "osd_internal.h"
26 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 17, 53, 0)
27 static int symlink_brw_stats;
28 module_param(symlink_brw_stats, int, 0644);
29 MODULE_PARM_DESC(symlink_brw_stats, "create /proc brw_stats symlink");
31 static void osd_symlink_brw_stats(struct osd_device *osd)
40 if (!symlink_brw_stats)
43 OBD_ALLOC(path, PATH_MAX);
47 p = dentry_path_raw(osd->od_dt_dev.dd_debugfs_entry, path, PATH_MAX);
51 root = osd->od_dt_dev.dd_debugfs_entry->d_sb->s_fs_info;
52 len_root = strlen(root);
54 if (len_root > (p - path) || len_root + len_path + 16 > PATH_MAX)
57 strscpy(path, root, len_root);
58 if (p > path + len_root) {
60 while ((*s++ = *p++) != '\0')
64 *(path + len_root + len_path) = '\0';
65 strcat(path, "/brw_stats");
66 lprocfs_add_symlink("brw_stats", osd->od_proc_entry,
67 "/sys/kernel/debug/%s", path);
70 OBD_FREE(path, PATH_MAX);
74 static int osd_stats_init(struct osd_device *osd)
76 char param[MAX_OBD_NAME * 4];
80 scnprintf(param, sizeof(param), "osd-zfs.%s.stats", osd_name(osd));
81 osd->od_stats = ldebugfs_stats_alloc(LPROC_OSD_LAST, param,
82 osd->od_dt_dev.dd_debugfs_entry,
85 lprocfs_counter_init(osd->od_stats, LPROC_OSD_GET_PAGE,
86 LPROCFS_CNTR_AVGMINMAX | LPROCFS_CNTR_STDDEV |
87 LPROCFS_TYPE_USECS, "get_page");
88 lprocfs_counter_init(osd->od_stats, LPROC_OSD_NO_PAGE,
89 LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_REQS,
91 lprocfs_counter_init(osd->od_stats, LPROC_OSD_CACHE_ACCESS,
92 LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_PAGES,
94 lprocfs_counter_init(osd->od_stats, LPROC_OSD_CACHE_HIT,
95 LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_PAGES,
97 lprocfs_counter_init(osd->od_stats, LPROC_OSD_CACHE_MISS,
98 LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_PAGES,
100 lprocfs_counter_init(osd->od_stats, LPROC_OSD_COPY_IO,
101 LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_PAGES,
103 lprocfs_counter_init(osd->od_stats, LPROC_OSD_ZEROCOPY_IO,
104 LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_PAGES,
106 lprocfs_counter_init(osd->od_stats, LPROC_OSD_TAIL_IO,
107 LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_PAGES,
109 #ifdef OSD_THANDLE_STATS
110 lprocfs_counter_init(osd->od_stats, LPROC_OSD_THANDLE_STARTING,
111 LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_USECS,
113 lprocfs_counter_init(osd->od_stats, LPROC_OSD_THANDLE_OPEN,
114 LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_USECS,
116 lprocfs_counter_init(osd->od_stats, LPROC_OSD_THANDLE_CLOSING,
117 LPROCFS_CNTR_AVGMINMAX | LPROCFS_TYPE_USECS,
123 ldebugfs_register_brw_stats(osd->od_dt_dev.dd_debugfs_entry,
126 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 17, 53, 0)
127 osd_symlink_brw_stats(osd);
130 /* These fields are not supported for ZFS */
131 osd->od_brw_stats.bs_props[BRW_R_DISCONT_BLOCKS / 2].bsp_name = NULL;
132 osd->od_brw_stats.bs_props[BRW_R_DIO_FRAGS / 2].bsp_name = NULL;
137 static int zfs_osd_oi_scrub_seq_show(struct seq_file *m, void *data)
139 struct osd_device *dev = osd_dt_dev((struct dt_device *)m->private);
141 LASSERT(dev != NULL);
145 scrub_dump(m, &dev->od_scrub);
148 LDEBUGFS_SEQ_FOPS_RO(zfs_osd_oi_scrub);
150 static ssize_t auto_scrub_show(struct kobject *kobj, struct attribute *attr,
153 struct dt_device *dt = container_of(kobj, struct dt_device,
155 struct osd_device *dev = osd_dt_dev(dt);
161 return scnprintf(buf, PAGE_SIZE, "%lld\n",
162 dev->od_scrub.os_auto_scrub_interval);
165 static ssize_t auto_scrub_store(struct kobject *kobj, struct attribute *attr,
166 const char *buffer, size_t count)
168 struct dt_device *dt = container_of(kobj, struct dt_device,
170 struct osd_device *dev = osd_dt_dev(dt);
178 rc = kstrtoull(buffer, 0, &val);
182 dev->od_scrub.os_auto_scrub_interval = val;
185 LUSTRE_RW_ATTR(auto_scrub);
187 static ssize_t fstype_show(struct kobject *kobj, struct attribute *attr,
190 return sprintf(buf, "zfs\n");
192 LUSTRE_RO_ATTR(fstype);
194 static ssize_t mntdev_show(struct kobject *kobj, struct attribute *attr,
197 struct dt_device *dt = container_of(kobj, struct dt_device,
199 struct osd_device *osd = osd_dt_dev(dt);
203 return sprintf(buf, "%s\n", osd->od_mntdev);
205 LUSTRE_RO_ATTR(mntdev);
207 static ssize_t force_sync_store(struct kobject *kobj, struct attribute *attr,
208 const char *buffer, size_t count)
210 struct dt_device *dt = container_of(kobj, struct dt_device,
215 rc = lu_env_init(&env, LCT_LOCAL);
219 rc = dt_sync(&env, dt);
222 return rc == 0 ? count : rc;
224 LUSTRE_WO_ATTR(force_sync);
226 static ssize_t sync_on_lseek_show(struct kobject *kobj, struct attribute *attr,
229 struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
230 struct osd_device *osd = osd_dt_dev(dt);
235 return sprintf(buf, "%u\n", osd->od_sync_on_lseek);
238 static ssize_t sync_on_lseek_store(struct kobject *kobj, struct attribute *attr,
239 const char *buffer, size_t count)
241 struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
242 struct osd_device *osd = osd_dt_dev(dt);
249 rc = kstrtobool(buffer, &val);
253 osd->od_sync_on_lseek = !!val;
257 LUSTRE_RW_ATTR(sync_on_lseek);
259 static ssize_t nonrotational_show(struct kobject *kobj, struct attribute *attr,
262 struct dt_device *dt = container_of(kobj, struct dt_device,
264 struct osd_device *osd = osd_dt_dev(dt);
270 return sprintf(buf, "%u\n", osd->od_nonrotational);
273 static ssize_t nonrotational_store(struct kobject *kobj,
274 struct attribute *attr, const char *buffer,
277 struct dt_device *dt = container_of(kobj, struct dt_device,
279 struct osd_device *osd = osd_dt_dev(dt);
287 rc = kstrtobool(buffer, &val);
291 osd->od_nonrotational = val;
294 LUSTRE_RW_ATTR(nonrotational);
296 static ssize_t index_backup_show(struct kobject *kobj, struct attribute *attr,
299 struct dt_device *dt = container_of(kobj, struct dt_device,
301 struct osd_device *dev = osd_dt_dev(dt);
307 return sprintf(buf, "%d\n", dev->od_index_backup_policy);
310 static ssize_t index_backup_store(struct kobject *kobj, struct attribute *attr,
311 const char *buffer, size_t count)
313 struct dt_device *dt = container_of(kobj, struct dt_device,
315 struct osd_device *dev = osd_dt_dev(dt);
323 rc = kstrtoint(buffer, 0, &val);
327 dev->od_index_backup_policy = val;
330 LUSTRE_RW_ATTR(index_backup);
332 static ssize_t readcache_max_filesize_show(struct kobject *kobj,
333 struct attribute *attr,
336 struct dt_device *dt = container_of(kobj, struct dt_device,
338 struct osd_device *osd = osd_dt_dev(dt);
340 LASSERT(osd != NULL);
341 if (unlikely(osd->od_os == NULL))
344 return scnprintf(buf, PAGE_SIZE, "%llu\n",
345 osd->od_readcache_max_filesize);
348 static ssize_t readcache_max_filesize_store(struct kobject *kobj,
349 struct attribute *attr,
350 const char *buffer, size_t count)
352 struct dt_device *dt = container_of(kobj, struct dt_device,
354 struct osd_device *osd = osd_dt_dev(dt);
358 LASSERT(osd != NULL);
359 if (unlikely(osd->od_os == NULL))
362 rc = sysfs_memparse(buffer, count, &val, "B");
366 osd->od_readcache_max_filesize = val > OSD_MAX_CACHE_SIZE ?
367 OSD_MAX_CACHE_SIZE : val;
370 LUSTRE_RW_ATTR(readcache_max_filesize);
372 static struct attribute *zfs_attrs[] = {
373 &lustre_attr_fstype.attr,
374 &lustre_attr_mntdev.attr,
375 &lustre_attr_force_sync.attr,
376 &lustre_attr_nonrotational.attr,
377 &lustre_attr_index_backup.attr,
378 &lustre_attr_auto_scrub.attr,
379 &lustre_attr_sync_on_lseek.attr,
380 &lustre_attr_readcache_max_filesize.attr,
384 static struct ldebugfs_vars ldebugfs_osd_obd_vars[] = {
385 { .name = "oi_scrub",
386 .fops = &zfs_osd_oi_scrub_fops },
390 KOBJ_ATTRIBUTE_GROUPS(zfs); /* creates zfs_groups from zfs_attrs */
392 int osd_procfs_init(struct osd_device *osd, const char *name)
394 struct obd_type *type;
399 /* at the moment there is no linkage between lu_type
400 * and obd_type, so we lookup obd_type this way
402 type = class_search_type(LUSTRE_OSD_ZFS_NAME);
407 /* put reference taken by class_search_type */
408 kobject_put(&type->typ_kobj);
410 osd->od_dt_dev.dd_ktype.default_groups = KOBJ_ATTR_GROUPS(zfs);
411 rc = dt_tunables_init(&osd->od_dt_dev, type, name,
412 ldebugfs_osd_obd_vars);
414 CERROR("%s: cannot setup sysfs / debugfs entry: %d\n",
419 if (osd->od_proc_entry)
422 osd->od_proc_entry = lprocfs_register(name, type->typ_procroot,
423 NULL, &osd->od_dt_dev);
424 if (IS_ERR(osd->od_proc_entry)) {
425 rc = PTR_ERR(osd->od_proc_entry);
426 CERROR("%s: error setting up lprocfs: rc = %d\n", name, rc);
427 osd->od_proc_entry = NULL;
431 rc = osd_stats_init(osd);
436 osd_procfs_fini(osd);
440 void osd_procfs_fini(struct osd_device *osd)
444 lprocfs_fini_brw_stats(&osd->od_brw_stats);
447 lprocfs_stats_free(&osd->od_stats);
449 if (osd->od_proc_entry) {
450 lprocfs_remove(&osd->od_proc_entry);
451 osd->od_proc_entry = NULL;
454 dt_tunables_fini(&osd->od_dt_dev);