Skip to content

Commit

Permalink
vsd mmap
Browse files Browse the repository at this point in the history
  • Loading branch information
e5l committed Mar 30, 2016
1 parent 595536b commit 2eeb4a5
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 28 deletions.
28 changes: 16 additions & 12 deletions tasks/vsd2/vsd_driver/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static ssize_t vsd_dev_read(struct file *filp,

if (copy_to_user(read_user_buf, vsd_dev->vbuf + *fpos, read_size))
return -EFAULT;

*fpos += read_size;
return read_size;
}
Expand Down Expand Up @@ -109,7 +109,7 @@ static long vsd_ioctl_get_size(vsd_ioctl_get_size_arg_t __user *uarg)
static long vsd_ioctl_set_size(vsd_ioctl_set_size_arg_t __user *uarg)
{
vsd_ioctl_set_size_arg_t arg;
if (0/* TODO device is currently mapped */)
if (vsd_dev->mmap_count > 0)
return -EBUSY;

if (copy_from_user(&arg, uarg, sizeof(arg)))
Expand Down Expand Up @@ -155,20 +155,24 @@ static struct vm_operations_struct vsd_dev_vma_ops = {

static int map_vmalloc_range(struct vm_area_struct *uvma, void *kaddr, size_t size)
{
int ret = 0;
struct page* page_to_map;

unsigned long uaddr = uvma->vm_start;

if (!PAGE_ALIGNED(uaddr) || !PAGE_ALIGNED(kaddr)
|| !PAGE_ALIGNED(size))
return -EINVAL;

/*
* Remember that all the work with memory is done using pages.
* PAGE_SIZE is minimal size of memory we can map/unmap
* anywhere.
* Note that vmalloced VSD address range is not physically
* continuous. So we need to map each vmalloced page separetely.
* Use vmalloc_to_page and vm_insert_page functions for this.
*/
// TODO
while (size > 0) {
page_to_map = vmalloc_to_page(kaddr);
if ((ret = vm_insert_page(uvma, uaddr, page_to_map)) == -EFAULT)

This comment has been minimized.

Copy link
@eabatalov

eabatalov Apr 7, 2016

Collaborator

Need to check for ANY error. It doesn't matter which one has happened. Just return it.

return ret;

kaddr += PAGE_SIZE;
uaddr += PAGE_SIZE;
size -= PAGE_SIZE;
}

uvma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
return 0;
Expand All @@ -193,7 +197,7 @@ static int vsd_dev_mmap(struct file *filp, struct vm_area_struct *vma)

vma->vm_ops = &vsd_dev_vma_ops;
vsd_dev_vma_open(vma);

return 0;
}

Expand Down
55 changes: 39 additions & 16 deletions tasks/vsd2/vsd_userspace/vsd_device.c
Original file line number Diff line number Diff line change
@@ -1,51 +1,74 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <stdlib.h>

#include "../vsd_driver/vsd_ioctl.h"
#include "vsd_device.h"

static int device;

int vsd_init()
{
// TODO
return -1;
device = open("/dev/vsd", O_RDWR);
return (device == -1) ? EXIT_FAILURE : EXIT_SUCCESS;

This comment has been minimized.

Copy link
@eabatalov

eabatalov Apr 7, 2016

Collaborator

EXIT_FAILURE and EXIT_SUCCESS are used only for process exit status

}

int vsd_deinit()
{
// TODO
return -1;
return close(device);
}

int vsd_get_size(size_t *out_size)
{
// TODO
return -1;
vsd_ioctl_get_size_arg_t size;

if (ioctl(device, VSD_IOCTL_GET_SIZE, &size) == -1)
return EXIT_FAILURE;

*out_size = size.size;
return EXIT_SUCCESS;
}

int vsd_set_size(size_t size)
{
// TODO
return -1;
vsd_ioctl_set_size_arg_t new_size;
new_size.size = size;

if (ioctl(device, VSD_IOCTL_SET_SIZE, &new_size) == -1)
return EXIT_FAILURE;

return EXIT_SUCCESS;
}

ssize_t vsd_read(char* dst, off_t offset, size_t size)
{
// TODO
return -1;
if (lseek(device, offset, SEEK_SET) < 0)
return -1;

return read(device, dst, size);
}

ssize_t vsd_write(const char* src, off_t offset, size_t size)
{
// TODO
return -1;
if (lseek(device, offset, SEEK_SET) < 0)
return -1;

return write(device, src, size);
}

void* vsd_mmap(size_t offset)
{
// TODO
return MAP_FAILED;
size_t len;
vsd_get_size(&len);

This comment has been minimized.

Copy link
@eabatalov

eabatalov Apr 7, 2016

Collaborator

Need to check vsd_get_size for errors.

return mmap(0, len - offset, PROT_READ | PROT_WRITE, MAP_SHARED, device, offset);
}

int vsd_munmap(void* addr, size_t offset)
{
// TODO
return -1;
size_t len;
vsd_get_size(&len);
return munmap(addr, len - offset);
}

0 comments on commit 2eeb4a5

Please sign in to comment.