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.c125
1 files changed, 82 insertions, 43 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index b18e06daeffb..a058b664859c 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -63,13 +63,21 @@ static u64 time_to_jiffies(unsigned long sec, unsigned long nsec)
63 * Set dentry and possibly attribute timeouts from the lookup/mk* 63 * Set dentry and possibly attribute timeouts from the lookup/mk*
64 * replies 64 * replies
65 */ 65 */
66static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o) 66static void fuse_change_entry_timeout(struct dentry *entry,
67 struct fuse_entry_out *o)
67{ 68{
68 fuse_dentry_settime(entry, 69 fuse_dentry_settime(entry,
69 time_to_jiffies(o->entry_valid, o->entry_valid_nsec)); 70 time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
70 if (entry->d_inode) 71}
71 get_fuse_inode(entry->d_inode)->i_time = 72
72 time_to_jiffies(o->attr_valid, o->attr_valid_nsec); 73static u64 attr_timeout(struct fuse_attr_out *o)
74{
75 return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
76}
77
78static u64 entry_attr_timeout(struct fuse_entry_out *o)
79{
80 return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
73} 81}
74 82
75/* 83/*
@@ -140,6 +148,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
140 struct fuse_req *req; 148 struct fuse_req *req;
141 struct fuse_req *forget_req; 149 struct fuse_req *forget_req;
142 struct dentry *parent; 150 struct dentry *parent;
151 u64 attr_version;
143 152
144 /* For negative dentries, always do a fresh lookup */ 153 /* For negative dentries, always do a fresh lookup */
145 if (!inode) 154 if (!inode)
@@ -156,6 +165,10 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
156 return 0; 165 return 0;
157 } 166 }
158 167
168 spin_lock(&fc->lock);
169 attr_version = fc->attr_version;
170 spin_unlock(&fc->lock);
171
159 parent = dget_parent(entry); 172 parent = dget_parent(entry);
160 fuse_lookup_init(req, parent->d_inode, entry, &outarg); 173 fuse_lookup_init(req, parent->d_inode, entry, &outarg);
161 request_send(fc, req); 174 request_send(fc, req);
@@ -180,8 +193,10 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
180 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) 193 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
181 return 0; 194 return 0;
182 195
183 fuse_change_attributes(inode, &outarg.attr); 196 fuse_change_attributes(inode, &outarg.attr,
184 fuse_change_timeout(entry, &outarg); 197 entry_attr_timeout(&outarg),
198 attr_version);
199 fuse_change_entry_timeout(entry, &outarg);
185 } 200 }
186 return 1; 201 return 1;
187} 202}
@@ -228,6 +243,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
228 struct fuse_conn *fc = get_fuse_conn(dir); 243 struct fuse_conn *fc = get_fuse_conn(dir);
229 struct fuse_req *req; 244 struct fuse_req *req;
230 struct fuse_req *forget_req; 245 struct fuse_req *forget_req;
246 u64 attr_version;
231 247
232 if (entry->d_name.len > FUSE_NAME_MAX) 248 if (entry->d_name.len > FUSE_NAME_MAX)
233 return ERR_PTR(-ENAMETOOLONG); 249 return ERR_PTR(-ENAMETOOLONG);
@@ -242,6 +258,10 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
242 return ERR_PTR(PTR_ERR(forget_req)); 258 return ERR_PTR(PTR_ERR(forget_req));
243 } 259 }
244 260
261 spin_lock(&fc->lock);
262 attr_version = fc->attr_version;
263 spin_unlock(&fc->lock);
264
245 fuse_lookup_init(req, dir, entry, &outarg); 265 fuse_lookup_init(req, dir, entry, &outarg);
246 request_send(fc, req); 266 request_send(fc, req);
247 err = req->out.h.error; 267 err = req->out.h.error;
@@ -253,7 +273,8 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
253 err = -EIO; 273 err = -EIO;
254 if (!err && outarg.nodeid) { 274 if (!err && outarg.nodeid) {
255 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, 275 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
256 &outarg.attr); 276 &outarg.attr, entry_attr_timeout(&outarg),
277 attr_version);
257 if (!inode) { 278 if (!inode) {
258 fuse_send_forget(fc, forget_req, outarg.nodeid, 1); 279 fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
259 return ERR_PTR(-ENOMEM); 280 return ERR_PTR(-ENOMEM);
@@ -276,7 +297,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
276 297
277 entry->d_op = &fuse_dentry_operations; 298 entry->d_op = &fuse_dentry_operations;
278 if (!err) 299 if (!err)
279 fuse_change_timeout(entry, &outarg); 300 fuse_change_entry_timeout(entry, &outarg);
280 else 301 else
281 fuse_invalidate_entry_cache(entry); 302 fuse_invalidate_entry_cache(entry);
282 return NULL; 303 return NULL;
@@ -363,7 +384,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
363 384
364 fuse_put_request(fc, req); 385 fuse_put_request(fc, req);
365 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, 386 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
366 &outentry.attr); 387 &outentry.attr, entry_attr_timeout(&outentry), 0);
367 if (!inode) { 388 if (!inode) {
368 flags &= ~(O_CREAT | O_EXCL | O_TRUNC); 389 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
369 ff->fh = outopen.fh; 390 ff->fh = outopen.fh;
@@ -373,7 +394,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
373 } 394 }
374 fuse_put_request(fc, forget_req); 395 fuse_put_request(fc, forget_req);
375 d_instantiate(entry, inode); 396 d_instantiate(entry, inode);
376 fuse_change_timeout(entry, &outentry); 397 fuse_change_entry_timeout(entry, &outentry);
377 file = lookup_instantiate_filp(nd, entry, generic_file_open); 398 file = lookup_instantiate_filp(nd, entry, generic_file_open);
378 if (IS_ERR(file)) { 399 if (IS_ERR(file)) {
379 ff->fh = outopen.fh; 400 ff->fh = outopen.fh;
@@ -428,7 +449,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
428 goto out_put_forget_req; 449 goto out_put_forget_req;
429 450
430 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, 451 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
431 &outarg.attr); 452 &outarg.attr, entry_attr_timeout(&outarg), 0);
432 if (!inode) { 453 if (!inode) {
433 fuse_send_forget(fc, forget_req, outarg.nodeid, 1); 454 fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
434 return -ENOMEM; 455 return -ENOMEM;
@@ -451,7 +472,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
451 } else 472 } else
452 d_instantiate(entry, inode); 473 d_instantiate(entry, inode);
453 474
454 fuse_change_timeout(entry, &outarg); 475 fuse_change_entry_timeout(entry, &outarg);
455 fuse_invalidate_attr(dir); 476 fuse_invalidate_attr(dir);
456 return 0; 477 return 0;
457 478
@@ -663,15 +684,43 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
663 return err; 684 return err;
664} 685}
665 686
666static int fuse_do_getattr(struct inode *inode) 687static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
688 struct kstat *stat)
689{
690 stat->dev = inode->i_sb->s_dev;
691 stat->ino = attr->ino;
692 stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
693 stat->nlink = attr->nlink;
694 stat->uid = attr->uid;
695 stat->gid = attr->gid;
696 stat->rdev = inode->i_rdev;
697 stat->atime.tv_sec = attr->atime;
698 stat->atime.tv_nsec = attr->atimensec;
699 stat->mtime.tv_sec = attr->mtime;
700 stat->mtime.tv_nsec = attr->mtimensec;
701 stat->ctime.tv_sec = attr->ctime;
702 stat->ctime.tv_nsec = attr->ctimensec;
703 stat->size = attr->size;
704 stat->blocks = attr->blocks;
705 stat->blksize = (1 << inode->i_blkbits);
706}
707
708static int fuse_do_getattr(struct inode *inode, struct kstat *stat)
667{ 709{
668 int err; 710 int err;
669 struct fuse_attr_out arg; 711 struct fuse_attr_out arg;
670 struct fuse_conn *fc = get_fuse_conn(inode); 712 struct fuse_conn *fc = get_fuse_conn(inode);
671 struct fuse_req *req = fuse_get_req(fc); 713 struct fuse_req *req;
714 u64 attr_version;
715
716 req = fuse_get_req(fc);
672 if (IS_ERR(req)) 717 if (IS_ERR(req))
673 return PTR_ERR(req); 718 return PTR_ERR(req);
674 719
720 spin_lock(&fc->lock);
721 attr_version = fc->attr_version;
722 spin_unlock(&fc->lock);
723
675 req->in.h.opcode = FUSE_GETATTR; 724 req->in.h.opcode = FUSE_GETATTR;
676 req->in.h.nodeid = get_node_id(inode); 725 req->in.h.nodeid = get_node_id(inode);
677 req->out.numargs = 1; 726 req->out.numargs = 1;
@@ -685,30 +734,17 @@ static int fuse_do_getattr(struct inode *inode)
685 make_bad_inode(inode); 734 make_bad_inode(inode);
686 err = -EIO; 735 err = -EIO;
687 } else { 736 } else {
688 struct fuse_inode *fi = get_fuse_inode(inode); 737 fuse_change_attributes(inode, &arg.attr,
689 fuse_change_attributes(inode, &arg.attr); 738 attr_timeout(&arg),
690 fi->i_time = time_to_jiffies(arg.attr_valid, 739 attr_version);
691 arg.attr_valid_nsec); 740 if (stat)
741 fuse_fillattr(inode, &arg.attr, stat);
692 } 742 }
693 } 743 }
694 return err; 744 return err;
695} 745}
696 746
697/* 747/*
698 * Check if attributes are still valid, and if not send a GETATTR
699 * request to refresh them.
700 */
701static int fuse_refresh_attributes(struct inode *inode)
702{
703 struct fuse_inode *fi = get_fuse_inode(inode);
704
705 if (fi->i_time < get_jiffies_64())
706 return fuse_do_getattr(inode);
707 else
708 return 0;
709}
710
711/*
712 * Calling into a user-controlled filesystem gives the filesystem 748 * Calling into a user-controlled filesystem gives the filesystem
713 * daemon ptrace-like capabilities over the requester process. This 749 * daemon ptrace-like capabilities over the requester process. This
714 * means, that the filesystem daemon is able to record the exact 750 * means, that the filesystem daemon is able to record the exact
@@ -795,11 +831,14 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
795 */ 831 */
796 if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || 832 if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
797 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { 833 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
798 err = fuse_refresh_attributes(inode); 834 struct fuse_inode *fi = get_fuse_inode(inode);
799 if (err) 835 if (fi->i_time < get_jiffies_64()) {
800 return err; 836 err = fuse_do_getattr(inode, NULL);
837 if (err)
838 return err;
801 839
802 refreshed = true; 840 refreshed = true;
841 }
803 } 842 }
804 843
805 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { 844 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
@@ -809,7 +848,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
809 attributes. This is also needed, because the root 848 attributes. This is also needed, because the root
810 node will at first have no permissions */ 849 node will at first have no permissions */
811 if (err == -EACCES && !refreshed) { 850 if (err == -EACCES && !refreshed) {
812 err = fuse_do_getattr(inode); 851 err = fuse_do_getattr(inode, NULL);
813 if (!err) 852 if (!err)
814 err = generic_permission(inode, mask, NULL); 853 err = generic_permission(inode, mask, NULL);
815 } 854 }
@@ -825,7 +864,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
825 if (refreshed) 864 if (refreshed)
826 return -EACCES; 865 return -EACCES;
827 866
828 err = fuse_do_getattr(inode); 867 err = fuse_do_getattr(inode, NULL);
829 if (!err && !(inode->i_mode & S_IXUGO)) 868 if (!err && !(inode->i_mode & S_IXUGO))
830 return -EACCES; 869 return -EACCES;
831 } 870 }
@@ -999,7 +1038,6 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
999{ 1038{
1000 struct inode *inode = entry->d_inode; 1039 struct inode *inode = entry->d_inode;
1001 struct fuse_conn *fc = get_fuse_conn(inode); 1040 struct fuse_conn *fc = get_fuse_conn(inode);
1002 struct fuse_inode *fi = get_fuse_inode(inode);
1003 struct fuse_req *req; 1041 struct fuse_req *req;
1004 struct fuse_setattr_in inarg; 1042 struct fuse_setattr_in inarg;
1005 struct fuse_attr_out outarg; 1043 struct fuse_attr_out outarg;
@@ -1053,8 +1091,7 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1053 return -EIO; 1091 return -EIO;
1054 } 1092 }
1055 1093
1056 fuse_change_attributes(inode, &outarg.attr); 1094 fuse_change_attributes(inode, &outarg.attr, attr_timeout(&outarg), 0);
1057 fi->i_time = time_to_jiffies(outarg.attr_valid, outarg.attr_valid_nsec);
1058 return 0; 1095 return 0;
1059} 1096}
1060 1097
@@ -1069,8 +1106,10 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1069 if (!fuse_allow_task(fc, current)) 1106 if (!fuse_allow_task(fc, current))
1070 return -EACCES; 1107 return -EACCES;
1071 1108
1072 err = fuse_refresh_attributes(inode); 1109 if (fi->i_time < get_jiffies_64())
1073 if (!err) { 1110 err = fuse_do_getattr(inode, stat);
1111 else {
1112 err = 0;
1074 generic_fillattr(inode, stat); 1113 generic_fillattr(inode, stat);
1075 stat->mode = fi->orig_i_mode; 1114 stat->mode = fi->orig_i_mode;
1076 } 1115 }