提交 a02de960 编写于 作者: D David Howells

VFS: Make more complete truncate operation available to CacheFiles

Make a more complete truncate operation available to CacheFiles (including
security checks and suchlike) so that it can use this to clear invalidated
cache files.
Signed-off-by: NDavid Howells <dhowells@redhat.com>
Acked-by: NAl Viro <viro@zeniv.linux.org.uk>
上级 ef778e7a
...@@ -61,33 +61,22 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, ...@@ -61,33 +61,22 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
return ret; return ret;
} }
static long do_sys_truncate(const char __user *pathname, loff_t length) long vfs_truncate(struct path *path, loff_t length)
{ {
struct path path;
struct inode *inode; struct inode *inode;
int error; long error;
error = -EINVAL;
if (length < 0) /* sorry, but loff_t says... */
goto out;
error = user_path(pathname, &path); inode = path->dentry->d_inode;
if (error)
goto out;
inode = path.dentry->d_inode;
/* For directories it's -EISDIR, for other non-regulars - -EINVAL */ /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
error = -EISDIR;
if (S_ISDIR(inode->i_mode)) if (S_ISDIR(inode->i_mode))
goto dput_and_out; return -EISDIR;
error = -EINVAL;
if (!S_ISREG(inode->i_mode)) if (!S_ISREG(inode->i_mode))
goto dput_and_out; return -EINVAL;
error = mnt_want_write(path.mnt); error = mnt_want_write(path->mnt);
if (error) if (error)
goto dput_and_out; goto out;
error = inode_permission(inode, MAY_WRITE); error = inode_permission(inode, MAY_WRITE);
if (error) if (error)
...@@ -111,19 +100,34 @@ static long do_sys_truncate(const char __user *pathname, loff_t length) ...@@ -111,19 +100,34 @@ static long do_sys_truncate(const char __user *pathname, loff_t length)
error = locks_verify_truncate(inode, NULL, length); error = locks_verify_truncate(inode, NULL, length);
if (!error) if (!error)
error = security_path_truncate(&path); error = security_path_truncate(path);
if (!error) if (!error)
error = do_truncate(path.dentry, length, 0, NULL); error = do_truncate(path->dentry, length, 0, NULL);
put_write_and_out: put_write_and_out:
put_write_access(inode); put_write_access(inode);
mnt_drop_write_and_out: mnt_drop_write_and_out:
mnt_drop_write(path.mnt); mnt_drop_write(path->mnt);
dput_and_out:
path_put(&path);
out: out:
return error; return error;
} }
EXPORT_SYMBOL_GPL(vfs_truncate);
static long do_sys_truncate(const char __user *pathname, loff_t length)
{
struct path path;
int error;
if (length < 0) /* sorry, but loff_t says... */
return -EINVAL;
error = user_path(pathname, &path);
if (!error) {
error = vfs_truncate(&path, length);
path_put(&path);
}
return error;
}
SYSCALL_DEFINE2(truncate, const char __user *, path, long, length) SYSCALL_DEFINE2(truncate, const char __user *, path, long, length)
{ {
......
...@@ -1999,6 +1999,7 @@ struct filename { ...@@ -1999,6 +1999,7 @@ struct filename {
bool separate; /* should "name" be freed? */ bool separate; /* should "name" be freed? */
}; };
extern long vfs_truncate(struct path *, loff_t);
extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
struct file *filp); struct file *filp);
extern int do_fallocate(struct file *file, int mode, loff_t offset, extern int do_fallocate(struct file *file, int mode, loff_t offset,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册