[PATCH] FUSE: tighten check for processes allowed access
[linux-2.6/cjktty.git] / fs / fuse / dir.c
blob65da6e1b6de54d88ad13f8d241e0219fec128eec
1 /*
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.
6 See the file COPYING.
7 */
9 #include "fuse_i.h"
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,
18 unsigned long nsec)
20 struct timespec ts = {sec, nsec};
21 return jiffies + timespec_to_jiffies(&ts);
24 static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
25 struct dentry *entry,
26 struct fuse_entry_out *outarg)
28 req->in.h.opcode = FUSE_LOOKUP;
29 req->in.h.nodeid = get_node_id(dir);
30 req->inode = dir;
31 req->in.numargs = 1;
32 req->in.args[0].size = entry->d_name.len + 1;
33 req->in.args[0].value = entry->d_name.name;
34 req->out.numargs = 1;
35 req->out.args[0].size = sizeof(struct fuse_entry_out);
36 req->out.args[0].value = outarg;
39 static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
41 if (!entry->d_inode || is_bad_inode(entry->d_inode))
42 return 0;
43 else if (time_after(jiffies, entry->d_time)) {
44 int err;
45 struct fuse_entry_out outarg;
46 struct inode *inode = entry->d_inode;
47 struct fuse_inode *fi = get_fuse_inode(inode);
48 struct fuse_conn *fc = get_fuse_conn(inode);
49 struct fuse_req *req = fuse_get_request_nonint(fc);
50 if (!req)
51 return 0;
53 fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg);
54 request_send_nonint(fc, req);
55 err = req->out.h.error;
56 if (!err) {
57 if (outarg.nodeid != get_node_id(inode)) {
58 fuse_send_forget(fc, req, outarg.nodeid, 1);
59 return 0;
61 fi->nlookup ++;
63 fuse_put_request(fc, req);
64 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
65 return 0;
67 fuse_change_attributes(inode, &outarg.attr);
68 entry->d_time = time_to_jiffies(outarg.entry_valid,
69 outarg.entry_valid_nsec);
70 fi->i_time = time_to_jiffies(outarg.attr_valid,
71 outarg.attr_valid_nsec);
73 return 1;
76 static struct dentry_operations fuse_dentry_operations = {
77 .d_revalidate = fuse_dentry_revalidate,
80 static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
81 struct inode **inodep)
83 int err;
84 struct fuse_entry_out outarg;
85 struct inode *inode = NULL;
86 struct fuse_conn *fc = get_fuse_conn(dir);
87 struct fuse_req *req;
89 if (entry->d_name.len > FUSE_NAME_MAX)
90 return -ENAMETOOLONG;
92 req = fuse_get_request(fc);
93 if (!req)
94 return -ERESTARTNOINTR;
96 fuse_lookup_init(req, dir, entry, &outarg);
97 request_send(fc, req);
98 err = req->out.h.error;
99 if (!err) {
100 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
101 &outarg.attr);
102 if (!inode) {
103 fuse_send_forget(fc, req, outarg.nodeid, 1);
104 return -ENOMEM;
107 fuse_put_request(fc, req);
108 if (err && err != -ENOENT)
109 return err;
111 if (inode) {
112 struct fuse_inode *fi = get_fuse_inode(inode);
113 entry->d_time = time_to_jiffies(outarg.entry_valid,
114 outarg.entry_valid_nsec);
115 fi->i_time = time_to_jiffies(outarg.attr_valid,
116 outarg.attr_valid_nsec);
119 entry->d_op = &fuse_dentry_operations;
120 *inodep = inode;
121 return 0;
124 void fuse_invalidate_attr(struct inode *inode)
126 get_fuse_inode(inode)->i_time = jiffies - 1;
129 static void fuse_invalidate_entry(struct dentry *entry)
131 d_invalidate(entry);
132 entry->d_time = jiffies - 1;
135 static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
136 struct inode *dir, struct dentry *entry,
137 int mode)
139 struct fuse_entry_out outarg;
140 struct inode *inode;
141 struct fuse_inode *fi;
142 int err;
144 req->in.h.nodeid = get_node_id(dir);
145 req->inode = dir;
146 req->out.numargs = 1;
147 req->out.args[0].size = sizeof(outarg);
148 req->out.args[0].value = &outarg;
149 request_send(fc, req);
150 err = req->out.h.error;
151 if (err) {
152 fuse_put_request(fc, req);
153 return err;
155 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
156 &outarg.attr);
157 if (!inode) {
158 fuse_send_forget(fc, req, outarg.nodeid, 1);
159 return -ENOMEM;
161 fuse_put_request(fc, req);
163 /* Don't allow userspace to do really stupid things... */
164 if ((inode->i_mode ^ mode) & S_IFMT) {
165 iput(inode);
166 return -EIO;
169 entry->d_time = time_to_jiffies(outarg.entry_valid,
170 outarg.entry_valid_nsec);
172 fi = get_fuse_inode(inode);
173 fi->i_time = time_to_jiffies(outarg.attr_valid,
174 outarg.attr_valid_nsec);
176 d_instantiate(entry, inode);
177 fuse_invalidate_attr(dir);
178 return 0;
181 static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
182 dev_t rdev)
184 struct fuse_mknod_in inarg;
185 struct fuse_conn *fc = get_fuse_conn(dir);
186 struct fuse_req *req = fuse_get_request(fc);
187 if (!req)
188 return -ERESTARTNOINTR;
190 memset(&inarg, 0, sizeof(inarg));
191 inarg.mode = mode;
192 inarg.rdev = new_encode_dev(rdev);
193 req->in.h.opcode = FUSE_MKNOD;
194 req->in.numargs = 2;
195 req->in.args[0].size = sizeof(inarg);
196 req->in.args[0].value = &inarg;
197 req->in.args[1].size = entry->d_name.len + 1;
198 req->in.args[1].value = entry->d_name.name;
199 return create_new_entry(fc, req, dir, entry, mode);
202 static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
203 struct nameidata *nd)
205 return fuse_mknod(dir, entry, mode, 0);
208 static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
210 struct fuse_mkdir_in inarg;
211 struct fuse_conn *fc = get_fuse_conn(dir);
212 struct fuse_req *req = fuse_get_request(fc);
213 if (!req)
214 return -ERESTARTNOINTR;
216 memset(&inarg, 0, sizeof(inarg));
217 inarg.mode = mode;
218 req->in.h.opcode = FUSE_MKDIR;
219 req->in.numargs = 2;
220 req->in.args[0].size = sizeof(inarg);
221 req->in.args[0].value = &inarg;
222 req->in.args[1].size = entry->d_name.len + 1;
223 req->in.args[1].value = entry->d_name.name;
224 return create_new_entry(fc, req, dir, entry, S_IFDIR);
227 static int fuse_symlink(struct inode *dir, struct dentry *entry,
228 const char *link)
230 struct fuse_conn *fc = get_fuse_conn(dir);
231 unsigned len = strlen(link) + 1;
232 struct fuse_req *req;
234 if (len > FUSE_SYMLINK_MAX)
235 return -ENAMETOOLONG;
237 req = fuse_get_request(fc);
238 if (!req)
239 return -ERESTARTNOINTR;
241 req->in.h.opcode = FUSE_SYMLINK;
242 req->in.numargs = 2;
243 req->in.args[0].size = entry->d_name.len + 1;
244 req->in.args[0].value = entry->d_name.name;
245 req->in.args[1].size = len;
246 req->in.args[1].value = link;
247 return create_new_entry(fc, req, dir, entry, S_IFLNK);
250 static int fuse_unlink(struct inode *dir, struct dentry *entry)
252 int err;
253 struct fuse_conn *fc = get_fuse_conn(dir);
254 struct fuse_req *req = fuse_get_request(fc);
255 if (!req)
256 return -ERESTARTNOINTR;
258 req->in.h.opcode = FUSE_UNLINK;
259 req->in.h.nodeid = get_node_id(dir);
260 req->inode = dir;
261 req->in.numargs = 1;
262 req->in.args[0].size = entry->d_name.len + 1;
263 req->in.args[0].value = entry->d_name.name;
264 request_send(fc, req);
265 err = req->out.h.error;
266 fuse_put_request(fc, req);
267 if (!err) {
268 struct inode *inode = entry->d_inode;
270 /* Set nlink to zero so the inode can be cleared, if
271 the inode does have more links this will be
272 discovered at the next lookup/getattr */
273 inode->i_nlink = 0;
274 fuse_invalidate_attr(inode);
275 fuse_invalidate_attr(dir);
276 } else if (err == -EINTR)
277 fuse_invalidate_entry(entry);
278 return err;
281 static int fuse_rmdir(struct inode *dir, struct dentry *entry)
283 int err;
284 struct fuse_conn *fc = get_fuse_conn(dir);
285 struct fuse_req *req = fuse_get_request(fc);
286 if (!req)
287 return -ERESTARTNOINTR;
289 req->in.h.opcode = FUSE_RMDIR;
290 req->in.h.nodeid = get_node_id(dir);
291 req->inode = dir;
292 req->in.numargs = 1;
293 req->in.args[0].size = entry->d_name.len + 1;
294 req->in.args[0].value = entry->d_name.name;
295 request_send(fc, req);
296 err = req->out.h.error;
297 fuse_put_request(fc, req);
298 if (!err) {
299 entry->d_inode->i_nlink = 0;
300 fuse_invalidate_attr(dir);
301 } else if (err == -EINTR)
302 fuse_invalidate_entry(entry);
303 return err;
306 static int fuse_rename(struct inode *olddir, struct dentry *oldent,
307 struct inode *newdir, struct dentry *newent)
309 int err;
310 struct fuse_rename_in inarg;
311 struct fuse_conn *fc = get_fuse_conn(olddir);
312 struct fuse_req *req = fuse_get_request(fc);
313 if (!req)
314 return -ERESTARTNOINTR;
316 memset(&inarg, 0, sizeof(inarg));
317 inarg.newdir = get_node_id(newdir);
318 req->in.h.opcode = FUSE_RENAME;
319 req->in.h.nodeid = get_node_id(olddir);
320 req->inode = olddir;
321 req->inode2 = newdir;
322 req->in.numargs = 3;
323 req->in.args[0].size = sizeof(inarg);
324 req->in.args[0].value = &inarg;
325 req->in.args[1].size = oldent->d_name.len + 1;
326 req->in.args[1].value = oldent->d_name.name;
327 req->in.args[2].size = newent->d_name.len + 1;
328 req->in.args[2].value = newent->d_name.name;
329 request_send(fc, req);
330 err = req->out.h.error;
331 fuse_put_request(fc, req);
332 if (!err) {
333 fuse_invalidate_attr(olddir);
334 if (olddir != newdir)
335 fuse_invalidate_attr(newdir);
336 } else if (err == -EINTR) {
337 /* If request was interrupted, DEITY only knows if the
338 rename actually took place. If the invalidation
339 fails (e.g. some process has CWD under the renamed
340 directory), then there can be inconsistency between
341 the dcache and the real filesystem. Tough luck. */
342 fuse_invalidate_entry(oldent);
343 if (newent->d_inode)
344 fuse_invalidate_entry(newent);
347 return err;
350 static int fuse_link(struct dentry *entry, struct inode *newdir,
351 struct dentry *newent)
353 int err;
354 struct fuse_link_in inarg;
355 struct inode *inode = entry->d_inode;
356 struct fuse_conn *fc = get_fuse_conn(inode);
357 struct fuse_req *req = fuse_get_request(fc);
358 if (!req)
359 return -ERESTARTNOINTR;
361 memset(&inarg, 0, sizeof(inarg));
362 inarg.oldnodeid = get_node_id(inode);
363 req->in.h.opcode = FUSE_LINK;
364 req->inode2 = inode;
365 req->in.numargs = 2;
366 req->in.args[0].size = sizeof(inarg);
367 req->in.args[0].value = &inarg;
368 req->in.args[1].size = newent->d_name.len + 1;
369 req->in.args[1].value = newent->d_name.name;
370 err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
371 /* Contrary to "normal" filesystems it can happen that link
372 makes two "logical" inodes point to the same "physical"
373 inode. We invalidate the attributes of the old one, so it
374 will reflect changes in the backing inode (link count,
375 etc.)
377 if (!err || err == -EINTR)
378 fuse_invalidate_attr(inode);
379 return err;
382 int fuse_do_getattr(struct inode *inode)
384 int err;
385 struct fuse_attr_out arg;
386 struct fuse_conn *fc = get_fuse_conn(inode);
387 struct fuse_req *req = fuse_get_request(fc);
388 if (!req)
389 return -ERESTARTNOINTR;
391 req->in.h.opcode = FUSE_GETATTR;
392 req->in.h.nodeid = get_node_id(inode);
393 req->inode = inode;
394 req->out.numargs = 1;
395 req->out.args[0].size = sizeof(arg);
396 req->out.args[0].value = &arg;
397 request_send(fc, req);
398 err = req->out.h.error;
399 fuse_put_request(fc, req);
400 if (!err) {
401 if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
402 make_bad_inode(inode);
403 err = -EIO;
404 } else {
405 struct fuse_inode *fi = get_fuse_inode(inode);
406 fuse_change_attributes(inode, &arg.attr);
407 fi->i_time = time_to_jiffies(arg.attr_valid,
408 arg.attr_valid_nsec);
411 return err;
415 * Calling into a user-controlled filesystem gives the filesystem
416 * daemon ptrace-like capabilities over the requester process. This
417 * means, that the filesystem daemon is able to record the exact
418 * filesystem operations performed, and can also control the behavior
419 * of the requester process in otherwise impossible ways. For example
420 * it can delay the operation for arbitrary length of time allowing
421 * DoS against the requester.
423 * For this reason only those processes can call into the filesystem,
424 * for which the owner of the mount has ptrace privilege. This
425 * excludes processes started by other users, suid or sgid processes.
427 static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
429 if (fc->flags & FUSE_ALLOW_OTHER)
430 return 1;
432 if (task->euid == fc->user_id &&
433 task->suid == fc->user_id &&
434 task->uid == fc->user_id &&
435 task->egid == fc->group_id &&
436 task->sgid == fc->group_id &&
437 task->gid == fc->group_id)
438 return 1;
440 return 0;
443 static int fuse_revalidate(struct dentry *entry)
445 struct inode *inode = entry->d_inode;
446 struct fuse_inode *fi = get_fuse_inode(inode);
447 struct fuse_conn *fc = get_fuse_conn(inode);
449 if (!fuse_allow_task(fc, current))
450 return -EACCES;
451 if (get_node_id(inode) != FUSE_ROOT_ID &&
452 time_before_eq(jiffies, fi->i_time))
453 return 0;
455 return fuse_do_getattr(inode);
458 static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
460 struct fuse_conn *fc = get_fuse_conn(inode);
462 if (!fuse_allow_task(fc, current))
463 return -EACCES;
464 else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
465 int err = generic_permission(inode, mask, NULL);
467 /* If permission is denied, try to refresh file
468 attributes. This is also needed, because the root
469 node will at first have no permissions */
470 if (err == -EACCES) {
471 err = fuse_do_getattr(inode);
472 if (!err)
473 err = generic_permission(inode, mask, NULL);
476 /* FIXME: Need some mechanism to revoke permissions:
477 currently if the filesystem suddenly changes the
478 file mode, we will not be informed about it, and
479 continue to allow access to the file/directory.
481 This is actually not so grave, since the user can
482 simply keep access to the file/directory anyway by
483 keeping it open... */
485 return err;
486 } else {
487 int mode = inode->i_mode;
488 if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
489 (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
490 return -EROFS;
491 if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
492 return -EACCES;
493 return 0;
497 static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
498 void *dstbuf, filldir_t filldir)
500 while (nbytes >= FUSE_NAME_OFFSET) {
501 struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
502 size_t reclen = FUSE_DIRENT_SIZE(dirent);
503 int over;
504 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
505 return -EIO;
506 if (reclen > nbytes)
507 break;
509 over = filldir(dstbuf, dirent->name, dirent->namelen,
510 file->f_pos, dirent->ino, dirent->type);
511 if (over)
512 break;
514 buf += reclen;
515 nbytes -= reclen;
516 file->f_pos = dirent->off;
519 return 0;
522 static int fuse_checkdir(struct file *cfile, struct file *file)
524 struct inode *inode;
525 if (!cfile)
526 return -EIO;
527 inode = cfile->f_dentry->d_inode;
528 if (!S_ISREG(inode->i_mode)) {
529 fput(cfile);
530 return -EIO;
533 file->private_data = cfile;
534 return 0;
537 static int fuse_getdir(struct file *file)
539 struct inode *inode = file->f_dentry->d_inode;
540 struct fuse_conn *fc = get_fuse_conn(inode);
541 struct fuse_req *req = fuse_get_request(fc);
542 struct fuse_getdir_out_i outarg;
543 int err;
545 if (!req)
546 return -ERESTARTNOINTR;
548 req->in.h.opcode = FUSE_GETDIR;
549 req->in.h.nodeid = get_node_id(inode);
550 req->inode = inode;
551 req->out.numargs = 1;
552 req->out.args[0].size = sizeof(struct fuse_getdir_out);
553 req->out.args[0].value = &outarg;
554 request_send(fc, req);
555 err = req->out.h.error;
556 fuse_put_request(fc, req);
557 if (!err)
558 err = fuse_checkdir(outarg.file, file);
559 return err;
562 static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
564 struct file *cfile = file->private_data;
565 char *buf;
566 int ret;
568 if (!cfile) {
569 ret = fuse_getdir(file);
570 if (ret)
571 return ret;
573 cfile = file->private_data;
576 buf = (char *) __get_free_page(GFP_KERNEL);
577 if (!buf)
578 return -ENOMEM;
580 ret = kernel_read(cfile, file->f_pos, buf, PAGE_SIZE);
581 if (ret > 0)
582 ret = parse_dirfile(buf, ret, file, dstbuf, filldir);
584 free_page((unsigned long) buf);
585 return ret;
588 static char *read_link(struct dentry *dentry)
590 struct inode *inode = dentry->d_inode;
591 struct fuse_conn *fc = get_fuse_conn(inode);
592 struct fuse_req *req = fuse_get_request(fc);
593 char *link;
595 if (!req)
596 return ERR_PTR(-ERESTARTNOINTR);
598 link = (char *) __get_free_page(GFP_KERNEL);
599 if (!link) {
600 link = ERR_PTR(-ENOMEM);
601 goto out;
603 req->in.h.opcode = FUSE_READLINK;
604 req->in.h.nodeid = get_node_id(inode);
605 req->inode = inode;
606 req->out.argvar = 1;
607 req->out.numargs = 1;
608 req->out.args[0].size = PAGE_SIZE - 1;
609 req->out.args[0].value = link;
610 request_send(fc, req);
611 if (req->out.h.error) {
612 free_page((unsigned long) link);
613 link = ERR_PTR(req->out.h.error);
614 } else
615 link[req->out.args[0].size] = '\0';
616 out:
617 fuse_put_request(fc, req);
618 return link;
621 static void free_link(char *link)
623 if (!IS_ERR(link))
624 free_page((unsigned long) link);
627 static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
629 nd_set_link(nd, read_link(dentry));
630 return NULL;
633 static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
635 free_link(nd_get_link(nd));
638 static int fuse_dir_open(struct inode *inode, struct file *file)
640 file->private_data = NULL;
641 return 0;
644 static int fuse_dir_release(struct inode *inode, struct file *file)
646 struct file *cfile = file->private_data;
648 if (cfile)
649 fput(cfile);
651 return 0;
654 static unsigned iattr_to_fattr(struct iattr *iattr, struct fuse_attr *fattr)
656 unsigned ivalid = iattr->ia_valid;
657 unsigned fvalid = 0;
659 memset(fattr, 0, sizeof(*fattr));
661 if (ivalid & ATTR_MODE)
662 fvalid |= FATTR_MODE, fattr->mode = iattr->ia_mode;
663 if (ivalid & ATTR_UID)
664 fvalid |= FATTR_UID, fattr->uid = iattr->ia_uid;
665 if (ivalid & ATTR_GID)
666 fvalid |= FATTR_GID, fattr->gid = iattr->ia_gid;
667 if (ivalid & ATTR_SIZE)
668 fvalid |= FATTR_SIZE, fattr->size = iattr->ia_size;
669 /* You can only _set_ these together (they may change by themselves) */
670 if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
671 fvalid |= FATTR_ATIME | FATTR_MTIME;
672 fattr->atime = iattr->ia_atime.tv_sec;
673 fattr->mtime = iattr->ia_mtime.tv_sec;
676 return fvalid;
679 static int fuse_setattr(struct dentry *entry, struct iattr *attr)
681 struct inode *inode = entry->d_inode;
682 struct fuse_conn *fc = get_fuse_conn(inode);
683 struct fuse_inode *fi = get_fuse_inode(inode);
684 struct fuse_req *req;
685 struct fuse_setattr_in inarg;
686 struct fuse_attr_out outarg;
687 int err;
688 int is_truncate = 0;
690 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
691 err = inode_change_ok(inode, attr);
692 if (err)
693 return err;
696 if (attr->ia_valid & ATTR_SIZE) {
697 unsigned long limit;
698 is_truncate = 1;
699 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
700 if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {
701 send_sig(SIGXFSZ, current, 0);
702 return -EFBIG;
706 req = fuse_get_request(fc);
707 if (!req)
708 return -ERESTARTNOINTR;
710 memset(&inarg, 0, sizeof(inarg));
711 inarg.valid = iattr_to_fattr(attr, &inarg.attr);
712 req->in.h.opcode = FUSE_SETATTR;
713 req->in.h.nodeid = get_node_id(inode);
714 req->inode = inode;
715 req->in.numargs = 1;
716 req->in.args[0].size = sizeof(inarg);
717 req->in.args[0].value = &inarg;
718 req->out.numargs = 1;
719 req->out.args[0].size = sizeof(outarg);
720 req->out.args[0].value = &outarg;
721 request_send(fc, req);
722 err = req->out.h.error;
723 fuse_put_request(fc, req);
724 if (!err) {
725 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
726 make_bad_inode(inode);
727 err = -EIO;
728 } else {
729 if (is_truncate) {
730 loff_t origsize = i_size_read(inode);
731 i_size_write(inode, outarg.attr.size);
732 if (origsize > outarg.attr.size)
733 vmtruncate(inode, outarg.attr.size);
735 fuse_change_attributes(inode, &outarg.attr);
736 fi->i_time = time_to_jiffies(outarg.attr_valid,
737 outarg.attr_valid_nsec);
739 } else if (err == -EINTR)
740 fuse_invalidate_attr(inode);
742 return err;
745 static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
746 struct kstat *stat)
748 struct inode *inode = entry->d_inode;
749 int err = fuse_revalidate(entry);
750 if (!err)
751 generic_fillattr(inode, stat);
753 return err;
756 static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
757 struct nameidata *nd)
759 struct inode *inode;
760 int err = fuse_lookup_iget(dir, entry, &inode);
761 if (err)
762 return ERR_PTR(err);
763 if (inode && S_ISDIR(inode->i_mode)) {
764 /* Don't allow creating an alias to a directory */
765 struct dentry *alias = d_find_alias(inode);
766 if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
767 dput(alias);
768 iput(inode);
769 return ERR_PTR(-EIO);
772 return d_splice_alias(inode, entry);
775 static int fuse_setxattr(struct dentry *entry, const char *name,
776 const void *value, size_t size, int flags)
778 struct inode *inode = entry->d_inode;
779 struct fuse_conn *fc = get_fuse_conn(inode);
780 struct fuse_req *req;
781 struct fuse_setxattr_in inarg;
782 int err;
784 if (size > FUSE_XATTR_SIZE_MAX)
785 return -E2BIG;
787 if (fc->no_setxattr)
788 return -EOPNOTSUPP;
790 req = fuse_get_request(fc);
791 if (!req)
792 return -ERESTARTNOINTR;
794 memset(&inarg, 0, sizeof(inarg));
795 inarg.size = size;
796 inarg.flags = flags;
797 req->in.h.opcode = FUSE_SETXATTR;
798 req->in.h.nodeid = get_node_id(inode);
799 req->inode = inode;
800 req->in.numargs = 3;
801 req->in.args[0].size = sizeof(inarg);
802 req->in.args[0].value = &inarg;
803 req->in.args[1].size = strlen(name) + 1;
804 req->in.args[1].value = name;
805 req->in.args[2].size = size;
806 req->in.args[2].value = value;
807 request_send(fc, req);
808 err = req->out.h.error;
809 fuse_put_request(fc, req);
810 if (err == -ENOSYS) {
811 fc->no_setxattr = 1;
812 err = -EOPNOTSUPP;
814 return err;
817 static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
818 void *value, size_t size)
820 struct inode *inode = entry->d_inode;
821 struct fuse_conn *fc = get_fuse_conn(inode);
822 struct fuse_req *req;
823 struct fuse_getxattr_in inarg;
824 struct fuse_getxattr_out outarg;
825 ssize_t ret;
827 if (fc->no_getxattr)
828 return -EOPNOTSUPP;
830 req = fuse_get_request(fc);
831 if (!req)
832 return -ERESTARTNOINTR;
834 memset(&inarg, 0, sizeof(inarg));
835 inarg.size = size;
836 req->in.h.opcode = FUSE_GETXATTR;
837 req->in.h.nodeid = get_node_id(inode);
838 req->inode = inode;
839 req->in.numargs = 2;
840 req->in.args[0].size = sizeof(inarg);
841 req->in.args[0].value = &inarg;
842 req->in.args[1].size = strlen(name) + 1;
843 req->in.args[1].value = name;
844 /* This is really two different operations rolled into one */
845 req->out.numargs = 1;
846 if (size) {
847 req->out.argvar = 1;
848 req->out.args[0].size = size;
849 req->out.args[0].value = value;
850 } else {
851 req->out.args[0].size = sizeof(outarg);
852 req->out.args[0].value = &outarg;
854 request_send(fc, req);
855 ret = req->out.h.error;
856 if (!ret)
857 ret = size ? req->out.args[0].size : outarg.size;
858 else {
859 if (ret == -ENOSYS) {
860 fc->no_getxattr = 1;
861 ret = -EOPNOTSUPP;
864 fuse_put_request(fc, req);
865 return ret;
868 static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
870 struct inode *inode = entry->d_inode;
871 struct fuse_conn *fc = get_fuse_conn(inode);
872 struct fuse_req *req;
873 struct fuse_getxattr_in inarg;
874 struct fuse_getxattr_out outarg;
875 ssize_t ret;
877 if (fc->no_listxattr)
878 return -EOPNOTSUPP;
880 req = fuse_get_request(fc);
881 if (!req)
882 return -ERESTARTNOINTR;
884 memset(&inarg, 0, sizeof(inarg));
885 inarg.size = size;
886 req->in.h.opcode = FUSE_LISTXATTR;
887 req->in.h.nodeid = get_node_id(inode);
888 req->inode = inode;
889 req->in.numargs = 1;
890 req->in.args[0].size = sizeof(inarg);
891 req->in.args[0].value = &inarg;
892 /* This is really two different operations rolled into one */
893 req->out.numargs = 1;
894 if (size) {
895 req->out.argvar = 1;
896 req->out.args[0].size = size;
897 req->out.args[0].value = list;
898 } else {
899 req->out.args[0].size = sizeof(outarg);
900 req->out.args[0].value = &outarg;
902 request_send(fc, req);
903 ret = req->out.h.error;
904 if (!ret)
905 ret = size ? req->out.args[0].size : outarg.size;
906 else {
907 if (ret == -ENOSYS) {
908 fc->no_listxattr = 1;
909 ret = -EOPNOTSUPP;
912 fuse_put_request(fc, req);
913 return ret;
916 static int fuse_removexattr(struct dentry *entry, const char *name)
918 struct inode *inode = entry->d_inode;
919 struct fuse_conn *fc = get_fuse_conn(inode);
920 struct fuse_req *req;
921 int err;
923 if (fc->no_removexattr)
924 return -EOPNOTSUPP;
926 req = fuse_get_request(fc);
927 if (!req)
928 return -ERESTARTNOINTR;
930 req->in.h.opcode = FUSE_REMOVEXATTR;
931 req->in.h.nodeid = get_node_id(inode);
932 req->inode = inode;
933 req->in.numargs = 1;
934 req->in.args[0].size = strlen(name) + 1;
935 req->in.args[0].value = name;
936 request_send(fc, req);
937 err = req->out.h.error;
938 fuse_put_request(fc, req);
939 if (err == -ENOSYS) {
940 fc->no_removexattr = 1;
941 err = -EOPNOTSUPP;
943 return err;
946 static struct inode_operations fuse_dir_inode_operations = {
947 .lookup = fuse_lookup,
948 .mkdir = fuse_mkdir,
949 .symlink = fuse_symlink,
950 .unlink = fuse_unlink,
951 .rmdir = fuse_rmdir,
952 .rename = fuse_rename,
953 .link = fuse_link,
954 .setattr = fuse_setattr,
955 .create = fuse_create,
956 .mknod = fuse_mknod,
957 .permission = fuse_permission,
958 .getattr = fuse_getattr,
959 .setxattr = fuse_setxattr,
960 .getxattr = fuse_getxattr,
961 .listxattr = fuse_listxattr,
962 .removexattr = fuse_removexattr,
965 static struct file_operations fuse_dir_operations = {
966 .llseek = generic_file_llseek,
967 .read = generic_read_dir,
968 .readdir = fuse_readdir,
969 .open = fuse_dir_open,
970 .release = fuse_dir_release,
973 static struct inode_operations fuse_common_inode_operations = {
974 .setattr = fuse_setattr,
975 .permission = fuse_permission,
976 .getattr = fuse_getattr,
977 .setxattr = fuse_setxattr,
978 .getxattr = fuse_getxattr,
979 .listxattr = fuse_listxattr,
980 .removexattr = fuse_removexattr,
983 static struct inode_operations fuse_symlink_inode_operations = {
984 .setattr = fuse_setattr,
985 .follow_link = fuse_follow_link,
986 .put_link = fuse_put_link,
987 .readlink = generic_readlink,
988 .getattr = fuse_getattr,
989 .setxattr = fuse_setxattr,
990 .getxattr = fuse_getxattr,
991 .listxattr = fuse_listxattr,
992 .removexattr = fuse_removexattr,
995 void fuse_init_common(struct inode *inode)
997 inode->i_op = &fuse_common_inode_operations;
1000 void fuse_init_dir(struct inode *inode)
1002 inode->i_op = &fuse_dir_inode_operations;
1003 inode->i_fop = &fuse_dir_operations;
1006 void fuse_init_symlink(struct inode *inode)
1008 inode->i_op = &fuse_symlink_inode_operations;