diff options
author | Maxim Patlasov <mpatlasov@parallels.com> | 2012-12-18 05:05:08 -0500 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2013-04-18 04:55:24 -0400 |
commit | efb9fa9e911b23c7ea5330215bda778a7c69dba8 (patch) | |
tree | 7af69df4b3f3c5b89dc0e245a974fec358f23028 /fs/fuse/dir.c | |
parent | 439ee5f0c5080d4fd15fda0c5bbee1fb3a57894e (diff) |
fuse: truncate file if async dio failed
The patch improves error handling in fuse_direct_IO(): if we successfully
submitted several fuse requests on behalf of synchronous direct write
extending file and some of them failed, let's try to do our best to clean-up.
Changed in v2: reuse fuse_do_setattr(). Thanks to Brian for suggestion.
Signed-off-by: Maxim Patlasov <mpatlasov@parallels.com>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Diffstat (limited to 'fs/fuse/dir.c')
-rw-r--r-- | fs/fuse/dir.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index ff15522481d4..254df56b847b 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -1562,10 +1562,9 @@ void fuse_release_nowrite(struct inode *inode) | |||
1562 | * vmtruncate() doesn't allow for this case, so do the rlimit checking | 1562 | * vmtruncate() doesn't allow for this case, so do the rlimit checking |
1563 | * and the actual truncation by hand. | 1563 | * and the actual truncation by hand. |
1564 | */ | 1564 | */ |
1565 | static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, | 1565 | int fuse_do_setattr(struct inode *inode, struct iattr *attr, |
1566 | struct file *file) | 1566 | struct file *file) |
1567 | { | 1567 | { |
1568 | struct inode *inode = entry->d_inode; | ||
1569 | struct fuse_conn *fc = get_fuse_conn(inode); | 1568 | struct fuse_conn *fc = get_fuse_conn(inode); |
1570 | struct fuse_req *req; | 1569 | struct fuse_req *req; |
1571 | struct fuse_setattr_in inarg; | 1570 | struct fuse_setattr_in inarg; |
@@ -1574,9 +1573,6 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, | |||
1574 | loff_t oldsize; | 1573 | loff_t oldsize; |
1575 | int err; | 1574 | int err; |
1576 | 1575 | ||
1577 | if (!fuse_allow_current_process(fc)) | ||
1578 | return -EACCES; | ||
1579 | |||
1580 | if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS)) | 1576 | if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS)) |
1581 | attr->ia_valid |= ATTR_FORCE; | 1577 | attr->ia_valid |= ATTR_FORCE; |
1582 | 1578 | ||
@@ -1671,10 +1667,15 @@ error: | |||
1671 | 1667 | ||
1672 | static int fuse_setattr(struct dentry *entry, struct iattr *attr) | 1668 | static int fuse_setattr(struct dentry *entry, struct iattr *attr) |
1673 | { | 1669 | { |
1670 | struct inode *inode = entry->d_inode; | ||
1671 | |||
1672 | if (!fuse_allow_current_process(get_fuse_conn(inode))) | ||
1673 | return -EACCES; | ||
1674 | |||
1674 | if (attr->ia_valid & ATTR_FILE) | 1675 | if (attr->ia_valid & ATTR_FILE) |
1675 | return fuse_do_setattr(entry, attr, attr->ia_file); | 1676 | return fuse_do_setattr(inode, attr, attr->ia_file); |
1676 | else | 1677 | else |
1677 | return fuse_do_setattr(entry, attr, NULL); | 1678 | return fuse_do_setattr(inode, attr, NULL); |
1678 | } | 1679 | } |
1679 | 1680 | ||
1680 | static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, | 1681 | static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, |