From 2c27c65ed0696f0b5df2dad2cf6462d72164d547 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 4 Jun 2010 11:30:04 +0200 Subject: check ATTR_SIZE contraints in inode_change_ok Make sure we check the truncate constraints early on in ->setattr by adding those checks to inode_change_ok. Also clean up and document inode_change_ok to make this obvious. As a fallout we don't have to call inode_newsize_ok from simple_setsize and simplify it down to a truncate_setsize which doesn't return an error. This simplifies a lot of setattr implementations and means we use truncate_setsize almost everywhere. Get rid of fat_setsize now that it's trivial and mark ext2_setsize static to make the calling convention obvious. Keep the inode_newsize_ok in vmtruncate for now as all callers need an audit for its removal anyway. Note: setattr code in ecryptfs doesn't call inode_change_ok at all and needs a deeper audit, but that is left for later. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/libfs.c | 51 ++------------------------------------------------- 1 file changed, 2 insertions(+), 49 deletions(-) (limited to 'fs/libfs.c') diff --git a/fs/libfs.c b/fs/libfs.c index 40562224b718..0a9da95317f7 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -326,49 +326,6 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry, return 0; } -/** - * simple_setsize - handle core mm and vfs requirements for file size change - * @inode: inode - * @newsize: new file size - * - * Returns 0 on success, -error on failure. - * - * simple_setsize must be called with inode_mutex held. - * - * simple_setsize will check that the requested new size is OK (see - * inode_newsize_ok), and then will perform the necessary i_size update - * and pagecache truncation (if necessary). It will be typically be called - * from the filesystem's setattr function when ATTR_SIZE is passed in. - * - * The inode itself must have correct permissions and attributes to allow - * i_size to be changed, this function then just checks that the new size - * requested is valid. - * - * In the case of simple in-memory filesystems with inodes stored solely - * in the inode cache, and file data in the pagecache, nothing more needs - * to be done to satisfy a truncate request. Filesystems with on-disk - * blocks for example will need to free them in the case of truncate, in - * that case it may be easier not to use simple_setsize (but each of its - * components will likely be required at some point to update pagecache - * and inode etc). - */ -int simple_setsize(struct inode *inode, loff_t newsize) -{ - loff_t oldsize; - int error; - - error = inode_newsize_ok(inode, newsize); - if (error) - return error; - - oldsize = inode->i_size; - i_size_write(inode, newsize); - truncate_pagecache(inode, oldsize, newsize); - - return error; -} -EXPORT_SYMBOL(simple_setsize); - /** * simple_setattr - setattr for simple filesystem * @dentry: dentry @@ -394,12 +351,8 @@ int simple_setattr(struct dentry *dentry, struct iattr *iattr) if (error) return error; - if (iattr->ia_valid & ATTR_SIZE) { - error = simple_setsize(inode, iattr->ia_size); - if (error) - return error; - } - + if (iattr->ia_valid & ATTR_SIZE) + truncate_setsize(inode, iattr->ia_size); setattr_copy(inode, iattr); mark_inode_dirty(inode); return 0; -- cgit v1.2.3-59-g8ed1b