Add preliminary support for more recent kernel (~4.15)
It is currently building with a Debian 4.15.11-1, but hasn't been tested and is expecting to crash really hard. Do no try unless you are ready to hard crash your system. It should support most version between the ~2.6.32 and this 4.15.11.
This commit is contained in:
parent
1afa952fb0
commit
48264ec40a
@ -6,12 +6,16 @@ FUSD: A Linux Framework for User-Space Devices
|
||||
|
||||
This is FUSD snapshot 20110401, released 18 January 2012. This fork is based
|
||||
on the found on the xiph.org SVN tracker. ( http://svn.xiph.org/trunk/fusd )
|
||||
They seems to no longuer update this tool (since 11 January 2007) and since it
|
||||
longuer compile with recent Linux kernel (at around 2.6.21) and since I need
|
||||
it in personal project, I ported it to newer version (current version is 2.6.32)
|
||||
They seems to no longer update this tool (since 11 January 2007) and since it
|
||||
longer compile with recent Linux kernel (at around 2.6.21) and since I need
|
||||
it in personal project, I ported it to newer version (current version is 2.6.32).
|
||||
It is currently no officialy supporting newer kernel, but changes are currently
|
||||
going on to support newer kernel up to 4.15. It is currently building under this
|
||||
line, but don't expect it to work.
|
||||
|
||||
|
||||
Some feature are still missing missing or buggy form the Xiph version (due to
|
||||
changes on the kernel source tree), but it's completly useable.
|
||||
changes on the kernel source tree), but it is still usable.
|
||||
|
||||
The official URL for this fork is:
|
||||
|
||||
@ -53,7 +57,7 @@ include the following rule:
|
||||
|
||||
5. Verify the fusd devices /dev/fusd/status and /dev/fusd/control
|
||||
exist. If the modprobe succeeds but no fusd devices appear,
|
||||
doublecheck the udev rule config change and make sure udevd restarted
|
||||
double-check the udev rule config change and make sure udevd restarted
|
||||
successfully. The kfusd kernel module must be inserted after udev has
|
||||
been correctly configured and restarted.
|
||||
|
||||
|
||||
@ -78,6 +78,10 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/highmem.h>
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||
#include <linux/sched/signal.h>
|
||||
#endif
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/ioctl.h>
|
||||
@ -132,6 +136,23 @@
|
||||
# define CLASS_DEVICE_DESTROY(a, b) device_destroy(a, b)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
|
||||
//result = GET_USER_PAGES(mmap_instance->fusd_dev->task, mmap_instance->fusd_dev->task->mm,
|
||||
// mmap_instance->addr + offset, 1, 1, 0, &page, NULL);
|
||||
#define GET_USER_PAGES(t,m,s,n,w,f,p,v) get_user_pages_remote(t,m,s,n,(w?FOLL_WRITE:0)|(f?FOLL_FORCE:0),p,v, NULL)
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
|
||||
|
||||
#define GET_USER_PAGES(t,m,s,n,w,f,p,v) get_user_pages_remote(t,m,s,n,w,f,p,v)
|
||||
#else
|
||||
#define GET_USER_PAGES(t,m,s,n,w,f,p,v) get_user_pages(t,m,s,n,w,f,p,v)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
|
||||
#define FULL_NAME_HASH(a, b) full_name_hash(0, a, b)
|
||||
#else
|
||||
#define FULL_NAME_HASH(a, b) full_name_hash(a, b)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
|
||||
|
||||
struct sysfs_elem_dir
|
||||
@ -847,7 +868,7 @@ STATIC int fusd_fops_call_send (fusd_file_t *fusd_file_arg,
|
||||
|
||||
/* fill the rest of the structure */
|
||||
fusd_msg->parm.fops_msg.pid = current->pid;
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
|
||||
fusd_msg->parm.fops_msg.uid = current_uid();
|
||||
fusd_msg->parm.fops_msg.gid = current_gid();
|
||||
#endif
|
||||
@ -1149,7 +1170,7 @@ int fusd_dev_add_file (struct file *file, fusd_dev_t *fusd_dev, fusd_file_t **fu
|
||||
init_waitqueue_head(&fusd_file->file_wait);
|
||||
init_waitqueue_head(&fusd_file->poll_wait);
|
||||
INIT_LIST_HEAD(&fusd_file->transactions);
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
|
||||
init_MUTEX(&fusd_file->file_sem);
|
||||
init_MUTEX(&fusd_file->transactions_sem);
|
||||
#else
|
||||
@ -1711,11 +1732,14 @@ static void fusd_client_mm_open (struct vm_area_struct * vma);
|
||||
static void fusd_client_mm_close (struct vm_area_struct * vma);
|
||||
|
||||
/* int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf); */
|
||||
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0)
|
||||
static int fusd_client_fault (struct vm_fault *vmf);
|
||||
#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
|
||||
static int fusd_client_fault (struct vm_area_struct *vma, struct vm_fault *vmf);
|
||||
#else
|
||||
static int fusd_client_fault (struct vm_area_struct *vma, struct vm_fault *vmf, int *type);
|
||||
#endif
|
||||
|
||||
static struct vm_operations_struct fusd_remap_vm_ops ={
|
||||
.open = fusd_client_mm_open,
|
||||
.close = fusd_client_mm_close,
|
||||
@ -1783,7 +1807,7 @@ static int fusd_client_mmap (struct file *file, struct vm_area_struct * vma)
|
||||
}
|
||||
|
||||
/* and wait for the reply */
|
||||
/* todo: store and retrieve the transid from the interrupted messsage */
|
||||
/* todo: store and retrieve the transid from the interrupted message */
|
||||
retval = fusd_fops_call_wait(fusd_file, &reply, transaction);
|
||||
|
||||
mmap_instance =
|
||||
@ -1800,7 +1824,11 @@ static int fusd_client_mmap (struct file *file, struct vm_area_struct * vma)
|
||||
|
||||
vma->vm_private_data = mmap_instance;
|
||||
vma->vm_ops = &fusd_remap_vm_ops;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)
|
||||
vma->vm_flags |= (VM_DONTEXPAND | VM_DONTDUMP);
|
||||
#else
|
||||
vma->vm_flags |= VM_RESERVED;
|
||||
#endif
|
||||
|
||||
fusd_client_mm_open(vma);
|
||||
|
||||
@ -1817,24 +1845,36 @@ invalid_file:
|
||||
return -EPIPE;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||
static int fusd_client_fault (struct vm_fault *vmf)
|
||||
#elif LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 30)
|
||||
static int fusd_client_fault (struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||
#else
|
||||
static int fusd_client_fault (struct vm_area_struct *vma, struct vm_fault *vmf, int *type)
|
||||
#endif
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
||||
struct vm_area_struct *vma = vmf->vma;
|
||||
#endif
|
||||
|
||||
struct fusd_mmap_instance* mmap_instance = (struct fusd_mmap_instance*) vma->vm_private_data;
|
||||
unsigned long offset;
|
||||
struct page *page = NULL;
|
||||
int result;
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
|
||||
offset = ( (unsigned long) vmf->address - vma->vm_start ) + ( vma->vm_pgoff << PAGE_SHIFT );
|
||||
#else
|
||||
offset = ( (unsigned long) vmf->virtual_address - vma->vm_start ) + ( vma->vm_pgoff << PAGE_SHIFT );
|
||||
#endif
|
||||
|
||||
// todo: worry about size
|
||||
if ( offset > mmap_instance->size )
|
||||
goto out;
|
||||
|
||||
down_read(&mmap_instance->fusd_dev->task->mm->mmap_sem);
|
||||
result = get_user_pages(mmap_instance->fusd_dev->task, mmap_instance->fusd_dev->task->mm, mmap_instance->addr + offset, 1, 1, 0, &page, NULL);
|
||||
result = GET_USER_PAGES(mmap_instance->fusd_dev->task, mmap_instance->fusd_dev->task->mm,
|
||||
mmap_instance->addr + offset, 1, 1, 0, &page, NULL);
|
||||
up_read(&mmap_instance->fusd_dev->task->mm->mmap_sem);
|
||||
|
||||
|
||||
@ -2207,8 +2247,11 @@ STATIC int fusd_register_device (fusd_dev_t *fusd_dev,
|
||||
if ( sysfs )
|
||||
{
|
||||
/* Get FS superblock */
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
|
||||
sb = sget(sysfs, systest, NULL, 0, NULL);
|
||||
#else
|
||||
sb = sget(sysfs, systest, NULL, NULL);
|
||||
|
||||
#endif
|
||||
/* because put_filesystem isn't exported */
|
||||
module_put(sysfs->owner);
|
||||
|
||||
@ -2224,7 +2267,8 @@ STATIC int fusd_register_device (fusd_dev_t *fusd_dev,
|
||||
/* Search for directory "class" in the root of this filesystem */
|
||||
name.name = "class";
|
||||
name.len = 5;
|
||||
name.hash = full_name_hash(name.name, name.len);
|
||||
name.hash = FULL_NAME_HASH(name.name, name.len);
|
||||
|
||||
classdir = d_lookup(root, &name);
|
||||
|
||||
if ( classdir )
|
||||
@ -2232,7 +2276,7 @@ STATIC int fusd_register_device (fusd_dev_t *fusd_dev,
|
||||
/* Found, now search for class wanted name */
|
||||
name.name = register_msg.clazz;
|
||||
name.len = strlen(name.name);
|
||||
name.hash = full_name_hash(name.name, name.len);
|
||||
name.hash = FULL_NAME_HASH(name.name, name.len);
|
||||
classdir2 = d_lookup(classdir, &name);
|
||||
|
||||
if ( classdir2 )
|
||||
@ -2659,6 +2703,31 @@ STATIC ssize_t fusd_writev (struct file *file,
|
||||
iov[0].iov_base, iov[0].iov_len,
|
||||
iov[1].iov_base, iov[1].iov_len);
|
||||
}
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
|
||||
ssize_t fusd_write_iter (struct kiocb *iocb, struct iov_iter *iov)
|
||||
{
|
||||
unsigned long count = iov_iter_count(iov);
|
||||
char *msg, *data;
|
||||
size_t msg_len, data_len;
|
||||
|
||||
if ( count != 2 )
|
||||
{
|
||||
RDEBUG(2, "fusd_writev: got illegal iov count of %ld", count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
msg = iov->iov->iov_base + iov->iov_offset;
|
||||
msg_len = iov_iter_single_seg_count(iov);
|
||||
|
||||
iov_iter_advance(iov, msg_len);
|
||||
|
||||
data = iov->iov->iov_base + iov->iov_offset;
|
||||
data_len = iov_iter_single_seg_count(iov);
|
||||
|
||||
return fusd_process_write(iocb->ki_filp,
|
||||
msg, msg_len,
|
||||
data, data_len);
|
||||
}
|
||||
#else
|
||||
STATIC ssize_t fusd_aio_write (struct kiocb *iocb,
|
||||
const struct iovec *iov,
|
||||
@ -2685,8 +2754,8 @@ STATIC long fusd_unlocked_ioctl (struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
#endif
|
||||
{
|
||||
void __user *argp = (void __user *) arg;
|
||||
#if 0
|
||||
void __user *argp = (void __user *) arg;
|
||||
struct iovec iov;
|
||||
|
||||
if ( ( argp != NULL ) && ( cmd == 0xb16b00b5 ) )
|
||||
@ -2914,7 +2983,11 @@ STATIC struct file_operations fusd_fops = {
|
||||
.open = fusd_open,
|
||||
.read = fusd_read,
|
||||
.write = fusd_write,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
|
||||
.write_iter = fusd_write_iter,
|
||||
#else
|
||||
.aio_write = fusd_aio_write,
|
||||
#endif
|
||||
.unlocked_ioctl = fusd_unlocked_ioctl,
|
||||
.release = fusd_release,
|
||||
.poll = fusd_poll,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user