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 int dir_alias(struct inode *inode)
79 if (S_ISDIR(inode->i_mode)) {
80 /* Don't allow creating an alias to a directory */
81 struct dentry *alias = d_find_alias(inode);
90 static struct dentry_operations fuse_dentry_operations = {
91 .d_revalidate = fuse_dentry_revalidate,
94 static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
95 struct inode **inodep)
98 struct fuse_entry_out outarg;
99 struct inode *inode = NULL;
100 struct fuse_conn *fc = get_fuse_conn(dir);
101 struct fuse_req *req;
103 if (entry->d_name.len > FUSE_NAME_MAX)
104 return -ENAMETOOLONG;
106 req = fuse_get_request(fc);
110 fuse_lookup_init(req, dir, entry, &outarg);
111 request_send(fc, req);
112 err = req->out.h.error;
113 if (!err && (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID))
116 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
119 fuse_send_forget(fc, req, outarg.nodeid, 1);
123 fuse_put_request(fc, req);
124 if (err && err != -ENOENT)
128 struct fuse_inode *fi = get_fuse_inode(inode);
129 entry->d_time = time_to_jiffies(outarg.entry_valid,
130 outarg.entry_valid_nsec);
131 fi->i_time = time_to_jiffies(outarg.attr_valid,
132 outarg.attr_valid_nsec);
135 entry->d_op = &fuse_dentry_operations;
140 void fuse_invalidate_attr(struct inode *inode)
142 get_fuse_inode(inode)->i_time = jiffies - 1;
145 static void fuse_invalidate_entry(struct dentry *entry)
148 entry->d_time = jiffies - 1;
151 static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
152 struct nameidata *nd)
156 struct fuse_conn *fc = get_fuse_conn(dir);
157 struct fuse_req *req;
158 struct fuse_open_in inarg;
159 struct fuse_open_out outopen;
160 struct fuse_entry_out outentry;
161 struct fuse_inode *fi;
162 struct fuse_file *ff;
164 int flags = nd->intent.open.flags - 1;
171 if (entry->d_name.len > FUSE_NAME_MAX)
175 req = fuse_get_request(fc);
179 ff = fuse_file_alloc();
181 goto out_put_request;
184 memset(&inarg, 0, sizeof(inarg));
187 req->in.h.opcode = FUSE_CREATE;
188 req->in.h.nodeid = get_node_id(dir);
191 req->in.args[0].size = sizeof(inarg);
192 req->in.args[0].value = &inarg;
193 req->in.args[1].size = entry->d_name.len + 1;
194 req->in.args[1].value = entry->d_name.name;
195 req->out.numargs = 2;
196 req->out.args[0].size = sizeof(outentry);
197 req->out.args[0].value = &outentry;
198 req->out.args[1].size = sizeof(outopen);
199 req->out.args[1].value = &outopen;
200 request_send(fc, req);
201 err = req->out.h.error;
209 if (!S_ISREG(outentry.attr.mode))
212 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
216 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
218 fuse_send_release(fc, ff, outentry.nodeid, NULL, flags, 0);
219 goto out_put_request;
221 fuse_put_request(fc, req);
222 entry->d_time = time_to_jiffies(outentry.entry_valid,
223 outentry.entry_valid_nsec);
224 fi = get_fuse_inode(inode);
225 fi->i_time = time_to_jiffies(outentry.attr_valid,
226 outentry.attr_valid_nsec);
228 d_instantiate(entry, inode);
229 file = lookup_instantiate_filp(nd, entry, generic_file_open);
232 fuse_send_release(fc, ff, outentry.nodeid, inode, flags, 0);
233 return PTR_ERR(file);
235 fuse_finish_open(inode, file, ff, &outopen);
241 fuse_put_request(fc, req);
246 static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
247 struct inode *dir, struct dentry *entry,
250 struct fuse_entry_out outarg;
252 struct fuse_inode *fi;
255 req->in.h.nodeid = get_node_id(dir);
257 req->out.numargs = 1;
258 req->out.args[0].size = sizeof(outarg);
259 req->out.args[0].value = &outarg;
260 request_send(fc, req);
261 err = req->out.h.error;
263 fuse_put_request(fc, req);
266 if (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID) {
267 fuse_put_request(fc, req);
270 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
273 fuse_send_forget(fc, req, outarg.nodeid, 1);
276 fuse_put_request(fc, req);
278 /* Don't allow userspace to do really stupid things... */
279 if (((inode->i_mode ^ mode) & S_IFMT) || dir_alias(inode)) {
284 entry->d_time = time_to_jiffies(outarg.entry_valid,
285 outarg.entry_valid_nsec);
287 fi = get_fuse_inode(inode);
288 fi->i_time = time_to_jiffies(outarg.attr_valid,
289 outarg.attr_valid_nsec);
291 d_instantiate(entry, inode);
292 fuse_invalidate_attr(dir);
296 static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
299 struct fuse_mknod_in inarg;
300 struct fuse_conn *fc = get_fuse_conn(dir);
301 struct fuse_req *req = fuse_get_request(fc);
305 memset(&inarg, 0, sizeof(inarg));
307 inarg.rdev = new_encode_dev(rdev);
308 req->in.h.opcode = FUSE_MKNOD;
310 req->in.args[0].size = sizeof(inarg);
311 req->in.args[0].value = &inarg;
312 req->in.args[1].size = entry->d_name.len + 1;
313 req->in.args[1].value = entry->d_name.name;
314 return create_new_entry(fc, req, dir, entry, mode);
317 static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
318 struct nameidata *nd)
320 if (nd && (nd->flags & LOOKUP_CREATE)) {
321 int err = fuse_create_open(dir, entry, mode, nd);
324 /* Fall back on mknod */
326 return fuse_mknod(dir, entry, mode, 0);
329 static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
331 struct fuse_mkdir_in inarg;
332 struct fuse_conn *fc = get_fuse_conn(dir);
333 struct fuse_req *req = fuse_get_request(fc);
337 memset(&inarg, 0, sizeof(inarg));
339 req->in.h.opcode = FUSE_MKDIR;
341 req->in.args[0].size = sizeof(inarg);
342 req->in.args[0].value = &inarg;
343 req->in.args[1].size = entry->d_name.len + 1;
344 req->in.args[1].value = entry->d_name.name;
345 return create_new_entry(fc, req, dir, entry, S_IFDIR);
348 static int fuse_symlink(struct inode *dir, struct dentry *entry,
351 struct fuse_conn *fc = get_fuse_conn(dir);
352 unsigned len = strlen(link) + 1;
353 struct fuse_req *req;
355 if (len > FUSE_SYMLINK_MAX)
356 return -ENAMETOOLONG;
358 req = fuse_get_request(fc);
362 req->in.h.opcode = FUSE_SYMLINK;
364 req->in.args[0].size = entry->d_name.len + 1;
365 req->in.args[0].value = entry->d_name.name;
366 req->in.args[1].size = len;
367 req->in.args[1].value = link;
368 return create_new_entry(fc, req, dir, entry, S_IFLNK);
371 static int fuse_unlink(struct inode *dir, struct dentry *entry)
374 struct fuse_conn *fc = get_fuse_conn(dir);
375 struct fuse_req *req = fuse_get_request(fc);
379 req->in.h.opcode = FUSE_UNLINK;
380 req->in.h.nodeid = get_node_id(dir);
383 req->in.args[0].size = entry->d_name.len + 1;
384 req->in.args[0].value = entry->d_name.name;
385 request_send(fc, req);
386 err = req->out.h.error;
387 fuse_put_request(fc, req);
389 struct inode *inode = entry->d_inode;
391 /* Set nlink to zero so the inode can be cleared, if
392 the inode does have more links this will be
393 discovered at the next lookup/getattr */
395 fuse_invalidate_attr(inode);
396 fuse_invalidate_attr(dir);
397 } else if (err == -EINTR)
398 fuse_invalidate_entry(entry);
402 static int fuse_rmdir(struct inode *dir, struct dentry *entry)
405 struct fuse_conn *fc = get_fuse_conn(dir);
406 struct fuse_req *req = fuse_get_request(fc);
410 req->in.h.opcode = FUSE_RMDIR;
411 req->in.h.nodeid = get_node_id(dir);
414 req->in.args[0].size = entry->d_name.len + 1;
415 req->in.args[0].value = entry->d_name.name;
416 request_send(fc, req);
417 err = req->out.h.error;
418 fuse_put_request(fc, req);
420 entry->d_inode->i_nlink = 0;
421 fuse_invalidate_attr(dir);
422 } else if (err == -EINTR)
423 fuse_invalidate_entry(entry);
427 static int fuse_rename(struct inode *olddir, struct dentry *oldent,
428 struct inode *newdir, struct dentry *newent)
431 struct fuse_rename_in inarg;
432 struct fuse_conn *fc = get_fuse_conn(olddir);
433 struct fuse_req *req = fuse_get_request(fc);
437 memset(&inarg, 0, sizeof(inarg));
438 inarg.newdir = get_node_id(newdir);
439 req->in.h.opcode = FUSE_RENAME;
440 req->in.h.nodeid = get_node_id(olddir);
442 req->inode2 = newdir;
444 req->in.args[0].size = sizeof(inarg);
445 req->in.args[0].value = &inarg;
446 req->in.args[1].size = oldent->d_name.len + 1;
447 req->in.args[1].value = oldent->d_name.name;
448 req->in.args[2].size = newent->d_name.len + 1;
449 req->in.args[2].value = newent->d_name.name;
450 request_send(fc, req);
451 err = req->out.h.error;
452 fuse_put_request(fc, req);
454 fuse_invalidate_attr(olddir);
455 if (olddir != newdir)
456 fuse_invalidate_attr(newdir);
457 } else if (err == -EINTR) {
458 /* If request was interrupted, DEITY only knows if the
459 rename actually took place. If the invalidation
460 fails (e.g. some process has CWD under the renamed
461 directory), then there can be inconsistency between
462 the dcache and the real filesystem. Tough luck. */
463 fuse_invalidate_entry(oldent);
465 fuse_invalidate_entry(newent);
471 static int fuse_link(struct dentry *entry, struct inode *newdir,
472 struct dentry *newent)
475 struct fuse_link_in inarg;
476 struct inode *inode = entry->d_inode;
477 struct fuse_conn *fc = get_fuse_conn(inode);
478 struct fuse_req *req = fuse_get_request(fc);
482 memset(&inarg, 0, sizeof(inarg));
483 inarg.oldnodeid = get_node_id(inode);
484 req->in.h.opcode = FUSE_LINK;
487 req->in.args[0].size = sizeof(inarg);
488 req->in.args[0].value = &inarg;
489 req->in.args[1].size = newent->d_name.len + 1;
490 req->in.args[1].value = newent->d_name.name;
491 err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
492 /* Contrary to "normal" filesystems it can happen that link
493 makes two "logical" inodes point to the same "physical"
494 inode. We invalidate the attributes of the old one, so it
495 will reflect changes in the backing inode (link count,
498 if (!err || err == -EINTR)
499 fuse_invalidate_attr(inode);
503 int fuse_do_getattr(struct inode *inode)
506 struct fuse_attr_out arg;
507 struct fuse_conn *fc = get_fuse_conn(inode);
508 struct fuse_req *req = fuse_get_request(fc);
512 req->in.h.opcode = FUSE_GETATTR;
513 req->in.h.nodeid = get_node_id(inode);
515 req->out.numargs = 1;
516 req->out.args[0].size = sizeof(arg);
517 req->out.args[0].value = &arg;
518 request_send(fc, req);
519 err = req->out.h.error;
520 fuse_put_request(fc, req);
522 if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
523 make_bad_inode(inode);
526 struct fuse_inode *fi = get_fuse_inode(inode);
527 fuse_change_attributes(inode, &arg.attr);
528 fi->i_time = time_to_jiffies(arg.attr_valid,
529 arg.attr_valid_nsec);
536 * Calling into a user-controlled filesystem gives the filesystem
537 * daemon ptrace-like capabilities over the requester process. This
538 * means, that the filesystem daemon is able to record the exact
539 * filesystem operations performed, and can also control the behavior
540 * of the requester process in otherwise impossible ways. For example
541 * it can delay the operation for arbitrary length of time allowing
542 * DoS against the requester.
544 * For this reason only those processes can call into the filesystem,
545 * for which the owner of the mount has ptrace privilege. This
546 * excludes processes started by other users, suid or sgid processes.
548 static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
550 if (fc->flags & FUSE_ALLOW_OTHER)
553 if (task->euid == fc->user_id &&
554 task->suid == fc->user_id &&
555 task->uid == fc->user_id &&
556 task->egid == fc->group_id &&
557 task->sgid == fc->group_id &&
558 task->gid == fc->group_id)
564 static int fuse_revalidate(struct dentry *entry)
566 struct inode *inode = entry->d_inode;
567 struct fuse_inode *fi = get_fuse_inode(inode);
568 struct fuse_conn *fc = get_fuse_conn(inode);
570 if (!fuse_allow_task(fc, current))
572 if (get_node_id(inode) != FUSE_ROOT_ID &&
573 time_before_eq(jiffies, fi->i_time))
576 return fuse_do_getattr(inode);
579 static int fuse_access(struct inode *inode, int mask)
581 struct fuse_conn *fc = get_fuse_conn(inode);
582 struct fuse_req *req;
583 struct fuse_access_in inarg;
589 req = fuse_get_request(fc);
593 memset(&inarg, 0, sizeof(inarg));
595 req->in.h.opcode = FUSE_ACCESS;
596 req->in.h.nodeid = get_node_id(inode);
599 req->in.args[0].size = sizeof(inarg);
600 req->in.args[0].value = &inarg;
601 request_send(fc, req);
602 err = req->out.h.error;
603 fuse_put_request(fc, req);
604 if (err == -ENOSYS) {
611 static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
613 struct fuse_conn *fc = get_fuse_conn(inode);
615 if (!fuse_allow_task(fc, current))
617 else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
618 int err = generic_permission(inode, mask, NULL);
620 /* If permission is denied, try to refresh file
621 attributes. This is also needed, because the root
622 node will at first have no permissions */
623 if (err == -EACCES) {
624 err = fuse_do_getattr(inode);
626 err = generic_permission(inode, mask, NULL);
629 /* FIXME: Need some mechanism to revoke permissions:
630 currently if the filesystem suddenly changes the
631 file mode, we will not be informed about it, and
632 continue to allow access to the file/directory.
634 This is actually not so grave, since the user can
635 simply keep access to the file/directory anyway by
636 keeping it open... */
640 int mode = inode->i_mode;
641 if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
644 if (nd && (nd->flags & LOOKUP_ACCESS))
645 return fuse_access(inode, mask);
650 static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
651 void *dstbuf, filldir_t filldir)
653 while (nbytes >= FUSE_NAME_OFFSET) {
654 struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
655 size_t reclen = FUSE_DIRENT_SIZE(dirent);
657 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
662 over = filldir(dstbuf, dirent->name, dirent->namelen,
663 file->f_pos, dirent->ino, dirent->type);
669 file->f_pos = dirent->off;
675 static inline size_t fuse_send_readdir(struct fuse_req *req, struct file *file,
676 struct inode *inode, loff_t pos,
679 return fuse_send_read_common(req, file, inode, pos, count, 1);
682 static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
687 struct inode *inode = file->f_dentry->d_inode;
688 struct fuse_conn *fc = get_fuse_conn(inode);
689 struct fuse_req *req = fuse_get_request(fc);
693 page = alloc_page(GFP_KERNEL);
695 fuse_put_request(fc, req);
699 req->pages[0] = page;
700 nbytes = fuse_send_readdir(req, file, inode, file->f_pos, PAGE_SIZE);
701 err = req->out.h.error;
702 fuse_put_request(fc, req);
704 err = parse_dirfile(page_address(page), nbytes, file, dstbuf,
708 fuse_invalidate_attr(inode); /* atime changed */
712 static char *read_link(struct dentry *dentry)
714 struct inode *inode = dentry->d_inode;
715 struct fuse_conn *fc = get_fuse_conn(inode);
716 struct fuse_req *req = fuse_get_request(fc);
720 return ERR_PTR(-EINTR);
722 link = (char *) __get_free_page(GFP_KERNEL);
724 link = ERR_PTR(-ENOMEM);
727 req->in.h.opcode = FUSE_READLINK;
728 req->in.h.nodeid = get_node_id(inode);
731 req->out.numargs = 1;
732 req->out.args[0].size = PAGE_SIZE - 1;
733 req->out.args[0].value = link;
734 request_send(fc, req);
735 if (req->out.h.error) {
736 free_page((unsigned long) link);
737 link = ERR_PTR(req->out.h.error);
739 link[req->out.args[0].size] = '\0';
741 fuse_put_request(fc, req);
742 fuse_invalidate_attr(inode); /* atime changed */
746 static void free_link(char *link)
749 free_page((unsigned long) link);
752 static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
754 nd_set_link(nd, read_link(dentry));
758 static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
760 free_link(nd_get_link(nd));
763 static int fuse_dir_open(struct inode *inode, struct file *file)
765 return fuse_open_common(inode, file, 1);
768 static int fuse_dir_release(struct inode *inode, struct file *file)
770 return fuse_release_common(inode, file, 1);
773 static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
775 /* nfsd can call this with no file */
776 return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
779 static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
781 unsigned ivalid = iattr->ia_valid;
783 if (ivalid & ATTR_MODE)
784 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
785 if (ivalid & ATTR_UID)
786 arg->valid |= FATTR_UID, arg->uid = iattr->ia_uid;
787 if (ivalid & ATTR_GID)
788 arg->valid |= FATTR_GID, arg->gid = iattr->ia_gid;
789 if (ivalid & ATTR_SIZE)
790 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
791 /* You can only _set_ these together (they may change by themselves) */
792 if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
793 arg->valid |= FATTR_ATIME | FATTR_MTIME;
794 arg->atime = iattr->ia_atime.tv_sec;
795 arg->mtime = iattr->ia_mtime.tv_sec;
797 if (ivalid & ATTR_FILE) {
798 struct fuse_file *ff = iattr->ia_file->private_data;
799 arg->valid |= FATTR_FH;
804 static int fuse_setattr(struct dentry *entry, struct iattr *attr)
806 struct inode *inode = entry->d_inode;
807 struct fuse_conn *fc = get_fuse_conn(inode);
808 struct fuse_inode *fi = get_fuse_inode(inode);
809 struct fuse_req *req;
810 struct fuse_setattr_in inarg;
811 struct fuse_attr_out outarg;
815 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
816 err = inode_change_ok(inode, attr);
821 if (attr->ia_valid & ATTR_SIZE) {
824 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
825 if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {
826 send_sig(SIGXFSZ, current, 0);
831 req = fuse_get_request(fc);
835 memset(&inarg, 0, sizeof(inarg));
836 iattr_to_fattr(attr, &inarg);
837 req->in.h.opcode = FUSE_SETATTR;
838 req->in.h.nodeid = get_node_id(inode);
841 req->in.args[0].size = sizeof(inarg);
842 req->in.args[0].value = &inarg;
843 req->out.numargs = 1;
844 req->out.args[0].size = sizeof(outarg);
845 req->out.args[0].value = &outarg;
846 request_send(fc, req);
847 err = req->out.h.error;
848 fuse_put_request(fc, req);
850 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
851 make_bad_inode(inode);
855 loff_t origsize = i_size_read(inode);
856 i_size_write(inode, outarg.attr.size);
857 if (origsize > outarg.attr.size)
858 vmtruncate(inode, outarg.attr.size);
860 fuse_change_attributes(inode, &outarg.attr);
861 fi->i_time = time_to_jiffies(outarg.attr_valid,
862 outarg.attr_valid_nsec);
864 } else if (err == -EINTR)
865 fuse_invalidate_attr(inode);
870 static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
873 struct inode *inode = entry->d_inode;
874 int err = fuse_revalidate(entry);
876 generic_fillattr(inode, stat);
881 static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
882 struct nameidata *nd)
887 err = fuse_lookup_iget(dir, entry, &inode);
890 if (inode && dir_alias(inode)) {
892 return ERR_PTR(-EIO);
898 static int fuse_setxattr(struct dentry *entry, const char *name,
899 const void *value, size_t size, int flags)
901 struct inode *inode = entry->d_inode;
902 struct fuse_conn *fc = get_fuse_conn(inode);
903 struct fuse_req *req;
904 struct fuse_setxattr_in inarg;
907 if (size > FUSE_XATTR_SIZE_MAX)
913 req = fuse_get_request(fc);
917 memset(&inarg, 0, sizeof(inarg));
920 req->in.h.opcode = FUSE_SETXATTR;
921 req->in.h.nodeid = get_node_id(inode);
924 req->in.args[0].size = sizeof(inarg);
925 req->in.args[0].value = &inarg;
926 req->in.args[1].size = strlen(name) + 1;
927 req->in.args[1].value = name;
928 req->in.args[2].size = size;
929 req->in.args[2].value = value;
930 request_send(fc, req);
931 err = req->out.h.error;
932 fuse_put_request(fc, req);
933 if (err == -ENOSYS) {
940 static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
941 void *value, size_t size)
943 struct inode *inode = entry->d_inode;
944 struct fuse_conn *fc = get_fuse_conn(inode);
945 struct fuse_req *req;
946 struct fuse_getxattr_in inarg;
947 struct fuse_getxattr_out outarg;
953 req = fuse_get_request(fc);
957 memset(&inarg, 0, sizeof(inarg));
959 req->in.h.opcode = FUSE_GETXATTR;
960 req->in.h.nodeid = get_node_id(inode);
963 req->in.args[0].size = sizeof(inarg);
964 req->in.args[0].value = &inarg;
965 req->in.args[1].size = strlen(name) + 1;
966 req->in.args[1].value = name;
967 /* This is really two different operations rolled into one */
968 req->out.numargs = 1;
971 req->out.args[0].size = size;
972 req->out.args[0].value = value;
974 req->out.args[0].size = sizeof(outarg);
975 req->out.args[0].value = &outarg;
977 request_send(fc, req);
978 ret = req->out.h.error;
980 ret = size ? req->out.args[0].size : outarg.size;
982 if (ret == -ENOSYS) {
987 fuse_put_request(fc, req);
991 static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
993 struct inode *inode = entry->d_inode;
994 struct fuse_conn *fc = get_fuse_conn(inode);
995 struct fuse_req *req;
996 struct fuse_getxattr_in inarg;
997 struct fuse_getxattr_out outarg;
1000 if (fc->no_listxattr)
1003 req = fuse_get_request(fc);
1007 memset(&inarg, 0, sizeof(inarg));
1009 req->in.h.opcode = FUSE_LISTXATTR;
1010 req->in.h.nodeid = get_node_id(inode);
1012 req->in.numargs = 1;
1013 req->in.args[0].size = sizeof(inarg);
1014 req->in.args[0].value = &inarg;
1015 /* This is really two different operations rolled into one */
1016 req->out.numargs = 1;
1018 req->out.argvar = 1;
1019 req->out.args[0].size = size;
1020 req->out.args[0].value = list;
1022 req->out.args[0].size = sizeof(outarg);
1023 req->out.args[0].value = &outarg;
1025 request_send(fc, req);
1026 ret = req->out.h.error;
1028 ret = size ? req->out.args[0].size : outarg.size;
1030 if (ret == -ENOSYS) {
1031 fc->no_listxattr = 1;
1035 fuse_put_request(fc, req);
1039 static int fuse_removexattr(struct dentry *entry, const char *name)
1041 struct inode *inode = entry->d_inode;
1042 struct fuse_conn *fc = get_fuse_conn(inode);
1043 struct fuse_req *req;
1046 if (fc->no_removexattr)
1049 req = fuse_get_request(fc);
1053 req->in.h.opcode = FUSE_REMOVEXATTR;
1054 req->in.h.nodeid = get_node_id(inode);
1056 req->in.numargs = 1;
1057 req->in.args[0].size = strlen(name) + 1;
1058 req->in.args[0].value = name;
1059 request_send(fc, req);
1060 err = req->out.h.error;
1061 fuse_put_request(fc, req);
1062 if (err == -ENOSYS) {
1063 fc->no_removexattr = 1;
1069 static struct inode_operations fuse_dir_inode_operations = {
1070 .lookup = fuse_lookup,
1071 .mkdir = fuse_mkdir,
1072 .symlink = fuse_symlink,
1073 .unlink = fuse_unlink,
1074 .rmdir = fuse_rmdir,
1075 .rename = fuse_rename,
1077 .setattr = fuse_setattr,
1078 .create = fuse_create,
1079 .mknod = fuse_mknod,
1080 .permission = fuse_permission,
1081 .getattr = fuse_getattr,
1082 .setxattr = fuse_setxattr,
1083 .getxattr = fuse_getxattr,
1084 .listxattr = fuse_listxattr,
1085 .removexattr = fuse_removexattr,
1088 static struct file_operations fuse_dir_operations = {
1089 .llseek = generic_file_llseek,
1090 .read = generic_read_dir,
1091 .readdir = fuse_readdir,
1092 .open = fuse_dir_open,
1093 .release = fuse_dir_release,
1094 .fsync = fuse_dir_fsync,
1097 static struct inode_operations fuse_common_inode_operations = {
1098 .setattr = fuse_setattr,
1099 .permission = fuse_permission,
1100 .getattr = fuse_getattr,
1101 .setxattr = fuse_setxattr,
1102 .getxattr = fuse_getxattr,
1103 .listxattr = fuse_listxattr,
1104 .removexattr = fuse_removexattr,
1107 static struct inode_operations fuse_symlink_inode_operations = {
1108 .setattr = fuse_setattr,
1109 .follow_link = fuse_follow_link,
1110 .put_link = fuse_put_link,
1111 .readlink = generic_readlink,
1112 .getattr = fuse_getattr,
1113 .setxattr = fuse_setxattr,
1114 .getxattr = fuse_getxattr,
1115 .listxattr = fuse_listxattr,
1116 .removexattr = fuse_removexattr,
1119 void fuse_init_common(struct inode *inode)
1121 inode->i_op = &fuse_common_inode_operations;
1124 void fuse_init_dir(struct inode *inode)
1126 inode->i_op = &fuse_dir_inode_operations;
1127 inode->i_fop = &fuse_dir_operations;
1130 void fuse_init_symlink(struct inode *inode)
1132 inode->i_op = &fuse_symlink_inode_operations;