aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2008-02-05 01:28:56 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-05 12:44:16 -0500
commit61d5048f149572434daee0cce5e1374a8a7cf3e8 (patch)
tree97ac9c25bc44a58145a750a99887195df31cbe40 /mm/memory.c
parent1b1b32f2c6f6bb32535d2da62075b51c980880eb (diff)
clean up vmtruncate
vmtruncate is a twisted maze of gotos, this patch cleans it up to have a proper if else for the two major cases of extending and truncating truncate and thus makes it a lot more readable while keeping exactly the same functinality. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c69
1 files changed, 34 insertions, 35 deletions
diff --git a/mm/memory.c b/mm/memory.c
index bc137751da7f..b7cb2e01705f 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1909,50 +1909,49 @@ EXPORT_SYMBOL(unmap_mapping_range);
1909 */ 1909 */
1910int vmtruncate(struct inode * inode, loff_t offset) 1910int vmtruncate(struct inode * inode, loff_t offset)
1911{ 1911{
1912 struct address_space *mapping = inode->i_mapping; 1912 if (inode->i_size < offset) {
1913 unsigned long limit; 1913 unsigned long limit;
1914
1915 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
1916 if (limit != RLIM_INFINITY && offset > limit)
1917 goto out_sig;
1918 if (offset > inode->i_sb->s_maxbytes)
1919 goto out_big;
1920 i_size_write(inode, offset);
1921 } else {
1922 struct address_space *mapping = inode->i_mapping;
1914 1923
1915 if (inode->i_size < offset) 1924 /*
1916 goto do_expand; 1925 * truncation of in-use swapfiles is disallowed - it would
1917 /* 1926 * cause subsequent swapout to scribble on the now-freed
1918 * truncation of in-use swapfiles is disallowed - it would cause 1927 * blocks.
1919 * subsequent swapout to scribble on the now-freed blocks. 1928 */
1920 */ 1929 if (IS_SWAPFILE(inode))
1921 if (IS_SWAPFILE(inode)) 1930 return -ETXTBSY;
1922 goto out_busy; 1931 i_size_write(inode, offset);
1923 i_size_write(inode, offset); 1932
1933 /*
1934 * unmap_mapping_range is called twice, first simply for
1935 * efficiency so that truncate_inode_pages does fewer
1936 * single-page unmaps. However after this first call, and
1937 * before truncate_inode_pages finishes, it is possible for
1938 * private pages to be COWed, which remain after
1939 * truncate_inode_pages finishes, hence the second
1940 * unmap_mapping_range call must be made for correctness.
1941 */
1942 unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1943 truncate_inode_pages(mapping, offset);
1944 unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1945 }
1924 1946
1925 /*
1926 * unmap_mapping_range is called twice, first simply for efficiency
1927 * so that truncate_inode_pages does fewer single-page unmaps. However
1928 * after this first call, and before truncate_inode_pages finishes,
1929 * it is possible for private pages to be COWed, which remain after
1930 * truncate_inode_pages finishes, hence the second unmap_mapping_range
1931 * call must be made for correctness.
1932 */
1933 unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1934 truncate_inode_pages(mapping, offset);
1935 unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1936 goto out_truncate;
1937
1938do_expand:
1939 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
1940 if (limit != RLIM_INFINITY && offset > limit)
1941 goto out_sig;
1942 if (offset > inode->i_sb->s_maxbytes)
1943 goto out_big;
1944 i_size_write(inode, offset);
1945
1946out_truncate:
1947 if (inode->i_op && inode->i_op->truncate) 1947 if (inode->i_op && inode->i_op->truncate)
1948 inode->i_op->truncate(inode); 1948 inode->i_op->truncate(inode);
1949 return 0; 1949 return 0;
1950
1950out_sig: 1951out_sig:
1951 send_sig(SIGXFSZ, current, 0); 1952 send_sig(SIGXFSZ, current, 0);
1952out_big: 1953out_big:
1953 return -EFBIG; 1954 return -EFBIG;
1954out_busy:
1955 return -ETXTBSY;
1956} 1955}
1957EXPORT_SYMBOL(vmtruncate); 1956EXPORT_SYMBOL(vmtruncate);
1958 1957