diff options
author | Jens Axboe <axboe@suse.de> | 2006-03-23 19:56:55 +0100 |
---|---|---|
committer | Jens Axboe <axboe@suse.de> | 2006-03-23 19:56:55 +0100 |
commit | b86ff981a8252d83d6a7719ae09f3a05307e3592 (patch) | |
tree | ba8839f46cb140664e6a1ff6c7361b7424a95a7f /fs/relayfs/buffers.c | |
parent | b0e6e962992b76580f4900b166a337bad7c1e81b (diff) |
[PATCH] relay: migrate from relayfs to a generic relay API
Original patch from Paul Mundt, sysfs parts removed by me since they
were broken.
Signed-off-by: Jens Axboe <axboe@suse.de>
Diffstat (limited to 'fs/relayfs/buffers.c')
-rw-r--r-- | fs/relayfs/buffers.c | 190 |
1 files changed, 0 insertions, 190 deletions
diff --git a/fs/relayfs/buffers.c b/fs/relayfs/buffers.c deleted file mode 100644 index 10187812771..00000000000 --- a/fs/relayfs/buffers.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * RelayFS buffer management code. - * - * Copyright (C) 2002-2005 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp - * Copyright (C) 1999-2005 - Karim Yaghmour (karim@opersys.com) - * - * This file is released under the GPL. - */ - -#include <linux/module.h> -#include <linux/vmalloc.h> -#include <linux/mm.h> -#include <linux/relayfs_fs.h> -#include "relay.h" -#include "buffers.h" - -/* - * close() vm_op implementation for relayfs file mapping. - */ -static void relay_file_mmap_close(struct vm_area_struct *vma) -{ - struct rchan_buf *buf = vma->vm_private_data; - buf->chan->cb->buf_unmapped(buf, vma->vm_file); -} - -/* - * nopage() vm_op implementation for relayfs file mapping. - */ -static struct page *relay_buf_nopage(struct vm_area_struct *vma, - unsigned long address, - int *type) -{ - struct page *page; - struct rchan_buf *buf = vma->vm_private_data; - unsigned long offset = address - vma->vm_start; - - if (address > vma->vm_end) - return NOPAGE_SIGBUS; /* Disallow mremap */ - if (!buf) - return NOPAGE_OOM; - - page = vmalloc_to_page(buf->start + offset); - if (!page) - return NOPAGE_OOM; - get_page(page); - - if (type) - *type = VM_FAULT_MINOR; - - return page; -} - -/* - * vm_ops for relay file mappings. - */ -static struct vm_operations_struct relay_file_mmap_ops = { - .nopage = relay_buf_nopage, - .close = relay_file_mmap_close, -}; - -/** - * relay_mmap_buf: - mmap channel buffer to process address space - * @buf: relay channel buffer - * @vma: vm_area_struct describing memory to be mapped - * - * Returns 0 if ok, negative on error - * - * Caller should already have grabbed mmap_sem. - */ -int relay_mmap_buf(struct rchan_buf *buf, struct vm_area_struct *vma) -{ - unsigned long length = vma->vm_end - vma->vm_start; - struct file *filp = vma->vm_file; - - if (!buf) - return -EBADF; - - if (length != (unsigned long)buf->chan->alloc_size) - return -EINVAL; - - vma->vm_ops = &relay_file_mmap_ops; - vma->vm_private_data = buf; - buf->chan->cb->buf_mapped(buf, filp); - - return 0; -} - -/** - * relay_alloc_buf - allocate a channel buffer - * @buf: the buffer struct - * @size: total size of the buffer - * - * Returns a pointer to the resulting buffer, NULL if unsuccessful - */ -static void *relay_alloc_buf(struct rchan_buf *buf, unsigned long size) -{ - void *mem; - unsigned int i, j, n_pages; - - size = PAGE_ALIGN(size); - n_pages = size >> PAGE_SHIFT; - - buf->page_array = kcalloc(n_pages, sizeof(struct page *), GFP_KERNEL); - if (!buf->page_array) - return NULL; - - for (i = 0; i < n_pages; i++) { - buf->page_array[i] = alloc_page(GFP_KERNEL); - if (unlikely(!buf->page_array[i])) - goto depopulate; - } - mem = vmap(buf->page_array, n_pages, VM_MAP, PAGE_KERNEL); - if (!mem) - goto depopulate; - - memset(mem, 0, size); - buf->page_count = n_pages; - return mem; - -depopulate: - for (j = 0; j < i; j++) - __free_page(buf->page_array[j]); - kfree(buf->page_array); - return NULL; -} - -/** - * relay_create_buf - allocate and initialize a channel buffer - * @alloc_size: size of the buffer to allocate - * @n_subbufs: number of sub-buffers in the channel - * - * Returns channel buffer if successful, NULL otherwise - */ -struct rchan_buf *relay_create_buf(struct rchan *chan) -{ - struct rchan_buf *buf = kcalloc(1, sizeof(struct rchan_buf), GFP_KERNEL); - if (!buf) - return NULL; - - buf->padding = kmalloc(chan->n_subbufs * sizeof(size_t *), GFP_KERNEL); - if (!buf->padding) - goto free_buf; - - buf->start = relay_alloc_buf(buf, chan->alloc_size); - if (!buf->start) - goto free_buf; - - buf->chan = chan; - kref_get(&buf->chan->kref); - return buf; - -free_buf: - kfree(buf->padding); - kfree(buf); - return NULL; -} - -/** - * relay_destroy_buf - destroy an rchan_buf struct and associated buffer - * @buf: the buffer struct - */ -void relay_destroy_buf(struct rchan_buf *buf) -{ - struct rchan *chan = buf->chan; - unsigned int i; - - if (likely(buf->start)) { - vunmap(buf->start); - for (i = 0; i < buf->page_count; i++) - __free_page(buf->page_array[i]); - kfree(buf->page_array); - } - kfree(buf->padding); - kfree(buf); - kref_put(&chan->kref, relay_destroy_channel); -} - -/** - * relay_remove_buf - remove a channel buffer - * - * Removes the file from the relayfs fileystem, which also frees the - * rchan_buf_struct and the channel buffer. Should only be called from - * kref_put(). - */ -void relay_remove_buf(struct kref *kref) -{ - struct rchan_buf *buf = container_of(kref, struct rchan_buf, kref); - buf->chan->cb->remove_buf_file(buf->dentry); - relay_destroy_buf(buf); -} |