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