Loading drivers/block/drbd/drbd_debugfs.c +148 −5 Original line number Diff line number Diff line Loading @@ -434,12 +434,10 @@ static int drbd_single_open(struct file *file, int (*show)(struct seq_file *, vo goto out; /* serialize with d_delete() */ mutex_lock(&parent->d_inode->i_mutex); if (!debugfs_positive(file->f_dentry)) goto out_unlock; /* Make sure the object is still alive */ if (kref_get_unless_zero(kref)) if (debugfs_positive(file->f_dentry) && kref_get_unless_zero(kref)) ret = 0; out_unlock: mutex_unlock(&parent->d_inode->i_mutex); if (!ret) { ret = single_open(file, show, data); Loading Loading @@ -592,6 +590,53 @@ static const struct file_operations connection_callback_history_fops = { .release = callback_history_release, }; static int connection_oldest_requests_show(struct seq_file *m, void *ignored) { struct drbd_connection *connection = m->private; unsigned long now = jiffies; struct drbd_request *r1, *r2; /* BUMP me if you change the file format/content/presentation */ seq_printf(m, "v: %u\n\n", 0); spin_lock_irq(&connection->resource->req_lock); r1 = connection->req_next; if (r1) seq_print_minor_vnr_req(m, r1, now); r2 = connection->req_ack_pending; if (r2 && r2 != r1) { r1 = r2; seq_print_minor_vnr_req(m, r1, now); } r2 = connection->req_not_net_done; if (r2 && r2 != r1) seq_print_minor_vnr_req(m, r2, now); spin_unlock_irq(&connection->resource->req_lock); return 0; } static int connection_oldest_requests_open(struct inode *inode, struct file *file) { struct drbd_connection *connection = inode->i_private; return drbd_single_open(file, connection_oldest_requests_show, connection, &connection->kref, drbd_destroy_connection); } static int connection_oldest_requests_release(struct inode *inode, struct file *file) { struct drbd_connection *connection = inode->i_private; kref_put(&connection->kref, drbd_destroy_connection); return single_release(inode, file); } static const struct file_operations connection_oldest_requests_fops = { .owner = THIS_MODULE, .open = connection_oldest_requests_open, .read = seq_read, .llseek = seq_lseek, .release = connection_oldest_requests_release, }; void drbd_debugfs_connection_add(struct drbd_connection *connection) { struct dentry *conns_dir = connection->resource->debugfs_res_connections; Loading Loading @@ -627,6 +672,89 @@ void drbd_debugfs_connection_cleanup(struct drbd_connection *connection) drbd_debugfs_remove(&connection->debugfs_conn); } static void resync_dump_detail(struct seq_file *m, struct lc_element *e) { struct bm_extent *bme = lc_entry(e, struct bm_extent, lce); seq_printf(m, "%5d %s %s %s\n", bme->rs_left, test_bit(BME_NO_WRITES, &bme->flags) ? "NO_WRITES" : "---------", test_bit(BME_LOCKED, &bme->flags) ? "LOCKED" : "------", test_bit(BME_PRIORITY, &bme->flags) ? "PRIORITY" : "--------" ); } static int device_resync_extents_show(struct seq_file *m, void *ignored) { struct drbd_device *device = m->private; if (get_ldev_if_state(device, D_FAILED)) { lc_seq_printf_stats(m, device->resync); lc_seq_dump_details(m, device->resync, "rs_left flags", resync_dump_detail); put_ldev(device); } return 0; } static int device_act_log_extents_show(struct seq_file *m, void *ignored) { struct drbd_device *device = m->private; if (get_ldev_if_state(device, D_FAILED)) { lc_seq_printf_stats(m, device->act_log); lc_seq_dump_details(m, device->act_log, "", NULL); put_ldev(device); } return 0; } static int device_oldest_requests_show(struct seq_file *m, void *ignored) { struct drbd_device *device = m->private; struct drbd_resource *resource = device->resource; unsigned long now = jiffies; struct drbd_request *r1, *r2; int i; seq_puts(m, RQ_HDR); spin_lock_irq(&resource->req_lock); /* WRITE, then READ */ for (i = 1; i >= 0; --i) { r1 = list_first_entry_or_null(&device->pending_master_completion[i], struct drbd_request, req_pending_master_completion); r2 = list_first_entry_or_null(&device->pending_completion[i], struct drbd_request, req_pending_local); if (r1) seq_print_one_request(m, r1, now); if (r2 && r2 != r1) seq_print_one_request(m, r2, now); } spin_unlock_irq(&resource->req_lock); return 0; } #define drbd_debugfs_device_attr(name) \ static int device_ ## name ## _open(struct inode *inode, struct file *file) \ { \ struct drbd_device *device = inode->i_private; \ return drbd_single_open(file, device_ ## name ## _show, device, \ &device->kref, drbd_destroy_device); \ } \ static int device_ ## name ## _release(struct inode *inode, struct file *file) \ { \ struct drbd_device *device = inode->i_private; \ kref_put(&device->kref, drbd_destroy_device); \ return single_release(inode, file); \ } \ static const struct file_operations device_ ## name ## _fops = { \ .owner = THIS_MODULE, \ .open = device_ ## name ## _open, \ .read = seq_read, \ .llseek = seq_lseek, \ .release = device_ ## name ## _release, \ }; drbd_debugfs_device_attr(oldest_requests) drbd_debugfs_device_attr(act_log_extents) drbd_debugfs_device_attr(resync_extents) void drbd_debugfs_device_add(struct drbd_device *device) { struct dentry *vols_dir = device->resource->debugfs_res_volumes; Loading @@ -650,10 +778,25 @@ void drbd_debugfs_device_add(struct drbd_device *device) if (!slink_name) goto fail; dentry = debugfs_create_symlink(minor_buf, drbd_debugfs_minors, slink_name); kfree(slink_name); slink_name = NULL; if (IS_ERR_OR_NULL(dentry)) goto fail; device->debugfs_minor = dentry; kfree(slink_name); #define DCF(name) do { \ dentry = debugfs_create_file(#name, S_IRUSR|S_IRGRP, \ device->debugfs_vol, device, \ &device_ ## name ## _fops); \ if (IS_ERR_OR_NULL(dentry)) \ goto fail; \ device->debugfs_vol_ ## name = dentry; \ } while (0) DCF(oldest_requests); DCF(act_log_extents); DCF(resync_extents); return; fail: drbd_debugfs_device_cleanup(device); Loading lib/lru_cache.c +12 −9 Original line number Diff line number Diff line Loading @@ -643,9 +643,10 @@ void lc_set(struct lru_cache *lc, unsigned int enr, int index) * lc_dump - Dump a complete LRU cache to seq in textual form. * @lc: the lru cache to operate on * @seq: the &struct seq_file pointer to seq_printf into * @utext: user supplied "heading" or other info * @utext: user supplied additional "heading" or other info * @detail: function pointer the user may provide to dump further details * of the object the lc_element is embedded in. * of the object the lc_element is embedded in. May be NULL. * Note: a leading space ' ' and trailing newline '\n' is implied. */ void lc_seq_dump_details(struct seq_file *seq, struct lru_cache *lc, char *utext, void (*detail) (struct seq_file *, struct lc_element *)) Loading @@ -654,16 +655,18 @@ void lc_seq_dump_details(struct seq_file *seq, struct lru_cache *lc, char *utext struct lc_element *e; int i; seq_printf(seq, "\tnn: lc_number refcnt %s\n ", utext); seq_printf(seq, "\tnn: lc_number (new nr) refcnt %s\n ", utext); for (i = 0; i < nr_elements; i++) { e = lc_element_by_index(lc, i); if (e->lc_number == LC_FREE) { seq_printf(seq, "\t%2d: FREE\n", i); } else { seq_printf(seq, "\t%2d: %4u %4u ", i, e->lc_number, e->refcnt); if (e->lc_number != e->lc_new_number) seq_printf(seq, "\t%5d: %6d %8d %6d ", i, e->lc_number, e->lc_new_number, e->refcnt); else seq_printf(seq, "\t%5d: %6d %-8s %6d ", i, e->lc_number, "-\"-", e->refcnt); if (detail) detail(seq, e); } seq_putc(seq, '\n'); } } Loading Loading
drivers/block/drbd/drbd_debugfs.c +148 −5 Original line number Diff line number Diff line Loading @@ -434,12 +434,10 @@ static int drbd_single_open(struct file *file, int (*show)(struct seq_file *, vo goto out; /* serialize with d_delete() */ mutex_lock(&parent->d_inode->i_mutex); if (!debugfs_positive(file->f_dentry)) goto out_unlock; /* Make sure the object is still alive */ if (kref_get_unless_zero(kref)) if (debugfs_positive(file->f_dentry) && kref_get_unless_zero(kref)) ret = 0; out_unlock: mutex_unlock(&parent->d_inode->i_mutex); if (!ret) { ret = single_open(file, show, data); Loading Loading @@ -592,6 +590,53 @@ static const struct file_operations connection_callback_history_fops = { .release = callback_history_release, }; static int connection_oldest_requests_show(struct seq_file *m, void *ignored) { struct drbd_connection *connection = m->private; unsigned long now = jiffies; struct drbd_request *r1, *r2; /* BUMP me if you change the file format/content/presentation */ seq_printf(m, "v: %u\n\n", 0); spin_lock_irq(&connection->resource->req_lock); r1 = connection->req_next; if (r1) seq_print_minor_vnr_req(m, r1, now); r2 = connection->req_ack_pending; if (r2 && r2 != r1) { r1 = r2; seq_print_minor_vnr_req(m, r1, now); } r2 = connection->req_not_net_done; if (r2 && r2 != r1) seq_print_minor_vnr_req(m, r2, now); spin_unlock_irq(&connection->resource->req_lock); return 0; } static int connection_oldest_requests_open(struct inode *inode, struct file *file) { struct drbd_connection *connection = inode->i_private; return drbd_single_open(file, connection_oldest_requests_show, connection, &connection->kref, drbd_destroy_connection); } static int connection_oldest_requests_release(struct inode *inode, struct file *file) { struct drbd_connection *connection = inode->i_private; kref_put(&connection->kref, drbd_destroy_connection); return single_release(inode, file); } static const struct file_operations connection_oldest_requests_fops = { .owner = THIS_MODULE, .open = connection_oldest_requests_open, .read = seq_read, .llseek = seq_lseek, .release = connection_oldest_requests_release, }; void drbd_debugfs_connection_add(struct drbd_connection *connection) { struct dentry *conns_dir = connection->resource->debugfs_res_connections; Loading Loading @@ -627,6 +672,89 @@ void drbd_debugfs_connection_cleanup(struct drbd_connection *connection) drbd_debugfs_remove(&connection->debugfs_conn); } static void resync_dump_detail(struct seq_file *m, struct lc_element *e) { struct bm_extent *bme = lc_entry(e, struct bm_extent, lce); seq_printf(m, "%5d %s %s %s\n", bme->rs_left, test_bit(BME_NO_WRITES, &bme->flags) ? "NO_WRITES" : "---------", test_bit(BME_LOCKED, &bme->flags) ? "LOCKED" : "------", test_bit(BME_PRIORITY, &bme->flags) ? "PRIORITY" : "--------" ); } static int device_resync_extents_show(struct seq_file *m, void *ignored) { struct drbd_device *device = m->private; if (get_ldev_if_state(device, D_FAILED)) { lc_seq_printf_stats(m, device->resync); lc_seq_dump_details(m, device->resync, "rs_left flags", resync_dump_detail); put_ldev(device); } return 0; } static int device_act_log_extents_show(struct seq_file *m, void *ignored) { struct drbd_device *device = m->private; if (get_ldev_if_state(device, D_FAILED)) { lc_seq_printf_stats(m, device->act_log); lc_seq_dump_details(m, device->act_log, "", NULL); put_ldev(device); } return 0; } static int device_oldest_requests_show(struct seq_file *m, void *ignored) { struct drbd_device *device = m->private; struct drbd_resource *resource = device->resource; unsigned long now = jiffies; struct drbd_request *r1, *r2; int i; seq_puts(m, RQ_HDR); spin_lock_irq(&resource->req_lock); /* WRITE, then READ */ for (i = 1; i >= 0; --i) { r1 = list_first_entry_or_null(&device->pending_master_completion[i], struct drbd_request, req_pending_master_completion); r2 = list_first_entry_or_null(&device->pending_completion[i], struct drbd_request, req_pending_local); if (r1) seq_print_one_request(m, r1, now); if (r2 && r2 != r1) seq_print_one_request(m, r2, now); } spin_unlock_irq(&resource->req_lock); return 0; } #define drbd_debugfs_device_attr(name) \ static int device_ ## name ## _open(struct inode *inode, struct file *file) \ { \ struct drbd_device *device = inode->i_private; \ return drbd_single_open(file, device_ ## name ## _show, device, \ &device->kref, drbd_destroy_device); \ } \ static int device_ ## name ## _release(struct inode *inode, struct file *file) \ { \ struct drbd_device *device = inode->i_private; \ kref_put(&device->kref, drbd_destroy_device); \ return single_release(inode, file); \ } \ static const struct file_operations device_ ## name ## _fops = { \ .owner = THIS_MODULE, \ .open = device_ ## name ## _open, \ .read = seq_read, \ .llseek = seq_lseek, \ .release = device_ ## name ## _release, \ }; drbd_debugfs_device_attr(oldest_requests) drbd_debugfs_device_attr(act_log_extents) drbd_debugfs_device_attr(resync_extents) void drbd_debugfs_device_add(struct drbd_device *device) { struct dentry *vols_dir = device->resource->debugfs_res_volumes; Loading @@ -650,10 +778,25 @@ void drbd_debugfs_device_add(struct drbd_device *device) if (!slink_name) goto fail; dentry = debugfs_create_symlink(minor_buf, drbd_debugfs_minors, slink_name); kfree(slink_name); slink_name = NULL; if (IS_ERR_OR_NULL(dentry)) goto fail; device->debugfs_minor = dentry; kfree(slink_name); #define DCF(name) do { \ dentry = debugfs_create_file(#name, S_IRUSR|S_IRGRP, \ device->debugfs_vol, device, \ &device_ ## name ## _fops); \ if (IS_ERR_OR_NULL(dentry)) \ goto fail; \ device->debugfs_vol_ ## name = dentry; \ } while (0) DCF(oldest_requests); DCF(act_log_extents); DCF(resync_extents); return; fail: drbd_debugfs_device_cleanup(device); Loading
lib/lru_cache.c +12 −9 Original line number Diff line number Diff line Loading @@ -643,9 +643,10 @@ void lc_set(struct lru_cache *lc, unsigned int enr, int index) * lc_dump - Dump a complete LRU cache to seq in textual form. * @lc: the lru cache to operate on * @seq: the &struct seq_file pointer to seq_printf into * @utext: user supplied "heading" or other info * @utext: user supplied additional "heading" or other info * @detail: function pointer the user may provide to dump further details * of the object the lc_element is embedded in. * of the object the lc_element is embedded in. May be NULL. * Note: a leading space ' ' and trailing newline '\n' is implied. */ void lc_seq_dump_details(struct seq_file *seq, struct lru_cache *lc, char *utext, void (*detail) (struct seq_file *, struct lc_element *)) Loading @@ -654,16 +655,18 @@ void lc_seq_dump_details(struct seq_file *seq, struct lru_cache *lc, char *utext struct lc_element *e; int i; seq_printf(seq, "\tnn: lc_number refcnt %s\n ", utext); seq_printf(seq, "\tnn: lc_number (new nr) refcnt %s\n ", utext); for (i = 0; i < nr_elements; i++) { e = lc_element_by_index(lc, i); if (e->lc_number == LC_FREE) { seq_printf(seq, "\t%2d: FREE\n", i); } else { seq_printf(seq, "\t%2d: %4u %4u ", i, e->lc_number, e->refcnt); if (e->lc_number != e->lc_new_number) seq_printf(seq, "\t%5d: %6d %8d %6d ", i, e->lc_number, e->lc_new_number, e->refcnt); else seq_printf(seq, "\t%5d: %6d %-8s %6d ", i, e->lc_number, "-\"-", e->refcnt); if (detail) detail(seq, e); } seq_putc(seq, '\n'); } } Loading