Magellan Linux

Annotation 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 - (hide annotations) (download)
Fri Jan 25 23:34:48 2008 UTC (16 years, 4 months ago) by niro
File size: 21351 byte(s)
-tiny-alx 2.6.21-tinyalx-r14

1 niro 453 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)