aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r--fs/fuse/inode.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 00bb5a255ded..2167fc4fcab8 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -117,12 +117,22 @@ static void fuse_truncate(struct address_space *mapping, loff_t offset)
117 unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); 117 unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
118} 118}
119 119
120void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr) 120
121void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
122 u64 attr_valid, u64 attr_version)
121{ 123{
122 struct fuse_conn *fc = get_fuse_conn(inode); 124 struct fuse_conn *fc = get_fuse_conn(inode);
123 struct fuse_inode *fi = get_fuse_inode(inode); 125 struct fuse_inode *fi = get_fuse_inode(inode);
124 loff_t oldsize; 126 loff_t oldsize;
125 127
128 spin_lock(&fc->lock);
129 if (attr_version != 0 && fi->attr_version > attr_version) {
130 spin_unlock(&fc->lock);
131 return;
132 }
133 fi->attr_version = ++fc->attr_version;
134 fi->i_time = attr_valid;
135
126 inode->i_ino = attr->ino; 136 inode->i_ino = attr->ino;
127 inode->i_mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); 137 inode->i_mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
128 inode->i_nlink = attr->nlink; 138 inode->i_nlink = attr->nlink;
@@ -145,7 +155,6 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
145 if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS)) 155 if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
146 inode->i_mode &= ~S_ISVTX; 156 inode->i_mode &= ~S_ISVTX;
147 157
148 spin_lock(&fc->lock);
149 oldsize = inode->i_size; 158 oldsize = inode->i_size;
150 i_size_write(inode, attr->size); 159 i_size_write(inode, attr->size);
151 spin_unlock(&fc->lock); 160 spin_unlock(&fc->lock);
@@ -194,7 +203,8 @@ static int fuse_inode_set(struct inode *inode, void *_nodeidp)
194} 203}
195 204
196struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, 205struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
197 int generation, struct fuse_attr *attr) 206 int generation, struct fuse_attr *attr,
207 u64 attr_valid, u64 attr_version)
198{ 208{
199 struct inode *inode; 209 struct inode *inode;
200 struct fuse_inode *fi; 210 struct fuse_inode *fi;
@@ -222,7 +232,8 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
222 spin_lock(&fc->lock); 232 spin_lock(&fc->lock);
223 fi->nlookup ++; 233 fi->nlookup ++;
224 spin_unlock(&fc->lock); 234 spin_unlock(&fc->lock);
225 fuse_change_attributes(inode, attr); 235 fuse_change_attributes(inode, attr, attr_valid, attr_version);
236
226 return inode; 237 return inode;
227} 238}
228 239
@@ -457,6 +468,7 @@ static struct fuse_conn *new_conn(void)
457 } 468 }
458 fc->reqctr = 0; 469 fc->reqctr = 0;
459 fc->blocked = 1; 470 fc->blocked = 1;
471 fc->attr_version = 1;
460 get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); 472 get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
461 } 473 }
462out: 474out:
@@ -488,7 +500,7 @@ static struct inode *get_root_inode(struct super_block *sb, unsigned mode)
488 attr.mode = mode; 500 attr.mode = mode;
489 attr.ino = FUSE_ROOT_ID; 501 attr.ino = FUSE_ROOT_ID;
490 attr.nlink = 1; 502 attr.nlink = 1;
491 return fuse_iget(sb, 1, 0, &attr); 503 return fuse_iget(sb, 1, 0, &attr, 0, 0);
492} 504}
493 505
494static const struct super_operations fuse_super_operations = { 506static const struct super_operations fuse_super_operations = {