aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/dir.c75
1 files changed, 23 insertions, 52 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 51f5da652771..0d1438a9dab3 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -13,7 +13,6 @@
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, 17static inline unsigned long time_to_jiffies(unsigned long sec,
19 unsigned long nsec) 18 unsigned long nsec)
@@ -22,6 +21,13 @@ static inline unsigned long time_to_jiffies(unsigned long sec,
22 return jiffies + timespec_to_jiffies(&ts); 21 return jiffies + timespec_to_jiffies(&ts);
23} 22}
24 23
24static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o)
25{
26 struct fuse_inode *fi = get_fuse_inode(entry->d_inode);
27 entry->d_time = time_to_jiffies(o->entry_valid, o->entry_valid_nsec);
28 fi->i_time = time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
29}
30
25static void fuse_lookup_init(struct fuse_req *req, struct inode *dir, 31static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
26 struct dentry *entry, 32 struct dentry *entry,
27 struct fuse_entry_out *outarg) 33 struct fuse_entry_out *outarg)
@@ -66,10 +72,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
66 return 0; 72 return 0;
67 73
68 fuse_change_attributes(inode, &outarg.attr); 74 fuse_change_attributes(inode, &outarg.attr);
69 entry->d_time = time_to_jiffies(outarg.entry_valid, 75 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 } 76 }
74 return 1; 77 return 1;
75} 78}
@@ -96,8 +99,8 @@ static struct dentry_operations fuse_dentry_operations = {
96 .d_revalidate = fuse_dentry_revalidate, 99 .d_revalidate = fuse_dentry_revalidate,
97}; 100};
98 101
99static int fuse_lookup_iget(struct inode *dir, struct dentry *entry, 102static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
100 struct inode **inodep) 103 struct nameidata *nd)
101{ 104{
102 int err; 105 int err;
103 struct fuse_entry_out outarg; 106 struct fuse_entry_out outarg;
@@ -106,11 +109,11 @@ static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
106 struct fuse_req *req; 109 struct fuse_req *req;
107 110
108 if (entry->d_name.len > FUSE_NAME_MAX) 111 if (entry->d_name.len > FUSE_NAME_MAX)
109 return -ENAMETOOLONG; 112 return ERR_PTR(-ENAMETOOLONG);
110 113
111 req = fuse_get_request(fc); 114 req = fuse_get_request(fc);
112 if (!req) 115 if (!req)
113 return -EINTR; 116 return ERR_PTR(-EINTR);
114 117
115 fuse_lookup_init(req, dir, entry, &outarg); 118 fuse_lookup_init(req, dir, entry, &outarg);
116 request_send(fc, req); 119 request_send(fc, req);
@@ -122,24 +125,22 @@ static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
122 &outarg.attr); 125 &outarg.attr);
123 if (!inode) { 126 if (!inode) {
124 fuse_send_forget(fc, req, outarg.nodeid, 1); 127 fuse_send_forget(fc, req, outarg.nodeid, 1);
125 return -ENOMEM; 128 return ERR_PTR(-ENOMEM);
126 } 129 }
127 } 130 }
128 fuse_put_request(fc, req); 131 fuse_put_request(fc, req);
129 if (err && err != -ENOENT) 132 if (err && err != -ENOENT)
130 return err; 133 return ERR_PTR(err);
131 134
132 if (inode) { 135 if (inode && dir_alias(inode)) {
133 struct fuse_inode *fi = get_fuse_inode(inode); 136 iput(inode);
134 entry->d_time = time_to_jiffies(outarg.entry_valid, 137 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 } 138 }
139 139 d_add(entry, inode);
140 entry->d_op = &fuse_dentry_operations; 140 entry->d_op = &fuse_dentry_operations;
141 *inodep = inode; 141 if (inode)
142 return 0; 142 fuse_change_timeout(entry, &outarg);
143 return NULL;
143} 144}
144 145
145void fuse_invalidate_attr(struct inode *inode) 146void fuse_invalidate_attr(struct inode *inode)
@@ -163,7 +164,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
163 struct fuse_open_in inarg; 164 struct fuse_open_in inarg;
164 struct fuse_open_out outopen; 165 struct fuse_open_out outopen;
165 struct fuse_entry_out outentry; 166 struct fuse_entry_out outentry;
166 struct fuse_inode *fi;
167 struct fuse_file *ff; 167 struct fuse_file *ff;
168 struct file *file; 168 struct file *file;
169 int flags = nd->intent.open.flags - 1; 169 int flags = nd->intent.open.flags - 1;
@@ -224,13 +224,8 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
224 goto out_put_request; 224 goto out_put_request;
225 } 225 }
226 fuse_put_request(fc, req); 226 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); 227 d_instantiate(entry, inode);
228 fuse_change_timeout(entry, &outentry);
234 file = lookup_instantiate_filp(nd, entry, generic_file_open); 229 file = lookup_instantiate_filp(nd, entry, generic_file_open);
235 if (IS_ERR(file)) { 230 if (IS_ERR(file)) {
236 ff->fh = outopen.fh; 231 ff->fh = outopen.fh;
@@ -254,7 +249,6 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
254{ 249{
255 struct fuse_entry_out outarg; 250 struct fuse_entry_out outarg;
256 struct inode *inode; 251 struct inode *inode;
257 struct fuse_inode *fi;
258 int err; 252 int err;
259 253
260 req->in.h.nodeid = get_node_id(dir); 254 req->in.h.nodeid = get_node_id(dir);
@@ -286,14 +280,8 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
286 return -EIO; 280 return -EIO;
287 } 281 }
288 282
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); 283 d_instantiate(entry, inode);
284 fuse_change_timeout(entry, &outarg);
297 fuse_invalidate_attr(dir); 285 fuse_invalidate_attr(dir);
298 return 0; 286 return 0;
299} 287}
@@ -883,23 +871,6 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
883 return err; 871 return err;
884} 872}
885 873
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, 874static int fuse_setxattr(struct dentry *entry, const char *name,
904 const void *value, size_t size, int flags) 875 const void *value, size_t size, int flags)
905{ 876{