Magellan Linux

Contents of /trunk/kernel26-tinyalx/patches-2.6.21-r14/0158-2.6.21.5-fuse-2.6.5.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 453 - (show annotations) (download)
Fri Jan 25 23:34:48 2008 UTC (16 years, 3 months ago) by niro
File size: 21351 byte(s)
-tiny-alx 2.6.21-tinyalx-r14

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