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>
13 #include <linux/gfp.h>
14 #include <linux/sched.h>
15 #include <linux/namei.h>
16 #include <linux/mount.h>
18 static inline unsigned long time_to_jiffies(unsigned long sec
,
21 struct timespec ts
= {sec
, nsec
};
22 return jiffies
+ timespec_to_jiffies(&ts
);
25 static void fuse_lookup_init(struct fuse_req
*req
, struct inode
*dir
,
27 struct fuse_entry_out
*outarg
)
29 req
->in
.h
.opcode
= FUSE_LOOKUP
;
30 req
->in
.h
.nodeid
= get_node_id(dir
);
33 req
->in
.args
[0].size
= entry
->d_name
.len
+ 1;
34 req
->in
.args
[0].value
= entry
->d_name
.name
;
36 req
->out
.args
[0].size
= sizeof(struct fuse_entry_out
);
37 req
->out
.args
[0].value
= outarg
;
40 static int fuse_dentry_revalidate(struct dentry
*entry
, struct nameidata
*nd
)
42 if (!entry
->d_inode
|| is_bad_inode(entry
->d_inode
))
44 else if (time_after(jiffies
, entry
->d_time
)) {
46 struct fuse_entry_out outarg
;
47 struct inode
*inode
= entry
->d_inode
;
48 struct fuse_inode
*fi
= get_fuse_inode(inode
);
49 struct fuse_conn
*fc
= get_fuse_conn(inode
);
50 struct fuse_req
*req
= fuse_get_request(fc
);
54 fuse_lookup_init(req
, entry
->d_parent
->d_inode
, entry
, &outarg
);
55 request_send(fc
, req
);
56 err
= req
->out
.h
.error
;
58 if (outarg
.nodeid
!= get_node_id(inode
)) {
59 fuse_send_forget(fc
, req
, outarg
.nodeid
, 1);
64 fuse_put_request(fc
, req
);
65 if (err
|| (outarg
.attr
.mode
^ inode
->i_mode
) & S_IFMT
)
68 fuse_change_attributes(inode
, &outarg
.attr
);
69 entry
->d_time
= time_to_jiffies(outarg
.entry_valid
,
70 outarg
.entry_valid_nsec
);
71 fi
->i_time
= time_to_jiffies(outarg
.attr_valid
,
72 outarg
.attr_valid_nsec
);
77 static struct dentry_operations fuse_dentry_operations
= {
78 .d_revalidate
= fuse_dentry_revalidate
,
81 static int fuse_lookup_iget(struct inode
*dir
, struct dentry
*entry
,
82 struct inode
**inodep
)
85 struct fuse_entry_out outarg
;
86 struct inode
*inode
= NULL
;
87 struct fuse_conn
*fc
= get_fuse_conn(dir
);
90 if (entry
->d_name
.len
> FUSE_NAME_MAX
)
93 req
= fuse_get_request(fc
);
97 fuse_lookup_init(req
, dir
, entry
, &outarg
);
98 request_send(fc
, req
);
99 err
= req
->out
.h
.error
;
100 if (!err
&& (!outarg
.nodeid
|| outarg
.nodeid
== FUSE_ROOT_ID
))
103 inode
= fuse_iget(dir
->i_sb
, outarg
.nodeid
, outarg
.generation
,
106 fuse_send_forget(fc
, req
, outarg
.nodeid
, 1);
110 fuse_put_request(fc
, req
);
111 if (err
&& err
!= -ENOENT
)
115 struct fuse_inode
*fi
= get_fuse_inode(inode
);
116 entry
->d_time
= time_to_jiffies(outarg
.entry_valid
,
117 outarg
.entry_valid_nsec
);
118 fi
->i_time
= time_to_jiffies(outarg
.attr_valid
,
119 outarg
.attr_valid_nsec
);
122 entry
->d_op
= &fuse_dentry_operations
;
127 void fuse_invalidate_attr(struct inode
*inode
)
129 get_fuse_inode(inode
)->i_time
= jiffies
- 1;
132 static void fuse_invalidate_entry(struct dentry
*entry
)
135 entry
->d_time
= jiffies
- 1;
138 static int fuse_create_open(struct inode
*dir
, struct dentry
*entry
, int mode
,
139 struct nameidata
*nd
)
143 struct fuse_conn
*fc
= get_fuse_conn(dir
);
144 struct fuse_req
*req
;
145 struct fuse_open_in inarg
;
146 struct fuse_open_out outopen
;
147 struct fuse_entry_out outentry
;
148 struct fuse_inode
*fi
;
149 struct fuse_file
*ff
;
151 int flags
= nd
->intent
.open
.flags
- 1;
158 if (entry
->d_name
.len
> FUSE_NAME_MAX
)
162 req
= fuse_get_request(fc
);
166 ff
= fuse_file_alloc();
168 goto out_put_request
;
171 memset(&inarg
, 0, sizeof(inarg
));
174 req
->in
.h
.opcode
= FUSE_CREATE
;
175 req
->in
.h
.nodeid
= get_node_id(dir
);
178 req
->in
.args
[0].size
= sizeof(inarg
);
179 req
->in
.args
[0].value
= &inarg
;
180 req
->in
.args
[1].size
= entry
->d_name
.len
+ 1;
181 req
->in
.args
[1].value
= entry
->d_name
.name
;
182 req
->out
.numargs
= 2;
183 req
->out
.args
[0].size
= sizeof(outentry
);
184 req
->out
.args
[0].value
= &outentry
;
185 req
->out
.args
[1].size
= sizeof(outopen
);
186 req
->out
.args
[1].value
= &outopen
;
187 request_send(fc
, req
);
188 err
= req
->out
.h
.error
;
196 if (!S_ISREG(outentry
.attr
.mode
))
199 inode
= fuse_iget(dir
->i_sb
, outentry
.nodeid
, outentry
.generation
,
203 flags
&= ~(O_CREAT
| O_EXCL
| O_TRUNC
);
205 fuse_send_release(fc
, ff
, outentry
.nodeid
, NULL
, flags
, 0);
206 goto out_put_request
;
208 fuse_put_request(fc
, req
);
209 entry
->d_time
= time_to_jiffies(outentry
.entry_valid
,
210 outentry
.entry_valid_nsec
);
211 fi
= get_fuse_inode(inode
);
212 fi
->i_time
= time_to_jiffies(outentry
.attr_valid
,
213 outentry
.attr_valid_nsec
);
215 d_instantiate(entry
, inode
);
216 file
= lookup_instantiate_filp(nd
, entry
, generic_file_open
);
219 fuse_send_release(fc
, ff
, outentry
.nodeid
, inode
, flags
, 0);
220 return PTR_ERR(file
);
222 fuse_finish_open(inode
, file
, ff
, &outopen
);
228 fuse_put_request(fc
, req
);
233 static int create_new_entry(struct fuse_conn
*fc
, struct fuse_req
*req
,
234 struct inode
*dir
, struct dentry
*entry
,
237 struct fuse_entry_out outarg
;
239 struct fuse_inode
*fi
;
242 req
->in
.h
.nodeid
= get_node_id(dir
);
244 req
->out
.numargs
= 1;
245 req
->out
.args
[0].size
= sizeof(outarg
);
246 req
->out
.args
[0].value
= &outarg
;
247 request_send(fc
, req
);
248 err
= req
->out
.h
.error
;
250 fuse_put_request(fc
, req
);
253 if (!outarg
.nodeid
|| outarg
.nodeid
== FUSE_ROOT_ID
) {
254 fuse_put_request(fc
, req
);
257 inode
= fuse_iget(dir
->i_sb
, outarg
.nodeid
, outarg
.generation
,
260 fuse_send_forget(fc
, req
, outarg
.nodeid
, 1);
263 fuse_put_request(fc
, req
);
265 /* Don't allow userspace to do really stupid things... */
266 if ((inode
->i_mode
^ mode
) & S_IFMT
) {
271 entry
->d_time
= time_to_jiffies(outarg
.entry_valid
,
272 outarg
.entry_valid_nsec
);
274 fi
= get_fuse_inode(inode
);
275 fi
->i_time
= time_to_jiffies(outarg
.attr_valid
,
276 outarg
.attr_valid_nsec
);
278 d_instantiate(entry
, inode
);
279 fuse_invalidate_attr(dir
);
283 static int fuse_mknod(struct inode
*dir
, struct dentry
*entry
, int mode
,
286 struct fuse_mknod_in inarg
;
287 struct fuse_conn
*fc
= get_fuse_conn(dir
);
288 struct fuse_req
*req
= fuse_get_request(fc
);
292 memset(&inarg
, 0, sizeof(inarg
));
294 inarg
.rdev
= new_encode_dev(rdev
);
295 req
->in
.h
.opcode
= FUSE_MKNOD
;
297 req
->in
.args
[0].size
= sizeof(inarg
);
298 req
->in
.args
[0].value
= &inarg
;
299 req
->in
.args
[1].size
= entry
->d_name
.len
+ 1;
300 req
->in
.args
[1].value
= entry
->d_name
.name
;
301 return create_new_entry(fc
, req
, dir
, entry
, mode
);
304 static int fuse_create(struct inode
*dir
, struct dentry
*entry
, int mode
,
305 struct nameidata
*nd
)
307 if (nd
&& (nd
->flags
& LOOKUP_CREATE
)) {
308 int err
= fuse_create_open(dir
, entry
, mode
, nd
);
311 /* Fall back on mknod */
313 return fuse_mknod(dir
, entry
, mode
, 0);
316 static int fuse_mkdir(struct inode
*dir
, struct dentry
*entry
, int mode
)
318 struct fuse_mkdir_in inarg
;
319 struct fuse_conn
*fc
= get_fuse_conn(dir
);
320 struct fuse_req
*req
= fuse_get_request(fc
);
324 memset(&inarg
, 0, sizeof(inarg
));
326 req
->in
.h
.opcode
= FUSE_MKDIR
;
328 req
->in
.args
[0].size
= sizeof(inarg
);
329 req
->in
.args
[0].value
= &inarg
;
330 req
->in
.args
[1].size
= entry
->d_name
.len
+ 1;
331 req
->in
.args
[1].value
= entry
->d_name
.name
;
332 return create_new_entry(fc
, req
, dir
, entry
, S_IFDIR
);
335 static int fuse_symlink(struct inode
*dir
, struct dentry
*entry
,
338 struct fuse_conn
*fc
= get_fuse_conn(dir
);
339 unsigned len
= strlen(link
) + 1;
340 struct fuse_req
*req
;
342 if (len
> FUSE_SYMLINK_MAX
)
343 return -ENAMETOOLONG
;
345 req
= fuse_get_request(fc
);
349 req
->in
.h
.opcode
= FUSE_SYMLINK
;
351 req
->in
.args
[0].size
= entry
->d_name
.len
+ 1;
352 req
->in
.args
[0].value
= entry
->d_name
.name
;
353 req
->in
.args
[1].size
= len
;
354 req
->in
.args
[1].value
= link
;
355 return create_new_entry(fc
, req
, dir
, entry
, S_IFLNK
);
358 static int fuse_unlink(struct inode
*dir
, struct dentry
*entry
)
361 struct fuse_conn
*fc
= get_fuse_conn(dir
);
362 struct fuse_req
*req
= fuse_get_request(fc
);
366 req
->in
.h
.opcode
= FUSE_UNLINK
;
367 req
->in
.h
.nodeid
= get_node_id(dir
);
370 req
->in
.args
[0].size
= entry
->d_name
.len
+ 1;
371 req
->in
.args
[0].value
= entry
->d_name
.name
;
372 request_send(fc
, req
);
373 err
= req
->out
.h
.error
;
374 fuse_put_request(fc
, req
);
376 struct inode
*inode
= entry
->d_inode
;
378 /* Set nlink to zero so the inode can be cleared, if
379 the inode does have more links this will be
380 discovered at the next lookup/getattr */
382 fuse_invalidate_attr(inode
);
383 fuse_invalidate_attr(dir
);
384 } else if (err
== -EINTR
)
385 fuse_invalidate_entry(entry
);
389 static int fuse_rmdir(struct inode
*dir
, struct dentry
*entry
)
392 struct fuse_conn
*fc
= get_fuse_conn(dir
);
393 struct fuse_req
*req
= fuse_get_request(fc
);
397 req
->in
.h
.opcode
= FUSE_RMDIR
;
398 req
->in
.h
.nodeid
= get_node_id(dir
);
401 req
->in
.args
[0].size
= entry
->d_name
.len
+ 1;
402 req
->in
.args
[0].value
= entry
->d_name
.name
;
403 request_send(fc
, req
);
404 err
= req
->out
.h
.error
;
405 fuse_put_request(fc
, req
);
407 entry
->d_inode
->i_nlink
= 0;
408 fuse_invalidate_attr(dir
);
409 } else if (err
== -EINTR
)
410 fuse_invalidate_entry(entry
);
414 static int fuse_rename(struct inode
*olddir
, struct dentry
*oldent
,
415 struct inode
*newdir
, struct dentry
*newent
)
418 struct fuse_rename_in inarg
;
419 struct fuse_conn
*fc
= get_fuse_conn(olddir
);
420 struct fuse_req
*req
= fuse_get_request(fc
);
424 memset(&inarg
, 0, sizeof(inarg
));
425 inarg
.newdir
= get_node_id(newdir
);
426 req
->in
.h
.opcode
= FUSE_RENAME
;
427 req
->in
.h
.nodeid
= get_node_id(olddir
);
429 req
->inode2
= newdir
;
431 req
->in
.args
[0].size
= sizeof(inarg
);
432 req
->in
.args
[0].value
= &inarg
;
433 req
->in
.args
[1].size
= oldent
->d_name
.len
+ 1;
434 req
->in
.args
[1].value
= oldent
->d_name
.name
;
435 req
->in
.args
[2].size
= newent
->d_name
.len
+ 1;
436 req
->in
.args
[2].value
= newent
->d_name
.name
;
437 request_send(fc
, req
);
438 err
= req
->out
.h
.error
;
439 fuse_put_request(fc
, req
);
441 fuse_invalidate_attr(olddir
);
442 if (olddir
!= newdir
)
443 fuse_invalidate_attr(newdir
);
444 } else if (err
== -EINTR
) {
445 /* If request was interrupted, DEITY only knows if the
446 rename actually took place. If the invalidation
447 fails (e.g. some process has CWD under the renamed
448 directory), then there can be inconsistency between
449 the dcache and the real filesystem. Tough luck. */
450 fuse_invalidate_entry(oldent
);
452 fuse_invalidate_entry(newent
);
458 static int fuse_link(struct dentry
*entry
, struct inode
*newdir
,
459 struct dentry
*newent
)
462 struct fuse_link_in inarg
;
463 struct inode
*inode
= entry
->d_inode
;
464 struct fuse_conn
*fc
= get_fuse_conn(inode
);
465 struct fuse_req
*req
= fuse_get_request(fc
);
469 memset(&inarg
, 0, sizeof(inarg
));
470 inarg
.oldnodeid
= get_node_id(inode
);
471 req
->in
.h
.opcode
= FUSE_LINK
;
474 req
->in
.args
[0].size
= sizeof(inarg
);
475 req
->in
.args
[0].value
= &inarg
;
476 req
->in
.args
[1].size
= newent
->d_name
.len
+ 1;
477 req
->in
.args
[1].value
= newent
->d_name
.name
;
478 err
= create_new_entry(fc
, req
, newdir
, newent
, inode
->i_mode
);
479 /* Contrary to "normal" filesystems it can happen that link
480 makes two "logical" inodes point to the same "physical"
481 inode. We invalidate the attributes of the old one, so it
482 will reflect changes in the backing inode (link count,
485 if (!err
|| err
== -EINTR
)
486 fuse_invalidate_attr(inode
);
490 int fuse_do_getattr(struct inode
*inode
)
493 struct fuse_attr_out arg
;
494 struct fuse_conn
*fc
= get_fuse_conn(inode
);
495 struct fuse_req
*req
= fuse_get_request(fc
);
499 req
->in
.h
.opcode
= FUSE_GETATTR
;
500 req
->in
.h
.nodeid
= get_node_id(inode
);
502 req
->out
.numargs
= 1;
503 req
->out
.args
[0].size
= sizeof(arg
);
504 req
->out
.args
[0].value
= &arg
;
505 request_send(fc
, req
);
506 err
= req
->out
.h
.error
;
507 fuse_put_request(fc
, req
);
509 if ((inode
->i_mode
^ arg
.attr
.mode
) & S_IFMT
) {
510 make_bad_inode(inode
);
513 struct fuse_inode
*fi
= get_fuse_inode(inode
);
514 fuse_change_attributes(inode
, &arg
.attr
);
515 fi
->i_time
= time_to_jiffies(arg
.attr_valid
,
516 arg
.attr_valid_nsec
);
523 * Calling into a user-controlled filesystem gives the filesystem
524 * daemon ptrace-like capabilities over the requester process. This
525 * means, that the filesystem daemon is able to record the exact
526 * filesystem operations performed, and can also control the behavior
527 * of the requester process in otherwise impossible ways. For example
528 * it can delay the operation for arbitrary length of time allowing
529 * DoS against the requester.
531 * For this reason only those processes can call into the filesystem,
532 * for which the owner of the mount has ptrace privilege. This
533 * excludes processes started by other users, suid or sgid processes.
535 static int fuse_allow_task(struct fuse_conn
*fc
, struct task_struct
*task
)
537 if (fc
->flags
& FUSE_ALLOW_OTHER
)
540 if (task
->euid
== fc
->user_id
&&
541 task
->suid
== fc
->user_id
&&
542 task
->uid
== fc
->user_id
&&
543 task
->egid
== fc
->group_id
&&
544 task
->sgid
== fc
->group_id
&&
545 task
->gid
== fc
->group_id
)
551 static int fuse_revalidate(struct dentry
*entry
)
553 struct inode
*inode
= entry
->d_inode
;
554 struct fuse_inode
*fi
= get_fuse_inode(inode
);
555 struct fuse_conn
*fc
= get_fuse_conn(inode
);
557 if (!fuse_allow_task(fc
, current
))
559 if (get_node_id(inode
) != FUSE_ROOT_ID
&&
560 time_before_eq(jiffies
, fi
->i_time
))
563 return fuse_do_getattr(inode
);
566 static int fuse_access(struct inode
*inode
, int mask
)
568 struct fuse_conn
*fc
= get_fuse_conn(inode
);
569 struct fuse_req
*req
;
570 struct fuse_access_in inarg
;
576 req
= fuse_get_request(fc
);
580 memset(&inarg
, 0, sizeof(inarg
));
582 req
->in
.h
.opcode
= FUSE_ACCESS
;
583 req
->in
.h
.nodeid
= get_node_id(inode
);
586 req
->in
.args
[0].size
= sizeof(inarg
);
587 req
->in
.args
[0].value
= &inarg
;
588 request_send(fc
, req
);
589 err
= req
->out
.h
.error
;
590 fuse_put_request(fc
, req
);
591 if (err
== -ENOSYS
) {
598 static int fuse_permission(struct inode
*inode
, int mask
, struct nameidata
*nd
)
600 struct fuse_conn
*fc
= get_fuse_conn(inode
);
602 if (!fuse_allow_task(fc
, current
))
604 else if (fc
->flags
& FUSE_DEFAULT_PERMISSIONS
) {
605 int err
= generic_permission(inode
, mask
, NULL
);
607 /* If permission is denied, try to refresh file
608 attributes. This is also needed, because the root
609 node will at first have no permissions */
610 if (err
== -EACCES
) {
611 err
= fuse_do_getattr(inode
);
613 err
= generic_permission(inode
, mask
, NULL
);
616 /* FIXME: Need some mechanism to revoke permissions:
617 currently if the filesystem suddenly changes the
618 file mode, we will not be informed about it, and
619 continue to allow access to the file/directory.
621 This is actually not so grave, since the user can
622 simply keep access to the file/directory anyway by
623 keeping it open... */
627 int mode
= inode
->i_mode
;
628 if ((mask
& MAY_EXEC
) && !S_ISDIR(mode
) && !(mode
& S_IXUGO
))
631 if (nd
&& (nd
->flags
& LOOKUP_ACCESS
))
632 return fuse_access(inode
, mask
);
637 static int parse_dirfile(char *buf
, size_t nbytes
, struct file
*file
,
638 void *dstbuf
, filldir_t filldir
)
640 while (nbytes
>= FUSE_NAME_OFFSET
) {
641 struct fuse_dirent
*dirent
= (struct fuse_dirent
*) buf
;
642 size_t reclen
= FUSE_DIRENT_SIZE(dirent
);
644 if (!dirent
->namelen
|| dirent
->namelen
> FUSE_NAME_MAX
)
649 over
= filldir(dstbuf
, dirent
->name
, dirent
->namelen
,
650 file
->f_pos
, dirent
->ino
, dirent
->type
);
656 file
->f_pos
= dirent
->off
;
662 static inline size_t fuse_send_readdir(struct fuse_req
*req
, struct file
*file
,
663 struct inode
*inode
, loff_t pos
,
666 return fuse_send_read_common(req
, file
, inode
, pos
, count
, 1);
669 static int fuse_readdir(struct file
*file
, void *dstbuf
, filldir_t filldir
)
674 struct inode
*inode
= file
->f_dentry
->d_inode
;
675 struct fuse_conn
*fc
= get_fuse_conn(inode
);
676 struct fuse_req
*req
= fuse_get_request(fc
);
680 page
= alloc_page(GFP_KERNEL
);
682 fuse_put_request(fc
, req
);
686 req
->pages
[0] = page
;
687 nbytes
= fuse_send_readdir(req
, file
, inode
, file
->f_pos
, PAGE_SIZE
);
688 err
= req
->out
.h
.error
;
689 fuse_put_request(fc
, req
);
691 err
= parse_dirfile(page_address(page
), nbytes
, file
, dstbuf
,
695 fuse_invalidate_attr(inode
); /* atime changed */
699 static char *read_link(struct dentry
*dentry
)
701 struct inode
*inode
= dentry
->d_inode
;
702 struct fuse_conn
*fc
= get_fuse_conn(inode
);
703 struct fuse_req
*req
= fuse_get_request(fc
);
707 return ERR_PTR(-EINTR
);
709 link
= (char *) __get_free_page(GFP_KERNEL
);
711 link
= ERR_PTR(-ENOMEM
);
714 req
->in
.h
.opcode
= FUSE_READLINK
;
715 req
->in
.h
.nodeid
= get_node_id(inode
);
718 req
->out
.numargs
= 1;
719 req
->out
.args
[0].size
= PAGE_SIZE
- 1;
720 req
->out
.args
[0].value
= link
;
721 request_send(fc
, req
);
722 if (req
->out
.h
.error
) {
723 free_page((unsigned long) link
);
724 link
= ERR_PTR(req
->out
.h
.error
);
726 link
[req
->out
.args
[0].size
] = '\0';
728 fuse_put_request(fc
, req
);
729 fuse_invalidate_attr(inode
); /* atime changed */
733 static void free_link(char *link
)
736 free_page((unsigned long) link
);
739 static void *fuse_follow_link(struct dentry
*dentry
, struct nameidata
*nd
)
741 nd_set_link(nd
, read_link(dentry
));
745 static void fuse_put_link(struct dentry
*dentry
, struct nameidata
*nd
, void *c
)
747 free_link(nd_get_link(nd
));
750 static int fuse_dir_open(struct inode
*inode
, struct file
*file
)
752 return fuse_open_common(inode
, file
, 1);
755 static int fuse_dir_release(struct inode
*inode
, struct file
*file
)
757 return fuse_release_common(inode
, file
, 1);
760 static int fuse_dir_fsync(struct file
*file
, struct dentry
*de
, int datasync
)
762 /* nfsd can call this with no file */
763 return file
? fuse_fsync_common(file
, de
, datasync
, 1) : 0;
766 static void iattr_to_fattr(struct iattr
*iattr
, struct fuse_setattr_in
*arg
)
768 unsigned ivalid
= iattr
->ia_valid
;
770 if (ivalid
& ATTR_MODE
)
771 arg
->valid
|= FATTR_MODE
, arg
->mode
= iattr
->ia_mode
;
772 if (ivalid
& ATTR_UID
)
773 arg
->valid
|= FATTR_UID
, arg
->uid
= iattr
->ia_uid
;
774 if (ivalid
& ATTR_GID
)
775 arg
->valid
|= FATTR_GID
, arg
->gid
= iattr
->ia_gid
;
776 if (ivalid
& ATTR_SIZE
)
777 arg
->valid
|= FATTR_SIZE
, arg
->size
= iattr
->ia_size
;
778 /* You can only _set_ these together (they may change by themselves) */
779 if ((ivalid
& (ATTR_ATIME
| ATTR_MTIME
)) == (ATTR_ATIME
| ATTR_MTIME
)) {
780 arg
->valid
|= FATTR_ATIME
| FATTR_MTIME
;
781 arg
->atime
= iattr
->ia_atime
.tv_sec
;
782 arg
->mtime
= iattr
->ia_mtime
.tv_sec
;
784 if (ivalid
& ATTR_FILE
) {
785 struct fuse_file
*ff
= iattr
->ia_file
->private_data
;
786 arg
->valid
|= FATTR_FH
;
791 static int fuse_setattr(struct dentry
*entry
, struct iattr
*attr
)
793 struct inode
*inode
= entry
->d_inode
;
794 struct fuse_conn
*fc
= get_fuse_conn(inode
);
795 struct fuse_inode
*fi
= get_fuse_inode(inode
);
796 struct fuse_req
*req
;
797 struct fuse_setattr_in inarg
;
798 struct fuse_attr_out outarg
;
802 if (fc
->flags
& FUSE_DEFAULT_PERMISSIONS
) {
803 err
= inode_change_ok(inode
, attr
);
808 if (attr
->ia_valid
& ATTR_SIZE
) {
811 limit
= current
->signal
->rlim
[RLIMIT_FSIZE
].rlim_cur
;
812 if (limit
!= RLIM_INFINITY
&& attr
->ia_size
> (loff_t
) limit
) {
813 send_sig(SIGXFSZ
, current
, 0);
818 req
= fuse_get_request(fc
);
822 memset(&inarg
, 0, sizeof(inarg
));
823 iattr_to_fattr(attr
, &inarg
);
824 req
->in
.h
.opcode
= FUSE_SETATTR
;
825 req
->in
.h
.nodeid
= get_node_id(inode
);
828 req
->in
.args
[0].size
= sizeof(inarg
);
829 req
->in
.args
[0].value
= &inarg
;
830 req
->out
.numargs
= 1;
831 req
->out
.args
[0].size
= sizeof(outarg
);
832 req
->out
.args
[0].value
= &outarg
;
833 request_send(fc
, req
);
834 err
= req
->out
.h
.error
;
835 fuse_put_request(fc
, req
);
837 if ((inode
->i_mode
^ outarg
.attr
.mode
) & S_IFMT
) {
838 make_bad_inode(inode
);
842 loff_t origsize
= i_size_read(inode
);
843 i_size_write(inode
, outarg
.attr
.size
);
844 if (origsize
> outarg
.attr
.size
)
845 vmtruncate(inode
, outarg
.attr
.size
);
847 fuse_change_attributes(inode
, &outarg
.attr
);
848 fi
->i_time
= time_to_jiffies(outarg
.attr_valid
,
849 outarg
.attr_valid_nsec
);
851 } else if (err
== -EINTR
)
852 fuse_invalidate_attr(inode
);
857 static int fuse_getattr(struct vfsmount
*mnt
, struct dentry
*entry
,
860 struct inode
*inode
= entry
->d_inode
;
861 int err
= fuse_revalidate(entry
);
863 generic_fillattr(inode
, stat
);
868 static struct dentry
*fuse_lookup(struct inode
*dir
, struct dentry
*entry
,
869 struct nameidata
*nd
)
874 err
= fuse_lookup_iget(dir
, entry
, &inode
);
877 if (inode
&& S_ISDIR(inode
->i_mode
)) {
878 /* Don't allow creating an alias to a directory */
879 struct dentry
*alias
= d_find_alias(inode
);
883 return ERR_PTR(-EIO
);
890 static int fuse_setxattr(struct dentry
*entry
, const char *name
,
891 const void *value
, size_t size
, int flags
)
893 struct inode
*inode
= entry
->d_inode
;
894 struct fuse_conn
*fc
= get_fuse_conn(inode
);
895 struct fuse_req
*req
;
896 struct fuse_setxattr_in inarg
;
899 if (size
> FUSE_XATTR_SIZE_MAX
)
905 req
= fuse_get_request(fc
);
909 memset(&inarg
, 0, sizeof(inarg
));
912 req
->in
.h
.opcode
= FUSE_SETXATTR
;
913 req
->in
.h
.nodeid
= get_node_id(inode
);
916 req
->in
.args
[0].size
= sizeof(inarg
);
917 req
->in
.args
[0].value
= &inarg
;
918 req
->in
.args
[1].size
= strlen(name
) + 1;
919 req
->in
.args
[1].value
= name
;
920 req
->in
.args
[2].size
= size
;
921 req
->in
.args
[2].value
= value
;
922 request_send(fc
, req
);
923 err
= req
->out
.h
.error
;
924 fuse_put_request(fc
, req
);
925 if (err
== -ENOSYS
) {
932 static ssize_t
fuse_getxattr(struct dentry
*entry
, const char *name
,
933 void *value
, size_t size
)
935 struct inode
*inode
= entry
->d_inode
;
936 struct fuse_conn
*fc
= get_fuse_conn(inode
);
937 struct fuse_req
*req
;
938 struct fuse_getxattr_in inarg
;
939 struct fuse_getxattr_out outarg
;
945 req
= fuse_get_request(fc
);
949 memset(&inarg
, 0, sizeof(inarg
));
951 req
->in
.h
.opcode
= FUSE_GETXATTR
;
952 req
->in
.h
.nodeid
= get_node_id(inode
);
955 req
->in
.args
[0].size
= sizeof(inarg
);
956 req
->in
.args
[0].value
= &inarg
;
957 req
->in
.args
[1].size
= strlen(name
) + 1;
958 req
->in
.args
[1].value
= name
;
959 /* This is really two different operations rolled into one */
960 req
->out
.numargs
= 1;
963 req
->out
.args
[0].size
= size
;
964 req
->out
.args
[0].value
= value
;
966 req
->out
.args
[0].size
= sizeof(outarg
);
967 req
->out
.args
[0].value
= &outarg
;
969 request_send(fc
, req
);
970 ret
= req
->out
.h
.error
;
972 ret
= size
? req
->out
.args
[0].size
: outarg
.size
;
974 if (ret
== -ENOSYS
) {
979 fuse_put_request(fc
, req
);
983 static ssize_t
fuse_listxattr(struct dentry
*entry
, char *list
, size_t size
)
985 struct inode
*inode
= entry
->d_inode
;
986 struct fuse_conn
*fc
= get_fuse_conn(inode
);
987 struct fuse_req
*req
;
988 struct fuse_getxattr_in inarg
;
989 struct fuse_getxattr_out outarg
;
992 if (fc
->no_listxattr
)
995 req
= fuse_get_request(fc
);
999 memset(&inarg
, 0, sizeof(inarg
));
1001 req
->in
.h
.opcode
= FUSE_LISTXATTR
;
1002 req
->in
.h
.nodeid
= get_node_id(inode
);
1004 req
->in
.numargs
= 1;
1005 req
->in
.args
[0].size
= sizeof(inarg
);
1006 req
->in
.args
[0].value
= &inarg
;
1007 /* This is really two different operations rolled into one */
1008 req
->out
.numargs
= 1;
1010 req
->out
.argvar
= 1;
1011 req
->out
.args
[0].size
= size
;
1012 req
->out
.args
[0].value
= list
;
1014 req
->out
.args
[0].size
= sizeof(outarg
);
1015 req
->out
.args
[0].value
= &outarg
;
1017 request_send(fc
, req
);
1018 ret
= req
->out
.h
.error
;
1020 ret
= size
? req
->out
.args
[0].size
: outarg
.size
;
1022 if (ret
== -ENOSYS
) {
1023 fc
->no_listxattr
= 1;
1027 fuse_put_request(fc
, req
);
1031 static int fuse_removexattr(struct dentry
*entry
, const char *name
)
1033 struct inode
*inode
= entry
->d_inode
;
1034 struct fuse_conn
*fc
= get_fuse_conn(inode
);
1035 struct fuse_req
*req
;
1038 if (fc
->no_removexattr
)
1041 req
= fuse_get_request(fc
);
1045 req
->in
.h
.opcode
= FUSE_REMOVEXATTR
;
1046 req
->in
.h
.nodeid
= get_node_id(inode
);
1048 req
->in
.numargs
= 1;
1049 req
->in
.args
[0].size
= strlen(name
) + 1;
1050 req
->in
.args
[0].value
= name
;
1051 request_send(fc
, req
);
1052 err
= req
->out
.h
.error
;
1053 fuse_put_request(fc
, req
);
1054 if (err
== -ENOSYS
) {
1055 fc
->no_removexattr
= 1;
1061 static struct inode_operations fuse_dir_inode_operations
= {
1062 .lookup
= fuse_lookup
,
1063 .mkdir
= fuse_mkdir
,
1064 .symlink
= fuse_symlink
,
1065 .unlink
= fuse_unlink
,
1066 .rmdir
= fuse_rmdir
,
1067 .rename
= fuse_rename
,
1069 .setattr
= fuse_setattr
,
1070 .create
= fuse_create
,
1071 .mknod
= fuse_mknod
,
1072 .permission
= fuse_permission
,
1073 .getattr
= fuse_getattr
,
1074 .setxattr
= fuse_setxattr
,
1075 .getxattr
= fuse_getxattr
,
1076 .listxattr
= fuse_listxattr
,
1077 .removexattr
= fuse_removexattr
,
1080 static struct file_operations fuse_dir_operations
= {
1081 .llseek
= generic_file_llseek
,
1082 .read
= generic_read_dir
,
1083 .readdir
= fuse_readdir
,
1084 .open
= fuse_dir_open
,
1085 .release
= fuse_dir_release
,
1086 .fsync
= fuse_dir_fsync
,
1089 static struct inode_operations fuse_common_inode_operations
= {
1090 .setattr
= fuse_setattr
,
1091 .permission
= fuse_permission
,
1092 .getattr
= fuse_getattr
,
1093 .setxattr
= fuse_setxattr
,
1094 .getxattr
= fuse_getxattr
,
1095 .listxattr
= fuse_listxattr
,
1096 .removexattr
= fuse_removexattr
,
1099 static struct inode_operations fuse_symlink_inode_operations
= {
1100 .setattr
= fuse_setattr
,
1101 .follow_link
= fuse_follow_link
,
1102 .put_link
= fuse_put_link
,
1103 .readlink
= generic_readlink
,
1104 .getattr
= fuse_getattr
,
1105 .setxattr
= fuse_setxattr
,
1106 .getxattr
= fuse_getxattr
,
1107 .listxattr
= fuse_listxattr
,
1108 .removexattr
= fuse_removexattr
,
1111 void fuse_init_common(struct inode
*inode
)
1113 inode
->i_op
= &fuse_common_inode_operations
;
1116 void fuse_init_dir(struct inode
*inode
)
1118 inode
->i_op
= &fuse_dir_inode_operations
;
1119 inode
->i_fop
= &fuse_dir_operations
;
1122 void fuse_init_symlink(struct inode
*inode
)
1124 inode
->i_op
= &fuse_symlink_inode_operations
;