diff options
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 10187812771e..000000000000 --- a/fs/relayfs/buffers.c +++ /dev/null | |||
@@ -1,190 +0,0 @@ | |||
1 | /* | ||
2 | * RelayFS buffer management code. | ||
3 | * | ||
4 | * Copyright (C) 2002-2005 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp | ||
5 | * Copyright (C) 1999-2005 - Karim Yaghmour (karim@opersys.com) | ||
6 | * | ||
7 | * This file is released under the GPL. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/vmalloc.h> | ||
12 | #include <linux/mm.h> | ||
13 | #include <linux/relayfs_fs.h> | ||
14 | #include "relay.h" | ||
15 | #include "buffers.h" | ||
16 | |||
17 | /* | ||
18 | * close() vm_op implementation for relayfs file mapping. | ||
19 | */ | ||
20 | static void relay_file_mmap_close(struct vm_area_struct *vma) | ||
21 | { | ||
22 | struct rchan_buf *buf = vma->vm_private_data; | ||
23 | buf->chan->cb->buf_unmapped(buf, vma->vm_file); | ||
24 | } | ||
25 | |||
26 | /* | ||
27 | * nopage() vm_op implementation for relayfs file mapping. | ||
28 | */ | ||
29 | static struct page *relay_buf_nopage(struct vm_area_struct *vma, | ||
30 | unsigned long address, | ||
31 | int *type) | ||
32 | { | ||
33 | struct page *page; | ||
34 | struct rchan_buf *buf = vma->vm_private_data; | ||
35 | unsigned long offset = address - vma->vm_start; | ||
36 | |||
37 | if (address > vma->vm_end) | ||
38 | return NOPAGE_SIGBUS; /* Disallow mremap */ | ||
39 | if (!buf) | ||
40 | return NOPAGE_OOM; | ||
41 | |||
42 | page = vmalloc_to_page(buf->start + offset); | ||
43 | if (!page) | ||
44 | return NOPAGE_OOM; | ||
45 | get_page(page); | ||
46 | |||
47 | if (type) | ||
48 | *type = VM_FAULT_MINOR; | ||
49 | |||
50 | return page; | ||
51 | } | ||
52 | |||
53 | /* | ||
54 | * vm_ops for relay file mappings. | ||
55 | */ | ||
56 | static struct vm_operations_struct relay_file_mmap_ops = { | ||
57 | .nopage = relay_buf_nopage, | ||
58 | .close = relay_file_mmap_close, | ||
59 | }; | ||
60 | |||
61 | /** | ||
62 | * relay_mmap_buf: - mmap channel buffer to process address space | ||
63 | * @buf: relay channel buffer | ||
64 | * @vma: vm_area_struct describing memory to be mapped | ||
65 | * | ||
66 | * Returns 0 if ok, negative on error | ||
67 | * | ||
68 | * Caller should already have grabbed mmap_sem. | ||
69 | */ | ||
70 | int relay_mmap_buf(struct rchan_buf *buf, struct vm_area_struct *vma) | ||
71 | { | ||
72 | unsigned long length = vma->vm_end - vma->vm_start; | ||
73 | struct file *filp = vma->vm_file; | ||
74 | |||
75 | if (!buf) | ||
76 | return -EBADF; | ||
77 | |||
78 | if (length != (unsigned long)buf->chan->alloc_size) | ||
79 | return -EINVAL; | ||
80 | |||
81 | vma->vm_ops = &relay_file_mmap_ops; | ||
82 | vma->vm_private_data = buf; | ||
83 | buf->chan->cb->buf_mapped(buf, filp); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | /** | ||
89 | * relay_alloc_buf - allocate a channel buffer | ||
90 | * @buf: the buffer struct | ||
91 | * @size: total size of the buffer | ||
92 | * | ||
93 | * Returns a pointer to the resulting buffer, NULL if unsuccessful | ||
94 | */ | ||
95 | static void *relay_alloc_buf(struct rchan_buf *buf, unsigned long size) | ||
96 | { | ||
97 | void *mem; | ||
98 | unsigned int i, j, n_pages; | ||
99 | |||
100 | size = PAGE_ALIGN(size); | ||
101 | n_pages = size >> PAGE_SHIFT; | ||
102 | |||
103 | buf->page_array = kcalloc(n_pages, sizeof(struct page *), GFP_KERNEL); | ||
104 | if (!buf->page_array) | ||
105 | return NULL; | ||
106 | |||
107 | for (i = 0; i < n_pages; i++) { | ||
108 | buf->page_array[i] = alloc_page(GFP_KERNEL); | ||
109 | if (unlikely(!buf->page_array[i])) | ||
110 | goto depopulate; | ||
111 | } | ||
112 | mem = vmap(buf->page_array, n_pages, VM_MAP, PAGE_KERNEL); | ||
113 | if (!mem) | ||
114 | goto depopulate; | ||
115 | |||
116 | memset(mem, 0, size); | ||
117 | buf->page_count = n_pages; | ||
118 | return mem; | ||
119 | |||
120 | depopulate: | ||
121 | for (j = 0; j < i; j++) | ||
122 | __free_page(buf->page_array[j]); | ||
123 | kfree(buf->page_array); | ||
124 | return NULL; | ||
125 | } | ||
126 | |||
127 | /** | ||
128 | * relay_create_buf - allocate and initialize a channel buffer | ||
129 | * @alloc_size: size of the buffer to allocate | ||
130 | * @n_subbufs: number of sub-buffers in the channel | ||
131 | * | ||
132 | * Returns channel buffer if successful, NULL otherwise | ||
133 | */ | ||
134 | struct rchan_buf *relay_create_buf(struct rchan *chan) | ||
135 | { | ||
136 | struct rchan_buf *buf = kcalloc(1, sizeof(struct rchan_buf), GFP_KERNEL); | ||
137 | if (!buf) | ||
138 | return NULL; | ||
139 | |||
140 | buf->padding = kmalloc(chan->n_subbufs * sizeof(size_t *), GFP_KERNEL); | ||
141 | if (!buf->padding) | ||
142 | goto free_buf; | ||
143 | |||
144 | buf->start = relay_alloc_buf(buf, chan->alloc_size); | ||
145 | if (!buf->start) | ||
146 | goto free_buf; | ||
147 | |||
148 | buf->chan = chan; | ||
149 | kref_get(&buf->chan->kref); | ||
150 | return buf; | ||
151 | |||
152 | free_buf: | ||
153 | kfree(buf->padding); | ||
154 | kfree(buf); | ||
155 | return NULL; | ||
156 | } | ||
157 | |||
158 | /** | ||
159 | * relay_destroy_buf - destroy an rchan_buf struct and associated buffer | ||
160 | * @buf: the buffer struct | ||
161 | */ | ||
162 | void relay_destroy_buf(struct rchan_buf *buf) | ||
163 | { | ||
164 | struct rchan *chan = buf->chan; | ||
165 | unsigned int i; | ||
166 | |||
167 | if (likely(buf->start)) { | ||
168 | vunmap(buf->start); | ||
169 | for (i = 0; i < buf->page_count; i++) | ||
170 | __free_page(buf->page_array[i]); | ||
171 | kfree(buf->page_array); | ||
172 | } | ||
173 | kfree(buf->padding); | ||
174 | kfree(buf); | ||
175 | kref_put(&chan->kref, relay_destroy_channel); | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * relay_remove_buf - remove a channel buffer | ||
180 | * | ||
181 | * Removes the file from the relayfs fileystem, which also frees the | ||
182 | * rchan_buf_struct and the channel buffer. Should only be called from | ||
183 | * kref_put(). | ||
184 | */ | ||
185 | void relay_remove_buf(struct kref *kref) | ||
186 | { | ||
187 | struct rchan_buf *buf = container_of(kref, struct rchan_buf, kref); | ||
188 | buf->chan->cb->remove_buf_file(buf->dentry); | ||
189 | relay_destroy_buf(buf); | ||
190 | } | ||