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 struct fuse_inode *fi = get_fuse_inode(entry->d_inode);
27 entry->d_time = time_to_jiffies(o->entry_valid, o->entry_valid_nsec);
28 fi->i_time = time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
31 static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
33 struct fuse_entry_out *outarg)
35 req->in.h.opcode = FUSE_LOOKUP;
36 req->in.h.nodeid = get_node_id(dir);
39 req->in.args[0].size = entry->d_name.len + 1;
40 req->in.args[0].value = entry->d_name.name;
42 req->out.args[0].size = sizeof(struct fuse_entry_out);
43 req->out.args[0].value = outarg;
46 static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
48 if (!entry->d_inode || is_bad_inode(entry->d_inode))
50 else if (time_after(jiffies, entry->d_time)) {
52 struct fuse_entry_out outarg;
53 struct inode *inode = entry->d_inode;
54 struct fuse_inode *fi = get_fuse_inode(inode);
55 struct fuse_conn *fc = get_fuse_conn(inode);
56 struct fuse_req *req = fuse_get_request(fc);
60 fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg);
61 request_send(fc, req);
62 err = req->out.h.error;
64 if (outarg.nodeid != get_node_id(inode)) {
65 fuse_send_forget(fc, req, outarg.nodeid, 1);
70 fuse_put_request(fc, req);
71 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
74 fuse_change_attributes(inode, &outarg.attr);
75 fuse_change_timeout(entry, &outarg);
80 static int dir_alias(struct inode *inode)
82 if (S_ISDIR(inode->i_mode)) {
83 /* Don't allow creating an alias to a directory */
84 struct dentry *alias = d_find_alias(inode);
93 static inline int invalid_nodeid(u64 nodeid)
95 return !nodeid || nodeid == FUSE_ROOT_ID;
98 static struct dentry_operations fuse_dentry_operations = {
99 .d_revalidate = fuse_dentry_revalidate,
102 static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
103 struct nameidata *nd)
106 struct fuse_entry_out outarg;
107 struct inode *inode = NULL;
108 struct fuse_conn *fc = get_fuse_conn(dir);
109 struct fuse_req *req;
111 if (entry->d_name.len > FUSE_NAME_MAX)
112 return ERR_PTR(-ENAMETOOLONG);
114 req = fuse_get_request(fc);
116 return ERR_PTR(-EINTR);
118 fuse_lookup_init(req, dir, entry, &outarg);
119 request_send(fc, req);
120 err = req->out.h.error;
121 if (!err && invalid_nodeid(outarg.nodeid))
124 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
127 fuse_send_forget(fc, req, outarg.nodeid, 1);
128 return ERR_PTR(-ENOMEM);
131 fuse_put_request(fc, req);
132 if (err && err != -ENOENT)
135 if (inode && dir_alias(inode)) {
137 return ERR_PTR(-EIO);
140 entry->d_op = &fuse_dentry_operations;
142 fuse_change_timeout(entry, &outarg);
146 void fuse_invalidate_attr(struct inode *inode)
148 get_fuse_inode(inode)->i_time = jiffies - 1;
151 static void fuse_invalidate_entry(struct dentry *entry)
154 entry->d_time = jiffies - 1;
157 static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
158 struct nameidata *nd)
162 struct fuse_conn *fc = get_fuse_conn(dir);
163 struct fuse_req *req;
164 struct fuse_open_in inarg;
165 struct fuse_open_out outopen;
166 struct fuse_entry_out outentry;
167 struct fuse_file *ff;
169 int flags = nd->intent.open.flags - 1;
176 if (entry->d_name.len > FUSE_NAME_MAX)
180 req = fuse_get_request(fc);
184 ff = fuse_file_alloc();
186 goto out_put_request;
189 memset(&inarg, 0, sizeof(inarg));
192 req->in.h.opcode = FUSE_CREATE;
193 req->in.h.nodeid = get_node_id(dir);
196 req->in.args[0].size = sizeof(inarg);
197 req->in.args[0].value = &inarg;
198 req->in.args[1].size = entry->d_name.len + 1;
199 req->in.args[1].value = entry->d_name.name;
200 req->out.numargs = 2;
201 req->out.args[0].size = sizeof(outentry);
202 req->out.args[0].value = &outentry;
203 req->out.args[1].size = sizeof(outopen);
204 req->out.args[1].value = &outopen;
205 request_send(fc, req);
206 err = req->out.h.error;
214 if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
217 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
221 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
223 fuse_send_release(fc, ff, outentry.nodeid, NULL, flags, 0);
224 goto out_put_request;
226 fuse_put_request(fc, req);
227 d_instantiate(entry, inode);
228 fuse_change_timeout(entry, &outentry);
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;
254 req->in.h.nodeid = get_node_id(dir);
256 req->out.numargs = 1;
257 req->out.args[0].size = sizeof(outarg);
258 req->out.args[0].value = &outarg;
259 request_send(fc, req);
260 err = req->out.h.error;
262 fuse_put_request(fc, req);
265 if (invalid_nodeid(outarg.nodeid)) {
266 fuse_put_request(fc, req);
269 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
272 fuse_send_forget(fc, req, outarg.nodeid, 1);
275 fuse_put_request(fc, req);
277 /* Don't allow userspace to do really stupid things... */
278 if (((inode->i_mode ^ mode) & S_IFMT) || dir_alias(inode)) {
283 d_instantiate(entry, inode);
284 fuse_change_timeout(entry, &outarg);
285 fuse_invalidate_attr(dir);
289 static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
292 struct fuse_mknod_in inarg;
293 struct fuse_conn *fc = get_fuse_conn(dir);
294 struct fuse_req *req = fuse_get_request(fc);
298 memset(&inarg, 0, sizeof(inarg));
300 inarg.rdev = new_encode_dev(rdev);
301 req->in.h.opcode = FUSE_MKNOD;
303 req->in.args[0].size = sizeof(inarg);
304 req->in.args[0].value = &inarg;
305 req->in.args[1].size = entry->d_name.len + 1;
306 req->in.args[1].value = entry->d_name.name;
307 return create_new_entry(fc, req, dir, entry, mode);
310 static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
311 struct nameidata *nd)
313 if (nd && (nd->flags & LOOKUP_CREATE)) {
314 int err = fuse_create_open(dir, entry, mode, nd);
317 /* Fall back on mknod */
319 return fuse_mknod(dir, entry, mode, 0);
322 static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
324 struct fuse_mkdir_in inarg;
325 struct fuse_conn *fc = get_fuse_conn(dir);
326 struct fuse_req *req = fuse_get_request(fc);
330 memset(&inarg, 0, sizeof(inarg));
332 req->in.h.opcode = FUSE_MKDIR;
334 req->in.args[0].size = sizeof(inarg);
335 req->in.args[0].value = &inarg;
336 req->in.args[1].size = entry->d_name.len + 1;
337 req->in.args[1].value = entry->d_name.name;
338 return create_new_entry(fc, req, dir, entry, S_IFDIR);
341 static int fuse_symlink(struct inode *dir, struct dentry *entry,
344 struct fuse_conn *fc = get_fuse_conn(dir);
345 unsigned len = strlen(link) + 1;
346 struct fuse_req *req;
348 if (len > FUSE_SYMLINK_MAX)
349 return -ENAMETOOLONG;
351 req = fuse_get_request(fc);
355 req->in.h.opcode = FUSE_SYMLINK;
357 req->in.args[0].size = entry->d_name.len + 1;
358 req->in.args[0].value = entry->d_name.name;
359 req->in.args[1].size = len;
360 req->in.args[1].value = link;
361 return create_new_entry(fc, req, dir, entry, S_IFLNK);
364 static int fuse_unlink(struct inode *dir, struct dentry *entry)
367 struct fuse_conn *fc = get_fuse_conn(dir);
368 struct fuse_req *req = fuse_get_request(fc);
372 req->in.h.opcode = FUSE_UNLINK;
373 req->in.h.nodeid = get_node_id(dir);
376 req->in.args[0].size = entry->d_name.len + 1;
377 req->in.args[0].value = entry->d_name.name;
378 request_send(fc, req);
379 err = req->out.h.error;
380 fuse_put_request(fc, req);
382 struct inode *inode = entry->d_inode;
384 /* Set nlink to zero so the inode can be cleared, if
385 the inode does have more links this will be
386 discovered at the next lookup/getattr */
388 fuse_invalidate_attr(inode);
389 fuse_invalidate_attr(dir);
390 } else if (err == -EINTR)
391 fuse_invalidate_entry(entry);
395 static int fuse_rmdir(struct inode *dir, struct dentry *entry)
398 struct fuse_conn *fc = get_fuse_conn(dir);
399 struct fuse_req *req = fuse_get_request(fc);
403 req->in.h.opcode = FUSE_RMDIR;
404 req->in.h.nodeid = get_node_id(dir);
407 req->in.args[0].size = entry->d_name.len + 1;
408 req->in.args[0].value = entry->d_name.name;
409 request_send(fc, req);
410 err = req->out.h.error;
411 fuse_put_request(fc, req);
413 entry->d_inode->i_nlink = 0;
414 fuse_invalidate_attr(dir);
415 } else if (err == -EINTR)
416 fuse_invalidate_entry(entry);
420 static int fuse_rename(struct inode *olddir, struct dentry *oldent,
421 struct inode *newdir, struct dentry *newent)
424 struct fuse_rename_in inarg;
425 struct fuse_conn *fc = get_fuse_conn(olddir);
426 struct fuse_req *req = fuse_get_request(fc);
430 memset(&inarg, 0, sizeof(inarg));
431 inarg.newdir = get_node_id(newdir);
432 req->in.h.opcode = FUSE_RENAME;
433 req->in.h.nodeid = get_node_id(olddir);
435 req->inode2 = newdir;
437 req->in.args[0].size = sizeof(inarg);
438 req->in.args[0].value = &inarg;
439 req->in.args[1].size = oldent->d_name.len + 1;
440 req->in.args[1].value = oldent->d_name.name;
441 req->in.args[2].size = newent->d_name.len + 1;
442 req->in.args[2].value = newent->d_name.name;
443 request_send(fc, req);
444 err = req->out.h.error;
445 fuse_put_request(fc, req);
447 fuse_invalidate_attr(olddir);
448 if (olddir != newdir)
449 fuse_invalidate_attr(newdir);
450 } else if (err == -EINTR) {
451 /* If request was interrupted, DEITY only knows if the
452 rename actually took place. If the invalidation
453 fails (e.g. some process has CWD under the renamed
454 directory), then there can be inconsistency between
455 the dcache and the real filesystem. Tough luck. */
456 fuse_invalidate_entry(oldent);
458 fuse_invalidate_entry(newent);
464 static int fuse_link(struct dentry *entry, struct inode *newdir,
465 struct dentry *newent)
468 struct fuse_link_in inarg;
469 struct inode *inode = entry->d_inode;
470 struct fuse_conn *fc = get_fuse_conn(inode);
471 struct fuse_req *req = fuse_get_request(fc);
475 memset(&inarg, 0, sizeof(inarg));
476 inarg.oldnodeid = get_node_id(inode);
477 req->in.h.opcode = FUSE_LINK;
480 req->in.args[0].size = sizeof(inarg);
481 req->in.args[0].value = &inarg;
482 req->in.args[1].size = newent->d_name.len + 1;
483 req->in.args[1].value = newent->d_name.name;
484 err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
485 /* Contrary to "normal" filesystems it can happen that link
486 makes two "logical" inodes point to the same "physical"
487 inode. We invalidate the attributes of the old one, so it
488 will reflect changes in the backing inode (link count,
491 if (!err || err == -EINTR)
492 fuse_invalidate_attr(inode);
496 int fuse_do_getattr(struct inode *inode)
499 struct fuse_attr_out arg;
500 struct fuse_conn *fc = get_fuse_conn(inode);
501 struct fuse_req *req = fuse_get_request(fc);
505 req->in.h.opcode = FUSE_GETATTR;
506 req->in.h.nodeid = get_node_id(inode);
508 req->out.numargs = 1;
509 req->out.args[0].size = sizeof(arg);
510 req->out.args[0].value = &arg;
511 request_send(fc, req);
512 err = req->out.h.error;
513 fuse_put_request(fc, req);
515 if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
516 make_bad_inode(inode);
519 struct fuse_inode *fi = get_fuse_inode(inode);
520 fuse_change_attributes(inode, &arg.attr);
521 fi->i_time = time_to_jiffies(arg.attr_valid,
522 arg.attr_valid_nsec);
529 * Calling into a user-controlled filesystem gives the filesystem
530 * daemon ptrace-like capabilities over the requester process. This
531 * means, that the filesystem daemon is able to record the exact
532 * filesystem operations performed, and can also control the behavior
533 * of the requester process in otherwise impossible ways. For example
534 * it can delay the operation for arbitrary length of time allowing
535 * DoS against the requester.
537 * For this reason only those processes can call into the filesystem,
538 * for which the owner of the mount has ptrace privilege. This
539 * excludes processes started by other users, suid or sgid processes.
541 static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
543 if (fc->flags & FUSE_ALLOW_OTHER)
546 if (task->euid == fc->user_id &&
547 task->suid == fc->user_id &&
548 task->uid == fc->user_id &&
549 task->egid == fc->group_id &&
550 task->sgid == fc->group_id &&
551 task->gid == fc->group_id)
557 static int fuse_revalidate(struct dentry *entry)
559 struct inode *inode = entry->d_inode;
560 struct fuse_inode *fi = get_fuse_inode(inode);
561 struct fuse_conn *fc = get_fuse_conn(inode);
563 if (!fuse_allow_task(fc, current))
565 if (get_node_id(inode) != FUSE_ROOT_ID &&
566 time_before_eq(jiffies, fi->i_time))
569 return fuse_do_getattr(inode);
572 static int fuse_access(struct inode *inode, int mask)
574 struct fuse_conn *fc = get_fuse_conn(inode);
575 struct fuse_req *req;
576 struct fuse_access_in inarg;
582 req = fuse_get_request(fc);
586 memset(&inarg, 0, sizeof(inarg));
588 req->in.h.opcode = FUSE_ACCESS;
589 req->in.h.nodeid = get_node_id(inode);
592 req->in.args[0].size = sizeof(inarg);
593 req->in.args[0].value = &inarg;
594 request_send(fc, req);
595 err = req->out.h.error;
596 fuse_put_request(fc, req);
597 if (err == -ENOSYS) {
604 static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
606 struct fuse_conn *fc = get_fuse_conn(inode);
608 if (!fuse_allow_task(fc, current))
610 else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
611 int err = generic_permission(inode, mask, NULL);
613 /* If permission is denied, try to refresh file
614 attributes. This is also needed, because the root
615 node will at first have no permissions */
616 if (err == -EACCES) {
617 err = fuse_do_getattr(inode);
619 err = generic_permission(inode, mask, NULL);
622 /* FIXME: Need some mechanism to revoke permissions:
623 currently if the filesystem suddenly changes the
624 file mode, we will not be informed about it, and
625 continue to allow access to the file/directory.
627 This is actually not so grave, since the user can
628 simply keep access to the file/directory anyway by
629 keeping it open... */
633 int mode = inode->i_mode;
634 if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
637 if (nd && (nd->flags & LOOKUP_ACCESS))
638 return fuse_access(inode, mask);
643 static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
644 void *dstbuf, filldir_t filldir)
646 while (nbytes >= FUSE_NAME_OFFSET) {
647 struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
648 size_t reclen = FUSE_DIRENT_SIZE(dirent);
650 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
655 over = filldir(dstbuf, dirent->name, dirent->namelen,
656 file->f_pos, dirent->ino, dirent->type);
662 file->f_pos = dirent->off;
668 static inline size_t fuse_send_readdir(struct fuse_req *req, struct file *file,
669 struct inode *inode, loff_t pos,
672 return fuse_send_read_common(req, file, inode, pos, count, 1);
675 static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
680 struct inode *inode = file->f_dentry->d_inode;
681 struct fuse_conn *fc = get_fuse_conn(inode);
682 struct fuse_req *req = fuse_get_request(fc);
686 page = alloc_page(GFP_KERNEL);
688 fuse_put_request(fc, req);
692 req->pages[0] = page;
693 nbytes = fuse_send_readdir(req, file, inode, file->f_pos, PAGE_SIZE);
694 err = req->out.h.error;
695 fuse_put_request(fc, req);
697 err = parse_dirfile(page_address(page), nbytes, file, dstbuf,
701 fuse_invalidate_attr(inode); /* atime changed */
705 static char *read_link(struct dentry *dentry)
707 struct inode *inode = dentry->d_inode;
708 struct fuse_conn *fc = get_fuse_conn(inode);
709 struct fuse_req *req = fuse_get_request(fc);
713 return ERR_PTR(-EINTR);
715 link = (char *) __get_free_page(GFP_KERNEL);
717 link = ERR_PTR(-ENOMEM);
720 req->in.h.opcode = FUSE_READLINK;
721 req->in.h.nodeid = get_node_id(inode);
724 req->out.numargs = 1;
725 req->out.args[0].size = PAGE_SIZE - 1;
726 req->out.args[0].value = link;
727 request_send(fc, req);
728 if (req->out.h.error) {
729 free_page((unsigned long) link);
730 link = ERR_PTR(req->out.h.error);
732 link[req->out.args[0].size] = '\0';
734 fuse_put_request(fc, req);
735 fuse_invalidate_attr(inode); /* atime changed */
739 static void free_link(char *link)
742 free_page((unsigned long) link);
745 static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
747 nd_set_link(nd, read_link(dentry));
751 static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
753 free_link(nd_get_link(nd));
756 static int fuse_dir_open(struct inode *inode, struct file *file)
758 return fuse_open_common(inode, file, 1);
761 static int fuse_dir_release(struct inode *inode, struct file *file)
763 return fuse_release_common(inode, file, 1);
766 static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
768 /* nfsd can call this with no file */
769 return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
772 static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
774 unsigned ivalid = iattr->ia_valid;
776 if (ivalid & ATTR_MODE)
777 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
778 if (ivalid & ATTR_UID)
779 arg->valid |= FATTR_UID, arg->uid = iattr->ia_uid;
780 if (ivalid & ATTR_GID)
781 arg->valid |= FATTR_GID, arg->gid = iattr->ia_gid;
782 if (ivalid & ATTR_SIZE)
783 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
784 /* You can only _set_ these together (they may change by themselves) */
785 if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
786 arg->valid |= FATTR_ATIME | FATTR_MTIME;
787 arg->atime = iattr->ia_atime.tv_sec;
788 arg->mtime = iattr->ia_mtime.tv_sec;
790 if (ivalid & ATTR_FILE) {
791 struct fuse_file *ff = iattr->ia_file->private_data;
792 arg->valid |= FATTR_FH;
797 static int fuse_setattr(struct dentry *entry, struct iattr *attr)
799 struct inode *inode = entry->d_inode;
800 struct fuse_conn *fc = get_fuse_conn(inode);
801 struct fuse_inode *fi = get_fuse_inode(inode);
802 struct fuse_req *req;
803 struct fuse_setattr_in inarg;
804 struct fuse_attr_out outarg;
808 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
809 err = inode_change_ok(inode, attr);
814 if (attr->ia_valid & ATTR_SIZE) {
817 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
818 if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {
819 send_sig(SIGXFSZ, current, 0);
824 req = fuse_get_request(fc);
828 memset(&inarg, 0, sizeof(inarg));
829 iattr_to_fattr(attr, &inarg);
830 req->in.h.opcode = FUSE_SETATTR;
831 req->in.h.nodeid = get_node_id(inode);
834 req->in.args[0].size = sizeof(inarg);
835 req->in.args[0].value = &inarg;
836 req->out.numargs = 1;
837 req->out.args[0].size = sizeof(outarg);
838 req->out.args[0].value = &outarg;
839 request_send(fc, req);
840 err = req->out.h.error;
841 fuse_put_request(fc, req);
843 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
844 make_bad_inode(inode);
848 loff_t origsize = i_size_read(inode);
849 i_size_write(inode, outarg.attr.size);
850 if (origsize > outarg.attr.size)
851 vmtruncate(inode, outarg.attr.size);
853 fuse_change_attributes(inode, &outarg.attr);
854 fi->i_time = time_to_jiffies(outarg.attr_valid,
855 outarg.attr_valid_nsec);
857 } else if (err == -EINTR)
858 fuse_invalidate_attr(inode);
863 static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
866 struct inode *inode = entry->d_inode;
867 int err = fuse_revalidate(entry);
869 generic_fillattr(inode, stat);
874 static int fuse_setxattr(struct dentry *entry, const char *name,
875 const void *value, size_t size, int flags)
877 struct inode *inode = entry->d_inode;
878 struct fuse_conn *fc = get_fuse_conn(inode);
879 struct fuse_req *req;
880 struct fuse_setxattr_in inarg;
883 if (size > FUSE_XATTR_SIZE_MAX)
889 req = fuse_get_request(fc);
893 memset(&inarg, 0, sizeof(inarg));
896 req->in.h.opcode = FUSE_SETXATTR;
897 req->in.h.nodeid = get_node_id(inode);
900 req->in.args[0].size = sizeof(inarg);
901 req->in.args[0].value = &inarg;
902 req->in.args[1].size = strlen(name) + 1;
903 req->in.args[1].value = name;
904 req->in.args[2].size = size;
905 req->in.args[2].value = value;
906 request_send(fc, req);
907 err = req->out.h.error;
908 fuse_put_request(fc, req);
909 if (err == -ENOSYS) {
916 static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
917 void *value, size_t size)
919 struct inode *inode = entry->d_inode;
920 struct fuse_conn *fc = get_fuse_conn(inode);
921 struct fuse_req *req;
922 struct fuse_getxattr_in inarg;
923 struct fuse_getxattr_out outarg;
929 req = fuse_get_request(fc);
933 memset(&inarg, 0, sizeof(inarg));
935 req->in.h.opcode = FUSE_GETXATTR;
936 req->in.h.nodeid = get_node_id(inode);
939 req->in.args[0].size = sizeof(inarg);
940 req->in.args[0].value = &inarg;
941 req->in.args[1].size = strlen(name) + 1;
942 req->in.args[1].value = name;
943 /* This is really two different operations rolled into one */
944 req->out.numargs = 1;
947 req->out.args[0].size = size;
948 req->out.args[0].value = value;
950 req->out.args[0].size = sizeof(outarg);
951 req->out.args[0].value = &outarg;
953 request_send(fc, req);
954 ret = req->out.h.error;
956 ret = size ? req->out.args[0].size : outarg.size;
958 if (ret == -ENOSYS) {
963 fuse_put_request(fc, req);
967 static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
969 struct inode *inode = entry->d_inode;
970 struct fuse_conn *fc = get_fuse_conn(inode);
971 struct fuse_req *req;
972 struct fuse_getxattr_in inarg;
973 struct fuse_getxattr_out outarg;
976 if (fc->no_listxattr)
979 req = fuse_get_request(fc);
983 memset(&inarg, 0, sizeof(inarg));
985 req->in.h.opcode = FUSE_LISTXATTR;
986 req->in.h.nodeid = get_node_id(inode);
989 req->in.args[0].size = sizeof(inarg);
990 req->in.args[0].value = &inarg;
991 /* This is really two different operations rolled into one */
992 req->out.numargs = 1;
995 req->out.args[0].size = size;
996 req->out.args[0].value = list;
998 req->out.args[0].size = sizeof(outarg);
999 req->out.args[0].value = &outarg;
1001 request_send(fc, req);
1002 ret = req->out.h.error;
1004 ret = size ? req->out.args[0].size : outarg.size;
1006 if (ret == -ENOSYS) {
1007 fc->no_listxattr = 1;
1011 fuse_put_request(fc, req);
1015 static int fuse_removexattr(struct dentry *entry, const char *name)
1017 struct inode *inode = entry->d_inode;
1018 struct fuse_conn *fc = get_fuse_conn(inode);
1019 struct fuse_req *req;
1022 if (fc->no_removexattr)
1025 req = fuse_get_request(fc);
1029 req->in.h.opcode = FUSE_REMOVEXATTR;
1030 req->in.h.nodeid = get_node_id(inode);
1032 req->in.numargs = 1;
1033 req->in.args[0].size = strlen(name) + 1;
1034 req->in.args[0].value = name;
1035 request_send(fc, req);
1036 err = req->out.h.error;
1037 fuse_put_request(fc, req);
1038 if (err == -ENOSYS) {
1039 fc->no_removexattr = 1;
1045 static struct inode_operations fuse_dir_inode_operations = {
1046 .lookup = fuse_lookup,
1047 .mkdir = fuse_mkdir,
1048 .symlink = fuse_symlink,
1049 .unlink = fuse_unlink,
1050 .rmdir = fuse_rmdir,
1051 .rename = fuse_rename,
1053 .setattr = fuse_setattr,
1054 .create = fuse_create,
1055 .mknod = fuse_mknod,
1056 .permission = fuse_permission,
1057 .getattr = fuse_getattr,
1058 .setxattr = fuse_setxattr,
1059 .getxattr = fuse_getxattr,
1060 .listxattr = fuse_listxattr,
1061 .removexattr = fuse_removexattr,
1064 static struct file_operations fuse_dir_operations = {
1065 .llseek = generic_file_llseek,
1066 .read = generic_read_dir,
1067 .readdir = fuse_readdir,
1068 .open = fuse_dir_open,
1069 .release = fuse_dir_release,
1070 .fsync = fuse_dir_fsync,
1073 static struct inode_operations fuse_common_inode_operations = {
1074 .setattr = fuse_setattr,
1075 .permission = fuse_permission,
1076 .getattr = fuse_getattr,
1077 .setxattr = fuse_setxattr,
1078 .getxattr = fuse_getxattr,
1079 .listxattr = fuse_listxattr,
1080 .removexattr = fuse_removexattr,
1083 static struct inode_operations fuse_symlink_inode_operations = {
1084 .setattr = fuse_setattr,
1085 .follow_link = fuse_follow_link,
1086 .put_link = fuse_put_link,
1087 .readlink = generic_readlink,
1088 .getattr = fuse_getattr,
1089 .setxattr = fuse_setxattr,
1090 .getxattr = fuse_getxattr,
1091 .listxattr = fuse_listxattr,
1092 .removexattr = fuse_removexattr,
1095 void fuse_init_common(struct inode *inode)
1097 inode->i_op = &fuse_common_inode_operations;
1100 void fuse_init_dir(struct inode *inode)
1102 inode->i_op = &fuse_dir_inode_operations;
1103 inode->i_fop = &fuse_dir_operations;
1106 void fuse_init_symlink(struct inode *inode)
1108 inode->i_op = &fuse_symlink_inode_operations;