aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/buffer.c10
-rw-r--r--fs/cifs/inode.c53
-rw-r--r--fs/fuse/dir.c14
-rw-r--r--fs/fuse/fuse_i.h2
-rw-r--r--fs/fuse/inode.c11
-rw-r--r--fs/nfs/inode.c54
-rw-r--r--fs/ramfs/file-nommu.c18
7 files changed, 35 insertions, 127 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 209f7f15f5f8..24afd7422ae8 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2239,16 +2239,10 @@ int generic_cont_expand_simple(struct inode *inode, loff_t size)
2239 struct address_space *mapping = inode->i_mapping; 2239 struct address_space *mapping = inode->i_mapping;
2240 struct page *page; 2240 struct page *page;
2241 void *fsdata; 2241 void *fsdata;
2242 unsigned long limit;
2243 int err; 2242 int err;
2244 2243
2245 err = -EFBIG; 2244 err = inode_newsize_ok(inode, size);
2246 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; 2245 if (err)
2247 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
2248 send_sig(SIGXFSZ, current, 0);
2249 goto out;
2250 }
2251 if (size > inode->i_sb->s_maxbytes)
2252 goto out; 2246 goto out;
2253 2247
2254 err = pagecache_write_begin(NULL, mapping, size, 0, 2248 err = pagecache_write_begin(NULL, mapping, size, 0,
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 1f09c7619319..5e2492535daa 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1557,57 +1557,24 @@ static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1557 1557
1558static int cifs_vmtruncate(struct inode *inode, loff_t offset) 1558static int cifs_vmtruncate(struct inode *inode, loff_t offset)
1559{ 1559{
1560 struct address_space *mapping = inode->i_mapping; 1560 loff_t oldsize;
1561 unsigned long limit; 1561 int err;
1562 1562
1563 spin_lock(&inode->i_lock); 1563 spin_lock(&inode->i_lock);
1564 if (inode->i_size < offset) 1564 err = inode_newsize_ok(inode, offset);
1565 goto do_expand; 1565 if (err) {
1566 /*
1567 * truncation of in-use swapfiles is disallowed - it would cause
1568 * subsequent swapout to scribble on the now-freed blocks.
1569 */
1570 if (IS_SWAPFILE(inode)) {
1571 spin_unlock(&inode->i_lock);
1572 goto out_busy;
1573 }
1574 i_size_write(inode, offset);
1575 spin_unlock(&inode->i_lock);
1576 /*
1577 * unmap_mapping_range is called twice, first simply for efficiency
1578 * so that truncate_inode_pages does fewer single-page unmaps. However
1579 * after this first call, and before truncate_inode_pages finishes,
1580 * it is possible for private pages to be COWed, which remain after
1581 * truncate_inode_pages finishes, hence the second unmap_mapping_range
1582 * call must be made for correctness.
1583 */
1584 unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1585 truncate_inode_pages(mapping, offset);
1586 unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1587 goto out_truncate;
1588
1589do_expand:
1590 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
1591 if (limit != RLIM_INFINITY && offset > limit) {
1592 spin_unlock(&inode->i_lock); 1566 spin_unlock(&inode->i_lock);
1593 goto out_sig; 1567 goto out;
1594 }
1595 if (offset > inode->i_sb->s_maxbytes) {
1596 spin_unlock(&inode->i_lock);
1597 goto out_big;
1598 } 1568 }
1569
1570 oldsize = inode->i_size;
1599 i_size_write(inode, offset); 1571 i_size_write(inode, offset);
1600 spin_unlock(&inode->i_lock); 1572 spin_unlock(&inode->i_lock);
1601out_truncate: 1573 truncate_pagecache(inode, oldsize, offset);
1602 if (inode->i_op->truncate) 1574 if (inode->i_op->truncate)
1603 inode->i_op->truncate(inode); 1575 inode->i_op->truncate(inode);
1604 return 0; 1576out:
1605out_sig: 1577 return err;
1606 send_sig(SIGXFSZ, current, 0);
1607out_big:
1608 return -EFBIG;
1609out_busy:
1610 return -ETXTBSY;
1611} 1578}
1612 1579
1613static int 1580static int
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index e703654e7f40..992f6c9410bb 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1276,14 +1276,9 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
1276 return 0; 1276 return 0;
1277 1277
1278 if (attr->ia_valid & ATTR_SIZE) { 1278 if (attr->ia_valid & ATTR_SIZE) {
1279 unsigned long limit; 1279 err = inode_newsize_ok(inode, attr->ia_size);
1280 if (IS_SWAPFILE(inode)) 1280 if (err)
1281 return -ETXTBSY; 1281 return err;
1282 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
1283 if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {
1284 send_sig(SIGXFSZ, current, 0);
1285 return -EFBIG;
1286 }
1287 is_truncate = true; 1282 is_truncate = true;
1288 } 1283 }
1289 1284
@@ -1350,8 +1345,7 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
1350 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock. 1345 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
1351 */ 1346 */
1352 if (S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) { 1347 if (S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
1353 if (outarg.attr.size < oldsize) 1348 truncate_pagecache(inode, oldsize, outarg.attr.size);
1354 fuse_truncate(inode->i_mapping, outarg.attr.size);
1355 invalidate_inode_pages2(inode->i_mapping); 1349 invalidate_inode_pages2(inode->i_mapping);
1356 } 1350 }
1357 1351
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index fc9c79feb5f7..01cc462ff45d 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -606,8 +606,6 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
606void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, 606void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
607 u64 attr_valid); 607 u64 attr_valid);
608 608
609void fuse_truncate(struct address_space *mapping, loff_t offset);
610
611/** 609/**
612 * Initialize the client device 610 * Initialize the client device
613 */ 611 */
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 6da947daabda..1a822ce2b24b 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -140,14 +140,6 @@ static int fuse_remount_fs(struct super_block *sb, int *flags, char *data)
140 return 0; 140 return 0;
141} 141}
142 142
143void fuse_truncate(struct address_space *mapping, loff_t offset)
144{
145 /* See vmtruncate() */
146 unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
147 truncate_inode_pages(mapping, offset);
148 unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
149}
150
151void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, 143void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
152 u64 attr_valid) 144 u64 attr_valid)
153{ 145{
@@ -205,8 +197,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
205 spin_unlock(&fc->lock); 197 spin_unlock(&fc->lock);
206 198
207 if (S_ISREG(inode->i_mode) && oldsize != attr->size) { 199 if (S_ISREG(inode->i_mode) && oldsize != attr->size) {
208 if (attr->size < oldsize) 200 truncate_pagecache(inode, oldsize, attr->size);
209 fuse_truncate(inode->i_mapping, attr->size);
210 invalidate_inode_pages2(inode->i_mapping); 201 invalidate_inode_pages2(inode->i_mapping);
211 } 202 }
212} 203}
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 060022b4651c..faa091865ad0 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -458,49 +458,21 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
458 */ 458 */
459static int nfs_vmtruncate(struct inode * inode, loff_t offset) 459static int nfs_vmtruncate(struct inode * inode, loff_t offset)
460{ 460{
461 if (i_size_read(inode) < offset) { 461 loff_t oldsize;
462 unsigned long limit; 462 int err;
463
464 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
465 if (limit != RLIM_INFINITY && offset > limit)
466 goto out_sig;
467 if (offset > inode->i_sb->s_maxbytes)
468 goto out_big;
469 spin_lock(&inode->i_lock);
470 i_size_write(inode, offset);
471 spin_unlock(&inode->i_lock);
472 } else {
473 struct address_space *mapping = inode->i_mapping;
474 463
475 /* 464 err = inode_newsize_ok(inode, offset);
476 * truncation of in-use swapfiles is disallowed - it would 465 if (err)
477 * cause subsequent swapout to scribble on the now-freed 466 goto out;
478 * blocks.
479 */
480 if (IS_SWAPFILE(inode))
481 return -ETXTBSY;
482 spin_lock(&inode->i_lock);
483 i_size_write(inode, offset);
484 spin_unlock(&inode->i_lock);
485 467
486 /* 468 spin_lock(&inode->i_lock);
487 * unmap_mapping_range is called twice, first simply for 469 oldsize = inode->i_size;
488 * efficiency so that truncate_inode_pages does fewer 470 i_size_write(inode, offset);
489 * single-page unmaps. However after this first call, and 471 spin_unlock(&inode->i_lock);
490 * before truncate_inode_pages finishes, it is possible for 472
491 * private pages to be COWed, which remain after 473 truncate_pagecache(inode, oldsize, offset);
492 * truncate_inode_pages finishes, hence the second 474out:
493 * unmap_mapping_range call must be made for correctness. 475 return err;
494 */
495 unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
496 truncate_inode_pages(mapping, offset);
497 unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
498 }
499 return 0;
500out_sig:
501 send_sig(SIGXFSZ, current, 0);
502out_big:
503 return -EFBIG;
504} 476}
505 477
506/** 478/**
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index 11f0c06316de..32fae4040ebf 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -69,14 +69,11 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
69 /* make various checks */ 69 /* make various checks */
70 order = get_order(newsize); 70 order = get_order(newsize);
71 if (unlikely(order >= MAX_ORDER)) 71 if (unlikely(order >= MAX_ORDER))
72 goto too_big; 72 return -EFBIG;
73 73
74 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; 74 ret = inode_newsize_ok(inode, newsize);
75 if (limit != RLIM_INFINITY && newsize > limit) 75 if (ret)
76 goto fsize_exceeded; 76 return ret;
77
78 if (newsize > inode->i_sb->s_maxbytes)
79 goto too_big;
80 77
81 i_size_write(inode, newsize); 78 i_size_write(inode, newsize);
82 79
@@ -118,12 +115,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
118 115
119 return 0; 116 return 0;
120 117
121 fsize_exceeded: 118add_error:
122 send_sig(SIGXFSZ, current, 0);
123 too_big:
124 return -EFBIG;
125
126 add_error:
127 while (loop < npages) 119 while (loop < npages)
128 __free_page(pages + loop++); 120 __free_page(pages + loop++);
129 return ret; 121 return ret;