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.c81
1 files changed, 51 insertions, 30 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 3763757f9fe7..80d2f5292cf9 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -132,6 +132,21 @@ static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
132 req->out.args[0].value = outarg; 132 req->out.args[0].value = outarg;
133} 133}
134 134
135static u64 fuse_get_attr_version(struct fuse_conn *fc)
136{
137 u64 curr_version;
138
139 /*
140 * The spin lock isn't actually needed on 64bit archs, but we
141 * don't yet care too much about such optimizations.
142 */
143 spin_lock(&fc->lock);
144 curr_version = fc->attr_version;
145 spin_unlock(&fc->lock);
146
147 return curr_version;
148}
149
135/* 150/*
136 * Check whether the dentry is still valid 151 * Check whether the dentry is still valid
137 * 152 *
@@ -171,9 +186,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
171 return 0; 186 return 0;
172 } 187 }
173 188
174 spin_lock(&fc->lock); 189 attr_version = fuse_get_attr_version(fc);
175 attr_version = fc->attr_version;
176 spin_unlock(&fc->lock);
177 190
178 parent = dget_parent(entry); 191 parent = dget_parent(entry);
179 fuse_lookup_init(req, parent->d_inode, entry, &outarg); 192 fuse_lookup_init(req, parent->d_inode, entry, &outarg);
@@ -264,9 +277,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
264 return ERR_PTR(PTR_ERR(forget_req)); 277 return ERR_PTR(PTR_ERR(forget_req));
265 } 278 }
266 279
267 spin_lock(&fc->lock); 280 attr_version = fuse_get_attr_version(fc);
268 attr_version = fc->attr_version;
269 spin_unlock(&fc->lock);
270 281
271 fuse_lookup_init(req, dir, entry, &outarg); 282 fuse_lookup_init(req, dir, entry, &outarg);
272 request_send(fc, req); 283 request_send(fc, req);
@@ -646,6 +657,9 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent,
646 err = req->out.h.error; 657 err = req->out.h.error;
647 fuse_put_request(fc, req); 658 fuse_put_request(fc, req);
648 if (!err) { 659 if (!err) {
660 /* ctime changes */
661 fuse_invalidate_attr(oldent->d_inode);
662
649 fuse_invalidate_attr(olddir); 663 fuse_invalidate_attr(olddir);
650 if (olddir != newdir) 664 if (olddir != newdir)
651 fuse_invalidate_attr(newdir); 665 fuse_invalidate_attr(newdir);
@@ -733,9 +747,7 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
733 if (IS_ERR(req)) 747 if (IS_ERR(req))
734 return PTR_ERR(req); 748 return PTR_ERR(req);
735 749
736 spin_lock(&fc->lock); 750 attr_version = fuse_get_attr_version(fc);
737 attr_version = fc->attr_version;
738 spin_unlock(&fc->lock);
739 751
740 memset(&inarg, 0, sizeof(inarg)); 752 memset(&inarg, 0, sizeof(inarg));
741 memset(&outarg, 0, sizeof(outarg)); 753 memset(&outarg, 0, sizeof(outarg));
@@ -775,6 +787,31 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
775 return err; 787 return err;
776} 788}
777 789
790int fuse_update_attributes(struct inode *inode, struct kstat *stat,
791 struct file *file, bool *refreshed)
792{
793 struct fuse_inode *fi = get_fuse_inode(inode);
794 int err;
795 bool r;
796
797 if (fi->i_time < get_jiffies_64()) {
798 r = true;
799 err = fuse_do_getattr(inode, stat, file);
800 } else {
801 r = false;
802 err = 0;
803 if (stat) {
804 generic_fillattr(inode, stat);
805 stat->mode = fi->orig_i_mode;
806 }
807 }
808
809 if (refreshed != NULL)
810 *refreshed = r;
811
812 return err;
813}
814
778/* 815/*
779 * Calling into a user-controlled filesystem gives the filesystem 816 * Calling into a user-controlled filesystem gives the filesystem
780 * daemon ptrace-like capabilities over the requester process. This 817 * daemon ptrace-like capabilities over the requester process. This
@@ -862,14 +899,9 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
862 */ 899 */
863 if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || 900 if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
864 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { 901 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
865 struct fuse_inode *fi = get_fuse_inode(inode); 902 err = fuse_update_attributes(inode, NULL, NULL, &refreshed);
866 if (fi->i_time < get_jiffies_64()) { 903 if (err)
867 err = fuse_do_getattr(inode, NULL, NULL); 904 return err;
868 if (err)
869 return err;
870
871 refreshed = true;
872 }
873 } 905 }
874 906
875 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { 907 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
@@ -935,7 +967,6 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
935 struct page *page; 967 struct page *page;
936 struct inode *inode = file->f_path.dentry->d_inode; 968 struct inode *inode = file->f_path.dentry->d_inode;
937 struct fuse_conn *fc = get_fuse_conn(inode); 969 struct fuse_conn *fc = get_fuse_conn(inode);
938 struct fuse_file *ff = file->private_data;
939 struct fuse_req *req; 970 struct fuse_req *req;
940 971
941 if (is_bad_inode(inode)) 972 if (is_bad_inode(inode))
@@ -952,7 +983,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
952 } 983 }
953 req->num_pages = 1; 984 req->num_pages = 1;
954 req->pages[0] = page; 985 req->pages[0] = page;
955 fuse_read_fill(req, ff, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR); 986 fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR);
956 request_send(fc, req); 987 request_send(fc, req);
957 nbytes = req->out.args[0].size; 988 nbytes = req->out.args[0].size;
958 err = req->out.h.error; 989 err = req->out.h.error;
@@ -1173,22 +1204,12 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1173 struct kstat *stat) 1204 struct kstat *stat)
1174{ 1205{
1175 struct inode *inode = entry->d_inode; 1206 struct inode *inode = entry->d_inode;
1176 struct fuse_inode *fi = get_fuse_inode(inode);
1177 struct fuse_conn *fc = get_fuse_conn(inode); 1207 struct fuse_conn *fc = get_fuse_conn(inode);
1178 int err;
1179 1208
1180 if (!fuse_allow_task(fc, current)) 1209 if (!fuse_allow_task(fc, current))
1181 return -EACCES; 1210 return -EACCES;
1182 1211
1183 if (fi->i_time < get_jiffies_64()) 1212 return fuse_update_attributes(inode, stat, NULL, NULL);
1184 err = fuse_do_getattr(inode, stat, NULL);
1185 else {
1186 err = 0;
1187 generic_fillattr(inode, stat);
1188 stat->mode = fi->orig_i_mode;
1189 }
1190
1191 return err;
1192} 1213}
1193 1214
1194static int fuse_setxattr(struct dentry *entry, const char *name, 1215static int fuse_setxattr(struct dentry *entry, const char *name,