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>
17 static inline unsigned long time_to_jiffies(unsigned long sec,
20 struct timespec ts = {sec, nsec};
21 return jiffies + timespec_to_jiffies(&ts);
24 static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o)
26 entry->d_time = time_to_jiffies(o->entry_valid, o->entry_valid_nsec);
28 get_fuse_inode(entry->d_inode)->i_time =
29 time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
32 void fuse_invalidate_attr(struct inode *inode)
34 get_fuse_inode(inode)->i_time = jiffies - 1;
37 static void fuse_invalidate_entry_cache(struct dentry *entry)
39 entry->d_time = jiffies - 1;
42 static void fuse_invalidate_entry(struct dentry *entry)
45 fuse_invalidate_entry_cache(entry);
48 static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
50 struct fuse_entry_out *outarg)
52 req->in.h.opcode = FUSE_LOOKUP;
53 req->in.h.nodeid = get_node_id(dir);
56 req->in.args[0].size = entry->d_name.len + 1;
57 req->in.args[0].value = entry->d_name.name;
59 req->out.args[0].size = sizeof(struct fuse_entry_out);
60 req->out.args[0].value = outarg;
63 static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
65 struct inode *inode = entry->d_inode;
67 if (inode && is_bad_inode(inode))
69 else if (time_after(jiffies, entry->d_time)) {
71 struct fuse_entry_out outarg;
75 fuse_invalidate_entry_cache(entry);
79 fc = get_fuse_conn(inode);
80 req = fuse_get_request(fc);
84 fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg);
85 request_send(fc, req);
86 err = req->out.h.error;
88 struct fuse_inode *fi = get_fuse_inode(inode);
89 if (outarg.nodeid != get_node_id(inode)) {
90 fuse_send_forget(fc, req, outarg.nodeid, 1);
95 fuse_put_request(fc, req);
96 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
99 fuse_change_attributes(inode, &outarg.attr);
100 fuse_change_timeout(entry, &outarg);
105 static int dir_alias(struct inode *inode)
107 if (S_ISDIR(inode->i_mode)) {
108 /* Don't allow creating an alias to a directory */
109 struct dentry *alias = d_find_alias(inode);
118 static inline int invalid_nodeid(u64 nodeid)
120 return !nodeid || nodeid == FUSE_ROOT_ID;
123 static struct dentry_operations fuse_dentry_operations = {
124 .d_revalidate = fuse_dentry_revalidate,
127 static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
128 struct nameidata *nd)
131 struct fuse_entry_out outarg;
132 struct inode *inode = NULL;
133 struct fuse_conn *fc = get_fuse_conn(dir);
134 struct fuse_req *req;
136 if (entry->d_name.len > FUSE_NAME_MAX)
137 return ERR_PTR(-ENAMETOOLONG);
139 req = fuse_get_request(fc);
141 return ERR_PTR(-EINTR);
143 fuse_lookup_init(req, dir, entry, &outarg);
144 request_send(fc, req);
145 err = req->out.h.error;
146 if (!err && outarg.nodeid && invalid_nodeid(outarg.nodeid))
148 if (!err && outarg.nodeid) {
149 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
152 fuse_send_forget(fc, req, outarg.nodeid, 1);
153 return ERR_PTR(-ENOMEM);
156 fuse_put_request(fc, req);
157 if (err && err != -ENOENT)
160 if (inode && dir_alias(inode)) {
162 return ERR_PTR(-EIO);
165 entry->d_op = &fuse_dentry_operations;
167 fuse_change_timeout(entry, &outarg);
169 fuse_invalidate_entry_cache(entry);
173 static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
174 struct nameidata *nd)
178 struct fuse_conn *fc = get_fuse_conn(dir);
179 struct fuse_req *req;
180 struct fuse_open_in inarg;
181 struct fuse_open_out outopen;
182 struct fuse_entry_out outentry;
183 struct fuse_file *ff;
185 int flags = nd->intent.open.flags - 1;
192 if (entry->d_name.len > FUSE_NAME_MAX)
196 req = fuse_get_request(fc);
200 ff = fuse_file_alloc();
202 goto out_put_request;
205 memset(&inarg, 0, sizeof(inarg));
208 req->in.h.opcode = FUSE_CREATE;
209 req->in.h.nodeid = get_node_id(dir);
212 req->in.args[0].size = sizeof(inarg);
213 req->in.args[0].value = &inarg;
214 req->in.args[1].size = entry->d_name.len + 1;
215 req->in.args[1].value = entry->d_name.name;
216 req->out.numargs = 2;
217 req->out.args[0].size = sizeof(outentry);
218 req->out.args[0].value = &outentry;
219 req->out.args[1].size = sizeof(outopen);
220 req->out.args[1].value = &outopen;
221 request_send(fc, req);
222 err = req->out.h.error;
230 if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
233 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
237 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
239 fuse_send_release(fc, ff, outentry.nodeid, NULL, flags, 0);
240 goto out_put_request;
242 fuse_put_request(fc, req);
243 d_instantiate(entry, inode);
244 fuse_change_timeout(entry, &outentry);
245 file = lookup_instantiate_filp(nd, entry, generic_file_open);
248 fuse_send_release(fc, ff, outentry.nodeid, inode, flags, 0);
249 return PTR_ERR(file);
251 fuse_finish_open(inode, file, ff, &outopen);
257 fuse_put_request(fc, req);
262 static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
263 struct inode *dir, struct dentry *entry,
266 struct fuse_entry_out outarg;
270 req->in.h.nodeid = get_node_id(dir);
272 req->out.numargs = 1;
273 req->out.args[0].size = sizeof(outarg);
274 req->out.args[0].value = &outarg;
275 request_send(fc, req);
276 err = req->out.h.error;
278 fuse_put_request(fc, req);
281 if (invalid_nodeid(outarg.nodeid)) {
282 fuse_put_request(fc, req);
285 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
288 fuse_send_forget(fc, req, outarg.nodeid, 1);
291 fuse_put_request(fc, req);
293 /* Don't allow userspace to do really stupid things... */
294 if (((inode->i_mode ^ mode) & S_IFMT) || dir_alias(inode)) {
299 d_instantiate(entry, inode);
300 fuse_change_timeout(entry, &outarg);
301 fuse_invalidate_attr(dir);
305 static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
308 struct fuse_mknod_in inarg;
309 struct fuse_conn *fc = get_fuse_conn(dir);
310 struct fuse_req *req = fuse_get_request(fc);
314 memset(&inarg, 0, sizeof(inarg));
316 inarg.rdev = new_encode_dev(rdev);
317 req->in.h.opcode = FUSE_MKNOD;
319 req->in.args[0].size = sizeof(inarg);
320 req->in.args[0].value = &inarg;
321 req->in.args[1].size = entry->d_name.len + 1;
322 req->in.args[1].value = entry->d_name.name;
323 return create_new_entry(fc, req, dir, entry, mode);
326 static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
327 struct nameidata *nd)
329 if (nd && (nd->flags & LOOKUP_CREATE)) {
330 int err = fuse_create_open(dir, entry, mode, nd);
333 /* Fall back on mknod */
335 return fuse_mknod(dir, entry, mode, 0);
338 static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
340 struct fuse_mkdir_in inarg;
341 struct fuse_conn *fc = get_fuse_conn(dir);
342 struct fuse_req *req = fuse_get_request(fc);
346 memset(&inarg, 0, sizeof(inarg));
348 req->in.h.opcode = FUSE_MKDIR;
350 req->in.args[0].size = sizeof(inarg);
351 req->in.args[0].value = &inarg;
352 req->in.args[1].size = entry->d_name.len + 1;
353 req->in.args[1].value = entry->d_name.name;
354 return create_new_entry(fc, req, dir, entry, S_IFDIR);
357 static int fuse_symlink(struct inode *dir, struct dentry *entry,
360 struct fuse_conn *fc = get_fuse_conn(dir);
361 unsigned len = strlen(link) + 1;
362 struct fuse_req *req;
364 if (len > FUSE_SYMLINK_MAX)
365 return -ENAMETOOLONG;
367 req = fuse_get_request(fc);
371 req->in.h.opcode = FUSE_SYMLINK;
373 req->in.args[0].size = entry->d_name.len + 1;
374 req->in.args[0].value = entry->d_name.name;
375 req->in.args[1].size = len;
376 req->in.args[1].value = link;
377 return create_new_entry(fc, req, dir, entry, S_IFLNK);
380 static int fuse_unlink(struct inode *dir, struct dentry *entry)
383 struct fuse_conn *fc = get_fuse_conn(dir);
384 struct fuse_req *req = fuse_get_request(fc);
388 req->in.h.opcode = FUSE_UNLINK;
389 req->in.h.nodeid = get_node_id(dir);
392 req->in.args[0].size = entry->d_name.len + 1;
393 req->in.args[0].value = entry->d_name.name;
394 request_send(fc, req);
395 err = req->out.h.error;
396 fuse_put_request(fc, req);
398 struct inode *inode = entry->d_inode;
400 /* Set nlink to zero so the inode can be cleared, if
401 the inode does have more links this will be
402 discovered at the next lookup/getattr */
404 fuse_invalidate_attr(inode);
405 fuse_invalidate_attr(dir);
406 fuse_invalidate_entry_cache(entry);
407 } else if (err == -EINTR)
408 fuse_invalidate_entry(entry);
412 static int fuse_rmdir(struct inode *dir, struct dentry *entry)
415 struct fuse_conn *fc = get_fuse_conn(dir);
416 struct fuse_req *req = fuse_get_request(fc);
420 req->in.h.opcode = FUSE_RMDIR;
421 req->in.h.nodeid = get_node_id(dir);
424 req->in.args[0].size = entry->d_name.len + 1;
425 req->in.args[0].value = entry->d_name.name;
426 request_send(fc, req);
427 err = req->out.h.error;
428 fuse_put_request(fc, req);
430 entry->d_inode->i_nlink = 0;
431 fuse_invalidate_attr(dir);
432 fuse_invalidate_entry_cache(entry);
433 } else if (err == -EINTR)
434 fuse_invalidate_entry(entry);
438 static int fuse_rename(struct inode *olddir, struct dentry *oldent,
439 struct inode *newdir, struct dentry *newent)
442 struct fuse_rename_in inarg;
443 struct fuse_conn *fc = get_fuse_conn(olddir);
444 struct fuse_req *req = fuse_get_request(fc);
448 memset(&inarg, 0, sizeof(inarg));
449 inarg.newdir = get_node_id(newdir);
450 req->in.h.opcode = FUSE_RENAME;
451 req->in.h.nodeid = get_node_id(olddir);
453 req->inode2 = newdir;
455 req->in.args[0].size = sizeof(inarg);
456 req->in.args[0].value = &inarg;
457 req->in.args[1].size = oldent->d_name.len + 1;
458 req->in.args[1].value = oldent->d_name.name;
459 req->in.args[2].size = newent->d_name.len + 1;
460 req->in.args[2].value = newent->d_name.name;
461 request_send(fc, req);
462 err = req->out.h.error;
463 fuse_put_request(fc, req);
465 fuse_invalidate_attr(olddir);
466 if (olddir != newdir)
467 fuse_invalidate_attr(newdir);
469 /* newent will end up negative */
471 fuse_invalidate_entry_cache(newent);
472 } else if (err == -EINTR) {
473 /* If request was interrupted, DEITY only knows if the
474 rename actually took place. If the invalidation
475 fails (e.g. some process has CWD under the renamed
476 directory), then there can be inconsistency between
477 the dcache and the real filesystem. Tough luck. */
478 fuse_invalidate_entry(oldent);
480 fuse_invalidate_entry(newent);
486 static int fuse_link(struct dentry *entry, struct inode *newdir,
487 struct dentry *newent)
490 struct fuse_link_in inarg;
491 struct inode *inode = entry->d_inode;
492 struct fuse_conn *fc = get_fuse_conn(inode);
493 struct fuse_req *req = fuse_get_request(fc);
497 memset(&inarg, 0, sizeof(inarg));
498 inarg.oldnodeid = get_node_id(inode);
499 req->in.h.opcode = FUSE_LINK;
502 req->in.args[0].size = sizeof(inarg);
503 req->in.args[0].value = &inarg;
504 req->in.args[1].size = newent->d_name.len + 1;
505 req->in.args[1].value = newent->d_name.name;
506 err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
507 /* Contrary to "normal" filesystems it can happen that link
508 makes two "logical" inodes point to the same "physical"
509 inode. We invalidate the attributes of the old one, so it
510 will reflect changes in the backing inode (link count,
513 if (!err || err == -EINTR)
514 fuse_invalidate_attr(inode);
518 int fuse_do_getattr(struct inode *inode)
521 struct fuse_attr_out arg;
522 struct fuse_conn *fc = get_fuse_conn(inode);
523 struct fuse_req *req = fuse_get_request(fc);
527 req->in.h.opcode = FUSE_GETATTR;
528 req->in.h.nodeid = get_node_id(inode);
530 req->out.numargs = 1;
531 req->out.args[0].size = sizeof(arg);
532 req->out.args[0].value = &arg;
533 request_send(fc, req);
534 err = req->out.h.error;
535 fuse_put_request(fc, req);
537 if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
538 make_bad_inode(inode);
541 struct fuse_inode *fi = get_fuse_inode(inode);
542 fuse_change_attributes(inode, &arg.attr);
543 fi->i_time = time_to_jiffies(arg.attr_valid,
544 arg.attr_valid_nsec);
551 * Calling into a user-controlled filesystem gives the filesystem
552 * daemon ptrace-like capabilities over the requester process. This
553 * means, that the filesystem daemon is able to record the exact
554 * filesystem operations performed, and can also control the behavior
555 * of the requester process in otherwise impossible ways. For example
556 * it can delay the operation for arbitrary length of time allowing
557 * DoS against the requester.
559 * For this reason only those processes can call into the filesystem,
560 * for which the owner of the mount has ptrace privilege. This
561 * excludes processes started by other users, suid or sgid processes.
563 static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
565 if (fc->flags & FUSE_ALLOW_OTHER)
568 if (task->euid == fc->user_id &&
569 task->suid == fc->user_id &&
570 task->uid == fc->user_id &&
571 task->egid == fc->group_id &&
572 task->sgid == fc->group_id &&
573 task->gid == fc->group_id)
579 static int fuse_revalidate(struct dentry *entry)
581 struct inode *inode = entry->d_inode;
582 struct fuse_inode *fi = get_fuse_inode(inode);
583 struct fuse_conn *fc = get_fuse_conn(inode);
585 if (!fuse_allow_task(fc, current))
587 if (get_node_id(inode) != FUSE_ROOT_ID &&
588 time_before_eq(jiffies, fi->i_time))
591 return fuse_do_getattr(inode);
594 static int fuse_access(struct inode *inode, int mask)
596 struct fuse_conn *fc = get_fuse_conn(inode);
597 struct fuse_req *req;
598 struct fuse_access_in inarg;
604 req = fuse_get_request(fc);
608 memset(&inarg, 0, sizeof(inarg));
610 req->in.h.opcode = FUSE_ACCESS;
611 req->in.h.nodeid = get_node_id(inode);
614 req->in.args[0].size = sizeof(inarg);
615 req->in.args[0].value = &inarg;
616 request_send(fc, req);
617 err = req->out.h.error;
618 fuse_put_request(fc, req);
619 if (err == -ENOSYS) {
626 static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
628 struct fuse_conn *fc = get_fuse_conn(inode);
630 if (!fuse_allow_task(fc, current))
632 else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
633 int err = generic_permission(inode, mask, NULL);
635 /* If permission is denied, try to refresh file
636 attributes. This is also needed, because the root
637 node will at first have no permissions */
638 if (err == -EACCES) {
639 err = fuse_do_getattr(inode);
641 err = generic_permission(inode, mask, NULL);
644 /* FIXME: Need some mechanism to revoke permissions:
645 currently if the filesystem suddenly changes the
646 file mode, we will not be informed about it, and
647 continue to allow access to the file/directory.
649 This is actually not so grave, since the user can
650 simply keep access to the file/directory anyway by
651 keeping it open... */
655 int mode = inode->i_mode;
656 if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
659 if (nd && (nd->flags & LOOKUP_ACCESS))
660 return fuse_access(inode, mask);
665 static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
666 void *dstbuf, filldir_t filldir)
668 while (nbytes >= FUSE_NAME_OFFSET) {
669 struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
670 size_t reclen = FUSE_DIRENT_SIZE(dirent);
672 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
677 over = filldir(dstbuf, dirent->name, dirent->namelen,
678 file->f_pos, dirent->ino, dirent->type);
684 file->f_pos = dirent->off;
690 static inline size_t fuse_send_readdir(struct fuse_req *req, struct file *file,
691 struct inode *inode, loff_t pos,
694 return fuse_send_read_common(req, file, inode, pos, count, 1);
697 static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
702 struct inode *inode = file->f_dentry->d_inode;
703 struct fuse_conn *fc = get_fuse_conn(inode);
704 struct fuse_req *req = fuse_get_request(fc);
708 page = alloc_page(GFP_KERNEL);
710 fuse_put_request(fc, req);
714 req->pages[0] = page;
715 nbytes = fuse_send_readdir(req, file, inode, file->f_pos, PAGE_SIZE);
716 err = req->out.h.error;
717 fuse_put_request(fc, req);
719 err = parse_dirfile(page_address(page), nbytes, file, dstbuf,
723 fuse_invalidate_attr(inode); /* atime changed */
727 static char *read_link(struct dentry *dentry)
729 struct inode *inode = dentry->d_inode;
730 struct fuse_conn *fc = get_fuse_conn(inode);
731 struct fuse_req *req = fuse_get_request(fc);
735 return ERR_PTR(-EINTR);
737 link = (char *) __get_free_page(GFP_KERNEL);
739 link = ERR_PTR(-ENOMEM);
742 req->in.h.opcode = FUSE_READLINK;
743 req->in.h.nodeid = get_node_id(inode);
746 req->out.numargs = 1;
747 req->out.args[0].size = PAGE_SIZE - 1;
748 req->out.args[0].value = link;
749 request_send(fc, req);
750 if (req->out.h.error) {
751 free_page((unsigned long) link);
752 link = ERR_PTR(req->out.h.error);
754 link[req->out.args[0].size] = '\0';
756 fuse_put_request(fc, req);
757 fuse_invalidate_attr(inode); /* atime changed */
761 static void free_link(char *link)
764 free_page((unsigned long) link);
767 static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
769 nd_set_link(nd, read_link(dentry));
773 static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
775 free_link(nd_get_link(nd));
778 static int fuse_dir_open(struct inode *inode, struct file *file)
780 return fuse_open_common(inode, file, 1);
783 static int fuse_dir_release(struct inode *inode, struct file *file)
785 return fuse_release_common(inode, file, 1);
788 static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
790 /* nfsd can call this with no file */
791 return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
794 static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
796 unsigned ivalid = iattr->ia_valid;
798 if (ivalid & ATTR_MODE)
799 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
800 if (ivalid & ATTR_UID)
801 arg->valid |= FATTR_UID, arg->uid = iattr->ia_uid;
802 if (ivalid & ATTR_GID)
803 arg->valid |= FATTR_GID, arg->gid = iattr->ia_gid;
804 if (ivalid & ATTR_SIZE)
805 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
806 /* You can only _set_ these together (they may change by themselves) */
807 if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
808 arg->valid |= FATTR_ATIME | FATTR_MTIME;
809 arg->atime = iattr->ia_atime.tv_sec;
810 arg->mtime = iattr->ia_mtime.tv_sec;
812 if (ivalid & ATTR_FILE) {
813 struct fuse_file *ff = iattr->ia_file->private_data;
814 arg->valid |= FATTR_FH;
819 static int fuse_setattr(struct dentry *entry, struct iattr *attr)
821 struct inode *inode = entry->d_inode;
822 struct fuse_conn *fc = get_fuse_conn(inode);
823 struct fuse_inode *fi = get_fuse_inode(inode);
824 struct fuse_req *req;
825 struct fuse_setattr_in inarg;
826 struct fuse_attr_out outarg;
830 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
831 err = inode_change_ok(inode, attr);
836 if (attr->ia_valid & ATTR_SIZE) {
839 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
840 if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {
841 send_sig(SIGXFSZ, current, 0);
846 req = fuse_get_request(fc);
850 memset(&inarg, 0, sizeof(inarg));
851 iattr_to_fattr(attr, &inarg);
852 req->in.h.opcode = FUSE_SETATTR;
853 req->in.h.nodeid = get_node_id(inode);
856 req->in.args[0].size = sizeof(inarg);
857 req->in.args[0].value = &inarg;
858 req->out.numargs = 1;
859 req->out.args[0].size = sizeof(outarg);
860 req->out.args[0].value = &outarg;
861 request_send(fc, req);
862 err = req->out.h.error;
863 fuse_put_request(fc, req);
865 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
866 make_bad_inode(inode);
870 loff_t origsize = i_size_read(inode);
871 i_size_write(inode, outarg.attr.size);
872 if (origsize > outarg.attr.size)
873 vmtruncate(inode, outarg.attr.size);
875 fuse_change_attributes(inode, &outarg.attr);
876 fi->i_time = time_to_jiffies(outarg.attr_valid,
877 outarg.attr_valid_nsec);
879 } else if (err == -EINTR)
880 fuse_invalidate_attr(inode);
885 static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
888 struct inode *inode = entry->d_inode;
889 int err = fuse_revalidate(entry);
891 generic_fillattr(inode, stat);
896 static int fuse_setxattr(struct dentry *entry, const char *name,
897 const void *value, size_t size, int flags)
899 struct inode *inode = entry->d_inode;
900 struct fuse_conn *fc = get_fuse_conn(inode);
901 struct fuse_req *req;
902 struct fuse_setxattr_in inarg;
905 if (size > FUSE_XATTR_SIZE_MAX)
911 req = fuse_get_request(fc);
915 memset(&inarg, 0, sizeof(inarg));
918 req->in.h.opcode = FUSE_SETXATTR;
919 req->in.h.nodeid = get_node_id(inode);
922 req->in.args[0].size = sizeof(inarg);
923 req->in.args[0].value = &inarg;
924 req->in.args[1].size = strlen(name) + 1;
925 req->in.args[1].value = name;
926 req->in.args[2].size = size;
927 req->in.args[2].value = value;
928 request_send(fc, req);
929 err = req->out.h.error;
930 fuse_put_request(fc, req);
931 if (err == -ENOSYS) {
938 static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
939 void *value, size_t size)
941 struct inode *inode = entry->d_inode;
942 struct fuse_conn *fc = get_fuse_conn(inode);
943 struct fuse_req *req;
944 struct fuse_getxattr_in inarg;
945 struct fuse_getxattr_out outarg;
951 req = fuse_get_request(fc);
955 memset(&inarg, 0, sizeof(inarg));
957 req->in.h.opcode = FUSE_GETXATTR;
958 req->in.h.nodeid = get_node_id(inode);
961 req->in.args[0].size = sizeof(inarg);
962 req->in.args[0].value = &inarg;
963 req->in.args[1].size = strlen(name) + 1;
964 req->in.args[1].value = name;
965 /* This is really two different operations rolled into one */
966 req->out.numargs = 1;
969 req->out.args[0].size = size;
970 req->out.args[0].value = value;
972 req->out.args[0].size = sizeof(outarg);
973 req->out.args[0].value = &outarg;
975 request_send(fc, req);
976 ret = req->out.h.error;
978 ret = size ? req->out.args[0].size : outarg.size;
980 if (ret == -ENOSYS) {
985 fuse_put_request(fc, req);
989 static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
991 struct inode *inode = entry->d_inode;
992 struct fuse_conn *fc = get_fuse_conn(inode);
993 struct fuse_req *req;
994 struct fuse_getxattr_in inarg;
995 struct fuse_getxattr_out outarg;
998 if (fc->no_listxattr)
1001 req = fuse_get_request(fc);
1005 memset(&inarg, 0, sizeof(inarg));
1007 req->in.h.opcode = FUSE_LISTXATTR;
1008 req->in.h.nodeid = get_node_id(inode);
1010 req->in.numargs = 1;
1011 req->in.args[0].size = sizeof(inarg);
1012 req->in.args[0].value = &inarg;
1013 /* This is really two different operations rolled into one */
1014 req->out.numargs = 1;
1016 req->out.argvar = 1;
1017 req->out.args[0].size = size;
1018 req->out.args[0].value = list;
1020 req->out.args[0].size = sizeof(outarg);
1021 req->out.args[0].value = &outarg;
1023 request_send(fc, req);
1024 ret = req->out.h.error;
1026 ret = size ? req->out.args[0].size : outarg.size;
1028 if (ret == -ENOSYS) {
1029 fc->no_listxattr = 1;
1033 fuse_put_request(fc, req);
1037 static int fuse_removexattr(struct dentry *entry, const char *name)
1039 struct inode *inode = entry->d_inode;
1040 struct fuse_conn *fc = get_fuse_conn(inode);
1041 struct fuse_req *req;
1044 if (fc->no_removexattr)
1047 req = fuse_get_request(fc);
1051 req->in.h.opcode = FUSE_REMOVEXATTR;
1052 req->in.h.nodeid = get_node_id(inode);
1054 req->in.numargs = 1;
1055 req->in.args[0].size = strlen(name) + 1;
1056 req->in.args[0].value = name;
1057 request_send(fc, req);
1058 err = req->out.h.error;
1059 fuse_put_request(fc, req);
1060 if (err == -ENOSYS) {
1061 fc->no_removexattr = 1;
1067 static struct inode_operations fuse_dir_inode_operations = {
1068 .lookup = fuse_lookup,
1069 .mkdir = fuse_mkdir,
1070 .symlink = fuse_symlink,
1071 .unlink = fuse_unlink,
1072 .rmdir = fuse_rmdir,
1073 .rename = fuse_rename,
1075 .setattr = fuse_setattr,
1076 .create = fuse_create,
1077 .mknod = fuse_mknod,
1078 .permission = fuse_permission,
1079 .getattr = fuse_getattr,
1080 .setxattr = fuse_setxattr,
1081 .getxattr = fuse_getxattr,
1082 .listxattr = fuse_listxattr,
1083 .removexattr = fuse_removexattr,
1086 static struct file_operations fuse_dir_operations = {
1087 .llseek = generic_file_llseek,
1088 .read = generic_read_dir,
1089 .readdir = fuse_readdir,
1090 .open = fuse_dir_open,
1091 .release = fuse_dir_release,
1092 .fsync = fuse_dir_fsync,
1095 static struct inode_operations fuse_common_inode_operations = {
1096 .setattr = fuse_setattr,
1097 .permission = fuse_permission,
1098 .getattr = fuse_getattr,
1099 .setxattr = fuse_setxattr,
1100 .getxattr = fuse_getxattr,
1101 .listxattr = fuse_listxattr,
1102 .removexattr = fuse_removexattr,
1105 static struct inode_operations fuse_symlink_inode_operations = {
1106 .setattr = fuse_setattr,
1107 .follow_link = fuse_follow_link,
1108 .put_link = fuse_put_link,
1109 .readlink = generic_readlink,
1110 .getattr = fuse_getattr,
1111 .setxattr = fuse_setxattr,
1112 .getxattr = fuse_getxattr,
1113 .listxattr = fuse_listxattr,
1114 .removexattr = fuse_removexattr,
1117 void fuse_init_common(struct inode *inode)
1119 inode->i_op = &fuse_common_inode_operations;
1122 void fuse_init_dir(struct inode *inode)
1124 inode->i_op = &fuse_dir_inode_operations;
1125 inode->i_fop = &fuse_dir_operations;
1128 void fuse_init_symlink(struct inode *inode)
1130 inode->i_op = &fuse_symlink_inode_operations;