Annotation of /trunk/kernel26-alx/patches-2.6.21-r15/0158-2.6.21.5-fuse-2.6.5.patch
Parent Directory | Revision Log
Revision 464 -
(hide annotations)
(download)
Wed Feb 6 09:19:36 2008 UTC (16 years, 8 months ago) by niro
File size: 21351 byte(s)
Wed Feb 6 09:19:36 2008 UTC (16 years, 8 months ago) by niro
File size: 21351 byte(s)
-rev bump to 2.6.21-alx-r15; added i686 support
1 | niro | 464 | 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(¤t->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(¤t->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(¤t->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) |