]>
Commit | Line | Data |
---|---|---|
d9b1f36d GKH |
1 | From a0822c55779d9319939eac69f00bb729ea9d23da Mon Sep 17 00:00:00 2001 |
2 | From: Ken Sumrall <ksumrall@android.com> | |
3 | Date: Wed, 24 Nov 2010 12:57:00 -0800 | |
4 | Subject: fuse: fix attributes after open(O_TRUNC) | |
5 | ||
6 | From: Ken Sumrall <ksumrall@android.com> | |
7 | ||
8 | commit a0822c55779d9319939eac69f00bb729ea9d23da upstream. | |
9 | ||
10 | The attribute cache for a file was not being cleared when a file is opened | |
11 | with O_TRUNC. | |
12 | ||
13 | If the filesystem's open operation truncates the file ("atomic_o_trunc" | |
14 | feature flag is set) then the kernel should invalidate the cached st_mtime | |
15 | and st_ctime attributes. | |
16 | ||
17 | Also i_size should be explicitly be set to zero as it is used sometimes | |
18 | without refreshing the cache. | |
19 | ||
20 | Signed-off-by: Ken Sumrall <ksumrall@android.com> | |
21 | Cc: Anfei <anfei.zhou@gmail.com> | |
22 | Cc: "Anand V. Avati" <avati@gluster.com> | |
23 | Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> | |
24 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | |
25 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
26 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
27 | ||
28 | --- | |
29 | fs/fuse/file.c | 10 ++++++++++ | |
30 | 1 file changed, 10 insertions(+) | |
31 | ||
32 | --- a/fs/fuse/file.c | |
33 | +++ b/fs/fuse/file.c | |
34 | @@ -134,6 +134,7 @@ EXPORT_SYMBOL_GPL(fuse_do_open); | |
35 | void fuse_finish_open(struct inode *inode, struct file *file) | |
36 | { | |
37 | struct fuse_file *ff = file->private_data; | |
38 | + struct fuse_conn *fc = get_fuse_conn(inode); | |
39 | ||
40 | if (ff->open_flags & FOPEN_DIRECT_IO) | |
41 | file->f_op = &fuse_direct_io_file_operations; | |
42 | @@ -141,6 +142,15 @@ void fuse_finish_open(struct inode *inod | |
43 | invalidate_inode_pages2(inode->i_mapping); | |
44 | if (ff->open_flags & FOPEN_NONSEEKABLE) | |
45 | nonseekable_open(inode, file); | |
46 | + if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC)) { | |
47 | + struct fuse_inode *fi = get_fuse_inode(inode); | |
48 | + | |
49 | + spin_lock(&fc->lock); | |
50 | + fi->attr_version = ++fc->attr_version; | |
51 | + i_size_write(inode, 0); | |
52 | + spin_unlock(&fc->lock); | |
53 | + fuse_invalidate_attr(inode); | |
54 | + } | |
55 | } | |
56 | ||
57 | int fuse_open_common(struct inode *inode, struct file *file, bool isdir) |