Magellan Linux

Contents of /trunk/kernel26-magellan/patches-2.6.21-r10/0158-2.6.21.7-fuse-2.7.0.patch

Parent Directory Parent Directory | Revision Log 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)
-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(&current->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(&current->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(&current->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)