diff options
Diffstat (limited to 'fs/sysv')
-rw-r--r-- | fs/sysv/file.c | 5 | ||||
-rw-r--r-- | fs/sysv/itree.c | 17 |
2 files changed, 15 insertions, 7 deletions
diff --git a/fs/sysv/file.c b/fs/sysv/file.c index 0a65939508e9..9d4dc6831792 100644 --- a/fs/sysv/file.c +++ b/fs/sysv/file.c | |||
@@ -41,9 +41,11 @@ static int sysv_setattr(struct dentry *dentry, struct iattr *attr) | |||
41 | 41 | ||
42 | if ((attr->ia_valid & ATTR_SIZE) && | 42 | if ((attr->ia_valid & ATTR_SIZE) && |
43 | attr->ia_size != i_size_read(inode)) { | 43 | attr->ia_size != i_size_read(inode)) { |
44 | error = vmtruncate(inode, attr->ia_size); | 44 | error = inode_newsize_ok(inode, attr->ia_size); |
45 | if (error) | 45 | if (error) |
46 | return error; | 46 | return error; |
47 | truncate_setsize(inode, attr->ia_size); | ||
48 | sysv_truncate(inode); | ||
47 | } | 49 | } |
48 | 50 | ||
49 | setattr_copy(inode, attr); | 51 | setattr_copy(inode, attr); |
@@ -52,7 +54,6 @@ static int sysv_setattr(struct dentry *dentry, struct iattr *attr) | |||
52 | } | 54 | } |
53 | 55 | ||
54 | const struct inode_operations sysv_file_inode_operations = { | 56 | const struct inode_operations sysv_file_inode_operations = { |
55 | .truncate = sysv_truncate, | ||
56 | .setattr = sysv_setattr, | 57 | .setattr = sysv_setattr, |
57 | .getattr = sysv_getattr, | 58 | .getattr = sysv_getattr, |
58 | }; | 59 | }; |
diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c index 90b54b438789..c1a591a4725b 100644 --- a/fs/sysv/itree.c +++ b/fs/sysv/itree.c | |||
@@ -464,6 +464,16 @@ int sysv_prepare_chunk(struct page *page, loff_t pos, unsigned len) | |||
464 | return __block_write_begin(page, pos, len, get_block); | 464 | return __block_write_begin(page, pos, len, get_block); |
465 | } | 465 | } |
466 | 466 | ||
467 | static void sysv_write_failed(struct address_space *mapping, loff_t to) | ||
468 | { | ||
469 | struct inode *inode = mapping->host; | ||
470 | |||
471 | if (to > inode->i_size) { | ||
472 | truncate_pagecache(inode, to, inode->i_size); | ||
473 | sysv_truncate(inode); | ||
474 | } | ||
475 | } | ||
476 | |||
467 | static int sysv_write_begin(struct file *file, struct address_space *mapping, | 477 | static int sysv_write_begin(struct file *file, struct address_space *mapping, |
468 | loff_t pos, unsigned len, unsigned flags, | 478 | loff_t pos, unsigned len, unsigned flags, |
469 | struct page **pagep, void **fsdata) | 479 | struct page **pagep, void **fsdata) |
@@ -471,11 +481,8 @@ static int sysv_write_begin(struct file *file, struct address_space *mapping, | |||
471 | int ret; | 481 | int ret; |
472 | 482 | ||
473 | ret = block_write_begin(mapping, pos, len, flags, pagep, get_block); | 483 | ret = block_write_begin(mapping, pos, len, flags, pagep, get_block); |
474 | if (unlikely(ret)) { | 484 | if (unlikely(ret)) |
475 | loff_t isize = mapping->host->i_size; | 485 | sysv_write_failed(mapping, pos + len); |
476 | if (pos + len > isize) | ||
477 | vmtruncate(mapping->host, isize); | ||
478 | } | ||
479 | 486 | ||
480 | return ret; | 487 | return ret; |
481 | } | 488 | } |