aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse/dir.c')
-rw-r--r--fs/fuse/dir.c278
1 files changed, 179 insertions, 99 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 51f5da652771..417bcee466f6 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -13,8 +13,16 @@
13#include <linux/gfp.h> 13#include <linux/gfp.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/namei.h> 15#include <linux/namei.h>
16#include <linux/mount.h>
17 16
17/*
18 * FUSE caches dentries and attributes with separate timeout. The
19 * time in jiffies until the dentry/attributes are valid is stored in
20 * dentry->d_time and fuse_inode->i_time respectively.
21 */
22
23/*
24 * Calculate the time in jiffies until a dentry/attributes are valid
25 */
18static inline unsigned long time_to_jiffies(unsigned long sec, 26static inline unsigned long time_to_jiffies(unsigned long sec,
19 unsigned long nsec) 27 unsigned long nsec)
20{ 28{
@@ -22,6 +30,50 @@ static inline unsigned long time_to_jiffies(unsigned long sec,
22 return jiffies + timespec_to_jiffies(&ts); 30 return jiffies + timespec_to_jiffies(&ts);
23} 31}
24 32
33/*
34 * Set dentry and possibly attribute timeouts from the lookup/mk*
35 * replies
36 */
37static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o)
38{
39 entry->d_time = time_to_jiffies(o->entry_valid, o->entry_valid_nsec);
40 if (entry->d_inode)
41 get_fuse_inode(entry->d_inode)->i_time =
42 time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
43}
44
45/*
46 * Mark the attributes as stale, so that at the next call to
47 * ->getattr() they will be fetched from userspace
48 */
49void fuse_invalidate_attr(struct inode *inode)
50{
51 get_fuse_inode(inode)->i_time = jiffies - 1;
52}
53
54/*
55 * Just mark the entry as stale, so that a next attempt to look it up
56 * will result in a new lookup call to userspace
57 *
58 * This is called when a dentry is about to become negative and the
59 * timeout is unknown (unlink, rmdir, rename and in some cases
60 * lookup)
61 */
62static void fuse_invalidate_entry_cache(struct dentry *entry)
63{
64 entry->d_time = jiffies - 1;
65}
66
67/*
68 * Same as fuse_invalidate_entry_cache(), but also try to remove the
69 * dentry from the hash
70 */
71static void fuse_invalidate_entry(struct dentry *entry)
72{
73 d_invalidate(entry);
74 fuse_invalidate_entry_cache(entry);
75}
76
25static void fuse_lookup_init(struct fuse_req *req, struct inode *dir, 77static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
26 struct dentry *entry, 78 struct dentry *entry,
27 struct fuse_entry_out *outarg) 79 struct fuse_entry_out *outarg)
@@ -37,17 +89,34 @@ static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
37 req->out.args[0].value = outarg; 89 req->out.args[0].value = outarg;
38} 90}
39 91
92/*
93 * Check whether the dentry is still valid
94 *
95 * If the entry validity timeout has expired and the dentry is
96 * positive, try to redo the lookup. If the lookup results in a
97 * different inode, then let the VFS invalidate the dentry and redo
98 * the lookup once more. If the lookup results in the same inode,
99 * then refresh the attributes, timeouts and mark the dentry valid.
100 */
40static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) 101static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
41{ 102{
42 if (!entry->d_inode || is_bad_inode(entry->d_inode)) 103 struct inode *inode = entry->d_inode;
104
105 if (inode && is_bad_inode(inode))
43 return 0; 106 return 0;
44 else if (time_after(jiffies, entry->d_time)) { 107 else if (time_after(jiffies, entry->d_time)) {
45 int err; 108 int err;
46 struct fuse_entry_out outarg; 109 struct fuse_entry_out outarg;
47 struct inode *inode = entry->d_inode; 110 struct fuse_conn *fc;
48 struct fuse_inode *fi = get_fuse_inode(inode); 111 struct fuse_req *req;
49 struct fuse_conn *fc = get_fuse_conn(inode); 112
50 struct fuse_req *req = fuse_get_request(fc); 113 /* Doesn't hurt to "reset" the validity timeout */
114 fuse_invalidate_entry_cache(entry);
115 if (!inode)
116 return 0;
117
118 fc = get_fuse_conn(inode);
119 req = fuse_get_request(fc);
51 if (!req) 120 if (!req)
52 return 0; 121 return 0;
53 122
@@ -55,6 +124,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
55 request_send(fc, req); 124 request_send(fc, req);
56 err = req->out.h.error; 125 err = req->out.h.error;
57 if (!err) { 126 if (!err) {
127 struct fuse_inode *fi = get_fuse_inode(inode);
58 if (outarg.nodeid != get_node_id(inode)) { 128 if (outarg.nodeid != get_node_id(inode)) {
59 fuse_send_forget(fc, req, outarg.nodeid, 1); 129 fuse_send_forget(fc, req, outarg.nodeid, 1);
60 return 0; 130 return 0;
@@ -66,18 +136,18 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
66 return 0; 136 return 0;
67 137
68 fuse_change_attributes(inode, &outarg.attr); 138 fuse_change_attributes(inode, &outarg.attr);
69 entry->d_time = time_to_jiffies(outarg.entry_valid, 139 fuse_change_timeout(entry, &outarg);
70 outarg.entry_valid_nsec);
71 fi->i_time = time_to_jiffies(outarg.attr_valid,
72 outarg.attr_valid_nsec);
73 } 140 }
74 return 1; 141 return 1;
75} 142}
76 143
144/*
145 * Check if there's already a hashed alias of this directory inode.
146 * If yes, then lookup and mkdir must not create a new alias.
147 */
77static int dir_alias(struct inode *inode) 148static int dir_alias(struct inode *inode)
78{ 149{
79 if (S_ISDIR(inode->i_mode)) { 150 if (S_ISDIR(inode->i_mode)) {
80 /* Don't allow creating an alias to a directory */
81 struct dentry *alias = d_find_alias(inode); 151 struct dentry *alias = d_find_alias(inode);
82 if (alias) { 152 if (alias) {
83 dput(alias); 153 dput(alias);
@@ -96,8 +166,14 @@ static struct dentry_operations fuse_dentry_operations = {
96 .d_revalidate = fuse_dentry_revalidate, 166 .d_revalidate = fuse_dentry_revalidate,
97}; 167};
98 168
99static int fuse_lookup_iget(struct inode *dir, struct dentry *entry, 169static inline int valid_mode(int m)
100 struct inode **inodep) 170{
171 return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
172 S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
173}
174
175static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
176 struct nameidata *nd)
101{ 177{
102 int err; 178 int err;
103 struct fuse_entry_out outarg; 179 struct fuse_entry_out outarg;
@@ -106,53 +182,49 @@ static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
106 struct fuse_req *req; 182 struct fuse_req *req;
107 183
108 if (entry->d_name.len > FUSE_NAME_MAX) 184 if (entry->d_name.len > FUSE_NAME_MAX)
109 return -ENAMETOOLONG; 185 return ERR_PTR(-ENAMETOOLONG);
110 186
111 req = fuse_get_request(fc); 187 req = fuse_get_request(fc);
112 if (!req) 188 if (!req)
113 return -EINTR; 189 return ERR_PTR(-EINTR);
114 190
115 fuse_lookup_init(req, dir, entry, &outarg); 191 fuse_lookup_init(req, dir, entry, &outarg);
116 request_send(fc, req); 192 request_send(fc, req);
117 err = req->out.h.error; 193 err = req->out.h.error;
118 if (!err && invalid_nodeid(outarg.nodeid)) 194 if (!err && ((outarg.nodeid && invalid_nodeid(outarg.nodeid)) ||
195 !valid_mode(outarg.attr.mode)))
119 err = -EIO; 196 err = -EIO;
120 if (!err) { 197 if (!err && outarg.nodeid) {
121 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, 198 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
122 &outarg.attr); 199 &outarg.attr);
123 if (!inode) { 200 if (!inode) {
124 fuse_send_forget(fc, req, outarg.nodeid, 1); 201 fuse_send_forget(fc, req, outarg.nodeid, 1);
125 return -ENOMEM; 202 return ERR_PTR(-ENOMEM);
126 } 203 }
127 } 204 }
128 fuse_put_request(fc, req); 205 fuse_put_request(fc, req);
129 if (err && err != -ENOENT) 206 if (err && err != -ENOENT)
130 return err; 207 return ERR_PTR(err);
131 208
132 if (inode) { 209 if (inode && dir_alias(inode)) {
133 struct fuse_inode *fi = get_fuse_inode(inode); 210 iput(inode);
134 entry->d_time = time_to_jiffies(outarg.entry_valid, 211 return ERR_PTR(-EIO);
135 outarg.entry_valid_nsec);
136 fi->i_time = time_to_jiffies(outarg.attr_valid,
137 outarg.attr_valid_nsec);
138 } 212 }
139 213 d_add(entry, inode);
140 entry->d_op = &fuse_dentry_operations; 214 entry->d_op = &fuse_dentry_operations;
141 *inodep = inode; 215 if (!err)
142 return 0; 216 fuse_change_timeout(entry, &outarg);
143} 217 else
144 218 fuse_invalidate_entry_cache(entry);
145void fuse_invalidate_attr(struct inode *inode) 219 return NULL;
146{
147 get_fuse_inode(inode)->i_time = jiffies - 1;
148}
149
150static void fuse_invalidate_entry(struct dentry *entry)
151{
152 d_invalidate(entry);
153 entry->d_time = jiffies - 1;
154} 220}
155 221
222/*
223 * Atomic create+open operation
224 *
225 * If the filesystem doesn't support this, then fall back to separate
226 * 'mknod' + 'open' requests.
227 */
156static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, 228static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
157 struct nameidata *nd) 229 struct nameidata *nd)
158{ 230{
@@ -163,7 +235,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
163 struct fuse_open_in inarg; 235 struct fuse_open_in inarg;
164 struct fuse_open_out outopen; 236 struct fuse_open_out outopen;
165 struct fuse_entry_out outentry; 237 struct fuse_entry_out outentry;
166 struct fuse_inode *fi;
167 struct fuse_file *ff; 238 struct fuse_file *ff;
168 struct file *file; 239 struct file *file;
169 int flags = nd->intent.open.flags - 1; 240 int flags = nd->intent.open.flags - 1;
@@ -172,10 +243,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
172 if (fc->no_create) 243 if (fc->no_create)
173 goto out; 244 goto out;
174 245
175 err = -ENAMETOOLONG;
176 if (entry->d_name.len > FUSE_NAME_MAX)
177 goto out;
178
179 err = -EINTR; 246 err = -EINTR;
180 req = fuse_get_request(fc); 247 req = fuse_get_request(fc);
181 if (!req) 248 if (!req)
@@ -220,17 +287,15 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
220 if (!inode) { 287 if (!inode) {
221 flags &= ~(O_CREAT | O_EXCL | O_TRUNC); 288 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
222 ff->fh = outopen.fh; 289 ff->fh = outopen.fh;
290 /* Special release, with inode = NULL, this will
291 trigger a 'forget' request when the release is
292 complete */
223 fuse_send_release(fc, ff, outentry.nodeid, NULL, flags, 0); 293 fuse_send_release(fc, ff, outentry.nodeid, NULL, flags, 0);
224 goto out_put_request; 294 goto out_put_request;
225 } 295 }
226 fuse_put_request(fc, req); 296 fuse_put_request(fc, req);
227 entry->d_time = time_to_jiffies(outentry.entry_valid,
228 outentry.entry_valid_nsec);
229 fi = get_fuse_inode(inode);
230 fi->i_time = time_to_jiffies(outentry.attr_valid,
231 outentry.attr_valid_nsec);
232
233 d_instantiate(entry, inode); 297 d_instantiate(entry, inode);
298 fuse_change_timeout(entry, &outentry);
234 file = lookup_instantiate_filp(nd, entry, generic_file_open); 299 file = lookup_instantiate_filp(nd, entry, generic_file_open);
235 if (IS_ERR(file)) { 300 if (IS_ERR(file)) {
236 ff->fh = outopen.fh; 301 ff->fh = outopen.fh;
@@ -248,13 +313,15 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
248 return err; 313 return err;
249} 314}
250 315
316/*
317 * Code shared between mknod, mkdir, symlink and link
318 */
251static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, 319static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
252 struct inode *dir, struct dentry *entry, 320 struct inode *dir, struct dentry *entry,
253 int mode) 321 int mode)
254{ 322{
255 struct fuse_entry_out outarg; 323 struct fuse_entry_out outarg;
256 struct inode *inode; 324 struct inode *inode;
257 struct fuse_inode *fi;
258 int err; 325 int err;
259 326
260 req->in.h.nodeid = get_node_id(dir); 327 req->in.h.nodeid = get_node_id(dir);
@@ -268,10 +335,13 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
268 fuse_put_request(fc, req); 335 fuse_put_request(fc, req);
269 return err; 336 return err;
270 } 337 }
271 if (invalid_nodeid(outarg.nodeid)) { 338 err = -EIO;
272 fuse_put_request(fc, req); 339 if (invalid_nodeid(outarg.nodeid))
273 return -EIO; 340 goto out_put_request;
274 } 341
342 if ((outarg.attr.mode ^ mode) & S_IFMT)
343 goto out_put_request;
344
275 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, 345 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
276 &outarg.attr); 346 &outarg.attr);
277 if (!inode) { 347 if (!inode) {
@@ -280,22 +350,19 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
280 } 350 }
281 fuse_put_request(fc, req); 351 fuse_put_request(fc, req);
282 352
283 /* Don't allow userspace to do really stupid things... */ 353 if (dir_alias(inode)) {
284 if (((inode->i_mode ^ mode) & S_IFMT) || dir_alias(inode)) {
285 iput(inode); 354 iput(inode);
286 return -EIO; 355 return -EIO;
287 } 356 }
288 357
289 entry->d_time = time_to_jiffies(outarg.entry_valid,
290 outarg.entry_valid_nsec);
291
292 fi = get_fuse_inode(inode);
293 fi->i_time = time_to_jiffies(outarg.attr_valid,
294 outarg.attr_valid_nsec);
295
296 d_instantiate(entry, inode); 358 d_instantiate(entry, inode);
359 fuse_change_timeout(entry, &outarg);
297 fuse_invalidate_attr(dir); 360 fuse_invalidate_attr(dir);
298 return 0; 361 return 0;
362
363 out_put_request:
364 fuse_put_request(fc, req);
365 return err;
299} 366}
300 367
301static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode, 368static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
@@ -355,12 +422,7 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry,
355{ 422{
356 struct fuse_conn *fc = get_fuse_conn(dir); 423 struct fuse_conn *fc = get_fuse_conn(dir);
357 unsigned len = strlen(link) + 1; 424 unsigned len = strlen(link) + 1;
358 struct fuse_req *req; 425 struct fuse_req *req = fuse_get_request(fc);
359
360 if (len > FUSE_SYMLINK_MAX)
361 return -ENAMETOOLONG;
362
363 req = fuse_get_request(fc);
364 if (!req) 426 if (!req)
365 return -EINTR; 427 return -EINTR;
366 428
@@ -399,6 +461,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
399 inode->i_nlink = 0; 461 inode->i_nlink = 0;
400 fuse_invalidate_attr(inode); 462 fuse_invalidate_attr(inode);
401 fuse_invalidate_attr(dir); 463 fuse_invalidate_attr(dir);
464 fuse_invalidate_entry_cache(entry);
402 } else if (err == -EINTR) 465 } else if (err == -EINTR)
403 fuse_invalidate_entry(entry); 466 fuse_invalidate_entry(entry);
404 return err; 467 return err;
@@ -424,6 +487,7 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
424 if (!err) { 487 if (!err) {
425 entry->d_inode->i_nlink = 0; 488 entry->d_inode->i_nlink = 0;
426 fuse_invalidate_attr(dir); 489 fuse_invalidate_attr(dir);
490 fuse_invalidate_entry_cache(entry);
427 } else if (err == -EINTR) 491 } else if (err == -EINTR)
428 fuse_invalidate_entry(entry); 492 fuse_invalidate_entry(entry);
429 return err; 493 return err;
@@ -459,6 +523,10 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
459 fuse_invalidate_attr(olddir); 523 fuse_invalidate_attr(olddir);
460 if (olddir != newdir) 524 if (olddir != newdir)
461 fuse_invalidate_attr(newdir); 525 fuse_invalidate_attr(newdir);
526
527 /* newent will end up negative */
528 if (newent->d_inode)
529 fuse_invalidate_entry_cache(newent);
462 } else if (err == -EINTR) { 530 } else if (err == -EINTR) {
463 /* If request was interrupted, DEITY only knows if the 531 /* If request was interrupted, DEITY only knows if the
464 rename actually took place. If the invalidation 532 rename actually took place. If the invalidation
@@ -566,6 +634,15 @@ static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
566 return 0; 634 return 0;
567} 635}
568 636
637/*
638 * Check whether the inode attributes are still valid
639 *
640 * If the attribute validity timeout has expired, then fetch the fresh
641 * attributes with a 'getattr' request
642 *
643 * I'm not sure why cached attributes are never returned for the root
644 * inode, this is probably being too cautious.
645 */
569static int fuse_revalidate(struct dentry *entry) 646static int fuse_revalidate(struct dentry *entry)
570{ 647{
571 struct inode *inode = entry->d_inode; 648 struct inode *inode = entry->d_inode;
@@ -613,6 +690,19 @@ static int fuse_access(struct inode *inode, int mask)
613 return err; 690 return err;
614} 691}
615 692
693/*
694 * Check permission. The two basic access models of FUSE are:
695 *
696 * 1) Local access checking ('default_permissions' mount option) based
697 * on file mode. This is the plain old disk filesystem permission
698 * modell.
699 *
700 * 2) "Remote" access checking, where server is responsible for
701 * checking permission in each inode operation. An exception to this
702 * is if ->permission() was invoked from sys_access() in which case an
703 * access request is sent. Execute permission is still checked
704 * locally based on file mode.
705 */
616static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) 706static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
617{ 707{
618 struct fuse_conn *fc = get_fuse_conn(inode); 708 struct fuse_conn *fc = get_fuse_conn(inode);
@@ -631,14 +721,10 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
631 err = generic_permission(inode, mask, NULL); 721 err = generic_permission(inode, mask, NULL);
632 } 722 }
633 723
634 /* FIXME: Need some mechanism to revoke permissions: 724 /* Note: the opposite of the above test does not
635 currently if the filesystem suddenly changes the 725 exist. So if permissions are revoked this won't be
636 file mode, we will not be informed about it, and 726 noticed immediately, only after the attribute
637 continue to allow access to the file/directory. 727 timeout has expired */
638
639 This is actually not so grave, since the user can
640 simply keep access to the file/directory anyway by
641 keeping it open... */
642 728
643 return err; 729 return err;
644 } else { 730 } else {
@@ -691,7 +777,12 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
691 struct page *page; 777 struct page *page;
692 struct inode *inode = file->f_dentry->d_inode; 778 struct inode *inode = file->f_dentry->d_inode;
693 struct fuse_conn *fc = get_fuse_conn(inode); 779 struct fuse_conn *fc = get_fuse_conn(inode);
694 struct fuse_req *req = fuse_get_request(fc); 780 struct fuse_req *req;
781
782 if (is_bad_inode(inode))
783 return -EIO;
784
785 req = fuse_get_request(fc);
695 if (!req) 786 if (!req)
696 return -EINTR; 787 return -EINTR;
697 788
@@ -806,6 +897,15 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
806 } 897 }
807} 898}
808 899
900/*
901 * Set attributes, and at the same time refresh them.
902 *
903 * Truncation is slightly complicated, because the 'truncate' request
904 * may fail, in which case we don't want to touch the mapping.
905 * vmtruncate() doesn't allow for this case. So do the rlimit
906 * checking by hand and call vmtruncate() only after the file has
907 * actually been truncated.
908 */
809static int fuse_setattr(struct dentry *entry, struct iattr *attr) 909static int fuse_setattr(struct dentry *entry, struct iattr *attr)
810{ 910{
811 struct inode *inode = entry->d_inode; 911 struct inode *inode = entry->d_inode;
@@ -883,23 +983,6 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
883 return err; 983 return err;
884} 984}
885 985
886static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
887 struct nameidata *nd)
888{
889 struct inode *inode;
890 int err;
891
892 err = fuse_lookup_iget(dir, entry, &inode);
893 if (err)
894 return ERR_PTR(err);
895 if (inode && dir_alias(inode)) {
896 iput(inode);
897 return ERR_PTR(-EIO);
898 }
899 d_add(entry, inode);
900 return NULL;
901}
902
903static int fuse_setxattr(struct dentry *entry, const char *name, 986static int fuse_setxattr(struct dentry *entry, const char *name,
904 const void *value, size_t size, int flags) 987 const void *value, size_t size, int flags)
905{ 988{
@@ -909,9 +992,6 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
909 struct fuse_setxattr_in inarg; 992 struct fuse_setxattr_in inarg;
910 int err; 993 int err;
911 994
912 if (size > FUSE_XATTR_SIZE_MAX)
913 return -E2BIG;
914
915 if (fc->no_setxattr) 995 if (fc->no_setxattr)
916 return -EOPNOTSUPP; 996 return -EOPNOTSUPP;
917 997