fix
[fuse.git] / kernel / dir.c
blob735e8fe0a7c718b874ccc78f76e655df3267ba66
1 /*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING.
7 */
9 #include "fuse_i.h"
11 #include <linux/pagemap.h>
12 #include <linux/file.h>
13 #ifdef KERNEL_2_6
14 #include <linux/gfp.h>
15 #else
16 #include <linux/mm.h>
17 #endif
18 #include <linux/sched.h>
19 #ifdef KERNEL_2_6
20 #include <linux/namei.h>
21 #endif
23 static inline unsigned long time_to_jiffies(unsigned long sec,
24 unsigned long nsec)
26 struct timespec ts = {sec, nsec};
27 return jiffies + timespec_to_jiffies(&ts);
30 static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
31 struct dentry *entry,
32 struct fuse_entry_out *outarg)
34 req->in.h.opcode = FUSE_LOOKUP;
35 req->in.h.nodeid = get_node_id(dir);
36 req->inode = dir;
37 req->in.numargs = 1;
38 req->in.args[0].size = entry->d_name.len + 1;
39 req->in.args[0].value = entry->d_name.name;
40 req->out.numargs = 1;
41 req->out.args[0].size = sizeof(struct fuse_entry_out);
42 req->out.args[0].value = outarg;
45 static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
47 if (!entry->d_inode || is_bad_inode(entry->d_inode))
48 return 0;
49 else if (time_after(jiffies, entry->d_time)) {
50 int err;
51 struct fuse_entry_out outarg;
52 struct inode *inode = entry->d_inode;
53 struct fuse_inode *fi = get_fuse_inode(inode);
54 struct fuse_conn *fc = get_fuse_conn(inode);
55 struct fuse_req *req = fuse_get_request(fc);
56 if (!req)
57 return 0;
59 fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg);
60 request_send(fc, req);
61 err = req->out.h.error;
62 if (!err) {
63 if (outarg.nodeid != get_node_id(inode)) {
64 fuse_send_forget(fc, req, outarg.nodeid, 1);
65 return 0;
67 fi->nlookup ++;
69 fuse_put_request(fc, req);
70 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
71 return 0;
73 fuse_change_attributes(inode, &outarg.attr);
74 entry->d_time = time_to_jiffies(outarg.entry_valid,
75 outarg.entry_valid_nsec);
76 fi->i_time = time_to_jiffies(outarg.attr_valid,
77 outarg.attr_valid_nsec);
79 return 1;
81 #ifndef KERNEL_2_6
82 static int fuse_dentry_revalidate_2_4(struct dentry *entry, int flags)
84 return fuse_dentry_revalidate(entry, NULL);
86 #endif
88 static struct dentry_operations fuse_dentry_operations = {
89 #ifdef KERNEL_2_6
90 .d_revalidate = fuse_dentry_revalidate,
91 #else
92 .d_revalidate = fuse_dentry_revalidate_2_4,
93 #endif
96 static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
97 struct inode **inodep)
99 int err;
100 struct fuse_entry_out outarg;
101 struct inode *inode = NULL;
102 struct fuse_conn *fc = get_fuse_conn(dir);
103 struct fuse_req *req;
105 if (entry->d_name.len > FUSE_NAME_MAX)
106 return -ENAMETOOLONG;
108 req = fuse_get_request(fc);
109 if (!req)
110 return -EINTR;
112 fuse_lookup_init(req, dir, entry, &outarg);
113 request_send(fc, req);
114 err = req->out.h.error;
115 if (!err && (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID))
116 err = -EIO;
117 if (!err) {
118 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
119 &outarg.attr);
120 if (!inode) {
121 fuse_send_forget(fc, req, outarg.nodeid, 1);
122 return -ENOMEM;
125 fuse_put_request(fc, req);
126 if (err && err != -ENOENT)
127 return err;
129 if (inode) {
130 struct fuse_inode *fi = get_fuse_inode(inode);
131 entry->d_time = time_to_jiffies(outarg.entry_valid,
132 outarg.entry_valid_nsec);
133 fi->i_time = time_to_jiffies(outarg.attr_valid,
134 outarg.attr_valid_nsec);
137 entry->d_op = &fuse_dentry_operations;
138 *inodep = inode;
139 return 0;
142 void fuse_invalidate_attr(struct inode *inode)
144 get_fuse_inode(inode)->i_time = jiffies - 1;
147 static void fuse_invalidate_entry(struct dentry *entry)
149 d_invalidate(entry);
150 entry->d_time = jiffies - 1;
153 static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
154 struct inode *dir, struct dentry *entry,
155 int mode)
157 struct fuse_entry_out outarg;
158 struct inode *inode;
159 struct fuse_inode *fi;
160 int err;
162 req->in.h.nodeid = get_node_id(dir);
163 req->inode = dir;
164 req->out.numargs = 1;
165 req->out.args[0].size = sizeof(outarg);
166 req->out.args[0].value = &outarg;
167 request_send(fc, req);
168 err = req->out.h.error;
169 if (err) {
170 fuse_put_request(fc, req);
171 return err;
173 if (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID) {
174 fuse_put_request(fc, req);
175 return -EIO;
177 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
178 &outarg.attr);
179 if (!inode) {
180 fuse_send_forget(fc, req, outarg.nodeid, 1);
181 return -ENOMEM;
183 fuse_put_request(fc, req);
185 /* Don't allow userspace to do really stupid things... */
186 if ((inode->i_mode ^ mode) & S_IFMT) {
187 iput(inode);
188 return -EIO;
191 entry->d_time = time_to_jiffies(outarg.entry_valid,
192 outarg.entry_valid_nsec);
194 fi = get_fuse_inode(inode);
195 fi->i_time = time_to_jiffies(outarg.attr_valid,
196 outarg.attr_valid_nsec);
198 d_instantiate(entry, inode);
199 fuse_invalidate_attr(dir);
200 return 0;
203 static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
204 dev_t rdev)
206 struct fuse_mknod_in inarg;
207 struct fuse_conn *fc = get_fuse_conn(dir);
208 struct fuse_req *req = fuse_get_request(fc);
209 if (!req)
210 return -EINTR;
212 memset(&inarg, 0, sizeof(inarg));
213 inarg.mode = mode;
214 inarg.rdev = new_encode_dev(rdev);
215 req->in.h.opcode = FUSE_MKNOD;
216 req->in.numargs = 2;
217 req->in.args[0].size = sizeof(inarg);
218 req->in.args[0].value = &inarg;
219 req->in.args[1].size = entry->d_name.len + 1;
220 req->in.args[1].value = entry->d_name.name;
221 return create_new_entry(fc, req, dir, entry, mode);
224 static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
225 struct nameidata *nd)
227 return fuse_mknod(dir, entry, mode, 0);
230 static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
232 struct fuse_mkdir_in inarg;
233 struct fuse_conn *fc = get_fuse_conn(dir);
234 struct fuse_req *req = fuse_get_request(fc);
235 if (!req)
236 return -EINTR;
238 memset(&inarg, 0, sizeof(inarg));
239 inarg.mode = mode;
240 req->in.h.opcode = FUSE_MKDIR;
241 req->in.numargs = 2;
242 req->in.args[0].size = sizeof(inarg);
243 req->in.args[0].value = &inarg;
244 req->in.args[1].size = entry->d_name.len + 1;
245 req->in.args[1].value = entry->d_name.name;
246 return create_new_entry(fc, req, dir, entry, S_IFDIR);
249 static int fuse_symlink(struct inode *dir, struct dentry *entry,
250 const char *link)
252 struct fuse_conn *fc = get_fuse_conn(dir);
253 unsigned len = strlen(link) + 1;
254 struct fuse_req *req;
256 if (len > FUSE_SYMLINK_MAX)
257 return -ENAMETOOLONG;
259 req = fuse_get_request(fc);
260 if (!req)
261 return -EINTR;
263 req->in.h.opcode = FUSE_SYMLINK;
264 req->in.numargs = 2;
265 req->in.args[0].size = entry->d_name.len + 1;
266 req->in.args[0].value = entry->d_name.name;
267 req->in.args[1].size = len;
268 req->in.args[1].value = link;
269 return create_new_entry(fc, req, dir, entry, S_IFLNK);
272 static int fuse_unlink(struct inode *dir, struct dentry *entry)
274 int err;
275 struct fuse_conn *fc = get_fuse_conn(dir);
276 struct fuse_req *req = fuse_get_request(fc);
277 if (!req)
278 return -EINTR;
280 req->in.h.opcode = FUSE_UNLINK;
281 req->in.h.nodeid = get_node_id(dir);
282 req->inode = dir;
283 req->in.numargs = 1;
284 req->in.args[0].size = entry->d_name.len + 1;
285 req->in.args[0].value = entry->d_name.name;
286 request_send(fc, req);
287 err = req->out.h.error;
288 fuse_put_request(fc, req);
289 if (!err) {
290 struct inode *inode = entry->d_inode;
292 /* Set nlink to zero so the inode can be cleared, if
293 the inode does have more links this will be
294 discovered at the next lookup/getattr */
295 inode->i_nlink = 0;
296 fuse_invalidate_attr(inode);
297 fuse_invalidate_attr(dir);
298 } else if (err == -EINTR)
299 fuse_invalidate_entry(entry);
300 return err;
303 static int fuse_rmdir(struct inode *dir, struct dentry *entry)
305 int err;
306 struct fuse_conn *fc = get_fuse_conn(dir);
307 struct fuse_req *req = fuse_get_request(fc);
308 if (!req)
309 return -EINTR;
311 req->in.h.opcode = FUSE_RMDIR;
312 req->in.h.nodeid = get_node_id(dir);
313 req->inode = dir;
314 req->in.numargs = 1;
315 req->in.args[0].size = entry->d_name.len + 1;
316 req->in.args[0].value = entry->d_name.name;
317 request_send(fc, req);
318 err = req->out.h.error;
319 fuse_put_request(fc, req);
320 if (!err) {
321 entry->d_inode->i_nlink = 0;
322 fuse_invalidate_attr(dir);
323 } else if (err == -EINTR)
324 fuse_invalidate_entry(entry);
325 return err;
328 static int fuse_rename(struct inode *olddir, struct dentry *oldent,
329 struct inode *newdir, struct dentry *newent)
331 int err;
332 struct fuse_rename_in inarg;
333 struct fuse_conn *fc = get_fuse_conn(olddir);
334 struct fuse_req *req = fuse_get_request(fc);
335 if (!req)
336 return -EINTR;
338 memset(&inarg, 0, sizeof(inarg));
339 inarg.newdir = get_node_id(newdir);
340 req->in.h.opcode = FUSE_RENAME;
341 req->in.h.nodeid = get_node_id(olddir);
342 req->inode = olddir;
343 req->inode2 = newdir;
344 req->in.numargs = 3;
345 req->in.args[0].size = sizeof(inarg);
346 req->in.args[0].value = &inarg;
347 req->in.args[1].size = oldent->d_name.len + 1;
348 req->in.args[1].value = oldent->d_name.name;
349 req->in.args[2].size = newent->d_name.len + 1;
350 req->in.args[2].value = newent->d_name.name;
351 request_send(fc, req);
352 err = req->out.h.error;
353 fuse_put_request(fc, req);
354 if (!err) {
355 fuse_invalidate_attr(olddir);
356 if (olddir != newdir)
357 fuse_invalidate_attr(newdir);
358 } else if (err == -EINTR) {
359 /* If request was interrupted, DEITY only knows if the
360 rename actually took place. If the invalidation
361 fails (e.g. some process has CWD under the renamed
362 directory), then there can be inconsistency between
363 the dcache and the real filesystem. Tough luck. */
364 fuse_invalidate_entry(oldent);
365 if (newent->d_inode)
366 fuse_invalidate_entry(newent);
369 return err;
372 static int fuse_link(struct dentry *entry, struct inode *newdir,
373 struct dentry *newent)
375 int err;
376 struct fuse_link_in inarg;
377 struct inode *inode = entry->d_inode;
378 struct fuse_conn *fc = get_fuse_conn(inode);
379 struct fuse_req *req = fuse_get_request(fc);
380 if (!req)
381 return -EINTR;
383 memset(&inarg, 0, sizeof(inarg));
384 inarg.oldnodeid = get_node_id(inode);
385 req->in.h.opcode = FUSE_LINK;
386 req->inode2 = inode;
387 req->in.numargs = 2;
388 req->in.args[0].size = sizeof(inarg);
389 req->in.args[0].value = &inarg;
390 req->in.args[1].size = newent->d_name.len + 1;
391 req->in.args[1].value = newent->d_name.name;
392 err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
393 /* Contrary to "normal" filesystems it can happen that link
394 makes two "logical" inodes point to the same "physical"
395 inode. We invalidate the attributes of the old one, so it
396 will reflect changes in the backing inode (link count,
397 etc.)
399 if (!err || err == -EINTR)
400 fuse_invalidate_attr(inode);
401 return err;
404 int fuse_do_getattr(struct inode *inode)
406 int err;
407 struct fuse_attr_out arg;
408 struct fuse_conn *fc = get_fuse_conn(inode);
409 struct fuse_req *req = fuse_get_request(fc);
410 if (!req)
411 return -EINTR;
413 req->in.h.opcode = FUSE_GETATTR;
414 req->in.h.nodeid = get_node_id(inode);
415 req->inode = inode;
416 req->out.numargs = 1;
417 req->out.args[0].size = sizeof(arg);
418 req->out.args[0].value = &arg;
419 request_send(fc, req);
420 err = req->out.h.error;
421 fuse_put_request(fc, req);
422 if (!err) {
423 if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
424 #ifndef KERNEL_2_6_12_PLUS
425 if (get_node_id(inode) != FUSE_ROOT_ID)
426 make_bad_inode(inode);
427 #else
428 make_bad_inode(inode);
429 #endif
430 err = -EIO;
431 } else {
432 struct fuse_inode *fi = get_fuse_inode(inode);
433 fuse_change_attributes(inode, &arg.attr);
434 fi->i_time = time_to_jiffies(arg.attr_valid,
435 arg.attr_valid_nsec);
438 return err;
442 * Calling into a user-controlled filesystem gives the filesystem
443 * daemon ptrace-like capabilities over the requester process. This
444 * means, that the filesystem daemon is able to record the exact
445 * filesystem operations performed, and can also control the behavior
446 * of the requester process in otherwise impossible ways. For example
447 * it can delay the operation for arbitrary length of time allowing
448 * DoS against the requester.
450 * For this reason only those processes can call into the filesystem,
451 * for which the owner of the mount has ptrace privilege. This
452 * excludes processes started by other users, suid or sgid processes.
454 static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
456 if (fc->flags & FUSE_ALLOW_OTHER)
457 return 1;
459 if (task->euid == fc->user_id &&
460 task->suid == fc->user_id &&
461 task->uid == fc->user_id &&
462 task->egid == fc->group_id &&
463 task->sgid == fc->group_id &&
464 task->gid == fc->group_id)
465 return 1;
467 return 0;
470 static int fuse_revalidate(struct dentry *entry)
472 struct inode *inode = entry->d_inode;
473 struct fuse_inode *fi = get_fuse_inode(inode);
474 struct fuse_conn *fc = get_fuse_conn(inode);
476 if (!fuse_allow_task(fc, current))
477 return -EACCES;
478 if (get_node_id(inode) != FUSE_ROOT_ID &&
479 time_before_eq(jiffies, fi->i_time))
480 return 0;
482 return fuse_do_getattr(inode);
485 static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
487 struct fuse_conn *fc = get_fuse_conn(inode);
489 if (!fuse_allow_task(fc, current))
490 return -EACCES;
491 else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
492 #ifdef KERNEL_2_6_10_PLUS
493 int err = generic_permission(inode, mask, NULL);
494 #else
495 int err = vfs_permission(inode, mask);
496 #endif
498 /* If permission is denied, try to refresh file
499 attributes. This is also needed, because the root
500 node will at first have no permissions */
501 if (err == -EACCES) {
502 err = fuse_do_getattr(inode);
503 if (!err)
504 #ifdef KERNEL_2_6_10_PLUS
505 err = generic_permission(inode, mask, NULL);
506 #else
507 err = vfs_permission(inode, mask);
508 #endif
511 /* FIXME: Need some mechanism to revoke permissions:
512 currently if the filesystem suddenly changes the
513 file mode, we will not be informed about it, and
514 continue to allow access to the file/directory.
516 This is actually not so grave, since the user can
517 simply keep access to the file/directory anyway by
518 keeping it open... */
520 return err;
521 } else {
522 int mode = inode->i_mode;
523 if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
524 (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
525 return -EROFS;
526 if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
527 return -EACCES;
528 return 0;
532 static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
533 void *dstbuf, filldir_t filldir)
535 while (nbytes >= FUSE_NAME_OFFSET) {
536 struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
537 size_t reclen = FUSE_DIRENT_SIZE(dirent);
538 int over;
539 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
540 return -EIO;
541 if (reclen > nbytes)
542 break;
544 over = filldir(dstbuf, dirent->name, dirent->namelen,
545 file->f_pos, dirent->ino, dirent->type);
546 if (over)
547 break;
549 buf += reclen;
550 nbytes -= reclen;
551 file->f_pos = dirent->off;
554 return 0;
557 static inline size_t fuse_send_readdir(struct fuse_req *req, struct file *file,
558 struct inode *inode, loff_t pos,
559 size_t count)
561 return fuse_send_read_common(req, file, inode, pos, count, 1);
564 static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
566 int err;
567 size_t nbytes;
568 struct page *page;
569 struct inode *inode = file->f_dentry->d_inode;
570 struct fuse_conn *fc = get_fuse_conn(inode);
571 struct fuse_req *req = fuse_get_request(fc);
572 if (!req)
573 return -EINTR;
575 page = alloc_page(GFP_KERNEL);
576 if (!page) {
577 fuse_put_request(fc, req);
578 return -ENOMEM;
580 req->num_pages = 1;
581 req->pages[0] = page;
582 nbytes = fuse_send_readdir(req, file, inode, file->f_pos, PAGE_SIZE);
583 err = req->out.h.error;
584 fuse_put_request(fc, req);
585 if (!err)
586 err = parse_dirfile(page_address(page), nbytes, file, dstbuf,
587 filldir);
589 __free_page(page);
590 fuse_invalidate_attr(inode); /* atime changed */
591 return err;
594 static char *read_link(struct dentry *dentry)
596 struct inode *inode = dentry->d_inode;
597 struct fuse_conn *fc = get_fuse_conn(inode);
598 struct fuse_req *req = fuse_get_request(fc);
599 char *link;
601 if (!req)
602 return ERR_PTR(-EINTR);
604 link = (char *) __get_free_page(GFP_KERNEL);
605 if (!link) {
606 link = ERR_PTR(-ENOMEM);
607 goto out;
609 req->in.h.opcode = FUSE_READLINK;
610 req->in.h.nodeid = get_node_id(inode);
611 req->inode = inode;
612 req->out.argvar = 1;
613 req->out.numargs = 1;
614 req->out.args[0].size = PAGE_SIZE - 1;
615 req->out.args[0].value = link;
616 request_send(fc, req);
617 if (req->out.h.error) {
618 free_page((unsigned long) link);
619 link = ERR_PTR(req->out.h.error);
620 } else
621 link[req->out.args[0].size] = '\0';
622 out:
623 fuse_put_request(fc, req);
624 fuse_invalidate_attr(inode); /* atime changed */
625 return link;
628 static void free_link(char *link)
630 if (!IS_ERR(link))
631 free_page((unsigned long) link);
634 #ifdef KERNEL_2_6_13_PLUS
635 static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
637 nd_set_link(nd, read_link(dentry));
638 return NULL;
641 static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
643 free_link(nd_get_link(nd));
645 #elif defined(KERNEL_2_6_8_PLUS)
646 static int fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
648 nd_set_link(nd, read_link(dentry));
649 return 0;
652 static void fuse_put_link(struct dentry *dentry, struct nameidata *nd)
654 free_link(nd_get_link(nd));
656 #else
657 static int fuse_readlink(struct dentry *dentry, char __user *buffer,
658 int buflen)
660 int ret;
661 char *link;
663 link = read_link(dentry);
664 ret = vfs_readlink(dentry, buffer, buflen, link);
665 free_link(link);
666 return ret;
669 static int fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
671 int ret;
672 char *link;
674 link = read_link(dentry);
675 ret = vfs_follow_link(nd, link);
676 free_link(link);
677 return ret;
679 #endif
681 static int fuse_dir_open(struct inode *inode, struct file *file)
683 return fuse_open_common(inode, file, 1);
686 static int fuse_dir_release(struct inode *inode, struct file *file)
688 return fuse_release_common(inode, file, 1);
691 static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
693 /* nfsd can call this with no file */
694 return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
697 static unsigned iattr_to_fattr(struct iattr *iattr, struct fuse_attr *fattr)
699 unsigned ivalid = iattr->ia_valid;
700 unsigned fvalid = 0;
702 memset(fattr, 0, sizeof(*fattr));
704 if (ivalid & ATTR_MODE)
705 fvalid |= FATTR_MODE, fattr->mode = iattr->ia_mode;
706 if (ivalid & ATTR_UID)
707 fvalid |= FATTR_UID, fattr->uid = iattr->ia_uid;
708 if (ivalid & ATTR_GID)
709 fvalid |= FATTR_GID, fattr->gid = iattr->ia_gid;
710 if (ivalid & ATTR_SIZE)
711 fvalid |= FATTR_SIZE, fattr->size = iattr->ia_size;
712 /* You can only _set_ these together (they may change by themselves) */
713 if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
714 fvalid |= FATTR_ATIME | FATTR_MTIME;
715 #ifdef KERNEL_2_6
716 fattr->atime = iattr->ia_atime.tv_sec;
717 fattr->mtime = iattr->ia_mtime.tv_sec;
718 #else
719 fattr->atime = iattr->ia_atime;
720 fattr->mtime = iattr->ia_mtime;
721 #endif
724 return fvalid;
727 static int fuse_setattr(struct dentry *entry, struct iattr *attr)
729 struct inode *inode = entry->d_inode;
730 struct fuse_conn *fc = get_fuse_conn(inode);
731 struct fuse_inode *fi = get_fuse_inode(inode);
732 struct fuse_req *req;
733 struct fuse_setattr_in inarg;
734 struct fuse_attr_out outarg;
735 int err;
736 int is_truncate = 0;
738 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
739 err = inode_change_ok(inode, attr);
740 if (err)
741 return err;
744 if (attr->ia_valid & ATTR_SIZE) {
745 unsigned long limit;
746 is_truncate = 1;
747 #ifdef KERNEL_2_6_10_PLUS
748 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
749 #else
750 limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
751 #endif
752 if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {
753 send_sig(SIGXFSZ, current, 0);
754 return -EFBIG;
758 req = fuse_get_request(fc);
759 if (!req)
760 return -EINTR;
762 memset(&inarg, 0, sizeof(inarg));
763 inarg.valid = iattr_to_fattr(attr, &inarg.attr);
764 req->in.h.opcode = FUSE_SETATTR;
765 req->in.h.nodeid = get_node_id(inode);
766 req->inode = inode;
767 req->in.numargs = 1;
768 req->in.args[0].size = sizeof(inarg);
769 req->in.args[0].value = &inarg;
770 req->out.numargs = 1;
771 req->out.args[0].size = sizeof(outarg);
772 req->out.args[0].value = &outarg;
773 request_send(fc, req);
774 err = req->out.h.error;
775 fuse_put_request(fc, req);
776 if (!err) {
777 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
778 #ifndef KERNEL_2_6_12_PLUS
779 if (get_node_id(inode) != FUSE_ROOT_ID)
780 make_bad_inode(inode);
781 #else
782 make_bad_inode(inode);
783 #endif
784 err = -EIO;
785 } else {
786 if (is_truncate) {
787 loff_t origsize = i_size_read(inode);
788 i_size_write(inode, outarg.attr.size);
789 if (origsize > outarg.attr.size)
790 vmtruncate(inode, outarg.attr.size);
792 fuse_change_attributes(inode, &outarg.attr);
793 fi->i_time = time_to_jiffies(outarg.attr_valid,
794 outarg.attr_valid_nsec);
796 } else if (err == -EINTR)
797 fuse_invalidate_attr(inode);
799 return err;
802 #ifdef KERNEL_2_6
803 static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
804 struct kstat *stat)
806 struct inode *inode = entry->d_inode;
807 int err = fuse_revalidate(entry);
808 if (!err)
809 generic_fillattr(inode, stat);
811 return err;
814 static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
815 struct nameidata *nd)
817 struct inode *inode;
818 int err = fuse_lookup_iget(dir, entry, &inode);
819 if (err)
820 return ERR_PTR(err);
821 if (inode && S_ISDIR(inode->i_mode)) {
822 /* Don't allow creating an alias to a directory */
823 struct dentry *alias = d_find_alias(inode);
824 if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
825 dput(alias);
826 iput(inode);
827 return ERR_PTR(-EIO);
830 return d_splice_alias(inode, entry);
832 #else /* KERNEL_2_6 */
833 static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry)
835 struct inode *inode;
836 struct dentry *alias;
838 int err = fuse_lookup_iget(dir, entry, &inode);
839 if (err)
840 return ERR_PTR(err);
842 if (inode && S_ISDIR(inode->i_mode) &&
843 (alias = d_find_alias(inode)) != NULL) {
844 dput(alias);
845 iput(inode);
846 return ERR_PTR(-EIO);
849 d_add(entry, inode);
850 return NULL;
853 static int fuse_mknod_2_4(struct inode *dir, struct dentry *entry, int mode,
854 int rdev)
856 return fuse_mknod(dir, entry, mode, rdev);
859 static int fuse_create_2_4(struct inode *dir, struct dentry *entry, int mode)
861 return fuse_create(dir, entry, mode, NULL);
864 static int fuse_permission_2_4(struct inode *inode, int mask)
866 return fuse_permission(inode, mask, NULL);
868 #endif /* KERNEL_2_6 */
870 #ifdef HAVE_KERNEL_XATTR
871 #ifdef KERNEL_2_6
872 static int fuse_setxattr(struct dentry *entry, const char *name,
873 const void *value, size_t size, int flags)
874 #else
875 static int fuse_setxattr(struct dentry *entry, const char *name,
876 void *value, size_t size, int flags)
877 #endif
879 struct inode *inode = entry->d_inode;
880 struct fuse_conn *fc = get_fuse_conn(inode);
881 struct fuse_req *req;
882 struct fuse_setxattr_in inarg;
883 int err;
885 if (size > FUSE_XATTR_SIZE_MAX)
886 return -E2BIG;
888 if (fc->no_setxattr)
889 return -EOPNOTSUPP;
891 req = fuse_get_request(fc);
892 if (!req)
893 return -EINTR;
895 memset(&inarg, 0, sizeof(inarg));
896 inarg.size = size;
897 inarg.flags = flags;
898 req->in.h.opcode = FUSE_SETXATTR;
899 req->in.h.nodeid = get_node_id(inode);
900 req->inode = inode;
901 req->in.numargs = 3;
902 req->in.args[0].size = sizeof(inarg);
903 req->in.args[0].value = &inarg;
904 req->in.args[1].size = strlen(name) + 1;
905 req->in.args[1].value = name;
906 req->in.args[2].size = size;
907 req->in.args[2].value = value;
908 request_send(fc, req);
909 err = req->out.h.error;
910 fuse_put_request(fc, req);
911 if (err == -ENOSYS) {
912 fc->no_setxattr = 1;
913 err = -EOPNOTSUPP;
915 return err;
918 static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
919 void *value, size_t size)
921 struct inode *inode = entry->d_inode;
922 struct fuse_conn *fc = get_fuse_conn(inode);
923 struct fuse_req *req;
924 struct fuse_getxattr_in inarg;
925 struct fuse_getxattr_out outarg;
926 ssize_t ret;
928 if (fc->no_getxattr)
929 return -EOPNOTSUPP;
931 req = fuse_get_request(fc);
932 if (!req)
933 return -EINTR;
935 memset(&inarg, 0, sizeof(inarg));
936 inarg.size = size;
937 req->in.h.opcode = FUSE_GETXATTR;
938 req->in.h.nodeid = get_node_id(inode);
939 req->inode = inode;
940 req->in.numargs = 2;
941 req->in.args[0].size = sizeof(inarg);
942 req->in.args[0].value = &inarg;
943 req->in.args[1].size = strlen(name) + 1;
944 req->in.args[1].value = name;
945 /* This is really two different operations rolled into one */
946 req->out.numargs = 1;
947 if (size) {
948 req->out.argvar = 1;
949 req->out.args[0].size = size;
950 req->out.args[0].value = value;
951 } else {
952 req->out.args[0].size = sizeof(outarg);
953 req->out.args[0].value = &outarg;
955 request_send(fc, req);
956 ret = req->out.h.error;
957 if (!ret)
958 ret = size ? req->out.args[0].size : outarg.size;
959 else {
960 if (ret == -ENOSYS) {
961 fc->no_getxattr = 1;
962 ret = -EOPNOTSUPP;
965 fuse_put_request(fc, req);
966 return ret;
969 static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
971 struct inode *inode = entry->d_inode;
972 struct fuse_conn *fc = get_fuse_conn(inode);
973 struct fuse_req *req;
974 struct fuse_getxattr_in inarg;
975 struct fuse_getxattr_out outarg;
976 ssize_t ret;
978 if (fc->no_listxattr)
979 return -EOPNOTSUPP;
981 req = fuse_get_request(fc);
982 if (!req)
983 return -EINTR;
985 memset(&inarg, 0, sizeof(inarg));
986 inarg.size = size;
987 req->in.h.opcode = FUSE_LISTXATTR;
988 req->in.h.nodeid = get_node_id(inode);
989 req->inode = inode;
990 req->in.numargs = 1;
991 req->in.args[0].size = sizeof(inarg);
992 req->in.args[0].value = &inarg;
993 /* This is really two different operations rolled into one */
994 req->out.numargs = 1;
995 if (size) {
996 req->out.argvar = 1;
997 req->out.args[0].size = size;
998 req->out.args[0].value = list;
999 } else {
1000 req->out.args[0].size = sizeof(outarg);
1001 req->out.args[0].value = &outarg;
1003 request_send(fc, req);
1004 ret = req->out.h.error;
1005 if (!ret)
1006 ret = size ? req->out.args[0].size : outarg.size;
1007 else {
1008 if (ret == -ENOSYS) {
1009 fc->no_listxattr = 1;
1010 ret = -EOPNOTSUPP;
1013 fuse_put_request(fc, req);
1014 return ret;
1017 static int fuse_removexattr(struct dentry *entry, const char *name)
1019 struct inode *inode = entry->d_inode;
1020 struct fuse_conn *fc = get_fuse_conn(inode);
1021 struct fuse_req *req;
1022 int err;
1024 if (fc->no_removexattr)
1025 return -EOPNOTSUPP;
1027 req = fuse_get_request(fc);
1028 if (!req)
1029 return -EINTR;
1031 req->in.h.opcode = FUSE_REMOVEXATTR;
1032 req->in.h.nodeid = get_node_id(inode);
1033 req->inode = inode;
1034 req->in.numargs = 1;
1035 req->in.args[0].size = strlen(name) + 1;
1036 req->in.args[0].value = name;
1037 request_send(fc, req);
1038 err = req->out.h.error;
1039 fuse_put_request(fc, req);
1040 if (err == -ENOSYS) {
1041 fc->no_removexattr = 1;
1042 err = -EOPNOTSUPP;
1044 return err;
1046 #endif
1048 static struct inode_operations fuse_dir_inode_operations = {
1049 .lookup = fuse_lookup,
1050 .mkdir = fuse_mkdir,
1051 .symlink = fuse_symlink,
1052 .unlink = fuse_unlink,
1053 .rmdir = fuse_rmdir,
1054 .rename = fuse_rename,
1055 .link = fuse_link,
1056 .setattr = fuse_setattr,
1057 #ifdef KERNEL_2_6
1058 .create = fuse_create,
1059 .mknod = fuse_mknod,
1060 .permission = fuse_permission,
1061 .getattr = fuse_getattr,
1062 #else
1063 .create = fuse_create_2_4,
1064 .mknod = fuse_mknod_2_4,
1065 .permission = fuse_permission_2_4,
1066 .revalidate = fuse_revalidate,
1067 #endif
1068 #ifdef HAVE_KERNEL_XATTR
1069 .setxattr = fuse_setxattr,
1070 .getxattr = fuse_getxattr,
1071 .listxattr = fuse_listxattr,
1072 .removexattr = fuse_removexattr,
1073 #endif
1076 static struct file_operations fuse_dir_operations = {
1077 .llseek = generic_file_llseek,
1078 .read = generic_read_dir,
1079 .readdir = fuse_readdir,
1080 .open = fuse_dir_open,
1081 .release = fuse_dir_release,
1082 .fsync = fuse_dir_fsync,
1085 static struct inode_operations fuse_common_inode_operations = {
1086 .setattr = fuse_setattr,
1087 #ifdef KERNEL_2_6
1088 .permission = fuse_permission,
1089 .getattr = fuse_getattr,
1090 #else
1091 .permission = fuse_permission_2_4,
1092 .revalidate = fuse_revalidate,
1093 #endif
1094 #ifdef HAVE_KERNEL_XATTR
1095 .setxattr = fuse_setxattr,
1096 .getxattr = fuse_getxattr,
1097 .listxattr = fuse_listxattr,
1098 .removexattr = fuse_removexattr,
1099 #endif
1102 static struct inode_operations fuse_symlink_inode_operations = {
1103 .setattr = fuse_setattr,
1104 .follow_link = fuse_follow_link,
1105 #ifdef KERNEL_2_6_8_PLUS
1106 .put_link = fuse_put_link,
1107 .readlink = generic_readlink,
1108 #else
1109 .readlink = fuse_readlink,
1110 #endif
1111 #ifdef KERNEL_2_6
1112 .getattr = fuse_getattr,
1113 #else
1114 .revalidate = fuse_revalidate,
1115 #endif
1116 #ifdef HAVE_KERNEL_XATTR
1117 .setxattr = fuse_setxattr,
1118 .getxattr = fuse_getxattr,
1119 .listxattr = fuse_listxattr,
1120 .removexattr = fuse_removexattr,
1121 #endif
1124 void fuse_init_common(struct inode *inode)
1126 inode->i_op = &fuse_common_inode_operations;
1129 void fuse_init_dir(struct inode *inode)
1131 inode->i_op = &fuse_dir_inode_operations;
1132 inode->i_fop = &fuse_dir_operations;
1135 void fuse_init_symlink(struct inode *inode)
1137 inode->i_op = &fuse_symlink_inode_operations;