Lines 52-57
Link Here
|
52 |
* problem above. Encryption modules that used to rely on the old scheme |
52 |
* problem above. Encryption modules that used to rely on the old scheme |
53 |
* should just call ->i_mapping->bmap() to calculate the physical block |
53 |
* should just call ->i_mapping->bmap() to calculate the physical block |
54 |
* number. |
54 |
* number. |
|
|
55 |
* |
56 |
* IV is now passed as (512 byte) sector number. |
57 |
* Jari Ruusu <jari.ruusu@pp.inet.fi>, May 18 2001 |
58 |
* |
59 |
* External encryption module locking bug fixed. |
60 |
* Ingo Rohloff <rohloff@in.tum.de>, June 21 2001 |
61 |
* |
62 |
* Make device backed loop work with swap (pre-allocated buffers + queue rewrite). |
63 |
* Jari Ruusu <jari.ruusu@pp.inet.fi>, September 2 2001 |
64 |
* |
65 |
* File backed code now uses file->f_op->read/write. Based on Andrew Morton's idea. |
66 |
* Jari Ruusu <jari.ruusu@pp.inet.fi>, May 23 2002 |
55 |
*/ |
67 |
*/ |
56 |
|
68 |
|
57 |
#include <linux/config.h> |
69 |
#include <linux/config.h> |
Lines 82-107
Link Here
|
82 |
static struct loop_device *loop_dev; |
94 |
static struct loop_device *loop_dev; |
83 |
static int *loop_sizes; |
95 |
static int *loop_sizes; |
84 |
static int *loop_blksizes; |
96 |
static int *loop_blksizes; |
|
|
97 |
static int *loop_hardsizes; |
85 |
static devfs_handle_t devfs_handle; /* For the directory */ |
98 |
static devfs_handle_t devfs_handle; /* For the directory */ |
86 |
|
99 |
|
87 |
/* |
100 |
/* |
88 |
* Transfer functions |
101 |
* Transfer functions |
89 |
*/ |
102 |
*/ |
90 |
static int transfer_none(struct loop_device *lo, int cmd, char *raw_buf, |
103 |
static int transfer_none(struct loop_device *lo, int cmd, char *raw_buf, |
91 |
char *loop_buf, int size, int real_block) |
104 |
char *loop_buf, int size, sector_t real_block) |
92 |
{ |
105 |
{ |
93 |
if (raw_buf != loop_buf) { |
106 |
/* this code is only called from file backed loop */ |
94 |
if (cmd == READ) |
107 |
/* and that code expects this function to be no-op */ |
95 |
memcpy(loop_buf, raw_buf, size); |
|
|
96 |
else |
97 |
memcpy(raw_buf, loop_buf, size); |
98 |
} |
99 |
|
108 |
|
|
|
109 |
if (current->need_resched) |
110 |
schedule(); |
100 |
return 0; |
111 |
return 0; |
101 |
} |
112 |
} |
102 |
|
113 |
|
103 |
static int transfer_xor(struct loop_device *lo, int cmd, char *raw_buf, |
114 |
static int transfer_xor(struct loop_device *lo, int cmd, char *raw_buf, |
104 |
char *loop_buf, int size, int real_block) |
115 |
char *loop_buf, int size, sector_t real_block) |
105 |
{ |
116 |
{ |
106 |
char *in, *out, *key; |
117 |
char *in, *out, *key; |
107 |
int i, keysize; |
118 |
int i, keysize; |
Lines 118-129
Link Here
|
118 |
keysize = lo->lo_encrypt_key_size; |
129 |
keysize = lo->lo_encrypt_key_size; |
119 |
for (i = 0; i < size; i++) |
130 |
for (i = 0; i < size; i++) |
120 |
*out++ = *in++ ^ key[(i & 511) % keysize]; |
131 |
*out++ = *in++ ^ key[(i & 511) % keysize]; |
|
|
132 |
if (current->need_resched) |
133 |
schedule(); |
121 |
return 0; |
134 |
return 0; |
122 |
} |
135 |
} |
123 |
|
136 |
|
124 |
static int none_status(struct loop_device *lo, struct loop_info *info) |
137 |
static int none_status(struct loop_device *lo, struct loop_info *info) |
125 |
{ |
138 |
{ |
126 |
lo->lo_flags |= LO_FLAGS_BH_REMAP; |
|
|
127 |
return 0; |
139 |
return 0; |
128 |
} |
140 |
} |
129 |
|
141 |
|
Lines 149-469
Link Here
|
149 |
/* xfer_funcs[0] is special - its release function is never called */ |
161 |
/* xfer_funcs[0] is special - its release function is never called */ |
150 |
struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = { |
162 |
struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = { |
151 |
&none_funcs, |
163 |
&none_funcs, |
152 |
&xor_funcs |
164 |
&xor_funcs, |
153 |
}; |
165 |
}; |
154 |
|
166 |
|
155 |
#define MAX_DISK_SIZE 1024*1024*1024 |
167 |
/* |
156 |
|
168 |
* First number of 'lo_prealloc' is the default number of RAM pages |
157 |
static int compute_loop_size(struct loop_device *lo, struct dentry * lo_dentry, kdev_t lodev) |
169 |
* to pre-allocate for each device backed loop. Every (configured) |
158 |
{ |
170 |
* device backed loop pre-allocates this amount of RAM pages unless |
159 |
if (S_ISREG(lo_dentry->d_inode->i_mode)) |
171 |
* later 'lo_prealloc' numbers provide an override. 'lo_prealloc' |
160 |
return (lo_dentry->d_inode->i_size - lo->lo_offset) >> BLOCK_SIZE_BITS; |
172 |
* overrides are defined in pairs: loop_index,number_of_pages |
161 |
if (blk_size[MAJOR(lodev)]) |
173 |
*/ |
162 |
return blk_size[MAJOR(lodev)][MINOR(lodev)] - |
174 |
static int lo_prealloc[9] = { 125, 999, 0, 999, 0, 999, 0, 999, 0 }; |
163 |
(lo->lo_offset >> BLOCK_SIZE_BITS); |
175 |
#define LO_PREALLOC_MIN 4 /* minimum user defined pre-allocated RAM pages */ |
164 |
return MAX_DISK_SIZE; |
176 |
#define LO_PREALLOC_MAX 512 /* maximum user defined pre-allocated RAM pages */ |
|
|
177 |
|
178 |
#ifdef MODULE |
179 |
MODULE_PARM(lo_prealloc, "1-9i"); |
180 |
MODULE_PARM_DESC(lo_prealloc, "Number of pre-allocated pages [,index,pages]..."); |
181 |
#else |
182 |
static int __init lo_prealloc_setup(char *str) |
183 |
{ |
184 |
int x, y, z; |
185 |
|
186 |
for (x = 0; x < (sizeof(lo_prealloc) / sizeof(int)); x++) { |
187 |
z = get_option(&str, &y); |
188 |
if (z > 0) |
189 |
lo_prealloc[x] = y; |
190 |
if (z < 2) |
191 |
break; |
192 |
} |
193 |
return 1; |
165 |
} |
194 |
} |
|
|
195 |
__setup("lo_prealloc=", lo_prealloc_setup); |
196 |
#endif |
166 |
|
197 |
|
167 |
static void figure_loop_size(struct loop_device *lo) |
198 |
/* |
168 |
{ |
199 |
* This is loop helper thread nice value in range |
169 |
loop_sizes[lo->lo_number] = compute_loop_size(lo, |
200 |
* from 0 (low priority) to -20 (high priority). |
170 |
lo->lo_backing_file->f_dentry, |
201 |
*/ |
171 |
lo->lo_device); |
202 |
#if defined(DEF_NICE) && defined(DEF_COUNTER) |
172 |
} |
203 |
static int lo_nice = -20; /* old scheduler default */ |
|
|
204 |
#else |
205 |
static int lo_nice = -1; /* O(1) scheduler default */ |
206 |
#endif |
173 |
|
207 |
|
174 |
static int lo_send(struct loop_device *lo, struct buffer_head *bh, int bsize, |
208 |
#ifdef MODULE |
175 |
loff_t pos) |
209 |
MODULE_PARM(lo_nice, "1i"); |
|
|
210 |
MODULE_PARM_DESC(lo_nice, "Loop thread scheduler nice (0 ... -20)"); |
211 |
#else |
212 |
static int __init lo_nice_setup(char *str) |
176 |
{ |
213 |
{ |
177 |
struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ |
214 |
int y; |
178 |
struct address_space *mapping = file->f_dentry->d_inode->i_mapping; |
|
|
179 |
struct address_space_operations *aops = mapping->a_ops; |
180 |
struct page *page; |
181 |
char *kaddr, *data; |
182 |
unsigned long index; |
183 |
unsigned size, offset; |
184 |
int len; |
185 |
|
186 |
down(&mapping->host->i_sem); |
187 |
index = pos >> PAGE_CACHE_SHIFT; |
188 |
offset = pos & (PAGE_CACHE_SIZE - 1); |
189 |
len = bh->b_size; |
190 |
data = bh->b_data; |
191 |
while (len > 0) { |
192 |
int IV = index * (PAGE_CACHE_SIZE/bsize) + offset/bsize; |
193 |
int transfer_result; |
194 |
|
215 |
|
195 |
size = PAGE_CACHE_SIZE - offset; |
216 |
if (get_option(&str, &y) == 1) |
196 |
if (size > len) |
217 |
lo_nice = y; |
197 |
size = len; |
218 |
return 1; |
198 |
|
|
|
199 |
page = grab_cache_page(mapping, index); |
200 |
if (!page) |
201 |
goto fail; |
202 |
kaddr = kmap(page); |
203 |
if (aops->prepare_write(file, page, offset, offset+size)) |
204 |
goto unlock; |
205 |
flush_dcache_page(page); |
206 |
transfer_result = lo_do_transfer(lo, WRITE, kaddr + offset, data, size, IV); |
207 |
if (transfer_result) { |
208 |
/* |
209 |
* The transfer failed, but we still write the data to |
210 |
* keep prepare/commit calls balanced. |
211 |
*/ |
212 |
printk(KERN_ERR "loop: transfer error block %ld\n", index); |
213 |
memset(kaddr + offset, 0, size); |
214 |
} |
215 |
if (aops->commit_write(file, page, offset, offset+size)) |
216 |
goto unlock; |
217 |
if (transfer_result) |
218 |
goto unlock; |
219 |
kunmap(page); |
220 |
data += size; |
221 |
len -= size; |
222 |
offset = 0; |
223 |
index++; |
224 |
pos += size; |
225 |
UnlockPage(page); |
226 |
page_cache_release(page); |
227 |
} |
228 |
up(&mapping->host->i_sem); |
229 |
return 0; |
230 |
|
231 |
unlock: |
232 |
kunmap(page); |
233 |
UnlockPage(page); |
234 |
page_cache_release(page); |
235 |
fail: |
236 |
up(&mapping->host->i_sem); |
237 |
return -1; |
238 |
} |
219 |
} |
|
|
220 |
__setup("lo_nice=", lo_nice_setup); |
221 |
#endif |
239 |
|
222 |
|
240 |
struct lo_read_data { |
223 |
typedef struct { |
241 |
struct loop_device *lo; |
224 |
struct buffer_head **q0; |
242 |
char *data; |
225 |
struct buffer_head **q1; |
243 |
int bsize; |
226 |
struct buffer_head **q2; |
244 |
}; |
227 |
int x0; |
|
|
228 |
int x1; |
229 |
int x2; |
230 |
} que_look_up_table; |
245 |
|
231 |
|
246 |
static int lo_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size) |
232 |
static void loop_prealloc_cleanup(struct loop_device *lo) |
247 |
{ |
233 |
{ |
248 |
char *kaddr; |
234 |
struct buffer_head *bh; |
249 |
unsigned long count = desc->count; |
235 |
|
250 |
struct lo_read_data *p = (struct lo_read_data*)desc->buf; |
236 |
while ((bh = lo->lo_bh_free)) { |
251 |
struct loop_device *lo = p->lo; |
237 |
__free_page(bh->b_page); |
252 |
int IV = page->index * (PAGE_CACHE_SIZE/p->bsize) + offset/p->bsize; |
238 |
lo->lo_bh_free = bh->b_reqnext; |
253 |
|
239 |
bh->b_reqnext = NULL; |
254 |
if (size > count) |
240 |
kmem_cache_free(bh_cachep, bh); |
255 |
size = count; |
241 |
} |
256 |
|
|
|
257 |
kaddr = kmap(page); |
258 |
if (lo_do_transfer(lo, READ, kaddr + offset, p->data, size, IV)) { |
259 |
size = 0; |
260 |
printk(KERN_ERR "loop: transfer error block %ld\n",page->index); |
261 |
desc->error = -EINVAL; |
262 |
} |
263 |
kunmap(page); |
264 |
|
265 |
desc->count = count - size; |
266 |
desc->written += size; |
267 |
p->data += size; |
268 |
return size; |
269 |
} |
270 |
|
271 |
static int lo_receive(struct loop_device *lo, struct buffer_head *bh, int bsize, |
272 |
loff_t pos) |
273 |
{ |
274 |
struct lo_read_data cookie; |
275 |
read_descriptor_t desc; |
276 |
struct file *file; |
277 |
|
278 |
cookie.lo = lo; |
279 |
cookie.data = bh->b_data; |
280 |
cookie.bsize = bsize; |
281 |
desc.written = 0; |
282 |
desc.count = bh->b_size; |
283 |
desc.buf = (char*)&cookie; |
284 |
desc.error = 0; |
285 |
spin_lock_irq(&lo->lo_lock); |
286 |
file = lo->lo_backing_file; |
287 |
spin_unlock_irq(&lo->lo_lock); |
288 |
do_generic_file_read(file, &pos, &desc, lo_read_actor); |
289 |
return desc.error; |
290 |
} |
242 |
} |
291 |
|
243 |
|
292 |
static inline int loop_get_bs(struct loop_device *lo) |
244 |
static int loop_prealloc_init(struct loop_device *lo, int y) |
293 |
{ |
245 |
{ |
294 |
int bs = 0; |
246 |
struct buffer_head *bh; |
|
|
247 |
int x; |
295 |
|
248 |
|
296 |
if (blksize_size[MAJOR(lo->lo_device)]) |
249 |
if(!y) { |
297 |
bs = blksize_size[MAJOR(lo->lo_device)][MINOR(lo->lo_device)]; |
250 |
y = lo_prealloc[0]; |
298 |
if (!bs) |
251 |
for (x = 1; x < (sizeof(lo_prealloc) / sizeof(int)); x += 2) { |
299 |
bs = BLOCK_SIZE; |
252 |
if (lo_prealloc[x + 1] && (lo->lo_number == lo_prealloc[x])) { |
|
|
253 |
y = lo_prealloc[x + 1]; |
254 |
break; |
255 |
} |
256 |
} |
257 |
} |
258 |
lo->lo_bh_flsh = (y * 3) / 4; |
300 |
|
259 |
|
301 |
return bs; |
260 |
for (x = 0; x < y; x++) { |
|
|
261 |
bh = kmem_cache_alloc(bh_cachep, SLAB_KERNEL); |
262 |
if (!bh) { |
263 |
loop_prealloc_cleanup(lo); |
264 |
return 1; |
265 |
} |
266 |
bh->b_page = alloc_page(GFP_KERNEL); |
267 |
if (!bh->b_page) { |
268 |
bh->b_reqnext = NULL; |
269 |
kmem_cache_free(bh_cachep, bh); |
270 |
loop_prealloc_cleanup(lo); |
271 |
return 1; |
272 |
} |
273 |
bh->b_reqnext = lo->lo_bh_free; |
274 |
lo->lo_bh_free = bh; |
275 |
} |
276 |
return 0; |
302 |
} |
277 |
} |
303 |
|
278 |
|
304 |
static inline unsigned long loop_get_iv(struct loop_device *lo, |
279 |
static void loop_add_queue_last(struct loop_device *lo, struct buffer_head *bh, struct buffer_head **q) |
305 |
unsigned long sector) |
|
|
306 |
{ |
280 |
{ |
307 |
int bs = loop_get_bs(lo); |
281 |
unsigned long flags; |
308 |
unsigned long offset, IV; |
|
|
309 |
|
282 |
|
310 |
IV = sector / (bs >> 9) + lo->lo_offset / bs; |
283 |
spin_lock_irqsave(&lo->lo_lock, flags); |
311 |
offset = ((sector % (bs >> 9)) << 9) + lo->lo_offset % bs; |
284 |
if (*q) { |
312 |
if (offset >= bs) |
285 |
bh->b_reqnext = (*q)->b_reqnext; |
313 |
IV++; |
286 |
(*q)->b_reqnext = bh; |
|
|
287 |
} else { |
288 |
bh->b_reqnext = bh; |
289 |
} |
290 |
*q = bh; |
291 |
spin_unlock_irqrestore(&lo->lo_lock, flags); |
314 |
|
292 |
|
315 |
return IV; |
293 |
if (waitqueue_active(&lo->lo_bh_wait)) |
|
|
294 |
wake_up_interruptible(&lo->lo_bh_wait); |
316 |
} |
295 |
} |
317 |
|
296 |
|
318 |
static int do_bh_filebacked(struct loop_device *lo, struct buffer_head *bh, int rw) |
297 |
static void loop_add_queue_first(struct loop_device *lo, struct buffer_head *bh, struct buffer_head **q) |
319 |
{ |
298 |
{ |
320 |
loff_t pos; |
299 |
spin_lock_irq(&lo->lo_lock); |
321 |
int ret; |
300 |
if (*q) { |
322 |
|
301 |
bh->b_reqnext = (*q)->b_reqnext; |
323 |
pos = ((loff_t) bh->b_rsector << 9) + lo->lo_offset; |
302 |
(*q)->b_reqnext = bh; |
324 |
|
303 |
} else { |
325 |
if (rw == WRITE) |
304 |
bh->b_reqnext = bh; |
326 |
ret = lo_send(lo, bh, loop_get_bs(lo), pos); |
305 |
*q = bh; |
327 |
else |
306 |
} |
328 |
ret = lo_receive(lo, bh, loop_get_bs(lo), pos); |
307 |
spin_unlock_irq(&lo->lo_lock); |
329 |
|
|
|
330 |
return ret; |
331 |
} |
308 |
} |
332 |
|
309 |
|
333 |
static void loop_end_io_transfer(struct buffer_head *bh, int uptodate); |
310 |
static struct buffer_head *loop_get_bh(struct loop_device *lo, int *list_nr, |
334 |
static void loop_put_buffer(struct buffer_head *bh) |
311 |
que_look_up_table *qt) |
335 |
{ |
312 |
{ |
336 |
/* |
313 |
struct buffer_head *bh = NULL, *last; |
337 |
* check b_end_io, may just be a remapped bh and not an allocated one |
314 |
|
338 |
*/ |
315 |
spin_lock_irq(&lo->lo_lock); |
339 |
if (bh && bh->b_end_io == loop_end_io_transfer) { |
316 |
if ((last = *qt->q0)) { |
340 |
__free_page(bh->b_page); |
317 |
bh = last->b_reqnext; |
341 |
kmem_cache_free(bh_cachep, bh); |
318 |
if (bh == last) |
|
|
319 |
*qt->q0 = NULL; |
320 |
else |
321 |
last->b_reqnext = bh->b_reqnext; |
322 |
bh->b_reqnext = NULL; |
323 |
*list_nr = qt->x0; |
324 |
} else if ((last = *qt->q1)) { |
325 |
bh = last->b_reqnext; |
326 |
if (bh == last) |
327 |
*qt->q1 = NULL; |
328 |
else |
329 |
last->b_reqnext = bh->b_reqnext; |
330 |
bh->b_reqnext = NULL; |
331 |
*list_nr = qt->x1; |
332 |
} else if ((last = *qt->q2)) { |
333 |
bh = last->b_reqnext; |
334 |
if (bh == last) |
335 |
*qt->q2 = NULL; |
336 |
else |
337 |
last->b_reqnext = bh->b_reqnext; |
338 |
bh->b_reqnext = NULL; |
339 |
*list_nr = qt->x2; |
342 |
} |
340 |
} |
|
|
341 |
spin_unlock_irq(&lo->lo_lock); |
342 |
return bh; |
343 |
} |
343 |
} |
344 |
|
344 |
|
345 |
/* |
345 |
static void loop_put_buffer(struct loop_device *lo, struct buffer_head *b) |
346 |
* Add buffer_head to back of pending list |
|
|
347 |
*/ |
348 |
static void loop_add_bh(struct loop_device *lo, struct buffer_head *bh) |
349 |
{ |
346 |
{ |
350 |
unsigned long flags; |
347 |
unsigned long flags; |
|
|
348 |
int wk; |
351 |
|
349 |
|
352 |
spin_lock_irqsave(&lo->lo_lock, flags); |
350 |
spin_lock_irqsave(&lo->lo_lock, flags); |
353 |
if (lo->lo_bhtail) { |
351 |
b->b_reqnext = lo->lo_bh_free; |
354 |
lo->lo_bhtail->b_reqnext = bh; |
352 |
lo->lo_bh_free = b; |
355 |
lo->lo_bhtail = bh; |
353 |
wk = lo->lo_bh_need; |
356 |
} else |
|
|
357 |
lo->lo_bh = lo->lo_bhtail = bh; |
358 |
spin_unlock_irqrestore(&lo->lo_lock, flags); |
354 |
spin_unlock_irqrestore(&lo->lo_lock, flags); |
359 |
|
355 |
|
360 |
up(&lo->lo_bh_mutex); |
356 |
if (wk && waitqueue_active(&lo->lo_bh_wait)) |
|
|
357 |
wake_up_interruptible(&lo->lo_bh_wait); |
361 |
} |
358 |
} |
362 |
|
359 |
|
363 |
/* |
360 |
static void loop_end_io_transfer_wr(struct buffer_head *bh, int uptodate) |
364 |
* Grab first pending buffer |
|
|
365 |
*/ |
366 |
static struct buffer_head *loop_get_bh(struct loop_device *lo) |
367 |
{ |
361 |
{ |
368 |
struct buffer_head *bh; |
362 |
struct loop_device *lo = &loop_dev[MINOR(bh->b_dev)]; |
369 |
|
363 |
struct buffer_head *rbh = bh->b_private; |
370 |
spin_lock_irq(&lo->lo_lock); |
|
|
371 |
if ((bh = lo->lo_bh)) { |
372 |
if (bh == lo->lo_bhtail) |
373 |
lo->lo_bhtail = NULL; |
374 |
lo->lo_bh = bh->b_reqnext; |
375 |
bh->b_reqnext = NULL; |
376 |
} |
377 |
spin_unlock_irq(&lo->lo_lock); |
378 |
|
364 |
|
379 |
return bh; |
365 |
rbh->b_reqnext = NULL; |
|
|
366 |
rbh->b_end_io(rbh, uptodate); |
367 |
loop_put_buffer(lo, bh); |
368 |
if (atomic_dec_and_test(&lo->lo_pending)) |
369 |
wake_up_interruptible(&lo->lo_bh_wait); |
380 |
} |
370 |
} |
381 |
|
371 |
|
382 |
/* |
372 |
static void loop_end_io_transfer_rd(struct buffer_head *bh, int uptodate) |
383 |
* when buffer i/o has completed. if BH_Dirty is set, this was a WRITE |
|
|
384 |
* and lo->transfer stuff has already been done. if not, it was a READ |
385 |
* so queue it for the loop thread and let it do the transfer out of |
386 |
* b_end_io context (we don't want to do decrypt of a page with irqs |
387 |
* disabled) |
388 |
*/ |
389 |
static void loop_end_io_transfer(struct buffer_head *bh, int uptodate) |
390 |
{ |
373 |
{ |
391 |
struct loop_device *lo = &loop_dev[MINOR(bh->b_dev)]; |
374 |
struct loop_device *lo = &loop_dev[MINOR(bh->b_dev)]; |
392 |
|
375 |
|
393 |
if (!uptodate || test_bit(BH_Dirty, &bh->b_state)) { |
376 |
if (!uptodate) |
394 |
struct buffer_head *rbh = bh->b_private; |
377 |
loop_end_io_transfer_wr(bh, uptodate); |
395 |
|
378 |
else |
396 |
rbh->b_end_io(rbh, uptodate); |
379 |
loop_add_queue_last(lo, bh, &lo->lo_bhQue0); |
397 |
if (atomic_dec_and_test(&lo->lo_pending)) |
|
|
398 |
up(&lo->lo_bh_mutex); |
399 |
loop_put_buffer(bh); |
400 |
} else |
401 |
loop_add_bh(lo, bh); |
402 |
} |
380 |
} |
403 |
|
381 |
|
404 |
static struct buffer_head *loop_get_buffer(struct loop_device *lo, |
382 |
static struct buffer_head *loop_get_buffer(struct loop_device *lo, |
405 |
struct buffer_head *rbh) |
383 |
struct buffer_head *rbh, int from_thread, int rw) |
406 |
{ |
384 |
{ |
407 |
struct buffer_head *bh; |
385 |
struct buffer_head *bh; |
|
|
386 |
struct page *p; |
387 |
unsigned long flags; |
408 |
|
388 |
|
409 |
/* |
389 |
spin_lock_irqsave(&lo->lo_lock, flags); |
410 |
* for xfer_funcs that can operate on the same bh, do that |
390 |
bh = lo->lo_bh_free; |
411 |
*/ |
391 |
if (bh) { |
412 |
if (lo->lo_flags & LO_FLAGS_BH_REMAP) { |
392 |
lo->lo_bh_free = bh->b_reqnext; |
413 |
bh = rbh; |
393 |
if (from_thread) |
414 |
goto out_bh; |
394 |
lo->lo_bh_need = 0; |
|
|
395 |
} else { |
396 |
if (from_thread) |
397 |
lo->lo_bh_need = 1; |
415 |
} |
398 |
} |
|
|
399 |
spin_unlock_irqrestore(&lo->lo_lock, flags); |
400 |
if (!bh) |
401 |
return (struct buffer_head *)0; |
416 |
|
402 |
|
417 |
do { |
403 |
p = bh->b_page; |
418 |
bh = kmem_cache_alloc(bh_cachep, SLAB_NOIO); |
404 |
memset(bh, 0, sizeof(struct buffer_head)); |
419 |
if (bh) |
405 |
bh->b_page = p; |
420 |
break; |
|
|
421 |
|
422 |
run_task_queue(&tq_disk); |
423 |
set_current_state(TASK_INTERRUPTIBLE); |
424 |
schedule_timeout(HZ); |
425 |
} while (1); |
426 |
memset(bh, 0, sizeof(*bh)); |
427 |
|
406 |
|
|
|
407 |
bh->b_private = rbh; |
428 |
bh->b_size = rbh->b_size; |
408 |
bh->b_size = rbh->b_size; |
429 |
bh->b_dev = rbh->b_rdev; |
409 |
bh->b_dev = rbh->b_rdev; |
|
|
410 |
bh->b_rdev = lo->lo_device; |
430 |
bh->b_state = (1 << BH_Req) | (1 << BH_Mapped) | (1 << BH_Lock); |
411 |
bh->b_state = (1 << BH_Req) | (1 << BH_Mapped) | (1 << BH_Lock); |
|
|
412 |
bh->b_data = page_address(bh->b_page); |
413 |
bh->b_end_io = (rw == WRITE) ? loop_end_io_transfer_wr : loop_end_io_transfer_rd; |
414 |
bh->b_rsector = rbh->b_rsector + (lo->lo_offset >> 9); |
415 |
init_waitqueue_head(&bh->b_wait); |
431 |
|
416 |
|
432 |
/* |
417 |
return bh; |
433 |
* easy way out, although it does waste some memory for < PAGE_SIZE |
418 |
} |
434 |
* blocks... if highmem bounce buffering can get away with it, |
|
|
435 |
* so can we :-) |
436 |
*/ |
437 |
do { |
438 |
bh->b_page = alloc_page(GFP_NOIO); |
439 |
if (bh->b_page) |
440 |
break; |
441 |
|
419 |
|
442 |
run_task_queue(&tq_disk); |
420 |
#define MAX_DISK_SIZE 1024*1024*1024 |
443 |
set_current_state(TASK_INTERRUPTIBLE); |
|
|
444 |
schedule_timeout(HZ); |
445 |
} while (1); |
446 |
|
421 |
|
447 |
bh->b_data = page_address(bh->b_page); |
422 |
static int compute_loop_size(struct loop_device *lo, struct dentry * lo_dentry, kdev_t lodev) |
448 |
bh->b_end_io = loop_end_io_transfer; |
423 |
{ |
449 |
bh->b_private = rbh; |
424 |
if (S_ISREG(lo_dentry->d_inode->i_mode)) |
450 |
init_waitqueue_head(&bh->b_wait); |
425 |
return (lo_dentry->d_inode->i_size - lo->lo_offset) >> BLOCK_SIZE_BITS; |
|
|
426 |
if (blk_size[MAJOR(lodev)]) |
427 |
return blk_size[MAJOR(lodev)][MINOR(lodev)] - |
428 |
(lo->lo_offset >> BLOCK_SIZE_BITS); |
429 |
return MAX_DISK_SIZE; |
430 |
} |
451 |
|
431 |
|
452 |
out_bh: |
432 |
static void figure_loop_size(struct loop_device *lo) |
453 |
bh->b_rsector = rbh->b_rsector + (lo->lo_offset >> 9); |
433 |
{ |
454 |
spin_lock_irq(&lo->lo_lock); |
434 |
loop_sizes[lo->lo_number] = compute_loop_size(lo, |
455 |
bh->b_rdev = lo->lo_device; |
435 |
lo->lo_backing_file->f_dentry, |
456 |
spin_unlock_irq(&lo->lo_lock); |
436 |
lo->lo_device); |
|
|
437 |
} |
457 |
|
438 |
|
458 |
return bh; |
439 |
static int loop_file_io(struct file *file, char *buf, int size, loff_t *ppos, int w) |
|
|
440 |
{ |
441 |
mm_segment_t fs; |
442 |
int x, y, z; |
443 |
|
444 |
y = 0; |
445 |
do { |
446 |
z = size - y; |
447 |
fs = get_fs(); |
448 |
set_fs(get_ds()); |
449 |
if (w) { |
450 |
x = file->f_op->write(file, buf + y, z, ppos); |
451 |
set_fs(fs); |
452 |
} else { |
453 |
x = file->f_op->read(file, buf + y, z, ppos); |
454 |
set_fs(fs); |
455 |
if (!x) |
456 |
return 1; |
457 |
} |
458 |
if (x < 0) { |
459 |
if ((x == -EAGAIN) || (x == -ENOMEM) || (x == -ERESTART) || (x == -EINTR)) { |
460 |
run_task_queue(&tq_disk); |
461 |
set_current_state(TASK_INTERRUPTIBLE); |
462 |
schedule_timeout(HZ / 2); |
463 |
continue; |
464 |
} |
465 |
return 1; |
466 |
} |
467 |
y += x; |
468 |
} while (y < size); |
469 |
return 0; |
470 |
} |
471 |
|
472 |
static int do_bh_filebacked(struct loop_device *lo, struct buffer_head *bh, int rw) |
473 |
{ |
474 |
loff_t pos; |
475 |
struct file *file = lo->lo_backing_file; |
476 |
char *data, *buf; |
477 |
unsigned int size, len; |
478 |
unsigned long IV; |
479 |
|
480 |
pos = ((loff_t) bh->b_rsector << 9) + lo->lo_offset; |
481 |
buf = page_address(lo->lo_bh_free->b_page); |
482 |
len = bh->b_size; |
483 |
data = bh->b_data; |
484 |
IV = bh->b_rsector + (lo->lo_offset >> 9); |
485 |
while (len > 0) { |
486 |
if (lo->lo_encrypt_type == LO_CRYPT_NONE) { |
487 |
/* this code relies that NONE transfer is a no-op */ |
488 |
buf = data; |
489 |
} |
490 |
size = PAGE_SIZE; |
491 |
if (size > len) |
492 |
size = len; |
493 |
if (rw == WRITE) { |
494 |
if (lo_do_transfer(lo, WRITE, buf, data, size, IV)) { |
495 |
printk(KERN_ERR "loop%d: write transfer error, sector %lu\n", lo->lo_number, IV); |
496 |
return 1; |
497 |
} |
498 |
if (loop_file_io(file, buf, size, &pos, 1)) { |
499 |
printk(KERN_ERR "loop%d: write i/o error, sector %lu\n", lo->lo_number, IV); |
500 |
return 1; |
501 |
} |
502 |
} else { |
503 |
if (loop_file_io(file, buf, size, &pos, 0)) { |
504 |
printk(KERN_ERR "loop%d: read i/o error, sector %lu\n", lo->lo_number, IV); |
505 |
return 1; |
506 |
} |
507 |
if (lo_do_transfer(lo, READ, buf, data, size, IV)) { |
508 |
printk(KERN_ERR "loop%d: read transfer error, sector %lu\n", lo->lo_number, IV); |
509 |
return 1; |
510 |
} |
511 |
} |
512 |
data += size; |
513 |
len -= size; |
514 |
IV += size >> 9; |
515 |
} |
516 |
return 0; |
459 |
} |
517 |
} |
460 |
|
518 |
|
461 |
static int loop_make_request(request_queue_t *q, int rw, struct buffer_head *rbh) |
519 |
static int loop_make_request(request_queue_t *q, int rw, struct buffer_head *rbh) |
462 |
{ |
520 |
{ |
463 |
struct buffer_head *bh = NULL; |
521 |
struct buffer_head *bh; |
464 |
struct loop_device *lo; |
522 |
struct loop_device *lo; |
465 |
unsigned long IV; |
|
|
466 |
|
523 |
|
|
|
524 |
set_current_state(TASK_RUNNING); |
467 |
if (!buffer_locked(rbh)) |
525 |
if (!buffer_locked(rbh)) |
468 |
BUG(); |
526 |
BUG(); |
469 |
|
527 |
|
Lines 483-489
Link Here
|
483 |
} else if (rw == READA) { |
541 |
} else if (rw == READA) { |
484 |
rw = READ; |
542 |
rw = READ; |
485 |
} else if (rw != READ) { |
543 |
} else if (rw != READ) { |
486 |
printk(KERN_ERR "loop: unknown command (%d)\n", rw); |
544 |
printk(KERN_ERR "loop%d: unknown command (%d)\n", lo->lo_number, rw); |
487 |
goto err; |
545 |
goto err; |
488 |
} |
546 |
} |
489 |
|
547 |
|
Lines 493-527
Link Here
|
493 |
* file backed, queue for loop_thread to handle |
551 |
* file backed, queue for loop_thread to handle |
494 |
*/ |
552 |
*/ |
495 |
if (lo->lo_flags & LO_FLAGS_DO_BMAP) { |
553 |
if (lo->lo_flags & LO_FLAGS_DO_BMAP) { |
496 |
/* |
554 |
loop_add_queue_last(lo, rbh, (rw == WRITE) ? &lo->lo_bhQue1 : &lo->lo_bhQue0); |
497 |
* rbh locked at this point, noone else should clear |
555 |
return 0; |
498 |
* the dirty flag |
556 |
} |
499 |
*/ |
557 |
|
500 |
if (rw == WRITE) |
558 |
/* |
501 |
set_bit(BH_Dirty, &rbh->b_state); |
559 |
* device backed, just remap rdev & rsector for NONE transfer |
502 |
loop_add_bh(lo, rbh); |
560 |
*/ |
|
|
561 |
if (lo->lo_encrypt_type == LO_CRYPT_NONE) { |
562 |
rbh->b_rsector += lo->lo_offset >> 9; |
563 |
rbh->b_rdev = lo->lo_device; |
564 |
generic_make_request(rw, rbh); |
565 |
if (atomic_dec_and_test(&lo->lo_pending)) |
566 |
wake_up_interruptible(&lo->lo_bh_wait); |
503 |
return 0; |
567 |
return 0; |
504 |
} |
568 |
} |
505 |
|
569 |
|
506 |
/* |
570 |
/* |
507 |
* piggy old buffer on original, and submit for I/O |
571 |
* device backed, start reads and writes now if buffer available |
508 |
*/ |
572 |
*/ |
509 |
bh = loop_get_buffer(lo, rbh); |
573 |
bh = loop_get_buffer(lo, rbh, 0, rw); |
510 |
IV = loop_get_iv(lo, rbh->b_rsector); |
574 |
if (!bh) { |
|
|
575 |
/* just queue request and let thread handle alloc later */ |
576 |
loop_add_queue_last(lo, rbh, (rw == WRITE) ? &lo->lo_bhQue1 : &lo->lo_bhQue2); |
577 |
return 0; |
578 |
} |
511 |
if (rw == WRITE) { |
579 |
if (rw == WRITE) { |
512 |
set_bit(BH_Dirty, &bh->b_state); |
580 |
if (lo_do_transfer(lo, WRITE, bh->b_data, rbh->b_data, bh->b_size, bh->b_rsector)) { |
513 |
if (lo_do_transfer(lo, WRITE, bh->b_data, rbh->b_data, |
581 |
loop_put_buffer(lo, bh); |
514 |
bh->b_size, IV)) |
|
|
515 |
goto err; |
582 |
goto err; |
|
|
583 |
} |
516 |
} |
584 |
} |
517 |
|
|
|
518 |
generic_make_request(rw, bh); |
585 |
generic_make_request(rw, bh); |
519 |
return 0; |
586 |
return 0; |
520 |
|
587 |
|
521 |
err: |
588 |
err: |
522 |
if (atomic_dec_and_test(&lo->lo_pending)) |
589 |
if (atomic_dec_and_test(&lo->lo_pending)) |
523 |
up(&lo->lo_bh_mutex); |
590 |
wake_up_interruptible(&lo->lo_bh_wait); |
524 |
loop_put_buffer(bh); |
|
|
525 |
out: |
591 |
out: |
526 |
buffer_IO_error(rbh); |
592 |
buffer_IO_error(rbh); |
527 |
return 0; |
593 |
return 0; |
Lines 530-559
Link Here
|
530 |
goto out; |
596 |
goto out; |
531 |
} |
597 |
} |
532 |
|
598 |
|
533 |
static inline void loop_handle_bh(struct loop_device *lo,struct buffer_head *bh) |
|
|
534 |
{ |
535 |
int ret; |
536 |
|
537 |
/* |
538 |
* For block backed loop, we know this is a READ |
539 |
*/ |
540 |
if (lo->lo_flags & LO_FLAGS_DO_BMAP) { |
541 |
int rw = !!test_and_clear_bit(BH_Dirty, &bh->b_state); |
542 |
|
543 |
ret = do_bh_filebacked(lo, bh, rw); |
544 |
bh->b_end_io(bh, !ret); |
545 |
} else { |
546 |
struct buffer_head *rbh = bh->b_private; |
547 |
unsigned long IV = loop_get_iv(lo, rbh->b_rsector); |
548 |
|
549 |
ret = lo_do_transfer(lo, READ, bh->b_data, rbh->b_data, |
550 |
bh->b_size, IV); |
551 |
|
552 |
rbh->b_end_io(rbh, !ret); |
553 |
loop_put_buffer(bh); |
554 |
} |
555 |
} |
556 |
|
557 |
/* |
599 |
/* |
558 |
* worker thread that handles reads/writes to file backed loop devices, |
600 |
* worker thread that handles reads/writes to file backed loop devices, |
559 |
* to avoid blocking in our make_request_fn. it also does loop decrypting |
601 |
* to avoid blocking in our make_request_fn. it also does loop decrypting |
Lines 563-570
Link Here
|
563 |
static int loop_thread(void *data) |
605 |
static int loop_thread(void *data) |
564 |
{ |
606 |
{ |
565 |
struct loop_device *lo = data; |
607 |
struct loop_device *lo = data; |
566 |
struct buffer_head *bh; |
608 |
struct buffer_head *bh, *xbh; |
|
|
609 |
int x, rw, qi = 0, flushcnt = 0; |
610 |
wait_queue_t waitq; |
611 |
que_look_up_table qt[4] = { |
612 |
{ &lo->lo_bhQue0, &lo->lo_bhQue1, &lo->lo_bhQue2, 0, 1, 2 }, |
613 |
{ &lo->lo_bhQue2, &lo->lo_bhQue0, &lo->lo_bhQue1, 2, 0, 1 }, |
614 |
{ &lo->lo_bhQue0, &lo->lo_bhQue2, &lo->lo_bhQue1, 0, 2, 1 }, |
615 |
{ &lo->lo_bhQue1, &lo->lo_bhQue0, &lo->lo_bhQue2, 1, 0, 2 } |
616 |
}; |
617 |
static const struct rlimit loop_rlim_defaults[RLIM_NLIMITS] = INIT_RLIMITS; |
567 |
|
618 |
|
|
|
619 |
init_waitqueue_entry(&waitq, current); |
620 |
memcpy(¤t->rlim[0], &loop_rlim_defaults[0], sizeof(current->rlim)); |
568 |
daemonize(); |
621 |
daemonize(); |
569 |
exit_files(current); |
622 |
exit_files(current); |
570 |
reparent_to_init(); |
623 |
reparent_to_init(); |
Lines 576-581
Link Here
|
576 |
flush_signals(current); |
629 |
flush_signals(current); |
577 |
spin_unlock_irq(¤t->sigmask_lock); |
630 |
spin_unlock_irq(¤t->sigmask_lock); |
578 |
|
631 |
|
|
|
632 |
if (lo_nice > 0) |
633 |
lo_nice = 0; |
634 |
if (lo_nice < -20) |
635 |
lo_nice = -20; |
636 |
#if defined(DEF_NICE) && defined(DEF_COUNTER) |
637 |
/* old scheduler syntax */ |
638 |
current->policy = SCHED_OTHER; |
639 |
current->nice = lo_nice; |
640 |
#else |
641 |
/* O(1) scheduler syntax */ |
642 |
set_user_nice(current, lo_nice); |
643 |
#endif |
644 |
|
579 |
spin_lock_irq(&lo->lo_lock); |
645 |
spin_lock_irq(&lo->lo_lock); |
580 |
lo->lo_state = Lo_bound; |
646 |
lo->lo_state = Lo_bound; |
581 |
atomic_inc(&lo->lo_pending); |
647 |
atomic_inc(&lo->lo_pending); |
Lines 589-611
Link Here
|
589 |
up(&lo->lo_sem); |
655 |
up(&lo->lo_sem); |
590 |
|
656 |
|
591 |
for (;;) { |
657 |
for (;;) { |
592 |
down_interruptible(&lo->lo_bh_mutex); |
658 |
add_wait_queue(&lo->lo_bh_wait, &waitq); |
|
|
659 |
for (;;) { |
660 |
set_current_state(TASK_INTERRUPTIBLE); |
661 |
if (!atomic_read(&lo->lo_pending)) |
662 |
break; |
663 |
|
664 |
x = 0; |
665 |
spin_lock_irq(&lo->lo_lock); |
666 |
if (lo->lo_bhQue0) { |
667 |
x = 1; |
668 |
} else if (lo->lo_bhQue1 || lo->lo_bhQue2) { |
669 |
/* file backed works too because lo->lo_bh_need == 0 */ |
670 |
if (lo->lo_bh_free || !lo->lo_bh_need) |
671 |
x = 1; |
672 |
} |
673 |
spin_unlock_irq(&lo->lo_lock); |
674 |
if (x) |
675 |
break; |
676 |
|
677 |
schedule(); |
678 |
} |
679 |
set_current_state(TASK_RUNNING); |
680 |
remove_wait_queue(&lo->lo_bh_wait, &waitq); |
681 |
|
593 |
/* |
682 |
/* |
594 |
* could be upped because of tear-down, not because of |
683 |
* could be woken because of tear-down, not because of |
595 |
* pending work |
684 |
* pending work |
596 |
*/ |
685 |
*/ |
597 |
if (!atomic_read(&lo->lo_pending)) |
686 |
if (!atomic_read(&lo->lo_pending)) |
598 |
break; |
687 |
break; |
599 |
|
688 |
|
600 |
bh = loop_get_bh(lo); |
689 |
/* |
601 |
if (!bh) { |
690 |
* read queues using alternating order to prevent starvation |
602 |
printk("loop: missing bh\n"); |
691 |
*/ |
|
|
692 |
bh = loop_get_bh(lo, &x, &qt[++qi & 3]); |
693 |
if (!bh) |
603 |
continue; |
694 |
continue; |
|
|
695 |
|
696 |
/* |
697 |
* x list tag usage(buffer-allocated) |
698 |
* --- ------------- ----------------------- |
699 |
* 0 lo->lo_bhQue0 dev-read(y) / file-read |
700 |
* 1 lo->lo_bhQue1 dev-write(n) / file-write |
701 |
* 2 lo->lo_bhQue2 dev-read(n) |
702 |
*/ |
703 |
rw = (x == 1) ? WRITE : READ; |
704 |
if ((x >= 1) && !(lo->lo_flags & LO_FLAGS_DO_BMAP)) { |
705 |
/* loop_make_request didn't allocate a buffer, do that now */ |
706 |
xbh = loop_get_buffer(lo, bh, 1, rw); |
707 |
if (!xbh) { |
708 |
run_task_queue(&tq_disk); |
709 |
flushcnt = 0; |
710 |
loop_add_queue_first(lo, bh, (rw == WRITE) ? &lo->lo_bhQue1 : &lo->lo_bhQue2); |
711 |
/* lo->lo_bh_need should be 1 now, go back to sleep */ |
712 |
continue; |
713 |
} |
714 |
if (rw == WRITE) { |
715 |
if (lo_do_transfer(lo, WRITE, xbh->b_data, bh->b_data, xbh->b_size, xbh->b_rsector)) { |
716 |
loop_put_buffer(lo, xbh); |
717 |
buffer_IO_error(bh); |
718 |
atomic_dec(&lo->lo_pending); |
719 |
continue; |
720 |
} |
721 |
} |
722 |
generic_make_request(rw, xbh); |
723 |
|
724 |
/* start I/O if there are no more requests lacking buffers */ |
725 |
x = 0; |
726 |
spin_lock_irq(&lo->lo_lock); |
727 |
if (!lo->lo_bhQue1 && !lo->lo_bhQue2) |
728 |
x = 1; |
729 |
spin_unlock_irq(&lo->lo_lock); |
730 |
if (x || (++flushcnt >= lo->lo_bh_flsh)) { |
731 |
run_task_queue(&tq_disk); |
732 |
flushcnt = 0; |
733 |
} |
734 |
|
735 |
/* request not completely processed yet */ |
736 |
continue; |
737 |
} |
738 |
if (lo->lo_flags & LO_FLAGS_DO_BMAP) { |
739 |
/* request is for file backed device */ |
740 |
x = do_bh_filebacked(lo, bh, rw); |
741 |
bh->b_reqnext = NULL; |
742 |
bh->b_end_io(bh, !x); |
743 |
} else { |
744 |
/* device backed read has completed, do decrypt now */ |
745 |
xbh = bh->b_private; |
746 |
/* must not use bh->b_rsector as IV, as it may be modified by LVM at this point */ |
747 |
/* instead, recompute IV from original request */ |
748 |
x = lo_do_transfer(lo, READ, bh->b_data, xbh->b_data, bh->b_size, xbh->b_rsector + (lo->lo_offset >> 9)); |
749 |
xbh->b_reqnext = NULL; |
750 |
xbh->b_end_io(xbh, !x); |
751 |
loop_put_buffer(lo, bh); |
604 |
} |
752 |
} |
605 |
loop_handle_bh(lo, bh); |
|
|
606 |
|
753 |
|
607 |
/* |
754 |
/* |
608 |
* upped both for pending work and tear-down, lo_pending |
755 |
* woken both for pending work and tear-down, lo_pending |
609 |
* will hit zero then |
756 |
* will hit zero then |
610 |
*/ |
757 |
*/ |
611 |
if (atomic_dec_and_test(&lo->lo_pending)) |
758 |
if (atomic_dec_and_test(&lo->lo_pending)) |
Lines 616-630
Link Here
|
616 |
return 0; |
763 |
return 0; |
617 |
} |
764 |
} |
618 |
|
765 |
|
|
|
766 |
static void loop_set_softblksz(struct loop_device *lo, kdev_t dev) |
767 |
{ |
768 |
int bs = 0, x; |
769 |
|
770 |
if (blksize_size[MAJOR(lo->lo_device)]) |
771 |
bs = blksize_size[MAJOR(lo->lo_device)][MINOR(lo->lo_device)]; |
772 |
if (!bs) |
773 |
bs = BLOCK_SIZE; |
774 |
if (lo->lo_flags & LO_FLAGS_DO_BMAP) { |
775 |
x = loop_sizes[lo->lo_number]; |
776 |
if ((bs == 8192) && (x & 7)) |
777 |
bs = 4096; |
778 |
if ((bs == 4096) && (x & 3)) |
779 |
bs = 2048; |
780 |
if ((bs == 2048) && (x & 1)) |
781 |
bs = 1024; |
782 |
} |
783 |
set_blocksize(dev, bs); |
784 |
} |
785 |
|
619 |
static int loop_set_fd(struct loop_device *lo, struct file *lo_file, kdev_t dev, |
786 |
static int loop_set_fd(struct loop_device *lo, struct file *lo_file, kdev_t dev, |
620 |
unsigned int arg) |
787 |
unsigned int arg) |
621 |
{ |
788 |
{ |
622 |
struct file *file; |
789 |
struct file *file; |
623 |
struct inode *inode; |
790 |
struct inode *inode; |
624 |
kdev_t lo_device; |
791 |
kdev_t lo_device; |
625 |
int lo_flags = 0; |
792 |
int lo_flags = 0, hardsz = 512; |
626 |
int error; |
793 |
int error; |
627 |
int bs; |
|
|
628 |
|
794 |
|
629 |
MOD_INC_USE_COUNT; |
795 |
MOD_INC_USE_COUNT; |
630 |
|
796 |
|
Lines 643-675
Link Here
|
643 |
if (!(file->f_mode & FMODE_WRITE)) |
809 |
if (!(file->f_mode & FMODE_WRITE)) |
644 |
lo_flags |= LO_FLAGS_READ_ONLY; |
810 |
lo_flags |= LO_FLAGS_READ_ONLY; |
645 |
|
811 |
|
|
|
812 |
lo->lo_bh_free = lo->lo_bhQue2 = lo->lo_bhQue1 = lo->lo_bhQue0 = NULL; |
813 |
lo->lo_bh_need = lo->lo_bh_flsh = 0; |
814 |
init_waitqueue_head(&lo->lo_bh_wait); |
646 |
if (S_ISBLK(inode->i_mode)) { |
815 |
if (S_ISBLK(inode->i_mode)) { |
647 |
lo_device = inode->i_rdev; |
816 |
lo_device = inode->i_rdev; |
648 |
if (lo_device == dev) { |
817 |
if (lo_device == dev) { |
649 |
error = -EBUSY; |
818 |
error = -EBUSY; |
650 |
goto out_putf; |
819 |
goto out_putf; |
651 |
} |
820 |
} |
|
|
821 |
if (loop_prealloc_init(lo, 0)) { |
822 |
error = -ENOMEM; |
823 |
goto out_putf; |
824 |
} |
825 |
hardsz = get_hardsect_size(lo_device); |
652 |
} else if (S_ISREG(inode->i_mode)) { |
826 |
} else if (S_ISREG(inode->i_mode)) { |
653 |
struct address_space_operations *aops = inode->i_mapping->a_ops; |
|
|
654 |
/* |
827 |
/* |
655 |
* If we can't read - sorry. If we only can't write - well, |
828 |
* If we can't read - sorry. If we only can't write - well, |
656 |
* it's going to be read-only. |
829 |
* it's going to be read-only. |
657 |
*/ |
830 |
*/ |
658 |
if (!aops->readpage) |
831 |
if (!file->f_op || !file->f_op->read) |
659 |
goto out_putf; |
832 |
goto out_putf; |
660 |
|
833 |
|
661 |
if (!aops->prepare_write || !aops->commit_write) |
834 |
if (!file->f_op->write) |
662 |
lo_flags |= LO_FLAGS_READ_ONLY; |
835 |
lo_flags |= LO_FLAGS_READ_ONLY; |
663 |
|
836 |
|
664 |
lo_device = inode->i_dev; |
837 |
lo_device = inode->i_dev; |
665 |
lo_flags |= LO_FLAGS_DO_BMAP; |
838 |
lo_flags |= LO_FLAGS_DO_BMAP; |
|
|
839 |
if (loop_prealloc_init(lo, 1)) { |
840 |
error = -ENOMEM; |
841 |
goto out_putf; |
842 |
} |
666 |
error = 0; |
843 |
error = 0; |
667 |
} else |
844 |
} else |
668 |
goto out_putf; |
845 |
goto out_putf; |
669 |
|
846 |
|
670 |
get_file(file); |
847 |
get_file(file); |
671 |
|
848 |
|
672 |
if (IS_RDONLY (inode) || is_read_only(lo_device) |
849 |
if ((S_ISREG(inode->i_mode) && IS_RDONLY(inode)) || is_read_only(lo_device) |
673 |
|| !(lo_file->f_mode & FMODE_WRITE)) |
850 |
|| !(lo_file->f_mode & FMODE_WRITE)) |
674 |
lo_flags |= LO_FLAGS_READ_ONLY; |
851 |
lo_flags |= LO_FLAGS_READ_ONLY; |
675 |
|
852 |
|
Lines 681-698
Link Here
|
681 |
lo->transfer = NULL; |
858 |
lo->transfer = NULL; |
682 |
lo->ioctl = NULL; |
859 |
lo->ioctl = NULL; |
683 |
figure_loop_size(lo); |
860 |
figure_loop_size(lo); |
684 |
lo->old_gfp_mask = inode->i_mapping->gfp_mask; |
|
|
685 |
inode->i_mapping->gfp_mask &= ~(__GFP_IO|__GFP_FS); |
686 |
|
861 |
|
687 |
bs = 0; |
862 |
if (lo_flags & LO_FLAGS_DO_BMAP) { |
688 |
if (blksize_size[MAJOR(lo_device)]) |
863 |
lo->old_gfp_mask = inode->i_mapping->gfp_mask; |
689 |
bs = blksize_size[MAJOR(lo_device)][MINOR(lo_device)]; |
864 |
inode->i_mapping->gfp_mask = GFP_NOIO | __GFP_HIGH; |
690 |
if (!bs) |
865 |
} else { |
691 |
bs = BLOCK_SIZE; |
866 |
lo->old_gfp_mask = -1; |
|
|
867 |
} |
692 |
|
868 |
|
693 |
set_blocksize(dev, bs); |
869 |
loop_hardsizes[MINOR(dev)] = hardsz; |
|
|
870 |
loop_set_softblksz(lo, dev); |
694 |
|
871 |
|
695 |
lo->lo_bh = lo->lo_bhtail = NULL; |
|
|
696 |
kernel_thread(loop_thread, lo, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); |
872 |
kernel_thread(loop_thread, lo, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); |
697 |
down(&lo->lo_sem); |
873 |
down(&lo->lo_sem); |
698 |
|
874 |
|
Lines 751-761
Link Here
|
751 |
spin_lock_irq(&lo->lo_lock); |
927 |
spin_lock_irq(&lo->lo_lock); |
752 |
lo->lo_state = Lo_rundown; |
928 |
lo->lo_state = Lo_rundown; |
753 |
if (atomic_dec_and_test(&lo->lo_pending)) |
929 |
if (atomic_dec_and_test(&lo->lo_pending)) |
754 |
up(&lo->lo_bh_mutex); |
930 |
wake_up_interruptible(&lo->lo_bh_wait); |
755 |
spin_unlock_irq(&lo->lo_lock); |
931 |
spin_unlock_irq(&lo->lo_lock); |
756 |
|
932 |
|
757 |
down(&lo->lo_sem); |
933 |
down(&lo->lo_sem); |
758 |
|
934 |
|
|
|
935 |
loop_prealloc_cleanup(lo); |
759 |
lo->lo_backing_file = NULL; |
936 |
lo->lo_backing_file = NULL; |
760 |
|
937 |
|
761 |
loop_release_xfer(lo); |
938 |
loop_release_xfer(lo); |
Lines 770-783
Link Here
|
770 |
memset(lo->lo_name, 0, LO_NAME_SIZE); |
947 |
memset(lo->lo_name, 0, LO_NAME_SIZE); |
771 |
loop_sizes[lo->lo_number] = 0; |
948 |
loop_sizes[lo->lo_number] = 0; |
772 |
invalidate_bdev(bdev, 0); |
949 |
invalidate_bdev(bdev, 0); |
773 |
filp->f_dentry->d_inode->i_mapping->gfp_mask = gfp; |
950 |
if (gfp != -1) |
|
|
951 |
filp->f_dentry->d_inode->i_mapping->gfp_mask = gfp; |
774 |
lo->lo_state = Lo_unbound; |
952 |
lo->lo_state = Lo_unbound; |
775 |
fput(filp); |
953 |
fput(filp); |
776 |
MOD_DEC_USE_COUNT; |
954 |
MOD_DEC_USE_COUNT; |
777 |
return 0; |
955 |
return 0; |
778 |
} |
956 |
} |
779 |
|
957 |
|
780 |
static int loop_set_status(struct loop_device *lo, struct loop_info *arg) |
958 |
static int loop_set_status(struct loop_device *lo, kdev_t dev, struct loop_info *arg) |
781 |
{ |
959 |
{ |
782 |
struct loop_info info; |
960 |
struct loop_info info; |
783 |
int err; |
961 |
int err; |
Lines 817-822
Link Here
|
817 |
lo->lo_key_owner = current->uid; |
995 |
lo->lo_key_owner = current->uid; |
818 |
} |
996 |
} |
819 |
figure_loop_size(lo); |
997 |
figure_loop_size(lo); |
|
|
998 |
loop_set_softblksz(lo, dev); |
820 |
return 0; |
999 |
return 0; |
821 |
} |
1000 |
} |
822 |
|
1001 |
|
Lines 872-878
Link Here
|
872 |
err = loop_clr_fd(lo, inode->i_bdev); |
1051 |
err = loop_clr_fd(lo, inode->i_bdev); |
873 |
break; |
1052 |
break; |
874 |
case LOOP_SET_STATUS: |
1053 |
case LOOP_SET_STATUS: |
875 |
err = loop_set_status(lo, (struct loop_info *) arg); |
1054 |
err = loop_set_status(lo, inode->i_rdev, (struct loop_info *) arg); |
876 |
break; |
1055 |
break; |
877 |
case LOOP_GET_STATUS: |
1056 |
case LOOP_GET_STATUS: |
878 |
err = loop_get_status(lo, (struct loop_info *) arg); |
1057 |
err = loop_get_status(lo, (struct loop_info *) arg); |
Lines 906-912
Link Here
|
906 |
static int lo_open(struct inode *inode, struct file *file) |
1085 |
static int lo_open(struct inode *inode, struct file *file) |
907 |
{ |
1086 |
{ |
908 |
struct loop_device *lo; |
1087 |
struct loop_device *lo; |
909 |
int dev, type; |
1088 |
int dev; |
910 |
|
1089 |
|
911 |
if (!inode) |
1090 |
if (!inode) |
912 |
return -EINVAL; |
1091 |
return -EINVAL; |
Lines 921-930
Link Here
|
921 |
lo = &loop_dev[dev]; |
1100 |
lo = &loop_dev[dev]; |
922 |
MOD_INC_USE_COUNT; |
1101 |
MOD_INC_USE_COUNT; |
923 |
down(&lo->lo_ctl_mutex); |
1102 |
down(&lo->lo_ctl_mutex); |
924 |
|
|
|
925 |
type = lo->lo_encrypt_type; |
926 |
if (type && xfer_funcs[type] && xfer_funcs[type]->lock) |
927 |
xfer_funcs[type]->lock(lo); |
928 |
lo->lo_refcnt++; |
1103 |
lo->lo_refcnt++; |
929 |
up(&lo->lo_ctl_mutex); |
1104 |
up(&lo->lo_ctl_mutex); |
930 |
return 0; |
1105 |
return 0; |
Lines 933-939
Link Here
|
933 |
static int lo_release(struct inode *inode, struct file *file) |
1108 |
static int lo_release(struct inode *inode, struct file *file) |
934 |
{ |
1109 |
{ |
935 |
struct loop_device *lo; |
1110 |
struct loop_device *lo; |
936 |
int dev, type; |
1111 |
int dev; |
937 |
|
1112 |
|
938 |
if (!inode) |
1113 |
if (!inode) |
939 |
return 0; |
1114 |
return 0; |
Lines 948-958
Link Here
|
948 |
|
1123 |
|
949 |
lo = &loop_dev[dev]; |
1124 |
lo = &loop_dev[dev]; |
950 |
down(&lo->lo_ctl_mutex); |
1125 |
down(&lo->lo_ctl_mutex); |
951 |
type = lo->lo_encrypt_type; |
|
|
952 |
--lo->lo_refcnt; |
1126 |
--lo->lo_refcnt; |
953 |
if (xfer_funcs[type] && xfer_funcs[type]->unlock) |
|
|
954 |
xfer_funcs[type]->unlock(lo); |
955 |
|
956 |
up(&lo->lo_ctl_mutex); |
1127 |
up(&lo->lo_ctl_mutex); |
957 |
MOD_DEC_USE_COUNT; |
1128 |
MOD_DEC_USE_COUNT; |
958 |
return 0; |
1129 |
return 0; |
Lines 974-980
Link Here
|
974 |
|
1145 |
|
975 |
int loop_register_transfer(struct loop_func_table *funcs) |
1146 |
int loop_register_transfer(struct loop_func_table *funcs) |
976 |
{ |
1147 |
{ |
977 |
if ((unsigned)funcs->number > MAX_LO_CRYPT || xfer_funcs[funcs->number]) |
1148 |
if ((unsigned)funcs->number >= MAX_LO_CRYPT || xfer_funcs[funcs->number]) |
978 |
return -EINVAL; |
1149 |
return -EINVAL; |
979 |
xfer_funcs[funcs->number] = funcs; |
1150 |
xfer_funcs[funcs->number] = funcs; |
980 |
return 0; |
1151 |
return 0; |
Lines 1017-1026
Link Here
|
1017 |
return -EIO; |
1188 |
return -EIO; |
1018 |
} |
1189 |
} |
1019 |
|
1190 |
|
1020 |
|
|
|
1021 |
loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL); |
1191 |
loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL); |
1022 |
if (!loop_dev) |
1192 |
if (!loop_dev) |
1023 |
return -ENOMEM; |
1193 |
goto out_dev; |
1024 |
|
1194 |
|
1025 |
loop_sizes = kmalloc(max_loop * sizeof(int), GFP_KERNEL); |
1195 |
loop_sizes = kmalloc(max_loop * sizeof(int), GFP_KERNEL); |
1026 |
if (!loop_sizes) |
1196 |
if (!loop_sizes) |
Lines 1030-1035
Link Here
|
1030 |
if (!loop_blksizes) |
1200 |
if (!loop_blksizes) |
1031 |
goto out_blksizes; |
1201 |
goto out_blksizes; |
1032 |
|
1202 |
|
|
|
1203 |
loop_hardsizes = kmalloc(max_loop * sizeof(int), GFP_KERNEL); |
1204 |
if (!loop_hardsizes) |
1205 |
goto out_hardsizes; |
1206 |
|
1033 |
blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), loop_make_request); |
1207 |
blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), loop_make_request); |
1034 |
|
1208 |
|
1035 |
for (i = 0; i < max_loop; i++) { |
1209 |
for (i = 0; i < max_loop; i++) { |
Lines 1037-1054
Link Here
|
1037 |
memset(lo, 0, sizeof(struct loop_device)); |
1211 |
memset(lo, 0, sizeof(struct loop_device)); |
1038 |
init_MUTEX(&lo->lo_ctl_mutex); |
1212 |
init_MUTEX(&lo->lo_ctl_mutex); |
1039 |
init_MUTEX_LOCKED(&lo->lo_sem); |
1213 |
init_MUTEX_LOCKED(&lo->lo_sem); |
1040 |
init_MUTEX_LOCKED(&lo->lo_bh_mutex); |
|
|
1041 |
lo->lo_number = i; |
1214 |
lo->lo_number = i; |
1042 |
spin_lock_init(&lo->lo_lock); |
1215 |
spin_lock_init(&lo->lo_lock); |
1043 |
} |
1216 |
} |
1044 |
|
1217 |
|
1045 |
memset(loop_sizes, 0, max_loop * sizeof(int)); |
1218 |
memset(loop_sizes, 0, max_loop * sizeof(int)); |
1046 |
memset(loop_blksizes, 0, max_loop * sizeof(int)); |
1219 |
memset(loop_blksizes, 0, max_loop * sizeof(int)); |
|
|
1220 |
memset(loop_hardsizes, 0, max_loop * sizeof(int)); |
1047 |
blk_size[MAJOR_NR] = loop_sizes; |
1221 |
blk_size[MAJOR_NR] = loop_sizes; |
1048 |
blksize_size[MAJOR_NR] = loop_blksizes; |
1222 |
blksize_size[MAJOR_NR] = loop_blksizes; |
|
|
1223 |
hardsect_size[MAJOR_NR] = loop_hardsizes; |
1049 |
for (i = 0; i < max_loop; i++) |
1224 |
for (i = 0; i < max_loop; i++) |
1050 |
register_disk(NULL, MKDEV(MAJOR_NR, i), 1, &lo_fops, 0); |
1225 |
register_disk(NULL, MKDEV(MAJOR_NR, i), 1, &lo_fops, 0); |
1051 |
|
1226 |
|
|
|
1227 |
for (i = 0; i < (sizeof(lo_prealloc) / sizeof(int)); i += 2) { |
1228 |
if (!lo_prealloc[i]) |
1229 |
continue; |
1230 |
if (lo_prealloc[i] < LO_PREALLOC_MIN) |
1231 |
lo_prealloc[i] = LO_PREALLOC_MIN; |
1232 |
if (lo_prealloc[i] > LO_PREALLOC_MAX) |
1233 |
lo_prealloc[i] = LO_PREALLOC_MAX; |
1234 |
} |
1235 |
|
1052 |
devfs_handle = devfs_mk_dir(NULL, "loop", NULL); |
1236 |
devfs_handle = devfs_mk_dir(NULL, "loop", NULL); |
1053 |
devfs_register_series(devfs_handle, "%u", max_loop, DEVFS_FL_DEFAULT, |
1237 |
devfs_register_series(devfs_handle, "%u", max_loop, DEVFS_FL_DEFAULT, |
1054 |
MAJOR_NR, 0, |
1238 |
MAJOR_NR, 0, |
Lines 1058-1067
Link Here
|
1058 |
printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop); |
1242 |
printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop); |
1059 |
return 0; |
1243 |
return 0; |
1060 |
|
1244 |
|
|
|
1245 |
out_hardsizes: |
1246 |
kfree(loop_blksizes); |
1061 |
out_blksizes: |
1247 |
out_blksizes: |
1062 |
kfree(loop_sizes); |
1248 |
kfree(loop_sizes); |
1063 |
out_sizes: |
1249 |
out_sizes: |
1064 |
kfree(loop_dev); |
1250 |
kfree(loop_dev); |
|
|
1251 |
out_dev: |
1065 |
if (devfs_unregister_blkdev(MAJOR_NR, "loop")) |
1252 |
if (devfs_unregister_blkdev(MAJOR_NR, "loop")) |
1066 |
printk(KERN_WARNING "loop: cannot unregister blkdev\n"); |
1253 |
printk(KERN_WARNING "loop: cannot unregister blkdev\n"); |
1067 |
printk(KERN_ERR "loop: ran out of memory\n"); |
1254 |
printk(KERN_ERR "loop: ran out of memory\n"); |
Lines 1073-1081
Link Here
|
1073 |
devfs_unregister(devfs_handle); |
1260 |
devfs_unregister(devfs_handle); |
1074 |
if (devfs_unregister_blkdev(MAJOR_NR, "loop")) |
1261 |
if (devfs_unregister_blkdev(MAJOR_NR, "loop")) |
1075 |
printk(KERN_WARNING "loop: cannot unregister blkdev\n"); |
1262 |
printk(KERN_WARNING "loop: cannot unregister blkdev\n"); |
|
|
1263 |
|
1264 |
blk_size[MAJOR_NR] = 0; |
1265 |
blksize_size[MAJOR_NR] = 0; |
1266 |
hardsect_size[MAJOR_NR] = 0; |
1076 |
kfree(loop_dev); |
1267 |
kfree(loop_dev); |
1077 |
kfree(loop_sizes); |
1268 |
kfree(loop_sizes); |
1078 |
kfree(loop_blksizes); |
1269 |
kfree(loop_blksizes); |
|
|
1270 |
kfree(loop_hardsizes); |
1079 |
} |
1271 |
} |
1080 |
|
1272 |
|
1081 |
module_init(loop_init); |
1273 |
module_init(loop_init); |