diff options
Diffstat (limited to 'fs/fuse')
-rw-r--r-- | fs/fuse/dir.c | 75 |
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 | ||
18 | static inline unsigned long time_to_jiffies(unsigned long sec, | 17 | static 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 | ||
24 | static 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 | |||
25 | static void fuse_lookup_init(struct fuse_req *req, struct inode *dir, | 31 | static 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 | ||
99 | static int fuse_lookup_iget(struct inode *dir, struct dentry *entry, | 102 | static 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 | ||
145 | void fuse_invalidate_attr(struct inode *inode) | 146 | void 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 | ||
886 | static 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 | |||
903 | static int fuse_setxattr(struct dentry *entry, const char *name, | 874 | static 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 | { |