fault_inject.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * Copyright (c) 2011 Bryan Schumaker <bjschuma@netapp.com>
  3. *
  4. * Uses debugfs to create fault injection points for client testing
  5. */
  6. #include <linux/types.h>
  7. #include <linux/fs.h>
  8. #include <linux/debugfs.h>
  9. #include <linux/module.h>
  10. #include "state.h"
  11. struct nfsd_fault_inject_op {
  12. char *file;
  13. u64 (*forget)(struct nfs4_client *, u64);
  14. };
  15. static struct nfsd_fault_inject_op inject_ops[] = {
  16. {
  17. .file = "forget_clients",
  18. .forget = nfsd_forget_client,
  19. },
  20. {
  21. .file = "forget_locks",
  22. .forget = nfsd_forget_client_locks,
  23. },
  24. {
  25. .file = "forget_openowners",
  26. .forget = nfsd_forget_client_openowners,
  27. },
  28. {
  29. .file = "forget_delegations",
  30. .forget = nfsd_forget_client_delegations,
  31. },
  32. {
  33. .file = "recall_delegations",
  34. .forget = nfsd_recall_client_delegations,
  35. },
  36. };
  37. static long int NUM_INJECT_OPS = sizeof(inject_ops) / sizeof(struct nfsd_fault_inject_op);
  38. static struct dentry *debug_dir;
  39. static int nfsd_inject_set(void *op_ptr, u64 val)
  40. {
  41. u64 count = 0;
  42. struct nfsd_fault_inject_op *op = op_ptr;
  43. if (val == 0)
  44. printk(KERN_INFO "NFSD Fault Injection: %s (all)", op->file);
  45. else
  46. printk(KERN_INFO "NFSD Fault Injection: %s (n = %llu)", op->file, val);
  47. nfs4_lock_state();
  48. count = nfsd_for_n_state(val, op->forget);
  49. nfs4_unlock_state();
  50. printk(KERN_INFO "NFSD: %s: found %llu", op->file, count);
  51. return 0;
  52. }
  53. static int nfsd_inject_get(void *data, u64 *val)
  54. {
  55. *val = 0;
  56. return 0;
  57. }
  58. DEFINE_SIMPLE_ATTRIBUTE(fops_nfsd, nfsd_inject_get, nfsd_inject_set, "%llu\n");
  59. void nfsd_fault_inject_cleanup(void)
  60. {
  61. debugfs_remove_recursive(debug_dir);
  62. }
  63. int nfsd_fault_inject_init(void)
  64. {
  65. unsigned int i;
  66. struct nfsd_fault_inject_op *op;
  67. umode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
  68. debug_dir = debugfs_create_dir("nfsd", NULL);
  69. if (!debug_dir)
  70. goto fail;
  71. for (i = 0; i < NUM_INJECT_OPS; i++) {
  72. op = &inject_ops[i];
  73. if (!debugfs_create_file(op->file, mode, debug_dir, op, &fops_nfsd))
  74. goto fail;
  75. }
  76. return 0;
  77. fail:
  78. nfsd_fault_inject_cleanup();
  79. return -ENOMEM;
  80. }