|
@@ -61,33 +61,22 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
|
|
|
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;
|
|
|
- int error;
|
|
|
-
|
|
|
- error = -EINVAL;
|
|
|
- if (length < 0) /* sorry, but loff_t says... */
|
|
|
- goto out;
|
|
|
+ long error;
|
|
|
|
|
|
- error = user_path(pathname, &path);
|
|
|
- if (error)
|
|
|
- goto out;
|
|
|
- inode = path.dentry->d_inode;
|
|
|
+ inode = path->dentry->d_inode;
|
|
|
|
|
|
/* For directories it's -EISDIR, for other non-regulars - -EINVAL */
|
|
|
- error = -EISDIR;
|
|
|
if (S_ISDIR(inode->i_mode))
|
|
|
- goto dput_and_out;
|
|
|
-
|
|
|
- error = -EINVAL;
|
|
|
+ return -EISDIR;
|
|
|
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)
|
|
|
- goto dput_and_out;
|
|
|
+ goto out;
|
|
|
|
|
|
error = inode_permission(inode, MAY_WRITE);
|
|
|
if (error)
|
|
@@ -111,19 +100,34 @@ static long do_sys_truncate(const char __user *pathname, loff_t length)
|
|
|
|
|
|
error = locks_verify_truncate(inode, NULL, length);
|
|
|
if (!error)
|
|
|
- error = security_path_truncate(&path);
|
|
|
+ error = security_path_truncate(path);
|
|
|
if (!error)
|
|
|
- error = do_truncate(path.dentry, length, 0, NULL);
|
|
|
+ error = do_truncate(path->dentry, length, 0, NULL);
|
|
|
|
|
|
put_write_and_out:
|
|
|
put_write_access(inode);
|
|
|
mnt_drop_write_and_out:
|
|
|
- mnt_drop_write(path.mnt);
|
|
|
-dput_and_out:
|
|
|
- path_put(&path);
|
|
|
+ mnt_drop_write(path->mnt);
|
|
|
out:
|
|
|
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)
|
|
|
{
|