2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
5 This program can be distributed under the terms of the GNU GPL.
11 #include <linux/pagemap.h>
12 #include <linux/file.h>
14 #include <linux/gfp.h>
18 #include <linux/sched.h>
20 #include <linux/namei.h>
23 static inline unsigned long time_to_jiffies(unsigned long sec
,
26 struct timespec ts
= {sec
, nsec
};
27 return jiffies
+ timespec_to_jiffies(&ts
);
30 static void fuse_lookup_init(struct fuse_req
*req
, struct inode
*dir
,
32 struct fuse_entry_out
*outarg
)
34 req
->in
.h
.opcode
= FUSE_LOOKUP
;
35 req
->in
.h
.nodeid
= get_node_id(dir
);
38 req
->in
.args
[0].size
= entry
->d_name
.len
+ 1;
39 req
->in
.args
[0].value
= entry
->d_name
.name
;
41 req
->out
.args
[0].size
= sizeof(struct fuse_entry_out
);
42 req
->out
.args
[0].value
= outarg
;
45 static int fuse_dentry_revalidate(struct dentry
*entry
, struct nameidata
*nd
)
47 if (!entry
->d_inode
|| is_bad_inode(entry
->d_inode
))
49 else if (time_after(jiffies
, entry
->d_time
)) {
51 struct fuse_entry_out outarg
;
52 struct inode
*inode
= entry
->d_inode
;
53 struct fuse_inode
*fi
= get_fuse_inode(inode
);
54 struct fuse_conn
*fc
= get_fuse_conn(inode
);
55 struct fuse_req
*req
= fuse_get_request(fc
);
59 fuse_lookup_init(req
, entry
->d_parent
->d_inode
, entry
, &outarg
);
60 request_send(fc
, req
);
61 err
= req
->out
.h
.error
;
63 if (outarg
.nodeid
!= get_node_id(inode
)) {
64 fuse_send_forget(fc
, req
, outarg
.nodeid
, 1);
69 fuse_put_request(fc
, req
);
70 if (err
|| (outarg
.attr
.mode
^ inode
->i_mode
) & S_IFMT
)
73 fuse_change_attributes(inode
, &outarg
.attr
);
74 entry
->d_time
= time_to_jiffies(outarg
.entry_valid
,
75 outarg
.entry_valid_nsec
);
76 fi
->i_time
= time_to_jiffies(outarg
.attr_valid
,
77 outarg
.attr_valid_nsec
);
82 static int fuse_dentry_revalidate_2_4(struct dentry
*entry
, int flags
)
84 return fuse_dentry_revalidate(entry
, NULL
);
88 static struct dentry_operations fuse_dentry_operations
= {
90 .d_revalidate
= fuse_dentry_revalidate
,
92 .d_revalidate
= fuse_dentry_revalidate_2_4
,
96 static int fuse_lookup_iget(struct inode
*dir
, struct dentry
*entry
,
97 struct inode
**inodep
)
100 struct fuse_entry_out outarg
;
101 struct inode
*inode
= NULL
;
102 struct fuse_conn
*fc
= get_fuse_conn(dir
);
103 struct fuse_req
*req
;
105 if (entry
->d_name
.len
> FUSE_NAME_MAX
)
106 return -ENAMETOOLONG
;
108 req
= fuse_get_request(fc
);
112 fuse_lookup_init(req
, dir
, entry
, &outarg
);
113 request_send(fc
, req
);
114 err
= req
->out
.h
.error
;
115 if (!err
&& (!outarg
.nodeid
|| outarg
.nodeid
== FUSE_ROOT_ID
))
118 inode
= fuse_iget(dir
->i_sb
, outarg
.nodeid
, outarg
.generation
,
121 fuse_send_forget(fc
, req
, outarg
.nodeid
, 1);
125 fuse_put_request(fc
, req
);
126 if (err
&& err
!= -ENOENT
)
130 struct fuse_inode
*fi
= get_fuse_inode(inode
);
131 entry
->d_time
= time_to_jiffies(outarg
.entry_valid
,
132 outarg
.entry_valid_nsec
);
133 fi
->i_time
= time_to_jiffies(outarg
.attr_valid
,
134 outarg
.attr_valid_nsec
);
137 entry
->d_op
= &fuse_dentry_operations
;
142 void fuse_invalidate_attr(struct inode
*inode
)
144 get_fuse_inode(inode
)->i_time
= jiffies
- 1;
147 static void fuse_invalidate_entry(struct dentry
*entry
)
150 entry
->d_time
= jiffies
- 1;
153 static int create_new_entry(struct fuse_conn
*fc
, struct fuse_req
*req
,
154 struct inode
*dir
, struct dentry
*entry
,
157 struct fuse_entry_out outarg
;
159 struct fuse_inode
*fi
;
162 req
->in
.h
.nodeid
= get_node_id(dir
);
164 req
->out
.numargs
= 1;
165 req
->out
.args
[0].size
= sizeof(outarg
);
166 req
->out
.args
[0].value
= &outarg
;
167 request_send(fc
, req
);
168 err
= req
->out
.h
.error
;
170 fuse_put_request(fc
, req
);
173 if (!outarg
.nodeid
|| outarg
.nodeid
== FUSE_ROOT_ID
) {
174 fuse_put_request(fc
, req
);
177 inode
= fuse_iget(dir
->i_sb
, outarg
.nodeid
, outarg
.generation
,
180 fuse_send_forget(fc
, req
, outarg
.nodeid
, 1);
183 fuse_put_request(fc
, req
);
185 /* Don't allow userspace to do really stupid things... */
186 if ((inode
->i_mode
^ mode
) & S_IFMT
) {
191 entry
->d_time
= time_to_jiffies(outarg
.entry_valid
,
192 outarg
.entry_valid_nsec
);
194 fi
= get_fuse_inode(inode
);
195 fi
->i_time
= time_to_jiffies(outarg
.attr_valid
,
196 outarg
.attr_valid_nsec
);
198 d_instantiate(entry
, inode
);
199 fuse_invalidate_attr(dir
);
203 static int fuse_mknod(struct inode
*dir
, struct dentry
*entry
, int mode
,
206 struct fuse_mknod_in inarg
;
207 struct fuse_conn
*fc
= get_fuse_conn(dir
);
208 struct fuse_req
*req
= fuse_get_request(fc
);
212 memset(&inarg
, 0, sizeof(inarg
));
214 inarg
.rdev
= new_encode_dev(rdev
);
215 req
->in
.h
.opcode
= FUSE_MKNOD
;
217 req
->in
.args
[0].size
= sizeof(inarg
);
218 req
->in
.args
[0].value
= &inarg
;
219 req
->in
.args
[1].size
= entry
->d_name
.len
+ 1;
220 req
->in
.args
[1].value
= entry
->d_name
.name
;
221 return create_new_entry(fc
, req
, dir
, entry
, mode
);
224 static int fuse_create(struct inode
*dir
, struct dentry
*entry
, int mode
,
225 struct nameidata
*nd
)
227 return fuse_mknod(dir
, entry
, mode
, 0);
230 static int fuse_mkdir(struct inode
*dir
, struct dentry
*entry
, int mode
)
232 struct fuse_mkdir_in inarg
;
233 struct fuse_conn
*fc
= get_fuse_conn(dir
);
234 struct fuse_req
*req
= fuse_get_request(fc
);
238 memset(&inarg
, 0, sizeof(inarg
));
240 req
->in
.h
.opcode
= FUSE_MKDIR
;
242 req
->in
.args
[0].size
= sizeof(inarg
);
243 req
->in
.args
[0].value
= &inarg
;
244 req
->in
.args
[1].size
= entry
->d_name
.len
+ 1;
245 req
->in
.args
[1].value
= entry
->d_name
.name
;
246 return create_new_entry(fc
, req
, dir
, entry
, S_IFDIR
);
249 static int fuse_symlink(struct inode
*dir
, struct dentry
*entry
,
252 struct fuse_conn
*fc
= get_fuse_conn(dir
);
253 unsigned len
= strlen(link
) + 1;
254 struct fuse_req
*req
;
256 if (len
> FUSE_SYMLINK_MAX
)
257 return -ENAMETOOLONG
;
259 req
= fuse_get_request(fc
);
263 req
->in
.h
.opcode
= FUSE_SYMLINK
;
265 req
->in
.args
[0].size
= entry
->d_name
.len
+ 1;
266 req
->in
.args
[0].value
= entry
->d_name
.name
;
267 req
->in
.args
[1].size
= len
;
268 req
->in
.args
[1].value
= link
;
269 return create_new_entry(fc
, req
, dir
, entry
, S_IFLNK
);
272 static int fuse_unlink(struct inode
*dir
, struct dentry
*entry
)
275 struct fuse_conn
*fc
= get_fuse_conn(dir
);
276 struct fuse_req
*req
= fuse_get_request(fc
);
280 req
->in
.h
.opcode
= FUSE_UNLINK
;
281 req
->in
.h
.nodeid
= get_node_id(dir
);
284 req
->in
.args
[0].size
= entry
->d_name
.len
+ 1;
285 req
->in
.args
[0].value
= entry
->d_name
.name
;
286 request_send(fc
, req
);
287 err
= req
->out
.h
.error
;
288 fuse_put_request(fc
, req
);
290 struct inode
*inode
= entry
->d_inode
;
292 /* Set nlink to zero so the inode can be cleared, if
293 the inode does have more links this will be
294 discovered at the next lookup/getattr */
296 fuse_invalidate_attr(inode
);
297 fuse_invalidate_attr(dir
);
298 } else if (err
== -EINTR
)
299 fuse_invalidate_entry(entry
);
303 static int fuse_rmdir(struct inode
*dir
, struct dentry
*entry
)
306 struct fuse_conn
*fc
= get_fuse_conn(dir
);
307 struct fuse_req
*req
= fuse_get_request(fc
);
311 req
->in
.h
.opcode
= FUSE_RMDIR
;
312 req
->in
.h
.nodeid
= get_node_id(dir
);
315 req
->in
.args
[0].size
= entry
->d_name
.len
+ 1;
316 req
->in
.args
[0].value
= entry
->d_name
.name
;
317 request_send(fc
, req
);
318 err
= req
->out
.h
.error
;
319 fuse_put_request(fc
, req
);
321 entry
->d_inode
->i_nlink
= 0;
322 fuse_invalidate_attr(dir
);
323 } else if (err
== -EINTR
)
324 fuse_invalidate_entry(entry
);
328 static int fuse_rename(struct inode
*olddir
, struct dentry
*oldent
,
329 struct inode
*newdir
, struct dentry
*newent
)
332 struct fuse_rename_in inarg
;
333 struct fuse_conn
*fc
= get_fuse_conn(olddir
);
334 struct fuse_req
*req
= fuse_get_request(fc
);
338 memset(&inarg
, 0, sizeof(inarg
));
339 inarg
.newdir
= get_node_id(newdir
);
340 req
->in
.h
.opcode
= FUSE_RENAME
;
341 req
->in
.h
.nodeid
= get_node_id(olddir
);
343 req
->inode2
= newdir
;
345 req
->in
.args
[0].size
= sizeof(inarg
);
346 req
->in
.args
[0].value
= &inarg
;
347 req
->in
.args
[1].size
= oldent
->d_name
.len
+ 1;
348 req
->in
.args
[1].value
= oldent
->d_name
.name
;
349 req
->in
.args
[2].size
= newent
->d_name
.len
+ 1;
350 req
->in
.args
[2].value
= newent
->d_name
.name
;
351 request_send(fc
, req
);
352 err
= req
->out
.h
.error
;
353 fuse_put_request(fc
, req
);
355 fuse_invalidate_attr(olddir
);
356 if (olddir
!= newdir
)
357 fuse_invalidate_attr(newdir
);
358 } else if (err
== -EINTR
) {
359 /* If request was interrupted, DEITY only knows if the
360 rename actually took place. If the invalidation
361 fails (e.g. some process has CWD under the renamed
362 directory), then there can be inconsistency between
363 the dcache and the real filesystem. Tough luck. */
364 fuse_invalidate_entry(oldent
);
366 fuse_invalidate_entry(newent
);
372 static int fuse_link(struct dentry
*entry
, struct inode
*newdir
,
373 struct dentry
*newent
)
376 struct fuse_link_in inarg
;
377 struct inode
*inode
= entry
->d_inode
;
378 struct fuse_conn
*fc
= get_fuse_conn(inode
);
379 struct fuse_req
*req
= fuse_get_request(fc
);
383 memset(&inarg
, 0, sizeof(inarg
));
384 inarg
.oldnodeid
= get_node_id(inode
);
385 req
->in
.h
.opcode
= FUSE_LINK
;
388 req
->in
.args
[0].size
= sizeof(inarg
);
389 req
->in
.args
[0].value
= &inarg
;
390 req
->in
.args
[1].size
= newent
->d_name
.len
+ 1;
391 req
->in
.args
[1].value
= newent
->d_name
.name
;
392 err
= create_new_entry(fc
, req
, newdir
, newent
, inode
->i_mode
);
393 /* Contrary to "normal" filesystems it can happen that link
394 makes two "logical" inodes point to the same "physical"
395 inode. We invalidate the attributes of the old one, so it
396 will reflect changes in the backing inode (link count,
399 if (!err
|| err
== -EINTR
)
400 fuse_invalidate_attr(inode
);
404 int fuse_do_getattr(struct inode
*inode
)
407 struct fuse_attr_out arg
;
408 struct fuse_conn
*fc
= get_fuse_conn(inode
);
409 struct fuse_req
*req
= fuse_get_request(fc
);
413 req
->in
.h
.opcode
= FUSE_GETATTR
;
414 req
->in
.h
.nodeid
= get_node_id(inode
);
416 req
->out
.numargs
= 1;
417 req
->out
.args
[0].size
= sizeof(arg
);
418 req
->out
.args
[0].value
= &arg
;
419 request_send(fc
, req
);
420 err
= req
->out
.h
.error
;
421 fuse_put_request(fc
, req
);
423 if ((inode
->i_mode
^ arg
.attr
.mode
) & S_IFMT
) {
424 #ifndef KERNEL_2_6_12_PLUS
425 if (get_node_id(inode
) != FUSE_ROOT_ID
)
426 make_bad_inode(inode
);
428 make_bad_inode(inode
);
432 struct fuse_inode
*fi
= get_fuse_inode(inode
);
433 fuse_change_attributes(inode
, &arg
.attr
);
434 fi
->i_time
= time_to_jiffies(arg
.attr_valid
,
435 arg
.attr_valid_nsec
);
442 * Calling into a user-controlled filesystem gives the filesystem
443 * daemon ptrace-like capabilities over the requester process. This
444 * means, that the filesystem daemon is able to record the exact
445 * filesystem operations performed, and can also control the behavior
446 * of the requester process in otherwise impossible ways. For example
447 * it can delay the operation for arbitrary length of time allowing
448 * DoS against the requester.
450 * For this reason only those processes can call into the filesystem,
451 * for which the owner of the mount has ptrace privilege. This
452 * excludes processes started by other users, suid or sgid processes.
454 static int fuse_allow_task(struct fuse_conn
*fc
, struct task_struct
*task
)
456 if (fc
->flags
& FUSE_ALLOW_OTHER
)
459 if (task
->euid
== fc
->user_id
&&
460 task
->suid
== fc
->user_id
&&
461 task
->uid
== fc
->user_id
&&
462 task
->egid
== fc
->group_id
&&
463 task
->sgid
== fc
->group_id
&&
464 task
->gid
== fc
->group_id
)
470 static int fuse_revalidate(struct dentry
*entry
)
472 struct inode
*inode
= entry
->d_inode
;
473 struct fuse_inode
*fi
= get_fuse_inode(inode
);
474 struct fuse_conn
*fc
= get_fuse_conn(inode
);
476 if (!fuse_allow_task(fc
, current
))
478 if (get_node_id(inode
) != FUSE_ROOT_ID
&&
479 time_before_eq(jiffies
, fi
->i_time
))
482 return fuse_do_getattr(inode
);
485 static int fuse_permission(struct inode
*inode
, int mask
, struct nameidata
*nd
)
487 struct fuse_conn
*fc
= get_fuse_conn(inode
);
489 if (!fuse_allow_task(fc
, current
))
491 else if (fc
->flags
& FUSE_DEFAULT_PERMISSIONS
) {
492 #ifdef KERNEL_2_6_10_PLUS
493 int err
= generic_permission(inode
, mask
, NULL
);
495 int err
= vfs_permission(inode
, mask
);
498 /* If permission is denied, try to refresh file
499 attributes. This is also needed, because the root
500 node will at first have no permissions */
501 if (err
== -EACCES
) {
502 err
= fuse_do_getattr(inode
);
504 #ifdef KERNEL_2_6_10_PLUS
505 err
= generic_permission(inode
, mask
, NULL
);
507 err
= vfs_permission(inode
, mask
);
511 /* FIXME: Need some mechanism to revoke permissions:
512 currently if the filesystem suddenly changes the
513 file mode, we will not be informed about it, and
514 continue to allow access to the file/directory.
516 This is actually not so grave, since the user can
517 simply keep access to the file/directory anyway by
518 keeping it open... */
522 int mode
= inode
->i_mode
;
523 if ((mask
& MAY_WRITE
) && IS_RDONLY(inode
) &&
524 (S_ISREG(mode
) || S_ISDIR(mode
) || S_ISLNK(mode
)))
526 if ((mask
& MAY_EXEC
) && !S_ISDIR(mode
) && !(mode
& S_IXUGO
))
532 static int parse_dirfile(char *buf
, size_t nbytes
, struct file
*file
,
533 void *dstbuf
, filldir_t filldir
)
535 while (nbytes
>= FUSE_NAME_OFFSET
) {
536 struct fuse_dirent
*dirent
= (struct fuse_dirent
*) buf
;
537 size_t reclen
= FUSE_DIRENT_SIZE(dirent
);
539 if (!dirent
->namelen
|| dirent
->namelen
> FUSE_NAME_MAX
)
544 over
= filldir(dstbuf
, dirent
->name
, dirent
->namelen
,
545 file
->f_pos
, dirent
->ino
, dirent
->type
);
551 file
->f_pos
= dirent
->off
;
557 static inline size_t fuse_send_readdir(struct fuse_req
*req
, struct file
*file
,
558 struct inode
*inode
, loff_t pos
,
561 return fuse_send_read_common(req
, file
, inode
, pos
, count
, 1);
564 static int fuse_readdir(struct file
*file
, void *dstbuf
, filldir_t filldir
)
569 struct inode
*inode
= file
->f_dentry
->d_inode
;
570 struct fuse_conn
*fc
= get_fuse_conn(inode
);
571 struct fuse_req
*req
= fuse_get_request(fc
);
575 page
= alloc_page(GFP_KERNEL
);
577 fuse_put_request(fc
, req
);
581 req
->pages
[0] = page
;
582 nbytes
= fuse_send_readdir(req
, file
, inode
, file
->f_pos
, PAGE_SIZE
);
583 err
= req
->out
.h
.error
;
584 fuse_put_request(fc
, req
);
586 err
= parse_dirfile(page_address(page
), nbytes
, file
, dstbuf
,
590 fuse_invalidate_attr(inode
); /* atime changed */
594 static char *read_link(struct dentry
*dentry
)
596 struct inode
*inode
= dentry
->d_inode
;
597 struct fuse_conn
*fc
= get_fuse_conn(inode
);
598 struct fuse_req
*req
= fuse_get_request(fc
);
602 return ERR_PTR(-EINTR
);
604 link
= (char *) __get_free_page(GFP_KERNEL
);
606 link
= ERR_PTR(-ENOMEM
);
609 req
->in
.h
.opcode
= FUSE_READLINK
;
610 req
->in
.h
.nodeid
= get_node_id(inode
);
613 req
->out
.numargs
= 1;
614 req
->out
.args
[0].size
= PAGE_SIZE
- 1;
615 req
->out
.args
[0].value
= link
;
616 request_send(fc
, req
);
617 if (req
->out
.h
.error
) {
618 free_page((unsigned long) link
);
619 link
= ERR_PTR(req
->out
.h
.error
);
621 link
[req
->out
.args
[0].size
] = '\0';
623 fuse_put_request(fc
, req
);
624 fuse_invalidate_attr(inode
); /* atime changed */
628 static void free_link(char *link
)
631 free_page((unsigned long) link
);
634 #ifdef KERNEL_2_6_13_PLUS
635 static void *fuse_follow_link(struct dentry
*dentry
, struct nameidata
*nd
)
637 nd_set_link(nd
, read_link(dentry
));
641 static void fuse_put_link(struct dentry
*dentry
, struct nameidata
*nd
, void *c
)
643 free_link(nd_get_link(nd
));
645 #elif defined(KERNEL_2_6_8_PLUS)
646 static int fuse_follow_link(struct dentry
*dentry
, struct nameidata
*nd
)
648 nd_set_link(nd
, read_link(dentry
));
652 static void fuse_put_link(struct dentry
*dentry
, struct nameidata
*nd
)
654 free_link(nd_get_link(nd
));
657 static int fuse_readlink(struct dentry
*dentry
, char __user
*buffer
,
663 link
= read_link(dentry
);
664 ret
= vfs_readlink(dentry
, buffer
, buflen
, link
);
669 static int fuse_follow_link(struct dentry
*dentry
, struct nameidata
*nd
)
674 link
= read_link(dentry
);
675 ret
= vfs_follow_link(nd
, link
);
681 static int fuse_dir_open(struct inode
*inode
, struct file
*file
)
683 return fuse_open_common(inode
, file
, 1);
686 static int fuse_dir_release(struct inode
*inode
, struct file
*file
)
688 return fuse_release_common(inode
, file
, 1);
691 static int fuse_dir_fsync(struct file
*file
, struct dentry
*de
, int datasync
)
693 /* nfsd can call this with no file */
694 return file
? fuse_fsync_common(file
, de
, datasync
, 1) : 0;
697 static unsigned iattr_to_fattr(struct iattr
*iattr
, struct fuse_attr
*fattr
)
699 unsigned ivalid
= iattr
->ia_valid
;
702 memset(fattr
, 0, sizeof(*fattr
));
704 if (ivalid
& ATTR_MODE
)
705 fvalid
|= FATTR_MODE
, fattr
->mode
= iattr
->ia_mode
;
706 if (ivalid
& ATTR_UID
)
707 fvalid
|= FATTR_UID
, fattr
->uid
= iattr
->ia_uid
;
708 if (ivalid
& ATTR_GID
)
709 fvalid
|= FATTR_GID
, fattr
->gid
= iattr
->ia_gid
;
710 if (ivalid
& ATTR_SIZE
)
711 fvalid
|= FATTR_SIZE
, fattr
->size
= iattr
->ia_size
;
712 /* You can only _set_ these together (they may change by themselves) */
713 if ((ivalid
& (ATTR_ATIME
| ATTR_MTIME
)) == (ATTR_ATIME
| ATTR_MTIME
)) {
714 fvalid
|= FATTR_ATIME
| FATTR_MTIME
;
716 fattr
->atime
= iattr
->ia_atime
.tv_sec
;
717 fattr
->mtime
= iattr
->ia_mtime
.tv_sec
;
719 fattr
->atime
= iattr
->ia_atime
;
720 fattr
->mtime
= iattr
->ia_mtime
;
727 static int fuse_setattr(struct dentry
*entry
, struct iattr
*attr
)
729 struct inode
*inode
= entry
->d_inode
;
730 struct fuse_conn
*fc
= get_fuse_conn(inode
);
731 struct fuse_inode
*fi
= get_fuse_inode(inode
);
732 struct fuse_req
*req
;
733 struct fuse_setattr_in inarg
;
734 struct fuse_attr_out outarg
;
738 if (fc
->flags
& FUSE_DEFAULT_PERMISSIONS
) {
739 err
= inode_change_ok(inode
, attr
);
744 if (attr
->ia_valid
& ATTR_SIZE
) {
747 #ifdef KERNEL_2_6_10_PLUS
748 limit
= current
->signal
->rlim
[RLIMIT_FSIZE
].rlim_cur
;
750 limit
= current
->rlim
[RLIMIT_FSIZE
].rlim_cur
;
752 if (limit
!= RLIM_INFINITY
&& attr
->ia_size
> (loff_t
) limit
) {
753 send_sig(SIGXFSZ
, current
, 0);
758 req
= fuse_get_request(fc
);
762 memset(&inarg
, 0, sizeof(inarg
));
763 inarg
.valid
= iattr_to_fattr(attr
, &inarg
.attr
);
764 req
->in
.h
.opcode
= FUSE_SETATTR
;
765 req
->in
.h
.nodeid
= get_node_id(inode
);
768 req
->in
.args
[0].size
= sizeof(inarg
);
769 req
->in
.args
[0].value
= &inarg
;
770 req
->out
.numargs
= 1;
771 req
->out
.args
[0].size
= sizeof(outarg
);
772 req
->out
.args
[0].value
= &outarg
;
773 request_send(fc
, req
);
774 err
= req
->out
.h
.error
;
775 fuse_put_request(fc
, req
);
777 if ((inode
->i_mode
^ outarg
.attr
.mode
) & S_IFMT
) {
778 #ifndef KERNEL_2_6_12_PLUS
779 if (get_node_id(inode
) != FUSE_ROOT_ID
)
780 make_bad_inode(inode
);
782 make_bad_inode(inode
);
787 loff_t origsize
= i_size_read(inode
);
788 i_size_write(inode
, outarg
.attr
.size
);
789 if (origsize
> outarg
.attr
.size
)
790 vmtruncate(inode
, outarg
.attr
.size
);
792 fuse_change_attributes(inode
, &outarg
.attr
);
793 fi
->i_time
= time_to_jiffies(outarg
.attr_valid
,
794 outarg
.attr_valid_nsec
);
796 } else if (err
== -EINTR
)
797 fuse_invalidate_attr(inode
);
803 static int fuse_getattr(struct vfsmount
*mnt
, struct dentry
*entry
,
806 struct inode
*inode
= entry
->d_inode
;
807 int err
= fuse_revalidate(entry
);
809 generic_fillattr(inode
, stat
);
814 static struct dentry
*fuse_lookup(struct inode
*dir
, struct dentry
*entry
,
815 struct nameidata
*nd
)
818 int err
= fuse_lookup_iget(dir
, entry
, &inode
);
821 if (inode
&& S_ISDIR(inode
->i_mode
)) {
822 /* Don't allow creating an alias to a directory */
823 struct dentry
*alias
= d_find_alias(inode
);
824 if (alias
&& !(alias
->d_flags
& DCACHE_DISCONNECTED
)) {
827 return ERR_PTR(-EIO
);
830 return d_splice_alias(inode
, entry
);
832 #else /* KERNEL_2_6 */
833 static struct dentry
*fuse_lookup(struct inode
*dir
, struct dentry
*entry
)
836 struct dentry
*alias
;
838 int err
= fuse_lookup_iget(dir
, entry
, &inode
);
842 if (inode
&& S_ISDIR(inode
->i_mode
) &&
843 (alias
= d_find_alias(inode
)) != NULL
) {
846 return ERR_PTR(-EIO
);
853 static int fuse_mknod_2_4(struct inode
*dir
, struct dentry
*entry
, int mode
,
856 return fuse_mknod(dir
, entry
, mode
, rdev
);
859 static int fuse_create_2_4(struct inode
*dir
, struct dentry
*entry
, int mode
)
861 return fuse_create(dir
, entry
, mode
, NULL
);
864 static int fuse_permission_2_4(struct inode
*inode
, int mask
)
866 return fuse_permission(inode
, mask
, NULL
);
868 #endif /* KERNEL_2_6 */
870 #ifdef HAVE_KERNEL_XATTR
872 static int fuse_setxattr(struct dentry
*entry
, const char *name
,
873 const void *value
, size_t size
, int flags
)
875 static int fuse_setxattr(struct dentry
*entry
, const char *name
,
876 void *value
, size_t size
, int flags
)
879 struct inode
*inode
= entry
->d_inode
;
880 struct fuse_conn
*fc
= get_fuse_conn(inode
);
881 struct fuse_req
*req
;
882 struct fuse_setxattr_in inarg
;
885 if (size
> FUSE_XATTR_SIZE_MAX
)
891 req
= fuse_get_request(fc
);
895 memset(&inarg
, 0, sizeof(inarg
));
898 req
->in
.h
.opcode
= FUSE_SETXATTR
;
899 req
->in
.h
.nodeid
= get_node_id(inode
);
902 req
->in
.args
[0].size
= sizeof(inarg
);
903 req
->in
.args
[0].value
= &inarg
;
904 req
->in
.args
[1].size
= strlen(name
) + 1;
905 req
->in
.args
[1].value
= name
;
906 req
->in
.args
[2].size
= size
;
907 req
->in
.args
[2].value
= value
;
908 request_send(fc
, req
);
909 err
= req
->out
.h
.error
;
910 fuse_put_request(fc
, req
);
911 if (err
== -ENOSYS
) {
918 static ssize_t
fuse_getxattr(struct dentry
*entry
, const char *name
,
919 void *value
, size_t size
)
921 struct inode
*inode
= entry
->d_inode
;
922 struct fuse_conn
*fc
= get_fuse_conn(inode
);
923 struct fuse_req
*req
;
924 struct fuse_getxattr_in inarg
;
925 struct fuse_getxattr_out outarg
;
931 req
= fuse_get_request(fc
);
935 memset(&inarg
, 0, sizeof(inarg
));
937 req
->in
.h
.opcode
= FUSE_GETXATTR
;
938 req
->in
.h
.nodeid
= get_node_id(inode
);
941 req
->in
.args
[0].size
= sizeof(inarg
);
942 req
->in
.args
[0].value
= &inarg
;
943 req
->in
.args
[1].size
= strlen(name
) + 1;
944 req
->in
.args
[1].value
= name
;
945 /* This is really two different operations rolled into one */
946 req
->out
.numargs
= 1;
949 req
->out
.args
[0].size
= size
;
950 req
->out
.args
[0].value
= value
;
952 req
->out
.args
[0].size
= sizeof(outarg
);
953 req
->out
.args
[0].value
= &outarg
;
955 request_send(fc
, req
);
956 ret
= req
->out
.h
.error
;
958 ret
= size
? req
->out
.args
[0].size
: outarg
.size
;
960 if (ret
== -ENOSYS
) {
965 fuse_put_request(fc
, req
);
969 static ssize_t
fuse_listxattr(struct dentry
*entry
, char *list
, size_t size
)
971 struct inode
*inode
= entry
->d_inode
;
972 struct fuse_conn
*fc
= get_fuse_conn(inode
);
973 struct fuse_req
*req
;
974 struct fuse_getxattr_in inarg
;
975 struct fuse_getxattr_out outarg
;
978 if (fc
->no_listxattr
)
981 req
= fuse_get_request(fc
);
985 memset(&inarg
, 0, sizeof(inarg
));
987 req
->in
.h
.opcode
= FUSE_LISTXATTR
;
988 req
->in
.h
.nodeid
= get_node_id(inode
);
991 req
->in
.args
[0].size
= sizeof(inarg
);
992 req
->in
.args
[0].value
= &inarg
;
993 /* This is really two different operations rolled into one */
994 req
->out
.numargs
= 1;
997 req
->out
.args
[0].size
= size
;
998 req
->out
.args
[0].value
= list
;
1000 req
->out
.args
[0].size
= sizeof(outarg
);
1001 req
->out
.args
[0].value
= &outarg
;
1003 request_send(fc
, req
);
1004 ret
= req
->out
.h
.error
;
1006 ret
= size
? req
->out
.args
[0].size
: outarg
.size
;
1008 if (ret
== -ENOSYS
) {
1009 fc
->no_listxattr
= 1;
1013 fuse_put_request(fc
, req
);
1017 static int fuse_removexattr(struct dentry
*entry
, const char *name
)
1019 struct inode
*inode
= entry
->d_inode
;
1020 struct fuse_conn
*fc
= get_fuse_conn(inode
);
1021 struct fuse_req
*req
;
1024 if (fc
->no_removexattr
)
1027 req
= fuse_get_request(fc
);
1031 req
->in
.h
.opcode
= FUSE_REMOVEXATTR
;
1032 req
->in
.h
.nodeid
= get_node_id(inode
);
1034 req
->in
.numargs
= 1;
1035 req
->in
.args
[0].size
= strlen(name
) + 1;
1036 req
->in
.args
[0].value
= name
;
1037 request_send(fc
, req
);
1038 err
= req
->out
.h
.error
;
1039 fuse_put_request(fc
, req
);
1040 if (err
== -ENOSYS
) {
1041 fc
->no_removexattr
= 1;
1048 static struct inode_operations fuse_dir_inode_operations
= {
1049 .lookup
= fuse_lookup
,
1050 .mkdir
= fuse_mkdir
,
1051 .symlink
= fuse_symlink
,
1052 .unlink
= fuse_unlink
,
1053 .rmdir
= fuse_rmdir
,
1054 .rename
= fuse_rename
,
1056 .setattr
= fuse_setattr
,
1058 .create
= fuse_create
,
1059 .mknod
= fuse_mknod
,
1060 .permission
= fuse_permission
,
1061 .getattr
= fuse_getattr
,
1063 .create
= fuse_create_2_4
,
1064 .mknod
= fuse_mknod_2_4
,
1065 .permission
= fuse_permission_2_4
,
1066 .revalidate
= fuse_revalidate
,
1068 #ifdef HAVE_KERNEL_XATTR
1069 .setxattr
= fuse_setxattr
,
1070 .getxattr
= fuse_getxattr
,
1071 .listxattr
= fuse_listxattr
,
1072 .removexattr
= fuse_removexattr
,
1076 static struct file_operations fuse_dir_operations
= {
1077 .llseek
= generic_file_llseek
,
1078 .read
= generic_read_dir
,
1079 .readdir
= fuse_readdir
,
1080 .open
= fuse_dir_open
,
1081 .release
= fuse_dir_release
,
1082 .fsync
= fuse_dir_fsync
,
1085 static struct inode_operations fuse_common_inode_operations
= {
1086 .setattr
= fuse_setattr
,
1088 .permission
= fuse_permission
,
1089 .getattr
= fuse_getattr
,
1091 .permission
= fuse_permission_2_4
,
1092 .revalidate
= fuse_revalidate
,
1094 #ifdef HAVE_KERNEL_XATTR
1095 .setxattr
= fuse_setxattr
,
1096 .getxattr
= fuse_getxattr
,
1097 .listxattr
= fuse_listxattr
,
1098 .removexattr
= fuse_removexattr
,
1102 static struct inode_operations fuse_symlink_inode_operations
= {
1103 .setattr
= fuse_setattr
,
1104 .follow_link
= fuse_follow_link
,
1105 #ifdef KERNEL_2_6_8_PLUS
1106 .put_link
= fuse_put_link
,
1107 .readlink
= generic_readlink
,
1109 .readlink
= fuse_readlink
,
1112 .getattr
= fuse_getattr
,
1114 .revalidate
= fuse_revalidate
,
1116 #ifdef HAVE_KERNEL_XATTR
1117 .setxattr
= fuse_setxattr
,
1118 .getxattr
= fuse_getxattr
,
1119 .listxattr
= fuse_listxattr
,
1120 .removexattr
= fuse_removexattr
,
1124 void fuse_init_common(struct inode
*inode
)
1126 inode
->i_op
= &fuse_common_inode_operations
;
1129 void fuse_init_dir(struct inode
*inode
)
1131 inode
->i_op
= &fuse_dir_inode_operations
;
1132 inode
->i_fop
= &fuse_dir_operations
;
1135 void fuse_init_symlink(struct inode
*inode
)
1137 inode
->i_op
= &fuse_symlink_inode_operations
;