Contents of /trunk/kernel26-magellan/patches-2.6.21-r10/0158-2.6.21.7-fuse-2.7.0.patch
Parent Directory | Revision Log
Revision 302 -
(show annotations)
(download)
Fri Aug 17 22:52:55 2007 UTC (16 years, 8 months ago) by niro
File size: 23428 byte(s)
Fri Aug 17 22:52:55 2007 UTC (16 years, 8 months ago) by niro
File size: 23428 byte(s)
-2.6.21-magellan-r10
1 | diff -Naur linux-2.6.21/fs/fuse/control.c linux-2.6.21-magellan-r10/fs/fuse/control.c |
2 | --- linux-2.6.21/fs/fuse/control.c 2007-04-26 05:08:32.000000000 +0200 |
3 | +++ linux-2.6.21-magellan-r10/fs/fuse/control.c 2007-08-17 13:33:29.000000000 +0200 |
4 | @@ -1,6 +1,6 @@ |
5 | /* |
6 | FUSE: Filesystem in Userspace |
7 | - Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> |
8 | + Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> |
9 | |
10 | This program can be distributed under the terms of the GNU GPL. |
11 | See the file COPYING. |
12 | @@ -23,7 +23,7 @@ |
13 | { |
14 | struct fuse_conn *fc; |
15 | mutex_lock(&fuse_mutex); |
16 | - fc = file->f_path.dentry->d_inode->i_private; |
17 | + fc = file->f_dentry->d_inode->i_private; |
18 | if (fc) |
19 | fc = fuse_conn_get(fc); |
20 | mutex_unlock(&fuse_mutex); |
21 | @@ -59,12 +59,12 @@ |
22 | return simple_read_from_buffer(buf, len, ppos, tmp, size); |
23 | } |
24 | |
25 | -static const struct file_operations fuse_ctl_abort_ops = { |
26 | +static struct file_operations fuse_ctl_abort_ops = { |
27 | .open = nonseekable_open, |
28 | .write = fuse_conn_abort_write, |
29 | }; |
30 | |
31 | -static const struct file_operations fuse_ctl_waiting_ops = { |
32 | +static struct file_operations fuse_ctl_waiting_ops = { |
33 | .open = nonseekable_open, |
34 | .read = fuse_conn_waiting_read, |
35 | }; |
36 | @@ -74,7 +74,8 @@ |
37 | const char *name, |
38 | int mode, int nlink, |
39 | const struct inode_operations *iop, |
40 | - const struct file_operations *fop) |
41 | + const struct file_operations *fop |
42 | +) |
43 | { |
44 | struct dentry *dentry; |
45 | struct inode *inode; |
46 | diff -Naur linux-2.6.21/fs/fuse/dev.c linux-2.6.21-magellan-r10/fs/fuse/dev.c |
47 | --- linux-2.6.21/fs/fuse/dev.c 2007-04-26 05:08:32.000000000 +0200 |
48 | +++ linux-2.6.21-magellan-r10/fs/fuse/dev.c 2007-08-17 13:33:29.000000000 +0200 |
49 | @@ -1,6 +1,6 @@ |
50 | /* |
51 | FUSE: Filesystem in Userspace |
52 | - Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> |
53 | + Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> |
54 | |
55 | This program can be distributed under the terms of the GNU GPL. |
56 | See the file COPYING. |
57 | @@ -17,7 +17,9 @@ |
58 | #include <linux/file.h> |
59 | #include <linux/slab.h> |
60 | |
61 | +#ifdef MODULE_ALIAS_MISCDEV |
62 | MODULE_ALIAS_MISCDEV(FUSE_MINOR); |
63 | +#endif |
64 | |
65 | static struct kmem_cache *fuse_req_cachep; |
66 | |
67 | @@ -212,7 +214,6 @@ |
68 | * Called with fc->lock, unlocks it |
69 | */ |
70 | static void request_end(struct fuse_conn *fc, struct fuse_req *req) |
71 | - __releases(fc->lock) |
72 | { |
73 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; |
74 | req->end = NULL; |
75 | @@ -482,6 +483,9 @@ |
76 | { |
77 | unsigned long offset; |
78 | int err; |
79 | +#ifdef DCACHE_BUG |
80 | + struct vm_area_struct *vma; |
81 | +#endif |
82 | |
83 | unlock_request(cs->fc, cs->req); |
84 | fuse_copy_finish(cs); |
85 | @@ -493,14 +497,22 @@ |
86 | cs->nr_segs --; |
87 | } |
88 | down_read(¤t->mm->mmap_sem); |
89 | +#ifndef DCACHE_BUG |
90 | err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0, |
91 | &cs->pg, NULL); |
92 | +#else |
93 | + err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0, |
94 | + &cs->pg, &vma); |
95 | +#endif |
96 | up_read(¤t->mm->mmap_sem); |
97 | if (err < 0) |
98 | return err; |
99 | BUG_ON(err != 1); |
100 | offset = cs->addr % PAGE_SIZE; |
101 | cs->mapaddr = kmap_atomic(cs->pg, KM_USER0); |
102 | +#ifdef DCACHE_BUG |
103 | + flush_cache_page(vma, cs->addr, page_to_pfn(cs->pg)); |
104 | +#endif |
105 | cs->buf = cs->mapaddr + offset; |
106 | cs->len = min(PAGE_SIZE - offset, cs->seglen); |
107 | cs->seglen -= cs->len; |
108 | @@ -641,7 +653,6 @@ |
109 | */ |
110 | static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req, |
111 | const struct iovec *iov, unsigned long nr_segs) |
112 | - __releases(fc->lock) |
113 | { |
114 | struct fuse_copy_state cs; |
115 | struct fuse_in_header ih; |
116 | @@ -680,15 +691,14 @@ |
117 | * request_end(). Otherwise add it to the processing list, and set |
118 | * the 'sent' flag. |
119 | */ |
120 | -static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov, |
121 | - unsigned long nr_segs, loff_t pos) |
122 | +static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov, |
123 | + unsigned long nr_segs, loff_t *off) |
124 | { |
125 | int err; |
126 | struct fuse_req *req; |
127 | struct fuse_in *in; |
128 | struct fuse_copy_state cs; |
129 | unsigned reqsize; |
130 | - struct file *file = iocb->ki_filp; |
131 | struct fuse_conn *fc = fuse_get_conn(file); |
132 | if (!fc) |
133 | return -EPERM; |
134 | @@ -762,6 +772,12 @@ |
135 | return err; |
136 | } |
137 | |
138 | +static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov, |
139 | + unsigned long nr_segs, loff_t pos) |
140 | +{ |
141 | + return fuse_dev_readv(iocb->ki_filp, iov, nr_segs, &pos); |
142 | +} |
143 | + |
144 | /* Look up request on processing list by unique ID */ |
145 | static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) |
146 | { |
147 | @@ -806,15 +822,15 @@ |
148 | * it from the list and copy the rest of the buffer to the request. |
149 | * The request is finished by calling request_end() |
150 | */ |
151 | -static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov, |
152 | - unsigned long nr_segs, loff_t pos) |
153 | +static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov, |
154 | + unsigned long nr_segs, loff_t *off) |
155 | { |
156 | int err; |
157 | unsigned nbytes = iov_length(iov, nr_segs); |
158 | struct fuse_req *req; |
159 | struct fuse_out_header oh; |
160 | struct fuse_copy_state cs; |
161 | - struct fuse_conn *fc = fuse_get_conn(iocb->ki_filp); |
162 | + struct fuse_conn *fc = fuse_get_conn(file); |
163 | if (!fc) |
164 | return -EPERM; |
165 | |
166 | @@ -890,6 +906,12 @@ |
167 | return err; |
168 | } |
169 | |
170 | +static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov, |
171 | + unsigned long nr_segs, loff_t pos) |
172 | +{ |
173 | + return fuse_dev_writev(iocb->ki_filp, iov, nr_segs, &pos); |
174 | +} |
175 | + |
176 | static unsigned fuse_dev_poll(struct file *file, poll_table *wait) |
177 | { |
178 | unsigned mask = POLLOUT | POLLWRNORM; |
179 | @@ -1021,7 +1043,7 @@ |
180 | return fasync_helper(fd, file, on, &fc->fasync); |
181 | } |
182 | |
183 | -const struct file_operations fuse_dev_operations = { |
184 | +struct file_operations fuse_dev_operations = { |
185 | .owner = THIS_MODULE, |
186 | .llseek = no_llseek, |
187 | .read = do_sync_read, |
188 | diff -Naur linux-2.6.21/fs/fuse/dir.c linux-2.6.21-magellan-r10/fs/fuse/dir.c |
189 | --- linux-2.6.21/fs/fuse/dir.c 2007-08-17 13:35:59.000000000 +0200 |
190 | +++ linux-2.6.21-magellan-r10/fs/fuse/dir.c 2007-08-17 13:33:29.000000000 +0200 |
191 | @@ -1,6 +1,6 @@ |
192 | /* |
193 | FUSE: Filesystem in Userspace |
194 | - Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> |
195 | + Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> |
196 | |
197 | This program can be distributed under the terms of the GNU GPL. |
198 | See the file COPYING. |
199 | @@ -205,18 +205,19 @@ |
200 | * Add a directory inode to a dentry, ensuring that no other dentry |
201 | * refers to this inode. Called with fc->inst_mutex. |
202 | */ |
203 | -static int fuse_d_add_directory(struct dentry *entry, struct inode *inode) |
204 | +static struct dentry *fuse_d_add_directory(struct dentry *entry, |
205 | + struct inode *inode) |
206 | { |
207 | struct dentry *alias = d_find_alias(inode); |
208 | - if (alias) { |
209 | + if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) { |
210 | /* This tries to shrink the subtree below alias */ |
211 | fuse_invalidate_entry(alias); |
212 | dput(alias); |
213 | if (!list_empty(&inode->i_dentry)) |
214 | - return -EBUSY; |
215 | - } |
216 | - d_add(entry, inode); |
217 | - return 0; |
218 | + return ERR_PTR(-EBUSY); |
219 | + } else |
220 | + dput(alias); |
221 | + return d_splice_alias(inode, entry); |
222 | } |
223 | |
224 | static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, |
225 | @@ -225,6 +226,7 @@ |
226 | int err; |
227 | struct fuse_entry_out outarg; |
228 | struct inode *inode = NULL; |
229 | + struct dentry *newent; |
230 | struct fuse_conn *fc = get_fuse_conn(dir); |
231 | struct fuse_req *req; |
232 | struct fuse_req *forget_req; |
233 | @@ -265,23 +267,25 @@ |
234 | |
235 | if (inode && S_ISDIR(inode->i_mode)) { |
236 | mutex_lock(&fc->inst_mutex); |
237 | - err = fuse_d_add_directory(entry, inode); |
238 | + newent = fuse_d_add_directory(entry, inode); |
239 | mutex_unlock(&fc->inst_mutex); |
240 | - if (err) { |
241 | + if (IS_ERR(newent)) { |
242 | iput(inode); |
243 | - return ERR_PTR(err); |
244 | + return newent; |
245 | } |
246 | } else |
247 | - d_add(entry, inode); |
248 | + newent = d_splice_alias(inode, entry); |
249 | |
250 | + entry = newent ? newent : entry; |
251 | entry->d_op = &fuse_dentry_operations; |
252 | if (!err) |
253 | fuse_change_timeout(entry, &outarg); |
254 | else |
255 | fuse_invalidate_entry_cache(entry); |
256 | - return NULL; |
257 | + return newent; |
258 | } |
259 | |
260 | +#ifdef HAVE_LOOKUP_INSTANTIATE_FILP |
261 | /* |
262 | * Synchronous release for the case when something goes wrong in CREATE_OPEN |
263 | */ |
264 | @@ -392,6 +396,7 @@ |
265 | fuse_put_request(fc, forget_req); |
266 | return err; |
267 | } |
268 | +#endif |
269 | |
270 | /* |
271 | * Code shared between mknod, mkdir, symlink and link |
272 | @@ -485,12 +490,14 @@ |
273 | static int fuse_create(struct inode *dir, struct dentry *entry, int mode, |
274 | struct nameidata *nd) |
275 | { |
276 | +#ifdef HAVE_LOOKUP_INSTANTIATE_FILP |
277 | if (nd && (nd->flags & LOOKUP_OPEN)) { |
278 | int err = fuse_create_open(dir, entry, mode, nd); |
279 | if (err != -ENOSYS) |
280 | return err; |
281 | /* Fall back on mknod */ |
282 | } |
283 | +#endif |
284 | return fuse_mknod(dir, entry, mode, 0); |
285 | } |
286 | |
287 | @@ -821,6 +828,9 @@ |
288 | if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO)) |
289 | return -EACCES; |
290 | |
291 | +#ifndef LOOKUP_CHDIR |
292 | +#define LOOKUP_CHDIR 0 |
293 | +#endif |
294 | if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) |
295 | return fuse_access(inode, mask); |
296 | return 0; |
297 | @@ -857,7 +867,7 @@ |
298 | int err; |
299 | size_t nbytes; |
300 | struct page *page; |
301 | - struct inode *inode = file->f_path.dentry->d_inode; |
302 | + struct inode *inode = file->f_dentry->d_inode; |
303 | struct fuse_conn *fc = get_fuse_conn(inode); |
304 | struct fuse_req *req; |
305 | |
306 | @@ -973,11 +983,13 @@ |
307 | arg->atime = iattr->ia_atime.tv_sec; |
308 | arg->mtime = iattr->ia_mtime.tv_sec; |
309 | } |
310 | +#ifdef ATTR_FILE |
311 | if (ivalid & ATTR_FILE) { |
312 | struct fuse_file *ff = iattr->ia_file->private_data; |
313 | arg->valid |= FATTR_FH; |
314 | arg->fh = ff->fh; |
315 | } |
316 | +#endif |
317 | } |
318 | |
319 | static void fuse_vmtruncate(struct inode *inode, loff_t offset) |
320 | @@ -1040,6 +1052,9 @@ |
321 | |
322 | memset(&inarg, 0, sizeof(inarg)); |
323 | iattr_to_fattr(attr, &inarg); |
324 | + /* Defend against future expansion of ATTR_FILE use */ |
325 | + if (S_ISDIR(inode->i_mode)) |
326 | + inarg.valid &= ~FATTR_FH; |
327 | req->in.h.opcode = FUSE_SETATTR; |
328 | req->in.h.nodeid = get_node_id(inode); |
329 | req->in.numargs = 1; |
330 | @@ -1074,6 +1089,8 @@ |
331 | struct inode *inode = entry->d_inode; |
332 | int err = fuse_revalidate(entry); |
333 | if (!err) |
334 | + /* FIXME: may want specialized function because of |
335 | + st_blksize on block devices on 2.6.19+ */ |
336 | generic_fillattr(inode, stat); |
337 | |
338 | return err; |
339 | @@ -1243,7 +1260,7 @@ |
340 | return err; |
341 | } |
342 | |
343 | -static const struct inode_operations fuse_dir_inode_operations = { |
344 | +static struct inode_operations fuse_dir_inode_operations = { |
345 | .lookup = fuse_lookup, |
346 | .mkdir = fuse_mkdir, |
347 | .symlink = fuse_symlink, |
348 | @@ -1262,7 +1279,7 @@ |
349 | .removexattr = fuse_removexattr, |
350 | }; |
351 | |
352 | -static const struct file_operations fuse_dir_operations = { |
353 | +static struct file_operations fuse_dir_operations = { |
354 | .llseek = generic_file_llseek, |
355 | .read = generic_read_dir, |
356 | .readdir = fuse_readdir, |
357 | @@ -1271,7 +1288,7 @@ |
358 | .fsync = fuse_dir_fsync, |
359 | }; |
360 | |
361 | -static const struct inode_operations fuse_common_inode_operations = { |
362 | +static struct inode_operations fuse_common_inode_operations = { |
363 | .setattr = fuse_setattr, |
364 | .permission = fuse_permission, |
365 | .getattr = fuse_getattr, |
366 | @@ -1281,7 +1298,7 @@ |
367 | .removexattr = fuse_removexattr, |
368 | }; |
369 | |
370 | -static const struct inode_operations fuse_symlink_inode_operations = { |
371 | +static struct inode_operations fuse_symlink_inode_operations = { |
372 | .setattr = fuse_setattr, |
373 | .follow_link = fuse_follow_link, |
374 | .put_link = fuse_put_link, |
375 | diff -Naur linux-2.6.21/fs/fuse/file.c linux-2.6.21-magellan-r10/fs/fuse/file.c |
376 | --- linux-2.6.21/fs/fuse/file.c 2007-04-26 05:08:32.000000000 +0200 |
377 | +++ linux-2.6.21-magellan-r10/fs/fuse/file.c 2007-08-17 13:33:29.000000000 +0200 |
378 | @@ -1,6 +1,6 @@ |
379 | /* |
380 | FUSE: Filesystem in Userspace |
381 | - Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> |
382 | + Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> |
383 | |
384 | This program can be distributed under the terms of the GNU GPL. |
385 | See the file COPYING. |
386 | @@ -11,8 +11,9 @@ |
387 | #include <linux/pagemap.h> |
388 | #include <linux/slab.h> |
389 | #include <linux/kernel.h> |
390 | +#include <linux/sched.h> |
391 | |
392 | -static const struct file_operations fuse_direct_io_file_operations; |
393 | +static struct file_operations fuse_direct_io_file_operations; |
394 | |
395 | static int fuse_send_open(struct inode *inode, struct file *file, int isdir, |
396 | struct fuse_open_out *outargp) |
397 | @@ -141,8 +142,8 @@ |
398 | isdir ? FUSE_RELEASEDIR : FUSE_RELEASE); |
399 | |
400 | /* Hold vfsmount and dentry until release is finished */ |
401 | - req->vfsmount = mntget(file->f_path.mnt); |
402 | - req->dentry = dget(file->f_path.dentry); |
403 | + req->vfsmount = mntget(file->f_vfsmnt); |
404 | + req->dentry = dget(file->f_dentry); |
405 | request_send_background(fc, req); |
406 | } |
407 | |
408 | @@ -184,7 +185,7 @@ |
409 | |
410 | static int fuse_flush(struct file *file, fl_owner_t id) |
411 | { |
412 | - struct inode *inode = file->f_path.dentry->d_inode; |
413 | + struct inode *inode = file->f_dentry->d_inode; |
414 | struct fuse_conn *fc = get_fuse_conn(inode); |
415 | struct fuse_file *ff = file->private_data; |
416 | struct fuse_req *req; |
417 | @@ -370,21 +371,32 @@ |
418 | struct fuse_req *req = data->req; |
419 | struct inode *inode = data->inode; |
420 | struct fuse_conn *fc = get_fuse_conn(inode); |
421 | + int err; |
422 | |
423 | - if (req->num_pages && |
424 | + if (req && req->num_pages && |
425 | (req->num_pages == FUSE_MAX_PAGES_PER_REQ || |
426 | (req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read || |
427 | req->pages[req->num_pages - 1]->index + 1 != page->index)) { |
428 | fuse_send_readpages(req, data->file, inode); |
429 | + req = NULL; |
430 | + } |
431 | + if (!req) { |
432 | + err = -EIO; |
433 | + if (is_bad_inode(inode)) |
434 | + goto out_unlock_page; |
435 | + |
436 | data->req = req = fuse_get_req(fc); |
437 | - if (IS_ERR(req)) { |
438 | - unlock_page(page); |
439 | - return PTR_ERR(req); |
440 | - } |
441 | + err = PTR_ERR(req); |
442 | + if (IS_ERR(req)) |
443 | + goto out_unlock_page; |
444 | } |
445 | req->pages[req->num_pages] = page; |
446 | req->num_pages ++; |
447 | return 0; |
448 | + |
449 | + out_unlock_page: |
450 | + unlock_page(page); |
451 | + return err; |
452 | } |
453 | |
454 | static int fuse_readpages(struct file *file, struct address_space *mapping, |
455 | @@ -395,25 +407,17 @@ |
456 | struct fuse_readpages_data data; |
457 | int err; |
458 | |
459 | - err = -EIO; |
460 | - if (is_bad_inode(inode)) |
461 | - goto out; |
462 | - |
463 | data.file = file; |
464 | data.inode = inode; |
465 | - data.req = fuse_get_req(fc); |
466 | - err = PTR_ERR(data.req); |
467 | - if (IS_ERR(data.req)) |
468 | - goto out; |
469 | + data.req = NULL; |
470 | |
471 | err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); |
472 | - if (!err) { |
473 | + if (!err && data.req) { |
474 | if (data.req->num_pages) |
475 | fuse_send_readpages(data.req, file, inode); |
476 | else |
477 | fuse_put_request(fc, data.req); |
478 | } |
479 | -out: |
480 | return err; |
481 | } |
482 | |
483 | @@ -515,7 +519,8 @@ |
484 | |
485 | nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT); |
486 | npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; |
487 | - npages = min(max(npages, 1), FUSE_MAX_PAGES_PER_REQ); |
488 | + npages = max(npages, 1); |
489 | + npages = min(npages, FUSE_MAX_PAGES_PER_REQ); |
490 | down_read(¤t->mm->mmap_sem); |
491 | npages = get_user_pages(current, current->mm, user_addr, npages, write, |
492 | 0, req->pages, NULL); |
493 | @@ -531,7 +536,7 @@ |
494 | static ssize_t fuse_direct_io(struct file *file, const char __user *buf, |
495 | size_t count, loff_t *ppos, int write) |
496 | { |
497 | - struct inode *inode = file->f_path.dentry->d_inode; |
498 | + struct inode *inode = file->f_dentry->d_inode; |
499 | struct fuse_conn *fc = get_fuse_conn(inode); |
500 | size_t nmax = write ? fc->max_write : fc->max_read; |
501 | loff_t pos = *ppos; |
502 | @@ -605,11 +610,13 @@ |
503 | static ssize_t fuse_direct_write(struct file *file, const char __user *buf, |
504 | size_t count, loff_t *ppos) |
505 | { |
506 | - struct inode *inode = file->f_path.dentry->d_inode; |
507 | + struct inode *inode = file->f_dentry->d_inode; |
508 | ssize_t res; |
509 | /* Don't allow parallel writes to the same file */ |
510 | mutex_lock(&inode->i_mutex); |
511 | - res = fuse_direct_io(file, buf, count, ppos, 1); |
512 | + res = generic_write_checks(file, ppos, &count, 0); |
513 | + if (!res) |
514 | + res = fuse_direct_io(file, buf, count, ppos, 1); |
515 | mutex_unlock(&inode->i_mutex); |
516 | return res; |
517 | } |
518 | @@ -660,7 +667,7 @@ |
519 | static void fuse_lk_fill(struct fuse_req *req, struct file *file, |
520 | const struct file_lock *fl, int opcode, pid_t pid) |
521 | { |
522 | - struct inode *inode = file->f_path.dentry->d_inode; |
523 | + struct inode *inode = file->f_dentry->d_inode; |
524 | struct fuse_conn *fc = get_fuse_conn(inode); |
525 | struct fuse_file *ff = file->private_data; |
526 | struct fuse_lk_in *arg = &req->misc.lk_in; |
527 | @@ -680,7 +687,7 @@ |
528 | |
529 | static int fuse_getlk(struct file *file, struct file_lock *fl) |
530 | { |
531 | - struct inode *inode = file->f_path.dentry->d_inode; |
532 | + struct inode *inode = file->f_dentry->d_inode; |
533 | struct fuse_conn *fc = get_fuse_conn(inode); |
534 | struct fuse_req *req; |
535 | struct fuse_lk_out outarg; |
536 | @@ -705,7 +712,7 @@ |
537 | |
538 | static int fuse_setlk(struct file *file, struct file_lock *fl) |
539 | { |
540 | - struct inode *inode = file->f_path.dentry->d_inode; |
541 | + struct inode *inode = file->f_dentry->d_inode; |
542 | struct fuse_conn *fc = get_fuse_conn(inode); |
543 | struct fuse_req *req; |
544 | int opcode = (fl->fl_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK; |
545 | @@ -732,7 +739,7 @@ |
546 | |
547 | static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl) |
548 | { |
549 | - struct inode *inode = file->f_path.dentry->d_inode; |
550 | + struct inode *inode = file->f_dentry->d_inode; |
551 | struct fuse_conn *fc = get_fuse_conn(inode); |
552 | int err; |
553 | |
554 | @@ -788,7 +795,7 @@ |
555 | return err ? 0 : outarg.block; |
556 | } |
557 | |
558 | -static const struct file_operations fuse_file_operations = { |
559 | +static struct file_operations fuse_file_operations = { |
560 | .llseek = generic_file_llseek, |
561 | .read = do_sync_read, |
562 | .aio_read = generic_file_aio_read, |
563 | @@ -803,7 +810,7 @@ |
564 | .sendfile = generic_file_sendfile, |
565 | }; |
566 | |
567 | -static const struct file_operations fuse_direct_io_file_operations = { |
568 | +static struct file_operations fuse_direct_io_file_operations = { |
569 | .llseek = generic_file_llseek, |
570 | .read = fuse_direct_read, |
571 | .write = fuse_direct_write, |
572 | @@ -815,7 +822,7 @@ |
573 | /* no mmap and sendfile */ |
574 | }; |
575 | |
576 | -static const struct address_space_operations fuse_file_aops = { |
577 | +static struct address_space_operations fuse_file_aops = { |
578 | .readpage = fuse_readpage, |
579 | .prepare_write = fuse_prepare_write, |
580 | .commit_write = fuse_commit_write, |
581 | diff -Naur linux-2.6.21/fs/fuse/fuse_i.h linux-2.6.21-magellan-r10/fs/fuse/fuse_i.h |
582 | --- linux-2.6.21/fs/fuse/fuse_i.h 2007-04-26 05:08:32.000000000 +0200 |
583 | +++ linux-2.6.21-magellan-r10/fs/fuse/fuse_i.h 2007-08-17 13:33:29.000000000 +0200 |
584 | @@ -1,6 +1,6 @@ |
585 | /* |
586 | FUSE: Filesystem in Userspace |
587 | - Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> |
588 | + Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> |
589 | |
590 | This program can be distributed under the terms of the GNU GPL. |
591 | See the file COPYING. |
592 | @@ -15,6 +15,12 @@ |
593 | #include <linux/mm.h> |
594 | #include <linux/backing-dev.h> |
595 | #include <linux/mutex.h> |
596 | +#ifndef FS_HAS_SUBTYPE |
597 | +#define FS_HAS_SUBTYPE 0 |
598 | +#endif |
599 | +#ifndef FS_SAFE |
600 | +#define FS_SAFE 0 |
601 | +#endif |
602 | |
603 | /** Max number of pages that can be used in a single read request */ |
604 | #define FUSE_MAX_PAGES_PER_REQ 32 |
605 | @@ -397,7 +403,7 @@ |
606 | } |
607 | |
608 | /** Device operations */ |
609 | -extern const struct file_operations fuse_dev_operations; |
610 | +extern struct file_operations fuse_dev_operations; |
611 | |
612 | /** |
613 | * Get a filled in inode |
614 | diff -Naur linux-2.6.21/fs/fuse/inode.c linux-2.6.21-magellan-r10/fs/fuse/inode.c |
615 | --- linux-2.6.21/fs/fuse/inode.c 2007-04-26 05:08:32.000000000 +0200 |
616 | +++ linux-2.6.21-magellan-r10/fs/fuse/inode.c 2007-08-17 13:33:29.000000000 +0200 |
617 | @@ -1,6 +1,6 @@ |
618 | /* |
619 | FUSE: Filesystem in Userspace |
620 | - Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> |
621 | + Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> |
622 | |
623 | This program can be distributed under the terms of the GNU GPL. |
624 | See the file COPYING. |
625 | @@ -17,10 +17,13 @@ |
626 | #include <linux/parser.h> |
627 | #include <linux/statfs.h> |
628 | #include <linux/random.h> |
629 | +#include <linux/sched.h> |
630 | |
631 | MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); |
632 | MODULE_DESCRIPTION("Filesystem in Userspace"); |
633 | +#ifdef MODULE_LICENSE |
634 | MODULE_LICENSE("GPL"); |
635 | +#endif |
636 | |
637 | static struct kmem_cache *fuse_inode_cachep; |
638 | struct list_head fuse_conn_list; |
639 | @@ -28,6 +31,9 @@ |
640 | |
641 | #define FUSE_SUPER_MAGIC 0x65735546 |
642 | |
643 | +#ifndef MAX_LFS_FILESIZE |
644 | +#define MAX_LFS_FILESIZE (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) |
645 | +#endif |
646 | struct fuse_mount_data { |
647 | int fd; |
648 | unsigned rootmode; |
649 | @@ -122,6 +128,9 @@ |
650 | spin_lock(&fc->lock); |
651 | i_size_write(inode, attr->size); |
652 | spin_unlock(&fc->lock); |
653 | +#ifdef HAVE_I_BLKSIZE |
654 | + inode->i_blksize = PAGE_CACHE_SIZE; |
655 | +#endif |
656 | inode->i_blocks = attr->blocks; |
657 | inode->i_atime.tv_sec = attr->atime; |
658 | inode->i_atime.tv_nsec = attr->atimensec; |
659 | @@ -200,11 +209,18 @@ |
660 | return inode; |
661 | } |
662 | |
663 | +#ifdef UMOUNT_BEGIN_VFSMOUNT |
664 | static void fuse_umount_begin(struct vfsmount *vfsmnt, int flags) |
665 | { |
666 | if (flags & MNT_FORCE) |
667 | fuse_abort_conn(get_fuse_conn_super(vfsmnt->mnt_sb)); |
668 | } |
669 | +#else |
670 | +static void fuse_umount_begin(struct super_block *sb) |
671 | +{ |
672 | + fuse_abort_conn(get_fuse_conn_super(sb)); |
673 | +} |
674 | +#endif |
675 | |
676 | static void fuse_send_destroy(struct fuse_conn *fc) |
677 | { |
678 | @@ -311,6 +327,19 @@ |
679 | d->max_read = ~0; |
680 | d->blksize = 512; |
681 | |
682 | + /* |
683 | + * For unprivileged mounts use current uid/gid. Still allow |
684 | + * "user_id" and "group_id" options for compatibility, but |
685 | + * only if they match these values. |
686 | + */ |
687 | + if (!capable(CAP_SYS_ADMIN)) { |
688 | + d->user_id = current->uid; |
689 | + d->user_id_present = 1; |
690 | + d->group_id = current->gid; |
691 | + d->group_id_present = 1; |
692 | + |
693 | + } |
694 | + |
695 | while ((p = strsep(&opt, ",")) != NULL) { |
696 | int token; |
697 | int value; |
698 | @@ -339,6 +368,8 @@ |
699 | case OPT_USER_ID: |
700 | if (match_int(&args[0], &value)) |
701 | return 0; |
702 | + if (d->user_id_present && d->user_id != value) |
703 | + return 0; |
704 | d->user_id = value; |
705 | d->user_id_present = 1; |
706 | break; |
707 | @@ -346,6 +377,8 @@ |
708 | case OPT_GROUP_ID: |
709 | if (match_int(&args[0], &value)) |
710 | return 0; |
711 | + if (d->group_id_present && d->group_id != value) |
712 | + return 0; |
713 | d->group_id = value; |
714 | d->group_id_present = 1; |
715 | break; |
716 | @@ -448,11 +481,12 @@ |
717 | return fuse_iget(sb, 1, 0, &attr); |
718 | } |
719 | |
720 | -static const struct super_operations fuse_super_operations = { |
721 | +static struct super_operations fuse_super_operations = { |
722 | .alloc_inode = fuse_alloc_inode, |
723 | .destroy_inode = fuse_destroy_inode, |
724 | .read_inode = fuse_read_inode, |
725 | .clear_inode = fuse_clear_inode, |
726 | + .drop_inode = generic_delete_inode, |
727 | .remount_fs = fuse_remount_fs, |
728 | .put_super = fuse_put_super, |
729 | .umount_begin = fuse_umount_begin, |
730 | @@ -536,6 +570,10 @@ |
731 | if (!parse_fuse_opt((char *) data, &d, is_bdev)) |
732 | return -EINVAL; |
733 | |
734 | + /* This is a privileged option */ |
735 | + if ((d.flags & FUSE_ALLOW_OTHER) && !capable(CAP_SYS_ADMIN)) |
736 | + return -EPERM; |
737 | + |
738 | if (is_bdev) { |
739 | #ifdef CONFIG_BLOCK |
740 | if (!sb_set_blocksize(sb, d.blksize)) |
741 | @@ -638,6 +676,7 @@ |
742 | .name = "fuse", |
743 | .get_sb = fuse_get_sb, |
744 | .kill_sb = kill_anon_super, |
745 | + .fs_flags = FS_HAS_SUBTYPE | FS_SAFE, |
746 | }; |
747 | |
748 | #ifdef CONFIG_BLOCK |
749 | @@ -654,7 +693,7 @@ |
750 | .name = "fuseblk", |
751 | .get_sb = fuse_get_sb_blk, |
752 | .kill_sb = kill_block_super, |
753 | - .fs_flags = FS_REQUIRES_DEV, |
754 | + .fs_flags = FS_REQUIRES_DEV | FS_HAS_SUBTYPE, |
755 | }; |
756 | |
757 | static inline int register_fuseblk(void) |
758 | @@ -687,7 +726,7 @@ |
759 | |
760 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == |
761 | SLAB_CTOR_CONSTRUCTOR) |
762 | - inode_init_once(inode); |
763 | + inode_init_once(inode); |
764 | } |
765 | |
766 | static int __init fuse_fs_init(void) |
767 | diff -Naur linux-2.6.21/include/linux/fuse.h linux-2.6.21-magellan-r10/include/linux/fuse.h |
768 | --- linux-2.6.21/include/linux/fuse.h 2007-04-26 05:08:32.000000000 +0200 |
769 | +++ linux-2.6.21-magellan-r10/include/linux/fuse.h 2007-08-17 12:00:33.000000000 +0200 |
770 | @@ -1,6 +1,6 @@ |
771 | /* |
772 | FUSE: Filesystem in Userspace |
773 | - Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu> |
774 | + Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> |
775 | |
776 | This program can be distributed under the terms of the GNU GPL. |
777 | See the file COPYING. |
778 | @@ -339,7 +339,7 @@ |
779 | char name[0]; |
780 | }; |
781 | |
782 | -#define FUSE_NAME_OFFSET ((unsigned) ((struct fuse_dirent *) 0)->name) |
783 | +#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name) |
784 | #define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1)) |
785 | #define FUSE_DIRENT_SIZE(d) \ |
786 | FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen) |