#include #include #include #include #include #include #define STUDENT_LOGIN "cchauvet" MODULE_LICENSE("GPL"); struct dentry *subdir; struct dentry *id_file; struct dentry *jiffies_file; struct dentry *foo_file; static ssize_t id_read(struct file *, char *, size_t, loff_t *); static ssize_t id_write(struct file *, const char *, size_t, loff_t *); const struct file_operations id_file_fops = { .owner = THIS_MODULE, .write = id_write, .read = id_read, }; static ssize_t foo_read(struct file *, char *, size_t, loff_t *); static ssize_t foo_write(struct file *, const char *, size_t, loff_t *); const struct file_operations foo_file_fops = { .owner = THIS_MODULE, .write = foo_write, .read = foo_read, }; char foo_data[PAGE_SIZE]; size_t foo_data_len = 0; DEFINE_MUTEX(foo_data_mutex); static int __init module_start(void) { subdir = debugfs_create_dir("fortytwo", NULL); if (!subdir) goto create_fail; id_file = debugfs_create_file("id", 0666, subdir, NULL, &id_file_fops); if (!id_file) goto create_fail; debugfs_create_size_t("jiffies", 0444, subdir, (size_t *) &jiffies); foo_file = debugfs_create_file("foo",0644, subdir, NULL, &foo_file_fops); if (!foo_file) goto create_fail; printk(KERN_INFO "Hello world !\n"); return 0; create_fail: debugfs_remove_recursive(subdir); return -ENOENT; } static void __exit module_end(void) { debugfs_remove_recursive(subdir); printk(KERN_INFO "Cleaning up module.\n"); } static ssize_t id_read(struct file *f, char *buf, size_t len, loff_t *f_pos) { char data[] = STUDENT_LOGIN; size_t data_len = strlen(data); if(*f_pos > 0) return 0; if (copy_to_user(buf, data, data_len)) return -EFAULT; *f_pos += data_len; return data_len; } static ssize_t id_write(struct file *f, const char *buf, size_t len, loff_t *offset) { char data[10]; size_t len_red = 10 > len ? len : 10; if (copy_from_user(data, buf, len_red)) return -EFAULT; if (strcmp(data, STUDENT_LOGIN)) return -EINVAL; return len_red; } static ssize_t foo_read(struct file *f, char __user *buf, size_t len, loff_t *offset) { size_t len_red; mutex_lock(&foo_data_mutex); if (!buf) return -EINVAL; if (*offset > foo_data_len) return 0; if (len + *offset >= foo_data_len) len_red = foo_data_len - *offset; else len_red = len; if (copy_to_user(buf, foo_data + *offset, len_red)) return -EFAULT; mutex_unlock(&foo_data_mutex); *offset += len_red; return len_red; } static ssize_t foo_write(struct file *, const char __user *buf, size_t len, loff_t *offset) { if (len > PAGE_SIZE) return -EINVAL; mutex_lock(&foo_data_mutex); if (copy_from_user(foo_data, buf, len)) return -EFAULT; foo_data_len = len; mutex_unlock(&foo_data_mutex); *offset = len; return len; } module_init(module_start); module_exit(module_end);