diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/buffer.c | 10 | ||||
-rw-r--r-- | fs/cifs/inode.c | 53 | ||||
-rw-r--r-- | fs/fuse/dir.c | 14 | ||||
-rw-r--r-- | fs/fuse/fuse_i.h | 2 | ||||
-rw-r--r-- | fs/fuse/inode.c | 11 | ||||
-rw-r--r-- | fs/nfs/inode.c | 54 | ||||
-rw-r--r-- | fs/ramfs/file-nommu.c | 18 |
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 | ||
1558 | static int cifs_vmtruncate(struct inode *inode, loff_t offset) | 1558 | static 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 | |||
1589 | do_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); |
1601 | out_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; | 1576 | out: |
1605 | out_sig: | 1577 | return err; |
1606 | send_sig(SIGXFSZ, current, 0); | ||
1607 | out_big: | ||
1608 | return -EFBIG; | ||
1609 | out_busy: | ||
1610 | return -ETXTBSY; | ||
1611 | } | 1578 | } |
1612 | 1579 | ||
1613 | static int | 1580 | static 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, | |||
606 | void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, | 606 | void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, |
607 | u64 attr_valid); | 607 | u64 attr_valid); |
608 | 608 | ||
609 | void 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 | ||
143 | void 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 | |||
151 | void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, | 143 | void 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 | */ |
459 | static int nfs_vmtruncate(struct inode * inode, loff_t offset) | 459 | static 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 | 474 | out: |
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; | ||
500 | out_sig: | ||
501 | send_sig(SIGXFSZ, current, 0); | ||
502 | out_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: | 118 | add_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; |