VFS helpers for reading files in kernel mode
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 19 Feb 2015 16:41:00 +0000 (11:41 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sun, 1 Mar 2015 14:36:16 +0000 (09:36 -0500)
It's a minor pain, esp due to the memcpy_to_user() business deep in
generic_file_read().

kern/include/vfs.h
kern/src/vfs.c

index fcfbef6..8756498 100644 (file)
@@ -481,6 +481,8 @@ int do_rename(char *old_path, char *new_path);
 int do_truncate(struct inode *inode, off64_t len);
 struct file *dentry_open(struct dentry *dentry, int flags);
 void file_release(struct kref *kref);
+ssize_t kread_file(struct file *file, void *buf, size_t sz);
+void *kread_whole_file(struct file *file);
 
 /* Process-related File management functions */
 struct file *get_file_from_fd(struct files_struct *open_files, int fd);
index 6d706ed..d58bd97 100644 (file)
@@ -2294,6 +2294,41 @@ void file_release(struct kref *kref)
        kmem_cache_free(file_kcache, file);
 }
 
+ssize_t kread_file(struct file *file, void *buf, size_t sz)
+{
+       /* TODO: (KFOP) (VFS kernel read/writes need to have no proc current) */
+       struct proc *old_proc = switch_to(0);
+       off64_t dummy = 0;
+       ssize_t cpy_amt = file->f_op->read(file, buf, sz, &dummy);
+       switch_back(0, old_proc);
+       return cpy_amt;
+}
+
+/* Reads the contents of an entire file into a buffer, returning that buffer.
+ * On error, prints something useful and returns 0 */
+void *kread_whole_file(struct file *file)
+{
+       size_t size;
+       void *contents;
+       ssize_t cpy_amt;
+
+       size = file->f_dentry->d_inode->i_size;
+       contents = kmalloc(size, KMALLOC_WAIT);
+       cpy_amt = kread_file(file, contents, size);
+       if (cpy_amt < 0) {
+               printk("Error %d reading file %s\n", get_errno(), file_name(file));
+               kfree(contents);
+               return 0;
+       }
+       if (cpy_amt != size) {
+               printk("Read %d, needed %d for file %s\n", cpy_amt, size,
+                      file_name(file));
+               kfree(contents);
+               return 0;
+       }
+       return contents;
+}
+
 /* Process-related File management functions */
 
 /* Given any FD, get the appropriate file, 0 o/w */