diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-11-16 12:20:10 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-11-16 12:20:10 -0500 |
commit | 984573abf8d09bace3cf8cda224bacb75b4c61d2 (patch) | |
tree | 3f3ca88a40facc0552fc204a154c9a8f1fc4394b /fs | |
parent | 116fc01f2ed7578e70ea85c67f6507ae50a5932e (diff) | |
parent | 59c3b76cc61d1d676f965c192cc7969aa5cb2744 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse
Pull fuse fixes from Miklos Szeredi:
"A regression fix and bug fix bound for stable"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
fuse: fix fuse_write_end() if zero bytes were copied
fuse: fix root dentry initialization
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fuse/dir.c | 5 | ||||
-rw-r--r-- | fs/fuse/file.c | 6 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 1 | ||||
-rw-r--r-- | fs/fuse/inode.c | 3 |
4 files changed, 14 insertions, 1 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 6a4d0e5418a1..b3ebe512d64c 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -286,6 +286,11 @@ const struct dentry_operations fuse_dentry_operations = { | |||
286 | .d_release = fuse_dentry_release, | 286 | .d_release = fuse_dentry_release, |
287 | }; | 287 | }; |
288 | 288 | ||
289 | const struct dentry_operations fuse_root_dentry_operations = { | ||
290 | .d_init = fuse_dentry_init, | ||
291 | .d_release = fuse_dentry_release, | ||
292 | }; | ||
293 | |||
289 | int fuse_valid_type(int m) | 294 | int fuse_valid_type(int m) |
290 | { | 295 | { |
291 | return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) || | 296 | return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) || |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index abc66a6237fd..2401c5dabb2a 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -1985,6 +1985,10 @@ static int fuse_write_end(struct file *file, struct address_space *mapping, | |||
1985 | { | 1985 | { |
1986 | struct inode *inode = page->mapping->host; | 1986 | struct inode *inode = page->mapping->host; |
1987 | 1987 | ||
1988 | /* Haven't copied anything? Skip zeroing, size extending, dirtying. */ | ||
1989 | if (!copied) | ||
1990 | goto unlock; | ||
1991 | |||
1988 | if (!PageUptodate(page)) { | 1992 | if (!PageUptodate(page)) { |
1989 | /* Zero any unwritten bytes at the end of the page */ | 1993 | /* Zero any unwritten bytes at the end of the page */ |
1990 | size_t endoff = (pos + copied) & ~PAGE_MASK; | 1994 | size_t endoff = (pos + copied) & ~PAGE_MASK; |
@@ -1995,6 +1999,8 @@ static int fuse_write_end(struct file *file, struct address_space *mapping, | |||
1995 | 1999 | ||
1996 | fuse_write_update_size(inode, pos + copied); | 2000 | fuse_write_update_size(inode, pos + copied); |
1997 | set_page_dirty(page); | 2001 | set_page_dirty(page); |
2002 | |||
2003 | unlock: | ||
1998 | unlock_page(page); | 2004 | unlock_page(page); |
1999 | put_page(page); | 2005 | put_page(page); |
2000 | 2006 | ||
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 0dfbb136e59a..91307940c8ac 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -692,6 +692,7 @@ static inline u64 get_node_id(struct inode *inode) | |||
692 | extern const struct file_operations fuse_dev_operations; | 692 | extern const struct file_operations fuse_dev_operations; |
693 | 693 | ||
694 | extern const struct dentry_operations fuse_dentry_operations; | 694 | extern const struct dentry_operations fuse_dentry_operations; |
695 | extern const struct dentry_operations fuse_root_dentry_operations; | ||
695 | 696 | ||
696 | /** | 697 | /** |
697 | * Inode to nodeid comparison. | 698 | * Inode to nodeid comparison. |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 17141099f2e7..6fe6a88ecb4a 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -1131,10 +1131,11 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
1131 | 1131 | ||
1132 | err = -ENOMEM; | 1132 | err = -ENOMEM; |
1133 | root = fuse_get_root_inode(sb, d.rootmode); | 1133 | root = fuse_get_root_inode(sb, d.rootmode); |
1134 | sb->s_d_op = &fuse_root_dentry_operations; | ||
1134 | root_dentry = d_make_root(root); | 1135 | root_dentry = d_make_root(root); |
1135 | if (!root_dentry) | 1136 | if (!root_dentry) |
1136 | goto err_dev_free; | 1137 | goto err_dev_free; |
1137 | /* only now - we want root dentry with NULL ->d_op */ | 1138 | /* Root dentry doesn't have .d_revalidate */ |
1138 | sb->s_d_op = &fuse_dentry_operations; | 1139 | sb->s_d_op = &fuse_dentry_operations; |
1139 | 1140 | ||
1140 | init_req = fuse_request_alloc(0); | 1141 | init_req = fuse_request_alloc(0); |