aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/dir.c
diff options
context:
space:
mode:
authorMaxim Patlasov <mpatlasov@parallels.com>2012-12-18 05:05:08 -0500
committerMiklos Szeredi <mszeredi@suse.cz>2013-04-18 04:55:24 -0400
commitefb9fa9e911b23c7ea5330215bda778a7c69dba8 (patch)
tree7af69df4b3f3c5b89dc0e245a974fec358f23028 /fs/fuse/dir.c
parent439ee5f0c5080d4fd15fda0c5bbee1fb3a57894e (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.c17
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 */
1565static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, 1565int 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
1672static int fuse_setattr(struct dentry *entry, struct iattr *attr) 1668static 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
1680static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, 1681static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,