[PATCH] FUSE: add access call
[safe/jmp/linux-2.6] / fs / fuse / dir.c
1 /*
2   FUSE: Filesystem in Userspace
3   Copyright (C) 2001-2005  Miklos Szeredi <miklos@szeredi.hu>
4
5   This program can be distributed under the terms of the GNU GPL.
6   See the file COPYING.
7 */
8
9 #include "fuse_i.h"
10
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
17 static inline unsigned long time_to_jiffies(unsigned long sec,
18                                             unsigned long nsec)
19 {
20         struct timespec ts = {sec, nsec};
21         return jiffies + timespec_to_jiffies(&ts);
22 }
23
24 static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
25                              struct dentry *entry,
26                              struct fuse_entry_out *outarg)
27 {
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;
37 }
38
39 static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
40 {
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(fc);
50                 if (!req)
51                         return 0;
52
53                 fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg);
54                 request_send(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;
60                         }
61                         fi->nlookup ++;
62                 }
63                 fuse_put_request(fc, req);
64                 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
65                         return 0;
66
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);
72         }
73         return 1;
74 }
75
76 static struct dentry_operations fuse_dentry_operations = {
77         .d_revalidate   = fuse_dentry_revalidate,
78 };
79
80 static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
81                             struct inode **inodep)
82 {
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;
88
89         if (entry->d_name.len > FUSE_NAME_MAX)
90                 return -ENAMETOOLONG;
91
92         req = fuse_get_request(fc);
93         if (!req)
94                 return -EINTR;
95
96         fuse_lookup_init(req, dir, entry, &outarg);
97         request_send(fc, req);
98         err = req->out.h.error;
99         if (!err && (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID))
100                 err = -EIO;
101         if (!err) {
102                 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
103                                   &outarg.attr);
104                 if (!inode) {
105                         fuse_send_forget(fc, req, outarg.nodeid, 1);
106                         return -ENOMEM;
107                 }
108         }
109         fuse_put_request(fc, req);
110         if (err && err != -ENOENT)
111                 return err;
112
113         if (inode) {
114                 struct fuse_inode *fi = get_fuse_inode(inode);
115                 entry->d_time = time_to_jiffies(outarg.entry_valid,
116                                                 outarg.entry_valid_nsec);
117                 fi->i_time = time_to_jiffies(outarg.attr_valid,
118                                              outarg.attr_valid_nsec);
119         }
120
121         entry->d_op = &fuse_dentry_operations;
122         *inodep = inode;
123         return 0;
124 }
125
126 void fuse_invalidate_attr(struct inode *inode)
127 {
128         get_fuse_inode(inode)->i_time = jiffies - 1;
129 }
130
131 static void fuse_invalidate_entry(struct dentry *entry)
132 {
133         d_invalidate(entry);
134         entry->d_time = jiffies - 1;
135 }
136
137 static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
138                             struct inode *dir, struct dentry *entry,
139                             int mode)
140 {
141         struct fuse_entry_out outarg;
142         struct inode *inode;
143         struct fuse_inode *fi;
144         int err;
145
146         req->in.h.nodeid = get_node_id(dir);
147         req->inode = dir;
148         req->out.numargs = 1;
149         req->out.args[0].size = sizeof(outarg);
150         req->out.args[0].value = &outarg;
151         request_send(fc, req);
152         err = req->out.h.error;
153         if (err) {
154                 fuse_put_request(fc, req);
155                 return err;
156         }
157         if (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID) {
158                 fuse_put_request(fc, req);
159                 return -EIO;
160         }
161         inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
162                           &outarg.attr);
163         if (!inode) {
164                 fuse_send_forget(fc, req, outarg.nodeid, 1);
165                 return -ENOMEM;
166         }
167         fuse_put_request(fc, req);
168
169         /* Don't allow userspace to do really stupid things... */
170         if ((inode->i_mode ^ mode) & S_IFMT) {
171                 iput(inode);
172                 return -EIO;
173         }
174
175         entry->d_time = time_to_jiffies(outarg.entry_valid,
176                                         outarg.entry_valid_nsec);
177
178         fi = get_fuse_inode(inode);
179         fi->i_time = time_to_jiffies(outarg.attr_valid,
180                                      outarg.attr_valid_nsec);
181
182         d_instantiate(entry, inode);
183         fuse_invalidate_attr(dir);
184         return 0;
185 }
186
187 static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
188                       dev_t rdev)
189 {
190         struct fuse_mknod_in inarg;
191         struct fuse_conn *fc = get_fuse_conn(dir);
192         struct fuse_req *req = fuse_get_request(fc);
193         if (!req)
194                 return -EINTR;
195
196         memset(&inarg, 0, sizeof(inarg));
197         inarg.mode = mode;
198         inarg.rdev = new_encode_dev(rdev);
199         req->in.h.opcode = FUSE_MKNOD;
200         req->in.numargs = 2;
201         req->in.args[0].size = sizeof(inarg);
202         req->in.args[0].value = &inarg;
203         req->in.args[1].size = entry->d_name.len + 1;
204         req->in.args[1].value = entry->d_name.name;
205         return create_new_entry(fc, req, dir, entry, mode);
206 }
207
208 static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
209                        struct nameidata *nd)
210 {
211         return fuse_mknod(dir, entry, mode, 0);
212 }
213
214 static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
215 {
216         struct fuse_mkdir_in inarg;
217         struct fuse_conn *fc = get_fuse_conn(dir);
218         struct fuse_req *req = fuse_get_request(fc);
219         if (!req)
220                 return -EINTR;
221
222         memset(&inarg, 0, sizeof(inarg));
223         inarg.mode = mode;
224         req->in.h.opcode = FUSE_MKDIR;
225         req->in.numargs = 2;
226         req->in.args[0].size = sizeof(inarg);
227         req->in.args[0].value = &inarg;
228         req->in.args[1].size = entry->d_name.len + 1;
229         req->in.args[1].value = entry->d_name.name;
230         return create_new_entry(fc, req, dir, entry, S_IFDIR);
231 }
232
233 static int fuse_symlink(struct inode *dir, struct dentry *entry,
234                         const char *link)
235 {
236         struct fuse_conn *fc = get_fuse_conn(dir);
237         unsigned len = strlen(link) + 1;
238         struct fuse_req *req;
239
240         if (len > FUSE_SYMLINK_MAX)
241                 return -ENAMETOOLONG;
242
243         req = fuse_get_request(fc);
244         if (!req)
245                 return -EINTR;
246
247         req->in.h.opcode = FUSE_SYMLINK;
248         req->in.numargs = 2;
249         req->in.args[0].size = entry->d_name.len + 1;
250         req->in.args[0].value = entry->d_name.name;
251         req->in.args[1].size = len;
252         req->in.args[1].value = link;
253         return create_new_entry(fc, req, dir, entry, S_IFLNK);
254 }
255
256 static int fuse_unlink(struct inode *dir, struct dentry *entry)
257 {
258         int err;
259         struct fuse_conn *fc = get_fuse_conn(dir);
260         struct fuse_req *req = fuse_get_request(fc);
261         if (!req)
262                 return -EINTR;
263
264         req->in.h.opcode = FUSE_UNLINK;
265         req->in.h.nodeid = get_node_id(dir);
266         req->inode = dir;
267         req->in.numargs = 1;
268         req->in.args[0].size = entry->d_name.len + 1;
269         req->in.args[0].value = entry->d_name.name;
270         request_send(fc, req);
271         err = req->out.h.error;
272         fuse_put_request(fc, req);
273         if (!err) {
274                 struct inode *inode = entry->d_inode;
275
276                 /* Set nlink to zero so the inode can be cleared, if
277                    the inode does have more links this will be
278                    discovered at the next lookup/getattr */
279                 inode->i_nlink = 0;
280                 fuse_invalidate_attr(inode);
281                 fuse_invalidate_attr(dir);
282         } else if (err == -EINTR)
283                 fuse_invalidate_entry(entry);
284         return err;
285 }
286
287 static int fuse_rmdir(struct inode *dir, struct dentry *entry)
288 {
289         int err;
290         struct fuse_conn *fc = get_fuse_conn(dir);
291         struct fuse_req *req = fuse_get_request(fc);
292         if (!req)
293                 return -EINTR;
294
295         req->in.h.opcode = FUSE_RMDIR;
296         req->in.h.nodeid = get_node_id(dir);
297         req->inode = dir;
298         req->in.numargs = 1;
299         req->in.args[0].size = entry->d_name.len + 1;
300         req->in.args[0].value = entry->d_name.name;
301         request_send(fc, req);
302         err = req->out.h.error;
303         fuse_put_request(fc, req);
304         if (!err) {
305                 entry->d_inode->i_nlink = 0;
306                 fuse_invalidate_attr(dir);
307         } else if (err == -EINTR)
308                 fuse_invalidate_entry(entry);
309         return err;
310 }
311
312 static int fuse_rename(struct inode *olddir, struct dentry *oldent,
313                        struct inode *newdir, struct dentry *newent)
314 {
315         int err;
316         struct fuse_rename_in inarg;
317         struct fuse_conn *fc = get_fuse_conn(olddir);
318         struct fuse_req *req = fuse_get_request(fc);
319         if (!req)
320                 return -EINTR;
321
322         memset(&inarg, 0, sizeof(inarg));
323         inarg.newdir = get_node_id(newdir);
324         req->in.h.opcode = FUSE_RENAME;
325         req->in.h.nodeid = get_node_id(olddir);
326         req->inode = olddir;
327         req->inode2 = newdir;
328         req->in.numargs = 3;
329         req->in.args[0].size = sizeof(inarg);
330         req->in.args[0].value = &inarg;
331         req->in.args[1].size = oldent->d_name.len + 1;
332         req->in.args[1].value = oldent->d_name.name;
333         req->in.args[2].size = newent->d_name.len + 1;
334         req->in.args[2].value = newent->d_name.name;
335         request_send(fc, req);
336         err = req->out.h.error;
337         fuse_put_request(fc, req);
338         if (!err) {
339                 fuse_invalidate_attr(olddir);
340                 if (olddir != newdir)
341                         fuse_invalidate_attr(newdir);
342         } else if (err == -EINTR) {
343                 /* If request was interrupted, DEITY only knows if the
344                    rename actually took place.  If the invalidation
345                    fails (e.g. some process has CWD under the renamed
346                    directory), then there can be inconsistency between
347                    the dcache and the real filesystem.  Tough luck. */
348                 fuse_invalidate_entry(oldent);
349                 if (newent->d_inode)
350                         fuse_invalidate_entry(newent);
351         }
352
353         return err;
354 }
355
356 static int fuse_link(struct dentry *entry, struct inode *newdir,
357                      struct dentry *newent)
358 {
359         int err;
360         struct fuse_link_in inarg;
361         struct inode *inode = entry->d_inode;
362         struct fuse_conn *fc = get_fuse_conn(inode);
363         struct fuse_req *req = fuse_get_request(fc);
364         if (!req)
365                 return -EINTR;
366
367         memset(&inarg, 0, sizeof(inarg));
368         inarg.oldnodeid = get_node_id(inode);
369         req->in.h.opcode = FUSE_LINK;
370         req->inode2 = inode;
371         req->in.numargs = 2;
372         req->in.args[0].size = sizeof(inarg);
373         req->in.args[0].value = &inarg;
374         req->in.args[1].size = newent->d_name.len + 1;
375         req->in.args[1].value = newent->d_name.name;
376         err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
377         /* Contrary to "normal" filesystems it can happen that link
378            makes two "logical" inodes point to the same "physical"
379            inode.  We invalidate the attributes of the old one, so it
380            will reflect changes in the backing inode (link count,
381            etc.)
382         */
383         if (!err || err == -EINTR)
384                 fuse_invalidate_attr(inode);
385         return err;
386 }
387
388 int fuse_do_getattr(struct inode *inode)
389 {
390         int err;
391         struct fuse_attr_out arg;
392         struct fuse_conn *fc = get_fuse_conn(inode);
393         struct fuse_req *req = fuse_get_request(fc);
394         if (!req)
395                 return -EINTR;
396
397         req->in.h.opcode = FUSE_GETATTR;
398         req->in.h.nodeid = get_node_id(inode);
399         req->inode = inode;
400         req->out.numargs = 1;
401         req->out.args[0].size = sizeof(arg);
402         req->out.args[0].value = &arg;
403         request_send(fc, req);
404         err = req->out.h.error;
405         fuse_put_request(fc, req);
406         if (!err) {
407                 if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
408                         make_bad_inode(inode);
409                         err = -EIO;
410                 } else {
411                         struct fuse_inode *fi = get_fuse_inode(inode);
412                         fuse_change_attributes(inode, &arg.attr);
413                         fi->i_time = time_to_jiffies(arg.attr_valid,
414                                                      arg.attr_valid_nsec);
415                 }
416         }
417         return err;
418 }
419
420 /*
421  * Calling into a user-controlled filesystem gives the filesystem
422  * daemon ptrace-like capabilities over the requester process.  This
423  * means, that the filesystem daemon is able to record the exact
424  * filesystem operations performed, and can also control the behavior
425  * of the requester process in otherwise impossible ways.  For example
426  * it can delay the operation for arbitrary length of time allowing
427  * DoS against the requester.
428  *
429  * For this reason only those processes can call into the filesystem,
430  * for which the owner of the mount has ptrace privilege.  This
431  * excludes processes started by other users, suid or sgid processes.
432  */
433 static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
434 {
435         if (fc->flags & FUSE_ALLOW_OTHER)
436                 return 1;
437
438         if (task->euid == fc->user_id &&
439             task->suid == fc->user_id &&
440             task->uid == fc->user_id &&
441             task->egid == fc->group_id &&
442             task->sgid == fc->group_id &&
443             task->gid == fc->group_id)
444                 return 1;
445
446         return 0;
447 }
448
449 static int fuse_revalidate(struct dentry *entry)
450 {
451         struct inode *inode = entry->d_inode;
452         struct fuse_inode *fi = get_fuse_inode(inode);
453         struct fuse_conn *fc = get_fuse_conn(inode);
454
455         if (!fuse_allow_task(fc, current))
456                 return -EACCES;
457         if (get_node_id(inode) != FUSE_ROOT_ID &&
458             time_before_eq(jiffies, fi->i_time))
459                 return 0;
460
461         return fuse_do_getattr(inode);
462 }
463
464 static int fuse_access(struct inode *inode, int mask)
465 {
466         struct fuse_conn *fc = get_fuse_conn(inode);
467         struct fuse_req *req;
468         struct fuse_access_in inarg;
469         int err;
470
471         if (fc->no_access)
472                 return 0;
473
474         req = fuse_get_request(fc);
475         if (!req)
476                 return -EINTR;
477
478         memset(&inarg, 0, sizeof(inarg));
479         inarg.mask = mask;
480         req->in.h.opcode = FUSE_ACCESS;
481         req->in.h.nodeid = get_node_id(inode);
482         req->inode = inode;
483         req->in.numargs = 1;
484         req->in.args[0].size = sizeof(inarg);
485         req->in.args[0].value = &inarg;
486         request_send(fc, req);
487         err = req->out.h.error;
488         fuse_put_request(fc, req);
489         if (err == -ENOSYS) {
490                 fc->no_access = 1;
491                 err = 0;
492         }
493         return err;
494 }
495
496 static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
497 {
498         struct fuse_conn *fc = get_fuse_conn(inode);
499
500         if (!fuse_allow_task(fc, current))
501                 return -EACCES;
502         else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
503                 int err = generic_permission(inode, mask, NULL);
504
505                 /* If permission is denied, try to refresh file
506                    attributes.  This is also needed, because the root
507                    node will at first have no permissions */
508                 if (err == -EACCES) {
509                         err = fuse_do_getattr(inode);
510                         if (!err)
511                                 err = generic_permission(inode, mask, NULL);
512                 }
513
514                 /* FIXME: Need some mechanism to revoke permissions:
515                    currently if the filesystem suddenly changes the
516                    file mode, we will not be informed about it, and
517                    continue to allow access to the file/directory.
518
519                    This is actually not so grave, since the user can
520                    simply keep access to the file/directory anyway by
521                    keeping it open... */
522
523                 return err;
524         } else {
525                 int mode = inode->i_mode;
526                 if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
527                         return -EACCES;
528
529                 if (nd && (nd->flags & LOOKUP_ACCESS))
530                         return fuse_access(inode, mask);
531                 return 0;
532         }
533 }
534
535 static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
536                          void *dstbuf, filldir_t filldir)
537 {
538         while (nbytes >= FUSE_NAME_OFFSET) {
539                 struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
540                 size_t reclen = FUSE_DIRENT_SIZE(dirent);
541                 int over;
542                 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
543                         return -EIO;
544                 if (reclen > nbytes)
545                         break;
546
547                 over = filldir(dstbuf, dirent->name, dirent->namelen,
548                                file->f_pos, dirent->ino, dirent->type);
549                 if (over)
550                         break;
551
552                 buf += reclen;
553                 nbytes -= reclen;
554                 file->f_pos = dirent->off;
555         }
556
557         return 0;
558 }
559
560 static inline size_t fuse_send_readdir(struct fuse_req *req, struct file *file,
561                                        struct inode *inode, loff_t pos,
562                                        size_t count)
563 {
564         return fuse_send_read_common(req, file, inode, pos, count, 1);
565 }
566
567 static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
568 {
569         int err;
570         size_t nbytes;
571         struct page *page;
572         struct inode *inode = file->f_dentry->d_inode;
573         struct fuse_conn *fc = get_fuse_conn(inode);
574         struct fuse_req *req = fuse_get_request(fc);
575         if (!req)
576                 return -EINTR;
577
578         page = alloc_page(GFP_KERNEL);
579         if (!page) {
580                 fuse_put_request(fc, req);
581                 return -ENOMEM;
582         }
583         req->num_pages = 1;
584         req->pages[0] = page;
585         nbytes = fuse_send_readdir(req, file, inode, file->f_pos, PAGE_SIZE);
586         err = req->out.h.error;
587         fuse_put_request(fc, req);
588         if (!err)
589                 err = parse_dirfile(page_address(page), nbytes, file, dstbuf,
590                                     filldir);
591
592         __free_page(page);
593         fuse_invalidate_attr(inode); /* atime changed */
594         return err;
595 }
596
597 static char *read_link(struct dentry *dentry)
598 {
599         struct inode *inode = dentry->d_inode;
600         struct fuse_conn *fc = get_fuse_conn(inode);
601         struct fuse_req *req = fuse_get_request(fc);
602         char *link;
603
604         if (!req)
605                 return ERR_PTR(-EINTR);
606
607         link = (char *) __get_free_page(GFP_KERNEL);
608         if (!link) {
609                 link = ERR_PTR(-ENOMEM);
610                 goto out;
611         }
612         req->in.h.opcode = FUSE_READLINK;
613         req->in.h.nodeid = get_node_id(inode);
614         req->inode = inode;
615         req->out.argvar = 1;
616         req->out.numargs = 1;
617         req->out.args[0].size = PAGE_SIZE - 1;
618         req->out.args[0].value = link;
619         request_send(fc, req);
620         if (req->out.h.error) {
621                 free_page((unsigned long) link);
622                 link = ERR_PTR(req->out.h.error);
623         } else
624                 link[req->out.args[0].size] = '\0';
625  out:
626         fuse_put_request(fc, req);
627         fuse_invalidate_attr(inode); /* atime changed */
628         return link;
629 }
630
631 static void free_link(char *link)
632 {
633         if (!IS_ERR(link))
634                 free_page((unsigned long) link);
635 }
636
637 static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
638 {
639         nd_set_link(nd, read_link(dentry));
640         return NULL;
641 }
642
643 static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
644 {
645         free_link(nd_get_link(nd));
646 }
647
648 static int fuse_dir_open(struct inode *inode, struct file *file)
649 {
650         return fuse_open_common(inode, file, 1);
651 }
652
653 static int fuse_dir_release(struct inode *inode, struct file *file)
654 {
655         return fuse_release_common(inode, file, 1);
656 }
657
658 static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
659 {
660         /* nfsd can call this with no file */
661         return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
662 }
663
664 static unsigned iattr_to_fattr(struct iattr *iattr, struct fuse_attr *fattr)
665 {
666         unsigned ivalid = iattr->ia_valid;
667         unsigned fvalid = 0;
668
669         memset(fattr, 0, sizeof(*fattr));
670
671         if (ivalid & ATTR_MODE)
672                 fvalid |= FATTR_MODE,   fattr->mode = iattr->ia_mode;
673         if (ivalid & ATTR_UID)
674                 fvalid |= FATTR_UID,    fattr->uid = iattr->ia_uid;
675         if (ivalid & ATTR_GID)
676                 fvalid |= FATTR_GID,    fattr->gid = iattr->ia_gid;
677         if (ivalid & ATTR_SIZE)
678                 fvalid |= FATTR_SIZE,   fattr->size = iattr->ia_size;
679         /* You can only _set_ these together (they may change by themselves) */
680         if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
681                 fvalid |= FATTR_ATIME | FATTR_MTIME;
682                 fattr->atime = iattr->ia_atime.tv_sec;
683                 fattr->mtime = iattr->ia_mtime.tv_sec;
684         }
685
686         return fvalid;
687 }
688
689 static int fuse_setattr(struct dentry *entry, struct iattr *attr)
690 {
691         struct inode *inode = entry->d_inode;
692         struct fuse_conn *fc = get_fuse_conn(inode);
693         struct fuse_inode *fi = get_fuse_inode(inode);
694         struct fuse_req *req;
695         struct fuse_setattr_in inarg;
696         struct fuse_attr_out outarg;
697         int err;
698         int is_truncate = 0;
699
700         if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
701                 err = inode_change_ok(inode, attr);
702                 if (err)
703                         return err;
704         }
705
706         if (attr->ia_valid & ATTR_SIZE) {
707                 unsigned long limit;
708                 is_truncate = 1;
709                 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
710                 if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {
711                         send_sig(SIGXFSZ, current, 0);
712                         return -EFBIG;
713                 }
714         }
715
716         req = fuse_get_request(fc);
717         if (!req)
718                 return -EINTR;
719
720         memset(&inarg, 0, sizeof(inarg));
721         inarg.valid = iattr_to_fattr(attr, &inarg.attr);
722         req->in.h.opcode = FUSE_SETATTR;
723         req->in.h.nodeid = get_node_id(inode);
724         req->inode = inode;
725         req->in.numargs = 1;
726         req->in.args[0].size = sizeof(inarg);
727         req->in.args[0].value = &inarg;
728         req->out.numargs = 1;
729         req->out.args[0].size = sizeof(outarg);
730         req->out.args[0].value = &outarg;
731         request_send(fc, req);
732         err = req->out.h.error;
733         fuse_put_request(fc, req);
734         if (!err) {
735                 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
736                         make_bad_inode(inode);
737                         err = -EIO;
738                 } else {
739                         if (is_truncate) {
740                                 loff_t origsize = i_size_read(inode);
741                                 i_size_write(inode, outarg.attr.size);
742                                 if (origsize > outarg.attr.size)
743                                         vmtruncate(inode, outarg.attr.size);
744                         }
745                         fuse_change_attributes(inode, &outarg.attr);
746                         fi->i_time = time_to_jiffies(outarg.attr_valid,
747                                                      outarg.attr_valid_nsec);
748                 }
749         } else if (err == -EINTR)
750                 fuse_invalidate_attr(inode);
751
752         return err;
753 }
754
755 static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
756                         struct kstat *stat)
757 {
758         struct inode *inode = entry->d_inode;
759         int err = fuse_revalidate(entry);
760         if (!err)
761                 generic_fillattr(inode, stat);
762
763         return err;
764 }
765
766 static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
767                                   struct nameidata *nd)
768 {
769         struct inode *inode;
770         int err = fuse_lookup_iget(dir, entry, &inode);
771         if (err)
772                 return ERR_PTR(err);
773         if (inode && S_ISDIR(inode->i_mode)) {
774                 /* Don't allow creating an alias to a directory  */
775                 struct dentry *alias = d_find_alias(inode);
776                 if (alias) {
777                         dput(alias);
778                         iput(inode);
779                         return ERR_PTR(-EIO);
780                 }
781         }
782         d_add(entry, inode);
783         return NULL;
784 }
785
786 static int fuse_setxattr(struct dentry *entry, const char *name,
787                          const void *value, size_t size, int flags)
788 {
789         struct inode *inode = entry->d_inode;
790         struct fuse_conn *fc = get_fuse_conn(inode);
791         struct fuse_req *req;
792         struct fuse_setxattr_in inarg;
793         int err;
794
795         if (size > FUSE_XATTR_SIZE_MAX)
796                 return -E2BIG;
797
798         if (fc->no_setxattr)
799                 return -EOPNOTSUPP;
800
801         req = fuse_get_request(fc);
802         if (!req)
803                 return -EINTR;
804
805         memset(&inarg, 0, sizeof(inarg));
806         inarg.size = size;
807         inarg.flags = flags;
808         req->in.h.opcode = FUSE_SETXATTR;
809         req->in.h.nodeid = get_node_id(inode);
810         req->inode = inode;
811         req->in.numargs = 3;
812         req->in.args[0].size = sizeof(inarg);
813         req->in.args[0].value = &inarg;
814         req->in.args[1].size = strlen(name) + 1;
815         req->in.args[1].value = name;
816         req->in.args[2].size = size;
817         req->in.args[2].value = value;
818         request_send(fc, req);
819         err = req->out.h.error;
820         fuse_put_request(fc, req);
821         if (err == -ENOSYS) {
822                 fc->no_setxattr = 1;
823                 err = -EOPNOTSUPP;
824         }
825         return err;
826 }
827
828 static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
829                              void *value, size_t size)
830 {
831         struct inode *inode = entry->d_inode;
832         struct fuse_conn *fc = get_fuse_conn(inode);
833         struct fuse_req *req;
834         struct fuse_getxattr_in inarg;
835         struct fuse_getxattr_out outarg;
836         ssize_t ret;
837
838         if (fc->no_getxattr)
839                 return -EOPNOTSUPP;
840
841         req = fuse_get_request(fc);
842         if (!req)
843                 return -EINTR;
844
845         memset(&inarg, 0, sizeof(inarg));
846         inarg.size = size;
847         req->in.h.opcode = FUSE_GETXATTR;
848         req->in.h.nodeid = get_node_id(inode);
849         req->inode = inode;
850         req->in.numargs = 2;
851         req->in.args[0].size = sizeof(inarg);
852         req->in.args[0].value = &inarg;
853         req->in.args[1].size = strlen(name) + 1;
854         req->in.args[1].value = name;
855         /* This is really two different operations rolled into one */
856         req->out.numargs = 1;
857         if (size) {
858                 req->out.argvar = 1;
859                 req->out.args[0].size = size;
860                 req->out.args[0].value = value;
861         } else {
862                 req->out.args[0].size = sizeof(outarg);
863                 req->out.args[0].value = &outarg;
864         }
865         request_send(fc, req);
866         ret = req->out.h.error;
867         if (!ret)
868                 ret = size ? req->out.args[0].size : outarg.size;
869         else {
870                 if (ret == -ENOSYS) {
871                         fc->no_getxattr = 1;
872                         ret = -EOPNOTSUPP;
873                 }
874         }
875         fuse_put_request(fc, req);
876         return ret;
877 }
878
879 static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
880 {
881         struct inode *inode = entry->d_inode;
882         struct fuse_conn *fc = get_fuse_conn(inode);
883         struct fuse_req *req;
884         struct fuse_getxattr_in inarg;
885         struct fuse_getxattr_out outarg;
886         ssize_t ret;
887
888         if (fc->no_listxattr)
889                 return -EOPNOTSUPP;
890
891         req = fuse_get_request(fc);
892         if (!req)
893                 return -EINTR;
894
895         memset(&inarg, 0, sizeof(inarg));
896         inarg.size = size;
897         req->in.h.opcode = FUSE_LISTXATTR;
898         req->in.h.nodeid = get_node_id(inode);
899         req->inode = inode;
900         req->in.numargs = 1;
901         req->in.args[0].size = sizeof(inarg);
902         req->in.args[0].value = &inarg;
903         /* This is really two different operations rolled into one */
904         req->out.numargs = 1;
905         if (size) {
906                 req->out.argvar = 1;
907                 req->out.args[0].size = size;
908                 req->out.args[0].value = list;
909         } else {
910                 req->out.args[0].size = sizeof(outarg);
911                 req->out.args[0].value = &outarg;
912         }
913         request_send(fc, req);
914         ret = req->out.h.error;
915         if (!ret)
916                 ret = size ? req->out.args[0].size : outarg.size;
917         else {
918                 if (ret == -ENOSYS) {
919                         fc->no_listxattr = 1;
920                         ret = -EOPNOTSUPP;
921                 }
922         }
923         fuse_put_request(fc, req);
924         return ret;
925 }
926
927 static int fuse_removexattr(struct dentry *entry, const char *name)
928 {
929         struct inode *inode = entry->d_inode;
930         struct fuse_conn *fc = get_fuse_conn(inode);
931         struct fuse_req *req;
932         int err;
933
934         if (fc->no_removexattr)
935                 return -EOPNOTSUPP;
936
937         req = fuse_get_request(fc);
938         if (!req)
939                 return -EINTR;
940
941         req->in.h.opcode = FUSE_REMOVEXATTR;
942         req->in.h.nodeid = get_node_id(inode);
943         req->inode = inode;
944         req->in.numargs = 1;
945         req->in.args[0].size = strlen(name) + 1;
946         req->in.args[0].value = name;
947         request_send(fc, req);
948         err = req->out.h.error;
949         fuse_put_request(fc, req);
950         if (err == -ENOSYS) {
951                 fc->no_removexattr = 1;
952                 err = -EOPNOTSUPP;
953         }
954         return err;
955 }
956
957 static struct inode_operations fuse_dir_inode_operations = {
958         .lookup         = fuse_lookup,
959         .mkdir          = fuse_mkdir,
960         .symlink        = fuse_symlink,
961         .unlink         = fuse_unlink,
962         .rmdir          = fuse_rmdir,
963         .rename         = fuse_rename,
964         .link           = fuse_link,
965         .setattr        = fuse_setattr,
966         .create         = fuse_create,
967         .mknod          = fuse_mknod,
968         .permission     = fuse_permission,
969         .getattr        = fuse_getattr,
970         .setxattr       = fuse_setxattr,
971         .getxattr       = fuse_getxattr,
972         .listxattr      = fuse_listxattr,
973         .removexattr    = fuse_removexattr,
974 };
975
976 static struct file_operations fuse_dir_operations = {
977         .llseek         = generic_file_llseek,
978         .read           = generic_read_dir,
979         .readdir        = fuse_readdir,
980         .open           = fuse_dir_open,
981         .release        = fuse_dir_release,
982         .fsync          = fuse_dir_fsync,
983 };
984
985 static struct inode_operations fuse_common_inode_operations = {
986         .setattr        = fuse_setattr,
987         .permission     = fuse_permission,
988         .getattr        = fuse_getattr,
989         .setxattr       = fuse_setxattr,
990         .getxattr       = fuse_getxattr,
991         .listxattr      = fuse_listxattr,
992         .removexattr    = fuse_removexattr,
993 };
994
995 static struct inode_operations fuse_symlink_inode_operations = {
996         .setattr        = fuse_setattr,
997         .follow_link    = fuse_follow_link,
998         .put_link       = fuse_put_link,
999         .readlink       = generic_readlink,
1000         .getattr        = fuse_getattr,
1001         .setxattr       = fuse_setxattr,
1002         .getxattr       = fuse_getxattr,
1003         .listxattr      = fuse_listxattr,
1004         .removexattr    = fuse_removexattr,
1005 };
1006
1007 void fuse_init_common(struct inode *inode)
1008 {
1009         inode->i_op = &fuse_common_inode_operations;
1010 }
1011
1012 void fuse_init_dir(struct inode *inode)
1013 {
1014         inode->i_op = &fuse_dir_inode_operations;
1015         inode->i_fop = &fuse_dir_operations;
1016 }
1017
1018 void fuse_init_symlink(struct inode *inode)
1019 {
1020         inode->i_op = &fuse_symlink_inode_operations;
1021 }