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