Loading fs/casio_smemfs/file.c +22 −4 Original line number Diff line number Diff line Loading @@ -4,17 +4,21 @@ #include <fs/inode.h> #include <interface/fixos/errno.h> #include "smemfs_primitives_ng.h" // used for memory areas... #include <fs/vfs_file.h> const struct file_operations smemfs_file_operations = { .release = smemfs_release, .read = smemfs_read, .lseek = smemfs_lseek .lseek = smemfs_lseek, .map_area = smemfs_map_area }; const struct mem_area_ops smemfs_mem_ops = { .area_pagefault = smemfs_area_pagefault .area_pagefault = smemfs_area_pagefault, .area_release = smemfs_area_release }; Loading Loading @@ -140,6 +144,17 @@ off_t smemfs_lseek (struct file *filep, off_t offset, int whence) { } int smemfs_map_area(struct file *filep, struct mem_area *area) { // not a lot of stuff to do for now... area->ops = &smemfs_mem_ops; area->file.filep = filep; // increase file usage count (mirrored in smemfs_area_release) filep->count++; return 0; } union pm_page smemfs_area_pagefault(struct mem_area *area, void *addr_fault) { size_t readsize; void *pmaddr; Loading Loading @@ -179,10 +194,13 @@ union pm_page smemfs_area_pagefault(struct mem_area *area, void *addr_fault) { return pmpage; } int smemfs_area_resize(struct mem_area *area, const struct mem_area *new_area) { /* int smemfs_area_resize(struct mem_area *area, size_t new_size) { return -1; } */ void smemfs_area_release(struct mem_area *area) { // release the file, by closing it at vfs level? vfs_close(area->file.filep); } fs/casio_smemfs/file.h +2 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ off_t smemfs_lseek (struct file *filep, off_t offset, int whence); // memory-mapped operations int smemfs_map_area(struct file *filep, struct mem_area *area); union pm_page smemfs_area_pagefault(struct mem_area *area, void *addr_fault); int smemfs_area_resize(struct mem_area *area, const struct mem_area *new_area); Loading fs/file_operations.h +20 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ struct file; struct mem_area; struct file_operations { /** * Release the file opened instance ("close" it). Loading Loading @@ -47,6 +49,24 @@ struct file_operations { * data is specific to command and device, may be not used. */ int (*ioctl) (struct file *filep, int cmd, void *data); /** * Create a memory map of this object in memory. * Devices may use it as they want to, for example to provide big buffers * shared with userland. * area should be set with all non-private fields having a valid value, * which is not very well defined... * At least field ops is not expected to be set, but the interface is not * well designed for now. * TODO either use a 'hints' argument with mem_area-like type, or define * exactly what should be set and what is set by this function itself * * NULL if device of filesystem do not implements memory mapped areas. * * Return 0 if mapping is accepted, negative value else. */ int (*map_area) (struct file *filep, struct mem_area *area); }; #endif //_FS_FILE_OPERATIONS_H Loading fs/vfs_file.c +36 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ #include "file_system.h" #include "file_operations.h" #include "vfs_directory.h" #include <sys/mem_area.h> // pool allocation for file struct Loading Loading @@ -157,3 +158,38 @@ int vfs_fstat(struct file *filep, struct stat *buf) { return -1; } } int vfs_map_area(struct file *filep, size_t size, size_t offset, void *address, int flags, size_t infile_size, struct process *proc) { int ret = -EINVAL; if(filep->op->map_area != NULL) { struct mem_area *area; area = mem_area_alloc(); if(area == NULL) { ret = -ENOMEM; } else { // prepare area struct from arguments area->address = address; area->max_size = size; area->flags = flags | MEM_AREA_TYPE_FILE; area->file.base_offset = offset; area->file.infile_size = (flags & MEM_AREA_PARTIAL) ? infile_size : size; area->file.filep = filep; ret = filep->op->map_area(filep, area); if(ret == 0) { ret = mem_area_insert(proc, area); } else { // failed, free area (do not *release* it, free directly) mem_area_free(area); } } } return ret; } fs/vfs_file.h +14 −0 Original line number Diff line number Diff line Loading @@ -90,4 +90,18 @@ int vfs_ioctl(struct file *filep, int cmd, void *data); int vfs_fstat(struct file *filep, struct stat *buf); struct process; /** * Map size bytes of the object in memory, from given offset, to given address * in the address space of a given process. * Area permissions, and additionnal flags, may be provided, using constants * from sys/mem_area.h * from_file is important only if flag contains MEM_AREA_PARTIAL * * TODO make a 'hints' structure to reduce number of arguments? */ int vfs_map_area(struct file *filep, size_t size, size_t offset, void *address, int flags, size_t infile_size, struct process *proc); #endif //_FS_VFS_FILE_H Loading
fs/casio_smemfs/file.c +22 −4 Original line number Diff line number Diff line Loading @@ -4,17 +4,21 @@ #include <fs/inode.h> #include <interface/fixos/errno.h> #include "smemfs_primitives_ng.h" // used for memory areas... #include <fs/vfs_file.h> const struct file_operations smemfs_file_operations = { .release = smemfs_release, .read = smemfs_read, .lseek = smemfs_lseek .lseek = smemfs_lseek, .map_area = smemfs_map_area }; const struct mem_area_ops smemfs_mem_ops = { .area_pagefault = smemfs_area_pagefault .area_pagefault = smemfs_area_pagefault, .area_release = smemfs_area_release }; Loading Loading @@ -140,6 +144,17 @@ off_t smemfs_lseek (struct file *filep, off_t offset, int whence) { } int smemfs_map_area(struct file *filep, struct mem_area *area) { // not a lot of stuff to do for now... area->ops = &smemfs_mem_ops; area->file.filep = filep; // increase file usage count (mirrored in smemfs_area_release) filep->count++; return 0; } union pm_page smemfs_area_pagefault(struct mem_area *area, void *addr_fault) { size_t readsize; void *pmaddr; Loading Loading @@ -179,10 +194,13 @@ union pm_page smemfs_area_pagefault(struct mem_area *area, void *addr_fault) { return pmpage; } int smemfs_area_resize(struct mem_area *area, const struct mem_area *new_area) { /* int smemfs_area_resize(struct mem_area *area, size_t new_size) { return -1; } */ void smemfs_area_release(struct mem_area *area) { // release the file, by closing it at vfs level? vfs_close(area->file.filep); }
fs/casio_smemfs/file.h +2 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ off_t smemfs_lseek (struct file *filep, off_t offset, int whence); // memory-mapped operations int smemfs_map_area(struct file *filep, struct mem_area *area); union pm_page smemfs_area_pagefault(struct mem_area *area, void *addr_fault); int smemfs_area_resize(struct mem_area *area, const struct mem_area *new_area); Loading
fs/file_operations.h +20 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ struct file; struct mem_area; struct file_operations { /** * Release the file opened instance ("close" it). Loading Loading @@ -47,6 +49,24 @@ struct file_operations { * data is specific to command and device, may be not used. */ int (*ioctl) (struct file *filep, int cmd, void *data); /** * Create a memory map of this object in memory. * Devices may use it as they want to, for example to provide big buffers * shared with userland. * area should be set with all non-private fields having a valid value, * which is not very well defined... * At least field ops is not expected to be set, but the interface is not * well designed for now. * TODO either use a 'hints' argument with mem_area-like type, or define * exactly what should be set and what is set by this function itself * * NULL if device of filesystem do not implements memory mapped areas. * * Return 0 if mapping is accepted, negative value else. */ int (*map_area) (struct file *filep, struct mem_area *area); }; #endif //_FS_FILE_OPERATIONS_H Loading
fs/vfs_file.c +36 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ #include "file_system.h" #include "file_operations.h" #include "vfs_directory.h" #include <sys/mem_area.h> // pool allocation for file struct Loading Loading @@ -157,3 +158,38 @@ int vfs_fstat(struct file *filep, struct stat *buf) { return -1; } } int vfs_map_area(struct file *filep, size_t size, size_t offset, void *address, int flags, size_t infile_size, struct process *proc) { int ret = -EINVAL; if(filep->op->map_area != NULL) { struct mem_area *area; area = mem_area_alloc(); if(area == NULL) { ret = -ENOMEM; } else { // prepare area struct from arguments area->address = address; area->max_size = size; area->flags = flags | MEM_AREA_TYPE_FILE; area->file.base_offset = offset; area->file.infile_size = (flags & MEM_AREA_PARTIAL) ? infile_size : size; area->file.filep = filep; ret = filep->op->map_area(filep, area); if(ret == 0) { ret = mem_area_insert(proc, area); } else { // failed, free area (do not *release* it, free directly) mem_area_free(area); } } } return ret; }
fs/vfs_file.h +14 −0 Original line number Diff line number Diff line Loading @@ -90,4 +90,18 @@ int vfs_ioctl(struct file *filep, int cmd, void *data); int vfs_fstat(struct file *filep, struct stat *buf); struct process; /** * Map size bytes of the object in memory, from given offset, to given address * in the address space of a given process. * Area permissions, and additionnal flags, may be provided, using constants * from sys/mem_area.h * from_file is important only if flag contains MEM_AREA_PARTIAL * * TODO make a 'hints' structure to reduce number of arguments? */ int vfs_map_area(struct file *filep, size_t size, size_t offset, void *address, int flags, size_t infile_size, struct process *proc); #endif //_FS_VFS_FILE_H