diff --git a/driver/dtrace_linux.c b/driver/dtrace_linux.c index ad67d58..759d952 100644 --- a/driver/dtrace_linux.c +++ b/driver/dtrace_linux.c @@ -17,12 +17,14 @@ #include "dtrace_linux.h" #include #include "dtrace_proto.h" +#include "proc_compat.h" #include #include #include #include #include +#include #include #include #include @@ -2679,40 +2681,43 @@ dtracedrv_write(struct file *file, const char __user *buf, } return count; } -static int proc_calc_metrics(char *page, char **start, off_t off, - int count, int *eof, int len) -{ - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - return len; -} -static int proc_dtrace_debug_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ int len; - len = snprintf(page, count, +/** + * "proc/dtrace" + */ + +/** "proc/dtrace/debug" */ +static int proc_dtrace_debug_show(struct seq_file *seq, void *v) +{ + seq_printf(seq, "here=%d\n" "cpuid=%d\n", dtrace_here, cpu_get_id()); - return proc_calc_metrics(page, start, off, count, eof, len); + return 0; } -static int proc_dtrace_security_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ int len = count; +static int proc_dtrace_debug_single_open(struct inode *inode, struct file *file) +{ + return single_open(file, &proc_dtrace_debug_show, NULL); +} +static struct file_operations proc_dtrace_debug = { + .owner = THIS_MODULE, + .open = proc_dtrace_debug_single_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release +}; + +/** "proc/dtrace/security" */ +static int proc_dtrace_security_show(struct seq_file *seq, void *v) +{ char tmpbuf[128]; int i; - int n = 0; - int size; - char *buf = page; /***********************************************/ /* Dump out the security table. */ /***********************************************/ - for (i = 0; i < di_cnt && di_list[i].di_type && len > 0; i++) { + for (i = 0; i < di_cnt && di_list[i].di_type; i++) { char *tp; char *tpend = tmpbuf + sizeof tmpbuf; strcpy(tmpbuf, @@ -2734,18 +2739,26 @@ static int proc_dtrace_security_read_proc(char *page, char **start, off_t off, if (di_list[i].di_priv & DTRACE_PRIV_OWNER) strcat(tp, " priv_owner"); - size = snprintf(buf, len, "%s\n", tmpbuf); - buf += size; - len -= size; - n += size; + seq_printf(seq, "%s\n", tmpbuf); } - return proc_calc_metrics(page, start, off, count, eof, n); + return 0; } -static int proc_dtrace_stats_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ int i, size; - int n = 0; - char *buf = page; + +static int proc_dtrace_security_single_open(struct inode *inode, struct file *file) +{ + return single_open(file, &proc_dtrace_security_show, NULL); +} +static struct file_operations proc_dtrace_security = { + .owner = THIS_MODULE, + .open = proc_dtrace_security_single_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release +}; + +/** "proc/dtrace/stats" */ +static int proc_dtrace_stats_show(struct seq_file *seq, void *v) +{ int i; extern unsigned long cnt_0x7f; extern unsigned long cnt_gpf1; extern unsigned long cnt_gpf2; @@ -2818,58 +2831,48 @@ static int proc_dtrace_stats_read_proc(char *page, char **start, off_t off, {0} }; - for (i = 0; i < MAX_DCNT && n < count; i++) { + for (i = 0; i < MAX_DCNT; i++) { if (dcnt[i] == 0) continue; - size = snprintf(buf, count - n, "dcnt%d=%lu\n", i, dcnt[i]); - buf += size; - n += size; - } + seq_printf(seq, "dcnt%d=%lu\n", i, dcnt[i]); + } for (i = 0; stats[i].name; i++) { if (stats[i].type == TYPE_LONG_LONG) - size = snprintf(buf, count - n, "%s=%llu\n", stats[i].name, *(unsigned long long *) stats[i].ptr); + seq_printf(seq, "%s=%llu\n", stats[i].name, *(unsigned long long *) stats[i].ptr); else if (stats[i].type == TYPE_LONG) - size = snprintf(buf, count - n, "%s=%lu\n", stats[i].name, *stats[i].ptr); + seq_printf(seq, "%s=%lu\n", stats[i].name, *stats[i].ptr); else - size = snprintf(buf, count - n, "%s=%d\n", stats[i].name, *(int *) stats[i].ptr); - buf += size; - n += size; + seq_printf(seq, "%s=%d\n", stats[i].name, *(int *) stats[i].ptr); } - return proc_calc_metrics(page, start, off, count, eof, n); + return 0; } -static int proc_dtrace_trace_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ int j; - int pos = 0; - int n = 0; - char *buf = page; - if (off >= log_bufsiz) { - *eof = 1; - return 0; - } +static int proc_dtrace_stats_single_open(struct inode *inode, struct file *file) +{ + return single_open(file, &proc_dtrace_stats_show, NULL); +} +static struct file_operations proc_dtrace_stats = { + .owner = THIS_MODULE, + .open = proc_dtrace_stats_single_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release +}; - j = (dbuf_i + 1) % log_bufsiz; - while (pos < off + count && n < count && j != dbuf_i) { - if (dtrace_buf[j] && pos++ >= off) { - *buf++ = dtrace_buf[j]; - n++; - } - j = (j + 1) % log_bufsiz; - } - if (j == dbuf_i) - *eof = 1; - *start = page; - return n; +/** "proc/dtrace/trace" */ +static int proc_dtrace_trace_show(struct seq_file *seq, void *v) +{ + // TODO: or we can use dtracedrv_read() instead + return seq_printf(seq, "%s\n", dtrace_buf); } /**********************************************************************/ /* Special hack for debugging. */ /**********************************************************************/ -static int proc_dtrace_trace_write_proc(struct file *file, const char __user *buffer, - unsigned long count, void *pda) -{ int n = count > 32 ? 32 : count; +static ssize_t proc_dtrace_trace_write_proc(struct file *fp, const char __user *buffer, size_t count, loff_t *off) +{ + int n = count > 32 ? 32 : count; dtrace_printf("proc_dtrace_trace_write_proc: %*.*s\n", n, n, buffer); if (strncmp(buffer, "stack", 5) == 0) @@ -2878,6 +2881,21 @@ static int proc_dtrace_trace_write_proc(struct file *file, const char __user *bu return count; } +static int proc_dtrace_trace_single_open(struct inode *inode, struct file *file) +{ + return single_open(file, &proc_dtrace_trace_show, NULL); +} +static struct file_operations proc_dtrace_trace = { + .owner = THIS_MODULE, + .open = proc_dtrace_trace_single_open, + .read = seq_read, // dtracedrv_read() ? + .llseek = seq_lseek, + .release = seq_release, + .write = proc_dtrace_trace_write_proc +}; + +/** \proc */ + static int dtracedrv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int ret; int rv = 0; @@ -2956,7 +2974,6 @@ static struct miscdevice helper_dev = { static int __init dtracedrv_init(void) { int i, ret; - struct proc_dir_entry *ent; /***********************************************/ /* Create the parent directory. */ @@ -3022,18 +3039,10 @@ static struct proc_dir_entry *dir; /***********************************************/ /* Create /proc/dtrace subentries. */ /***********************************************/ - ent = create_proc_entry("debug", S_IFREG | S_IRUGO | S_IWUGO, dir); - ent->read_proc = proc_dtrace_debug_read_proc; - - ent = create_proc_entry("security", S_IFREG | S_IRUGO | S_IWUGO, dir); - ent->read_proc = proc_dtrace_security_read_proc; - - ent = create_proc_entry("stats", S_IFREG | S_IRUGO | S_IWUGO, dir); - ent->read_proc = proc_dtrace_stats_read_proc; - - ent = create_proc_entry("trace", S_IFREG | S_IRUGO | S_IWUGO, dir); - ent->read_proc = proc_dtrace_trace_read_proc; - ent->write_proc = proc_dtrace_trace_write_proc; + proc_create("debug", S_IFREG | S_IRUGO | S_IWUGO, dir, &proc_dtrace_debug); + proc_create("security", S_IFREG | S_IRUGO | S_IWUGO, dir, &proc_dtrace_security); + proc_create("stats", S_IFREG | S_IRUGO | S_IWUGO, dir, &proc_dtrace_stats); + proc_create("trace", S_IFREG | S_IRUGO | S_IWUGO, dir, &proc_dtrace_trace); /***********************************************/ /* Helper not presently implemented :-( */ diff --git a/driver/fasttrap.c b/driver/fasttrap.c index 2ce3615..52d3fdf 100644 --- a/driver/fasttrap.c +++ b/driver/fasttrap.c @@ -28,6 +28,8 @@ # if linux #include "dtrace_linux.h" +#include "proc_compat.h" + #include #include #include @@ -2471,7 +2473,6 @@ fasttrap_attach(void) { ulong_t nent = 1000; int i; - struct proc_dir_entry *ent; # if defined(sun) switch (cmd) { @@ -2570,9 +2571,7 @@ HERE(); } HERE(); - ent = create_proc_entry("dtrace/fasttrap", 0444, NULL); - if (ent) - ent->proc_fops = &fasttrap_proc_fops; + proc_create("dtrace/fasttrap", 0444, NULL, &fasttrap_proc_fops); (void) dtrace_meta_register("fasttrap", &fasttrap_mops, NULL, &fasttrap_meta_id); HERE(); diff --git a/driver/fbt_linux.c b/driver/fbt_linux.c index 613134b..6f50590 100644 --- a/driver/fbt_linux.c +++ b/driver/fbt_linux.c @@ -20,6 +20,8 @@ //#pragma ident "@(#)fbt.c 1.11 04/12/18 SMI" #include +#include "proc_compat.h" + #include #include #include @@ -1403,7 +1405,6 @@ static int initted; int fbt_init(void) { int ret; - struct proc_dir_entry *ent; ret = misc_register(&fbt_dev); if (ret) { @@ -1425,9 +1426,7 @@ int fbt_init(void) /* dtrace_invop_add(fbt_invop);*/ - ent = create_proc_entry("dtrace/fbt", 0444, NULL); - if (ent) - ent->proc_fops = &fbt_proc_fops; + proc_create("dtrace/fbt", 0444, NULL, &fbt_proc_fops); if (dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_KERNEL, 0, &fbt_pops, NULL, &fbt_id)) { diff --git a/driver/instr_linux.c b/driver/instr_linux.c index 7b34903..aa829b6 100644 --- a/driver/instr_linux.c +++ b/driver/instr_linux.c @@ -21,6 +21,8 @@ /**********************************************************************/ #include +#include "proc_compat.h" + #include #include #include @@ -1109,7 +1111,6 @@ int instr_init(void) { # if !defined(__arm__) int ret; - struct proc_dir_entry *ent; ret = misc_register(&instr_dev); if (ret) { @@ -1131,9 +1132,7 @@ int instr_init(void) dtrace_invop_add(instr_invop); - ent = create_proc_entry("dtrace/instr", 0444, NULL); - if (ent) - ent->proc_fops = &instr_proc_fops; + proc_create("dtrace/instr", 0444, NULL, &instr_proc_fops); if (dtrace_register("instr", &instr_attr, DTRACE_PRIV_KERNEL, 0, &instr_pops, NULL, &instr_id)) { diff --git a/driver/intr.c b/driver/intr.c index 3eb2fe1..6699632 100644 --- a/driver/intr.c +++ b/driver/intr.c @@ -16,6 +16,7 @@ #include "dtrace_linux.h" #include #include "dtrace_proto.h" +#include "proc_compat.h" #include #include @@ -1230,7 +1231,6 @@ intr_init(void) return; # else - struct proc_dir_entry *ent; static struct x86_descriptor desc1; my_kallsyms_lookup = get_proc_addr("kallsyms_lookup"); @@ -1277,12 +1277,8 @@ static struct x86_descriptor desc1; /* Add an /proc/dtrace/idt, so we can see */ /* what it looks like from user space. */ /***********************************************/ - ent = create_proc_entry("dtrace/idt", 0444, NULL); - if (ent) - ent->proc_fops = &idt_proc_fops; - ent = create_proc_entry("dtrace/gdt", 0444, NULL); - if (ent) - ent->proc_fops = &gdt_proc_fops; + proc_create("dtrace/idt", 0444, NULL, &idt_proc_fops); + proc_create("dtrace/gdt", 0444, NULL, &gdt_proc_fops); /***********************************************/ /* Lock the page fault handler into */ diff --git a/driver/proc_compat.h b/driver/proc_compat.h new file mode 100644 index 0000000..62f5a7c --- /dev/null +++ b/driver/proc_compat.h @@ -0,0 +1,25 @@ + +/** + * proc compat with kernel older 3.10 + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) +inline struct proc_dir_entry* proc_create_data( + const char *name, umode_t mode, struct proc_dir_entry *parent, + const struct file_operations *proc_fops, void *data) +{ + struct proc_dir_entry *ent = create_proc_entry(name, mode, parent); + if (ent != NULL) { + ent->proc_fops = proc_fops; + ent->data = data; + } + return ent; +} + +static inline struct proc_dir_entry *proc_create( + const char *name, umode_t mode, struct proc_dir_entry *parent, + const struct file_operations *proc_fops) +{ + return proc_create_data(name, mode, parent, proc_fops, NULL); +} + +#endif diff --git a/driver/systrace.c b/driver/systrace.c index af6068d..9ccc092 100644 --- a/driver/systrace.c +++ b/driver/systrace.c @@ -72,6 +72,8 @@ Feb 2011 # undef zone # define zone linux_zone #include +#include "proc_compat.h" + #include #include #include @@ -2394,7 +2396,6 @@ static int initted; int systrace_init(void) { int ret; - struct proc_dir_entry *ent; /***********************************************/ /* This is a run-time and not a compile */ @@ -2419,9 +2420,7 @@ int systrace_init(void) systrace_attach(); - ent = create_proc_entry("dtrace/syscall", 0444, NULL); - if (ent) - ent->proc_fops = &sys_proc_fops; + proc_create("dtrace/syscall", 0444, NULL, &sys_proc_fops); return 0; }