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.c241
1 files changed, 180 insertions, 61 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index d1acab931330..3763757f9fe7 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/*
@@ -108,13 +116,19 @@ static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
108 struct dentry *entry, 116 struct dentry *entry,
109 struct fuse_entry_out *outarg) 117 struct fuse_entry_out *outarg)
110{ 118{
119 struct fuse_conn *fc = get_fuse_conn(dir);
120
121 memset(outarg, 0, sizeof(struct fuse_entry_out));
111 req->in.h.opcode = FUSE_LOOKUP; 122 req->in.h.opcode = FUSE_LOOKUP;
112 req->in.h.nodeid = get_node_id(dir); 123 req->in.h.nodeid = get_node_id(dir);
113 req->in.numargs = 1; 124 req->in.numargs = 1;
114 req->in.args[0].size = entry->d_name.len + 1; 125 req->in.args[0].size = entry->d_name.len + 1;
115 req->in.args[0].value = entry->d_name.name; 126 req->in.args[0].value = entry->d_name.name;
116 req->out.numargs = 1; 127 req->out.numargs = 1;
117 req->out.args[0].size = sizeof(struct fuse_entry_out); 128 if (fc->minor < 9)
129 req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
130 else
131 req->out.args[0].size = sizeof(struct fuse_entry_out);
118 req->out.args[0].value = outarg; 132 req->out.args[0].value = outarg;
119} 133}
120 134
@@ -140,6 +154,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
140 struct fuse_req *req; 154 struct fuse_req *req;
141 struct fuse_req *forget_req; 155 struct fuse_req *forget_req;
142 struct dentry *parent; 156 struct dentry *parent;
157 u64 attr_version;
143 158
144 /* For negative dentries, always do a fresh lookup */ 159 /* For negative dentries, always do a fresh lookup */
145 if (!inode) 160 if (!inode)
@@ -156,6 +171,10 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
156 return 0; 171 return 0;
157 } 172 }
158 173
174 spin_lock(&fc->lock);
175 attr_version = fc->attr_version;
176 spin_unlock(&fc->lock);
177
159 parent = dget_parent(entry); 178 parent = dget_parent(entry);
160 fuse_lookup_init(req, parent->d_inode, entry, &outarg); 179 fuse_lookup_init(req, parent->d_inode, entry, &outarg);
161 request_send(fc, req); 180 request_send(fc, req);
@@ -180,8 +199,10 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
180 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) 199 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
181 return 0; 200 return 0;
182 201
183 fuse_change_attributes(inode, &outarg.attr); 202 fuse_change_attributes(inode, &outarg.attr,
184 fuse_change_timeout(entry, &outarg); 203 entry_attr_timeout(&outarg),
204 attr_version);
205 fuse_change_entry_timeout(entry, &outarg);
185 } 206 }
186 return 1; 207 return 1;
187} 208}
@@ -228,6 +249,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
228 struct fuse_conn *fc = get_fuse_conn(dir); 249 struct fuse_conn *fc = get_fuse_conn(dir);
229 struct fuse_req *req; 250 struct fuse_req *req;
230 struct fuse_req *forget_req; 251 struct fuse_req *forget_req;
252 u64 attr_version;
231 253
232 if (entry->d_name.len > FUSE_NAME_MAX) 254 if (entry->d_name.len > FUSE_NAME_MAX)
233 return ERR_PTR(-ENAMETOOLONG); 255 return ERR_PTR(-ENAMETOOLONG);
@@ -242,6 +264,10 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
242 return ERR_PTR(PTR_ERR(forget_req)); 264 return ERR_PTR(PTR_ERR(forget_req));
243 } 265 }
244 266
267 spin_lock(&fc->lock);
268 attr_version = fc->attr_version;
269 spin_unlock(&fc->lock);
270
245 fuse_lookup_init(req, dir, entry, &outarg); 271 fuse_lookup_init(req, dir, entry, &outarg);
246 request_send(fc, req); 272 request_send(fc, req);
247 err = req->out.h.error; 273 err = req->out.h.error;
@@ -253,7 +279,8 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
253 err = -EIO; 279 err = -EIO;
254 if (!err && outarg.nodeid) { 280 if (!err && outarg.nodeid) {
255 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, 281 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
256 &outarg.attr); 282 &outarg.attr, entry_attr_timeout(&outarg),
283 attr_version);
257 if (!inode) { 284 if (!inode) {
258 fuse_send_forget(fc, forget_req, outarg.nodeid, 1); 285 fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
259 return ERR_PTR(-ENOMEM); 286 return ERR_PTR(-ENOMEM);
@@ -276,7 +303,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
276 303
277 entry->d_op = &fuse_dentry_operations; 304 entry->d_op = &fuse_dentry_operations;
278 if (!err) 305 if (!err)
279 fuse_change_timeout(entry, &outarg); 306 fuse_change_entry_timeout(entry, &outarg);
280 else 307 else
281 fuse_invalidate_entry_cache(entry); 308 fuse_invalidate_entry_cache(entry);
282 return NULL; 309 return NULL;
@@ -335,6 +362,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
335 362
336 flags &= ~O_NOCTTY; 363 flags &= ~O_NOCTTY;
337 memset(&inarg, 0, sizeof(inarg)); 364 memset(&inarg, 0, sizeof(inarg));
365 memset(&outentry, 0, sizeof(outentry));
338 inarg.flags = flags; 366 inarg.flags = flags;
339 inarg.mode = mode; 367 inarg.mode = mode;
340 req->in.h.opcode = FUSE_CREATE; 368 req->in.h.opcode = FUSE_CREATE;
@@ -345,7 +373,10 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
345 req->in.args[1].size = entry->d_name.len + 1; 373 req->in.args[1].size = entry->d_name.len + 1;
346 req->in.args[1].value = entry->d_name.name; 374 req->in.args[1].value = entry->d_name.name;
347 req->out.numargs = 2; 375 req->out.numargs = 2;
348 req->out.args[0].size = sizeof(outentry); 376 if (fc->minor < 9)
377 req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
378 else
379 req->out.args[0].size = sizeof(outentry);
349 req->out.args[0].value = &outentry; 380 req->out.args[0].value = &outentry;
350 req->out.args[1].size = sizeof(outopen); 381 req->out.args[1].size = sizeof(outopen);
351 req->out.args[1].value = &outopen; 382 req->out.args[1].value = &outopen;
@@ -363,7 +394,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
363 394
364 fuse_put_request(fc, req); 395 fuse_put_request(fc, req);
365 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, 396 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
366 &outentry.attr); 397 &outentry.attr, entry_attr_timeout(&outentry), 0);
367 if (!inode) { 398 if (!inode) {
368 flags &= ~(O_CREAT | O_EXCL | O_TRUNC); 399 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
369 ff->fh = outopen.fh; 400 ff->fh = outopen.fh;
@@ -373,7 +404,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
373 } 404 }
374 fuse_put_request(fc, forget_req); 405 fuse_put_request(fc, forget_req);
375 d_instantiate(entry, inode); 406 d_instantiate(entry, inode);
376 fuse_change_timeout(entry, &outentry); 407 fuse_change_entry_timeout(entry, &outentry);
377 file = lookup_instantiate_filp(nd, entry, generic_file_open); 408 file = lookup_instantiate_filp(nd, entry, generic_file_open);
378 if (IS_ERR(file)) { 409 if (IS_ERR(file)) {
379 ff->fh = outopen.fh; 410 ff->fh = outopen.fh;
@@ -410,9 +441,13 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
410 return PTR_ERR(forget_req); 441 return PTR_ERR(forget_req);
411 } 442 }
412 443
444 memset(&outarg, 0, sizeof(outarg));
413 req->in.h.nodeid = get_node_id(dir); 445 req->in.h.nodeid = get_node_id(dir);
414 req->out.numargs = 1; 446 req->out.numargs = 1;
415 req->out.args[0].size = sizeof(outarg); 447 if (fc->minor < 9)
448 req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
449 else
450 req->out.args[0].size = sizeof(outarg);
416 req->out.args[0].value = &outarg; 451 req->out.args[0].value = &outarg;
417 request_send(fc, req); 452 request_send(fc, req);
418 err = req->out.h.error; 453 err = req->out.h.error;
@@ -428,7 +463,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
428 goto out_put_forget_req; 463 goto out_put_forget_req;
429 464
430 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, 465 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
431 &outarg.attr); 466 &outarg.attr, entry_attr_timeout(&outarg), 0);
432 if (!inode) { 467 if (!inode) {
433 fuse_send_forget(fc, forget_req, outarg.nodeid, 1); 468 fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
434 return -ENOMEM; 469 return -ENOMEM;
@@ -451,7 +486,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
451 } else 486 } else
452 d_instantiate(entry, inode); 487 d_instantiate(entry, inode);
453 488
454 fuse_change_timeout(entry, &outarg); 489 fuse_change_entry_timeout(entry, &outarg);
455 fuse_invalidate_attr(dir); 490 fuse_invalidate_attr(dir);
456 return 0; 491 return 0;
457 492
@@ -663,52 +698,84 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
663 return err; 698 return err;
664} 699}
665 700
666static int fuse_do_getattr(struct inode *inode) 701static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
702 struct kstat *stat)
703{
704 stat->dev = inode->i_sb->s_dev;
705 stat->ino = attr->ino;
706 stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
707 stat->nlink = attr->nlink;
708 stat->uid = attr->uid;
709 stat->gid = attr->gid;
710 stat->rdev = inode->i_rdev;
711 stat->atime.tv_sec = attr->atime;
712 stat->atime.tv_nsec = attr->atimensec;
713 stat->mtime.tv_sec = attr->mtime;
714 stat->mtime.tv_nsec = attr->mtimensec;
715 stat->ctime.tv_sec = attr->ctime;
716 stat->ctime.tv_nsec = attr->ctimensec;
717 stat->size = attr->size;
718 stat->blocks = attr->blocks;
719 stat->blksize = (1 << inode->i_blkbits);
720}
721
722static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
723 struct file *file)
667{ 724{
668 int err; 725 int err;
669 struct fuse_attr_out arg; 726 struct fuse_getattr_in inarg;
727 struct fuse_attr_out outarg;
670 struct fuse_conn *fc = get_fuse_conn(inode); 728 struct fuse_conn *fc = get_fuse_conn(inode);
671 struct fuse_req *req = fuse_get_req(fc); 729 struct fuse_req *req;
730 u64 attr_version;
731
732 req = fuse_get_req(fc);
672 if (IS_ERR(req)) 733 if (IS_ERR(req))
673 return PTR_ERR(req); 734 return PTR_ERR(req);
674 735
736 spin_lock(&fc->lock);
737 attr_version = fc->attr_version;
738 spin_unlock(&fc->lock);
739
740 memset(&inarg, 0, sizeof(inarg));
741 memset(&outarg, 0, sizeof(outarg));
742 /* Directories have separate file-handle space */
743 if (file && S_ISREG(inode->i_mode)) {
744 struct fuse_file *ff = file->private_data;
745
746 inarg.getattr_flags |= FUSE_GETATTR_FH;
747 inarg.fh = ff->fh;
748 }
675 req->in.h.opcode = FUSE_GETATTR; 749 req->in.h.opcode = FUSE_GETATTR;
676 req->in.h.nodeid = get_node_id(inode); 750 req->in.h.nodeid = get_node_id(inode);
751 req->in.numargs = 1;
752 req->in.args[0].size = sizeof(inarg);
753 req->in.args[0].value = &inarg;
677 req->out.numargs = 1; 754 req->out.numargs = 1;
678 req->out.args[0].size = sizeof(arg); 755 if (fc->minor < 9)
679 req->out.args[0].value = &arg; 756 req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
757 else
758 req->out.args[0].size = sizeof(outarg);
759 req->out.args[0].value = &outarg;
680 request_send(fc, req); 760 request_send(fc, req);
681 err = req->out.h.error; 761 err = req->out.h.error;
682 fuse_put_request(fc, req); 762 fuse_put_request(fc, req);
683 if (!err) { 763 if (!err) {
684 if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) { 764 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
685 make_bad_inode(inode); 765 make_bad_inode(inode);
686 err = -EIO; 766 err = -EIO;
687 } else { 767 } else {
688 struct fuse_inode *fi = get_fuse_inode(inode); 768 fuse_change_attributes(inode, &outarg.attr,
689 fuse_change_attributes(inode, &arg.attr); 769 attr_timeout(&outarg),
690 fi->i_time = time_to_jiffies(arg.attr_valid, 770 attr_version);
691 arg.attr_valid_nsec); 771 if (stat)
772 fuse_fillattr(inode, &outarg.attr, stat);
692 } 773 }
693 } 774 }
694 return err; 775 return err;
695} 776}
696 777
697/* 778/*
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 779 * Calling into a user-controlled filesystem gives the filesystem
713 * daemon ptrace-like capabilities over the requester process. This 780 * daemon ptrace-like capabilities over the requester process. This
714 * means, that the filesystem daemon is able to record the exact 781 * means, that the filesystem daemon is able to record the exact
@@ -721,7 +788,7 @@ static int fuse_refresh_attributes(struct inode *inode)
721 * for which the owner of the mount has ptrace privilege. This 788 * for which the owner of the mount has ptrace privilege. This
722 * excludes processes started by other users, suid or sgid processes. 789 * excludes processes started by other users, suid or sgid processes.
723 */ 790 */
724static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task) 791int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
725{ 792{
726 if (fc->flags & FUSE_ALLOW_OTHER) 793 if (fc->flags & FUSE_ALLOW_OTHER)
727 return 1; 794 return 1;
@@ -795,11 +862,14 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
795 */ 862 */
796 if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || 863 if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
797 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { 864 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
798 err = fuse_refresh_attributes(inode); 865 struct fuse_inode *fi = get_fuse_inode(inode);
799 if (err) 866 if (fi->i_time < get_jiffies_64()) {
800 return err; 867 err = fuse_do_getattr(inode, NULL, NULL);
868 if (err)
869 return err;
801 870
802 refreshed = true; 871 refreshed = true;
872 }
803 } 873 }
804 874
805 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { 875 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
@@ -809,7 +879,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
809 attributes. This is also needed, because the root 879 attributes. This is also needed, because the root
810 node will at first have no permissions */ 880 node will at first have no permissions */
811 if (err == -EACCES && !refreshed) { 881 if (err == -EACCES && !refreshed) {
812 err = fuse_do_getattr(inode); 882 err = fuse_do_getattr(inode, NULL, NULL);
813 if (!err) 883 if (!err)
814 err = generic_permission(inode, mask, NULL); 884 err = generic_permission(inode, mask, NULL);
815 } 885 }
@@ -825,7 +895,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
825 if (refreshed) 895 if (refreshed)
826 return -EACCES; 896 return -EACCES;
827 897
828 err = fuse_do_getattr(inode); 898 err = fuse_do_getattr(inode, NULL, NULL);
829 if (!err && !(inode->i_mode & S_IXUGO)) 899 if (!err && !(inode->i_mode & S_IXUGO))
830 return -EACCES; 900 return -EACCES;
831 } 901 }
@@ -962,6 +1032,20 @@ static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
962 return file ? fuse_fsync_common(file, de, datasync, 1) : 0; 1032 return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
963} 1033}
964 1034
1035static bool update_mtime(unsigned ivalid)
1036{
1037 /* Always update if mtime is explicitly set */
1038 if (ivalid & ATTR_MTIME_SET)
1039 return true;
1040
1041 /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
1042 if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
1043 return false;
1044
1045 /* In all other cases update */
1046 return true;
1047}
1048
965static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) 1049static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
966{ 1050{
967 unsigned ivalid = iattr->ia_valid; 1051 unsigned ivalid = iattr->ia_valid;
@@ -974,16 +1058,19 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
974 arg->valid |= FATTR_GID, arg->gid = iattr->ia_gid; 1058 arg->valid |= FATTR_GID, arg->gid = iattr->ia_gid;
975 if (ivalid & ATTR_SIZE) 1059 if (ivalid & ATTR_SIZE)
976 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size; 1060 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
977 /* You can only _set_ these together (they may change by themselves) */ 1061 if (ivalid & ATTR_ATIME) {
978 if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) { 1062 arg->valid |= FATTR_ATIME;
979 arg->valid |= FATTR_ATIME | FATTR_MTIME;
980 arg->atime = iattr->ia_atime.tv_sec; 1063 arg->atime = iattr->ia_atime.tv_sec;
981 arg->mtime = iattr->ia_mtime.tv_sec; 1064 arg->atimensec = iattr->ia_atime.tv_nsec;
1065 if (!(ivalid & ATTR_ATIME_SET))
1066 arg->valid |= FATTR_ATIME_NOW;
982 } 1067 }
983 if (ivalid & ATTR_FILE) { 1068 if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) {
984 struct fuse_file *ff = iattr->ia_file->private_data; 1069 arg->valid |= FATTR_MTIME;
985 arg->valid |= FATTR_FH; 1070 arg->mtime = iattr->ia_mtime.tv_sec;
986 arg->fh = ff->fh; 1071 arg->mtimensec = iattr->ia_mtime.tv_nsec;
1072 if (!(ivalid & ATTR_MTIME_SET))
1073 arg->valid |= FATTR_MTIME_NOW;
987 } 1074 }
988} 1075}
989 1076
@@ -995,22 +1082,28 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
995 * vmtruncate() doesn't allow for this case, so do the rlimit checking 1082 * vmtruncate() doesn't allow for this case, so do the rlimit checking
996 * and the actual truncation by hand. 1083 * and the actual truncation by hand.
997 */ 1084 */
998static int fuse_setattr(struct dentry *entry, struct iattr *attr) 1085static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
1086 struct file *file)
999{ 1087{
1000 struct inode *inode = entry->d_inode; 1088 struct inode *inode = entry->d_inode;
1001 struct fuse_conn *fc = get_fuse_conn(inode); 1089 struct fuse_conn *fc = get_fuse_conn(inode);
1002 struct fuse_inode *fi = get_fuse_inode(inode);
1003 struct fuse_req *req; 1090 struct fuse_req *req;
1004 struct fuse_setattr_in inarg; 1091 struct fuse_setattr_in inarg;
1005 struct fuse_attr_out outarg; 1092 struct fuse_attr_out outarg;
1006 int err; 1093 int err;
1007 1094
1095 if (!fuse_allow_task(fc, current))
1096 return -EACCES;
1097
1008 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { 1098 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
1009 err = inode_change_ok(inode, attr); 1099 err = inode_change_ok(inode, attr);
1010 if (err) 1100 if (err)
1011 return err; 1101 return err;
1012 } 1102 }
1013 1103
1104 if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc)
1105 return 0;
1106
1014 if (attr->ia_valid & ATTR_SIZE) { 1107 if (attr->ia_valid & ATTR_SIZE) {
1015 unsigned long limit; 1108 unsigned long limit;
1016 if (IS_SWAPFILE(inode)) 1109 if (IS_SWAPFILE(inode))
@@ -1027,14 +1120,28 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1027 return PTR_ERR(req); 1120 return PTR_ERR(req);
1028 1121
1029 memset(&inarg, 0, sizeof(inarg)); 1122 memset(&inarg, 0, sizeof(inarg));
1123 memset(&outarg, 0, sizeof(outarg));
1030 iattr_to_fattr(attr, &inarg); 1124 iattr_to_fattr(attr, &inarg);
1125 if (file) {
1126 struct fuse_file *ff = file->private_data;
1127 inarg.valid |= FATTR_FH;
1128 inarg.fh = ff->fh;
1129 }
1130 if (attr->ia_valid & ATTR_SIZE) {
1131 /* For mandatory locking in truncate */
1132 inarg.valid |= FATTR_LOCKOWNER;
1133 inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1134 }
1031 req->in.h.opcode = FUSE_SETATTR; 1135 req->in.h.opcode = FUSE_SETATTR;
1032 req->in.h.nodeid = get_node_id(inode); 1136 req->in.h.nodeid = get_node_id(inode);
1033 req->in.numargs = 1; 1137 req->in.numargs = 1;
1034 req->in.args[0].size = sizeof(inarg); 1138 req->in.args[0].size = sizeof(inarg);
1035 req->in.args[0].value = &inarg; 1139 req->in.args[0].value = &inarg;
1036 req->out.numargs = 1; 1140 req->out.numargs = 1;
1037 req->out.args[0].size = sizeof(outarg); 1141 if (fc->minor < 9)
1142 req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
1143 else
1144 req->out.args[0].size = sizeof(outarg);
1038 req->out.args[0].value = &outarg; 1145 req->out.args[0].value = &outarg;
1039 request_send(fc, req); 1146 request_send(fc, req);
1040 err = req->out.h.error; 1147 err = req->out.h.error;
@@ -1050,11 +1157,18 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1050 return -EIO; 1157 return -EIO;
1051 } 1158 }
1052 1159
1053 fuse_change_attributes(inode, &outarg.attr); 1160 fuse_change_attributes(inode, &outarg.attr, attr_timeout(&outarg), 0);
1054 fi->i_time = time_to_jiffies(outarg.attr_valid, outarg.attr_valid_nsec);
1055 return 0; 1161 return 0;
1056} 1162}
1057 1163
1164static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1165{
1166 if (attr->ia_valid & ATTR_FILE)
1167 return fuse_do_setattr(entry, attr, attr->ia_file);
1168 else
1169 return fuse_do_setattr(entry, attr, NULL);
1170}
1171
1058static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, 1172static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1059 struct kstat *stat) 1173 struct kstat *stat)
1060{ 1174{
@@ -1066,8 +1180,10 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1066 if (!fuse_allow_task(fc, current)) 1180 if (!fuse_allow_task(fc, current))
1067 return -EACCES; 1181 return -EACCES;
1068 1182
1069 err = fuse_refresh_attributes(inode); 1183 if (fi->i_time < get_jiffies_64())
1070 if (!err) { 1184 err = fuse_do_getattr(inode, stat, NULL);
1185 else {
1186 err = 0;
1071 generic_fillattr(inode, stat); 1187 generic_fillattr(inode, stat);
1072 stat->mode = fi->orig_i_mode; 1188 stat->mode = fi->orig_i_mode;
1073 } 1189 }
@@ -1172,6 +1288,9 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
1172 struct fuse_getxattr_out outarg; 1288 struct fuse_getxattr_out outarg;
1173 ssize_t ret; 1289 ssize_t ret;
1174 1290
1291 if (!fuse_allow_task(fc, current))
1292 return -EACCES;
1293
1175 if (fc->no_listxattr) 1294 if (fc->no_listxattr)
1176 return -EOPNOTSUPP; 1295 return -EOPNOTSUPP;
1177 1296