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.c315
1 files changed, 201 insertions, 114 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index c045cc70c749..21fd59c7bc24 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -13,15 +13,66 @@
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
18static inline unsigned long time_to_jiffies(unsigned long sec, 17/*
19 unsigned long nsec) 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 */
26static unsigned long time_to_jiffies(unsigned long sec, unsigned long nsec)
20{ 27{
21 struct timespec ts = {sec, nsec}; 28 struct timespec ts = {sec, nsec};
22 return jiffies + timespec_to_jiffies(&ts); 29 return jiffies + timespec_to_jiffies(&ts);
23} 30}
24 31
32/*
33 * Set dentry and possibly attribute timeouts from the lookup/mk*
34 * replies
35 */
36static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o)
37{
38 entry->d_time = time_to_jiffies(o->entry_valid, o->entry_valid_nsec);
39 if (entry->d_inode)
40 get_fuse_inode(entry->d_inode)->i_time =
41 time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
42}
43
44/*
45 * Mark the attributes as stale, so that at the next call to
46 * ->getattr() they will be fetched from userspace
47 */
48void fuse_invalidate_attr(struct inode *inode)
49{
50 get_fuse_inode(inode)->i_time = jiffies - 1;
51}
52
53/*
54 * Just mark the entry as stale, so that a next attempt to look it up
55 * will result in a new lookup call to userspace
56 *
57 * This is called when a dentry is about to become negative and the
58 * timeout is unknown (unlink, rmdir, rename and in some cases
59 * lookup)
60 */
61static void fuse_invalidate_entry_cache(struct dentry *entry)
62{
63 entry->d_time = jiffies - 1;
64}
65
66/*
67 * Same as fuse_invalidate_entry_cache(), but also try to remove the
68 * dentry from the hash
69 */
70static void fuse_invalidate_entry(struct dentry *entry)
71{
72 d_invalidate(entry);
73 fuse_invalidate_entry_cache(entry);
74}
75
25static void fuse_lookup_init(struct fuse_req *req, struct inode *dir, 76static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
26 struct dentry *entry, 77 struct dentry *entry,
27 struct fuse_entry_out *outarg) 78 struct fuse_entry_out *outarg)
@@ -37,17 +88,34 @@ static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
37 req->out.args[0].value = outarg; 88 req->out.args[0].value = outarg;
38} 89}
39 90
91/*
92 * Check whether the dentry is still valid
93 *
94 * If the entry validity timeout has expired and the dentry is
95 * positive, try to redo the lookup. If the lookup results in a
96 * different inode, then let the VFS invalidate the dentry and redo
97 * the lookup once more. If the lookup results in the same inode,
98 * then refresh the attributes, timeouts and mark the dentry valid.
99 */
40static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) 100static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
41{ 101{
42 if (!entry->d_inode || is_bad_inode(entry->d_inode)) 102 struct inode *inode = entry->d_inode;
103
104 if (inode && is_bad_inode(inode))
43 return 0; 105 return 0;
44 else if (time_after(jiffies, entry->d_time)) { 106 else if (time_after(jiffies, entry->d_time)) {
45 int err; 107 int err;
46 struct fuse_entry_out outarg; 108 struct fuse_entry_out outarg;
47 struct inode *inode = entry->d_inode; 109 struct fuse_conn *fc;
48 struct fuse_inode *fi = get_fuse_inode(inode); 110 struct fuse_req *req;
49 struct fuse_conn *fc = get_fuse_conn(inode); 111
50 struct fuse_req *req = fuse_get_request(fc); 112 /* Doesn't hurt to "reset" the validity timeout */
113 fuse_invalidate_entry_cache(entry);
114 if (!inode)
115 return 0;
116
117 fc = get_fuse_conn(inode);
118 req = fuse_get_request(fc);
51 if (!req) 119 if (!req)
52 return 0; 120 return 0;
53 121
@@ -55,6 +123,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
55 request_send(fc, req); 123 request_send(fc, req);
56 err = req->out.h.error; 124 err = req->out.h.error;
57 if (!err) { 125 if (!err) {
126 struct fuse_inode *fi = get_fuse_inode(inode);
58 if (outarg.nodeid != get_node_id(inode)) { 127 if (outarg.nodeid != get_node_id(inode)) {
59 fuse_send_forget(fc, req, outarg.nodeid, 1); 128 fuse_send_forget(fc, req, outarg.nodeid, 1);
60 return 0; 129 return 0;
@@ -66,20 +135,44 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
66 return 0; 135 return 0;
67 136
68 fuse_change_attributes(inode, &outarg.attr); 137 fuse_change_attributes(inode, &outarg.attr);
69 entry->d_time = time_to_jiffies(outarg.entry_valid, 138 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 } 139 }
74 return 1; 140 return 1;
75} 141}
76 142
143/*
144 * Check if there's already a hashed alias of this directory inode.
145 * If yes, then lookup and mkdir must not create a new alias.
146 */
147static int dir_alias(struct inode *inode)
148{
149 if (S_ISDIR(inode->i_mode)) {
150 struct dentry *alias = d_find_alias(inode);
151 if (alias) {
152 dput(alias);
153 return 1;
154 }
155 }
156 return 0;
157}
158
159static int invalid_nodeid(u64 nodeid)
160{
161 return !nodeid || nodeid == FUSE_ROOT_ID;
162}
163
77static struct dentry_operations fuse_dentry_operations = { 164static struct dentry_operations fuse_dentry_operations = {
78 .d_revalidate = fuse_dentry_revalidate, 165 .d_revalidate = fuse_dentry_revalidate,
79}; 166};
80 167
81static int fuse_lookup_iget(struct inode *dir, struct dentry *entry, 168static int valid_mode(int m)
82 struct inode **inodep) 169{
170 return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
171 S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
172}
173
174static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
175 struct nameidata *nd)
83{ 176{
84 int err; 177 int err;
85 struct fuse_entry_out outarg; 178 struct fuse_entry_out outarg;
@@ -88,53 +181,49 @@ static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
88 struct fuse_req *req; 181 struct fuse_req *req;
89 182
90 if (entry->d_name.len > FUSE_NAME_MAX) 183 if (entry->d_name.len > FUSE_NAME_MAX)
91 return -ENAMETOOLONG; 184 return ERR_PTR(-ENAMETOOLONG);
92 185
93 req = fuse_get_request(fc); 186 req = fuse_get_request(fc);
94 if (!req) 187 if (!req)
95 return -EINTR; 188 return ERR_PTR(-EINTR);
96 189
97 fuse_lookup_init(req, dir, entry, &outarg); 190 fuse_lookup_init(req, dir, entry, &outarg);
98 request_send(fc, req); 191 request_send(fc, req);
99 err = req->out.h.error; 192 err = req->out.h.error;
100 if (!err && (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID)) 193 if (!err && ((outarg.nodeid && invalid_nodeid(outarg.nodeid)) ||
194 !valid_mode(outarg.attr.mode)))
101 err = -EIO; 195 err = -EIO;
102 if (!err) { 196 if (!err && outarg.nodeid) {
103 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, 197 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
104 &outarg.attr); 198 &outarg.attr);
105 if (!inode) { 199 if (!inode) {
106 fuse_send_forget(fc, req, outarg.nodeid, 1); 200 fuse_send_forget(fc, req, outarg.nodeid, 1);
107 return -ENOMEM; 201 return ERR_PTR(-ENOMEM);
108 } 202 }
109 } 203 }
110 fuse_put_request(fc, req); 204 fuse_put_request(fc, req);
111 if (err && err != -ENOENT) 205 if (err && err != -ENOENT)
112 return err; 206 return ERR_PTR(err);
113 207
114 if (inode) { 208 if (inode && dir_alias(inode)) {
115 struct fuse_inode *fi = get_fuse_inode(inode); 209 iput(inode);
116 entry->d_time = time_to_jiffies(outarg.entry_valid, 210 return ERR_PTR(-EIO);
117 outarg.entry_valid_nsec);
118 fi->i_time = time_to_jiffies(outarg.attr_valid,
119 outarg.attr_valid_nsec);
120 } 211 }
121 212 d_add(entry, inode);
122 entry->d_op = &fuse_dentry_operations; 213 entry->d_op = &fuse_dentry_operations;
123 *inodep = inode; 214 if (!err)
124 return 0; 215 fuse_change_timeout(entry, &outarg);
125} 216 else
126 217 fuse_invalidate_entry_cache(entry);
127void fuse_invalidate_attr(struct inode *inode) 218 return NULL;
128{
129 get_fuse_inode(inode)->i_time = jiffies - 1;
130}
131
132static void fuse_invalidate_entry(struct dentry *entry)
133{
134 d_invalidate(entry);
135 entry->d_time = jiffies - 1;
136} 219}
137 220
221/*
222 * Atomic create+open operation
223 *
224 * If the filesystem doesn't support this, then fall back to separate
225 * 'mknod' + 'open' requests.
226 */
138static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, 227static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
139 struct nameidata *nd) 228 struct nameidata *nd)
140{ 229{
@@ -145,7 +234,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
145 struct fuse_open_in inarg; 234 struct fuse_open_in inarg;
146 struct fuse_open_out outopen; 235 struct fuse_open_out outopen;
147 struct fuse_entry_out outentry; 236 struct fuse_entry_out outentry;
148 struct fuse_inode *fi;
149 struct fuse_file *ff; 237 struct fuse_file *ff;
150 struct file *file; 238 struct file *file;
151 int flags = nd->intent.open.flags - 1; 239 int flags = nd->intent.open.flags - 1;
@@ -154,10 +242,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
154 if (fc->no_create) 242 if (fc->no_create)
155 goto out; 243 goto out;
156 244
157 err = -ENAMETOOLONG;
158 if (entry->d_name.len > FUSE_NAME_MAX)
159 goto out;
160
161 err = -EINTR; 245 err = -EINTR;
162 req = fuse_get_request(fc); 246 req = fuse_get_request(fc);
163 if (!req) 247 if (!req)
@@ -193,7 +277,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
193 } 277 }
194 278
195 err = -EIO; 279 err = -EIO;
196 if (!S_ISREG(outentry.attr.mode)) 280 if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
197 goto out_free_ff; 281 goto out_free_ff;
198 282
199 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, 283 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
@@ -202,17 +286,15 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
202 if (!inode) { 286 if (!inode) {
203 flags &= ~(O_CREAT | O_EXCL | O_TRUNC); 287 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
204 ff->fh = outopen.fh; 288 ff->fh = outopen.fh;
289 /* Special release, with inode = NULL, this will
290 trigger a 'forget' request when the release is
291 complete */
205 fuse_send_release(fc, ff, outentry.nodeid, NULL, flags, 0); 292 fuse_send_release(fc, ff, outentry.nodeid, NULL, flags, 0);
206 goto out_put_request; 293 goto out_put_request;
207 } 294 }
208 fuse_put_request(fc, req); 295 fuse_put_request(fc, req);
209 entry->d_time = time_to_jiffies(outentry.entry_valid,
210 outentry.entry_valid_nsec);
211 fi = get_fuse_inode(inode);
212 fi->i_time = time_to_jiffies(outentry.attr_valid,
213 outentry.attr_valid_nsec);
214
215 d_instantiate(entry, inode); 296 d_instantiate(entry, inode);
297 fuse_change_timeout(entry, &outentry);
216 file = lookup_instantiate_filp(nd, entry, generic_file_open); 298 file = lookup_instantiate_filp(nd, entry, generic_file_open);
217 if (IS_ERR(file)) { 299 if (IS_ERR(file)) {
218 ff->fh = outopen.fh; 300 ff->fh = outopen.fh;
@@ -230,13 +312,15 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
230 return err; 312 return err;
231} 313}
232 314
315/*
316 * Code shared between mknod, mkdir, symlink and link
317 */
233static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, 318static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
234 struct inode *dir, struct dentry *entry, 319 struct inode *dir, struct dentry *entry,
235 int mode) 320 int mode)
236{ 321{
237 struct fuse_entry_out outarg; 322 struct fuse_entry_out outarg;
238 struct inode *inode; 323 struct inode *inode;
239 struct fuse_inode *fi;
240 int err; 324 int err;
241 325
242 req->in.h.nodeid = get_node_id(dir); 326 req->in.h.nodeid = get_node_id(dir);
@@ -250,10 +334,13 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
250 fuse_put_request(fc, req); 334 fuse_put_request(fc, req);
251 return err; 335 return err;
252 } 336 }
253 if (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID) { 337 err = -EIO;
254 fuse_put_request(fc, req); 338 if (invalid_nodeid(outarg.nodeid))
255 return -EIO; 339 goto out_put_request;
256 } 340
341 if ((outarg.attr.mode ^ mode) & S_IFMT)
342 goto out_put_request;
343
257 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, 344 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
258 &outarg.attr); 345 &outarg.attr);
259 if (!inode) { 346 if (!inode) {
@@ -262,22 +349,19 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
262 } 349 }
263 fuse_put_request(fc, req); 350 fuse_put_request(fc, req);
264 351
265 /* Don't allow userspace to do really stupid things... */ 352 if (dir_alias(inode)) {
266 if ((inode->i_mode ^ mode) & S_IFMT) {
267 iput(inode); 353 iput(inode);
268 return -EIO; 354 return -EIO;
269 } 355 }
270 356
271 entry->d_time = time_to_jiffies(outarg.entry_valid,
272 outarg.entry_valid_nsec);
273
274 fi = get_fuse_inode(inode);
275 fi->i_time = time_to_jiffies(outarg.attr_valid,
276 outarg.attr_valid_nsec);
277
278 d_instantiate(entry, inode); 357 d_instantiate(entry, inode);
358 fuse_change_timeout(entry, &outarg);
279 fuse_invalidate_attr(dir); 359 fuse_invalidate_attr(dir);
280 return 0; 360 return 0;
361
362 out_put_request:
363 fuse_put_request(fc, req);
364 return err;
281} 365}
282 366
283static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode, 367static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
@@ -337,12 +421,7 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry,
337{ 421{
338 struct fuse_conn *fc = get_fuse_conn(dir); 422 struct fuse_conn *fc = get_fuse_conn(dir);
339 unsigned len = strlen(link) + 1; 423 unsigned len = strlen(link) + 1;
340 struct fuse_req *req; 424 struct fuse_req *req = fuse_get_request(fc);
341
342 if (len > FUSE_SYMLINK_MAX)
343 return -ENAMETOOLONG;
344
345 req = fuse_get_request(fc);
346 if (!req) 425 if (!req)
347 return -EINTR; 426 return -EINTR;
348 427
@@ -381,6 +460,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
381 inode->i_nlink = 0; 460 inode->i_nlink = 0;
382 fuse_invalidate_attr(inode); 461 fuse_invalidate_attr(inode);
383 fuse_invalidate_attr(dir); 462 fuse_invalidate_attr(dir);
463 fuse_invalidate_entry_cache(entry);
384 } else if (err == -EINTR) 464 } else if (err == -EINTR)
385 fuse_invalidate_entry(entry); 465 fuse_invalidate_entry(entry);
386 return err; 466 return err;
@@ -406,6 +486,7 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
406 if (!err) { 486 if (!err) {
407 entry->d_inode->i_nlink = 0; 487 entry->d_inode->i_nlink = 0;
408 fuse_invalidate_attr(dir); 488 fuse_invalidate_attr(dir);
489 fuse_invalidate_entry_cache(entry);
409 } else if (err == -EINTR) 490 } else if (err == -EINTR)
410 fuse_invalidate_entry(entry); 491 fuse_invalidate_entry(entry);
411 return err; 492 return err;
@@ -441,6 +522,10 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
441 fuse_invalidate_attr(olddir); 522 fuse_invalidate_attr(olddir);
442 if (olddir != newdir) 523 if (olddir != newdir)
443 fuse_invalidate_attr(newdir); 524 fuse_invalidate_attr(newdir);
525
526 /* newent will end up negative */
527 if (newent->d_inode)
528 fuse_invalidate_entry_cache(newent);
444 } else if (err == -EINTR) { 529 } else if (err == -EINTR) {
445 /* If request was interrupted, DEITY only knows if the 530 /* If request was interrupted, DEITY only knows if the
446 rename actually took place. If the invalidation 531 rename actually took place. If the invalidation
@@ -548,6 +633,15 @@ static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
548 return 0; 633 return 0;
549} 634}
550 635
636/*
637 * Check whether the inode attributes are still valid
638 *
639 * If the attribute validity timeout has expired, then fetch the fresh
640 * attributes with a 'getattr' request
641 *
642 * I'm not sure why cached attributes are never returned for the root
643 * inode, this is probably being too cautious.
644 */
551static int fuse_revalidate(struct dentry *entry) 645static int fuse_revalidate(struct dentry *entry)
552{ 646{
553 struct inode *inode = entry->d_inode; 647 struct inode *inode = entry->d_inode;
@@ -595,6 +689,19 @@ static int fuse_access(struct inode *inode, int mask)
595 return err; 689 return err;
596} 690}
597 691
692/*
693 * Check permission. The two basic access models of FUSE are:
694 *
695 * 1) Local access checking ('default_permissions' mount option) based
696 * on file mode. This is the plain old disk filesystem permission
697 * modell.
698 *
699 * 2) "Remote" access checking, where server is responsible for
700 * checking permission in each inode operation. An exception to this
701 * is if ->permission() was invoked from sys_access() in which case an
702 * access request is sent. Execute permission is still checked
703 * locally based on file mode.
704 */
598static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) 705static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
599{ 706{
600 struct fuse_conn *fc = get_fuse_conn(inode); 707 struct fuse_conn *fc = get_fuse_conn(inode);
@@ -613,14 +720,10 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
613 err = generic_permission(inode, mask, NULL); 720 err = generic_permission(inode, mask, NULL);
614 } 721 }
615 722
616 /* FIXME: Need some mechanism to revoke permissions: 723 /* Note: the opposite of the above test does not
617 currently if the filesystem suddenly changes the 724 exist. So if permissions are revoked this won't be
618 file mode, we will not be informed about it, and 725 noticed immediately, only after the attribute
619 continue to allow access to the file/directory. 726 timeout has expired */
620
621 This is actually not so grave, since the user can
622 simply keep access to the file/directory anyway by
623 keeping it open... */
624 727
625 return err; 728 return err;
626 } else { 729 } else {
@@ -659,13 +762,6 @@ static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
659 return 0; 762 return 0;
660} 763}
661 764
662static inline size_t fuse_send_readdir(struct fuse_req *req, struct file *file,
663 struct inode *inode, loff_t pos,
664 size_t count)
665{
666 return fuse_send_read_common(req, file, inode, pos, count, 1);
667}
668
669static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) 765static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
670{ 766{
671 int err; 767 int err;
@@ -673,7 +769,12 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
673 struct page *page; 769 struct page *page;
674 struct inode *inode = file->f_dentry->d_inode; 770 struct inode *inode = file->f_dentry->d_inode;
675 struct fuse_conn *fc = get_fuse_conn(inode); 771 struct fuse_conn *fc = get_fuse_conn(inode);
676 struct fuse_req *req = fuse_get_request(fc); 772 struct fuse_req *req;
773
774 if (is_bad_inode(inode))
775 return -EIO;
776
777 req = fuse_get_request(fc);
677 if (!req) 778 if (!req)
678 return -EINTR; 779 return -EINTR;
679 780
@@ -684,7 +785,9 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
684 } 785 }
685 req->num_pages = 1; 786 req->num_pages = 1;
686 req->pages[0] = page; 787 req->pages[0] = page;
687 nbytes = fuse_send_readdir(req, file, inode, file->f_pos, PAGE_SIZE); 788 fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR);
789 request_send(fc, req);
790 nbytes = req->out.args[0].size;
688 err = req->out.h.error; 791 err = req->out.h.error;
689 fuse_put_request(fc, req); 792 fuse_put_request(fc, req);
690 if (!err) 793 if (!err)
@@ -788,6 +891,15 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
788 } 891 }
789} 892}
790 893
894/*
895 * Set attributes, and at the same time refresh them.
896 *
897 * Truncation is slightly complicated, because the 'truncate' request
898 * may fail, in which case we don't want to touch the mapping.
899 * vmtruncate() doesn't allow for this case. So do the rlimit
900 * checking by hand and call vmtruncate() only after the file has
901 * actually been truncated.
902 */
791static int fuse_setattr(struct dentry *entry, struct iattr *attr) 903static int fuse_setattr(struct dentry *entry, struct iattr *attr)
792{ 904{
793 struct inode *inode = entry->d_inode; 905 struct inode *inode = entry->d_inode;
@@ -865,28 +977,6 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
865 return err; 977 return err;
866} 978}
867 979
868static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
869 struct nameidata *nd)
870{
871 struct inode *inode;
872 int err;
873
874 err = fuse_lookup_iget(dir, entry, &inode);
875 if (err)
876 return ERR_PTR(err);
877 if (inode && S_ISDIR(inode->i_mode)) {
878 /* Don't allow creating an alias to a directory */
879 struct dentry *alias = d_find_alias(inode);
880 if (alias) {
881 dput(alias);
882 iput(inode);
883 return ERR_PTR(-EIO);
884 }
885 }
886 d_add(entry, inode);
887 return NULL;
888}
889
890static int fuse_setxattr(struct dentry *entry, const char *name, 980static int fuse_setxattr(struct dentry *entry, const char *name,
891 const void *value, size_t size, int flags) 981 const void *value, size_t size, int flags)
892{ 982{
@@ -896,9 +986,6 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
896 struct fuse_setxattr_in inarg; 986 struct fuse_setxattr_in inarg;
897 int err; 987 int err;
898 988
899 if (size > FUSE_XATTR_SIZE_MAX)
900 return -E2BIG;
901
902 if (fc->no_setxattr) 989 if (fc->no_setxattr)
903 return -EOPNOTSUPP; 990 return -EOPNOTSUPP;
904 991