Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fuse: invalidate inode mapping if mtime changes

We currently invalidate the inode address space mapping
if the file size changes unexpectedly. In the case of a
fuse network filesystem, a portion of a file could be
overwritten remotely without changing the file size.
Compare the old mtime as well to detect this condition
and invalidate the mapping if the file has been updated.

The original logic (to ignore changes in mtime) is
preserved unless the client specifies FUSE_AUTO_INVAL_DATA
on init.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>

authored by

Brian Foster and committed by
Miklos Szeredi
eed2179e 72d0d248

+24 -3
+24 -3
fs/fuse/inode.c
··· 197 197 struct fuse_conn *fc = get_fuse_conn(inode); 198 198 struct fuse_inode *fi = get_fuse_inode(inode); 199 199 loff_t oldsize; 200 + struct timespec old_mtime; 200 201 201 202 spin_lock(&fc->lock); 202 203 if (attr_version != 0 && fi->attr_version > attr_version) { ··· 205 204 return; 206 205 } 207 206 207 + old_mtime = inode->i_mtime; 208 208 fuse_change_attributes_common(inode, attr, attr_valid); 209 209 210 210 oldsize = inode->i_size; 211 211 i_size_write(inode, attr->size); 212 212 spin_unlock(&fc->lock); 213 213 214 - if (S_ISREG(inode->i_mode) && oldsize != attr->size) { 215 - truncate_pagecache(inode, oldsize, attr->size); 216 - invalidate_inode_pages2(inode->i_mapping); 214 + if (S_ISREG(inode->i_mode)) { 215 + bool inval = false; 216 + 217 + if (oldsize != attr->size) { 218 + truncate_pagecache(inode, oldsize, attr->size); 219 + inval = true; 220 + } else if (fc->auto_inval_data) { 221 + struct timespec new_mtime = { 222 + .tv_sec = attr->mtime, 223 + .tv_nsec = attr->mtimensec, 224 + }; 225 + 226 + /* 227 + * Auto inval mode also checks and invalidates if mtime 228 + * has changed. 229 + */ 230 + if (!timespec_equal(&old_mtime, &new_mtime)) 231 + inval = true; 232 + } 233 + 234 + if (inval) 235 + invalidate_inode_pages2(inode->i_mapping); 217 236 } 218 237 } 219 238