diff options
Diffstat (limited to 'fs/open.c')
-rw-r--r-- | fs/open.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/fs/open.c b/fs/open.c index 9b33c0cbfacf..68354466879f 100644 --- a/fs/open.c +++ b/fs/open.c @@ -30,6 +30,7 @@ #include <linux/fs_struct.h> #include <linux/ima.h> #include <linux/dnotify.h> +#include <linux/compat.h> #include "internal.h" @@ -140,6 +141,13 @@ SYSCALL_DEFINE2(truncate, const char __user *, path, long, length) return do_sys_truncate(path, length); } +#ifdef CONFIG_COMPAT +COMPAT_SYSCALL_DEFINE2(truncate, const char __user *, path, compat_off_t, length) +{ + return do_sys_truncate(path, length); +} +#endif + static long do_sys_ftruncate(unsigned int fd, loff_t length, int small) { struct inode *inode; @@ -195,6 +203,13 @@ SYSCALL_DEFINE2(ftruncate, unsigned int, fd, unsigned long, length) return ret; } +#ifdef CONFIG_COMPAT +COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_ulong_t, length) +{ + return do_sys_ftruncate(fd, length, 1); +} +#endif + /* LFS versions of truncate are only needed on 32 bit machines */ #if BITS_PER_LONG == 32 SYSCALL_DEFINE(truncate64)(const char __user * path, loff_t length) @@ -228,7 +243,7 @@ SYSCALL_ALIAS(sys_ftruncate64, SyS_ftruncate64); int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) { - struct inode *inode = file->f_path.dentry->d_inode; + struct inode *inode = file_inode(file); long ret; if (offset < 0 || len <= 0) @@ -426,7 +441,7 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd) if (!f.file) goto out; - inode = f.file->f_path.dentry->d_inode; + inode = file_inode(f.file); error = -ENOTDIR; if (!S_ISDIR(inode->i_mode)) @@ -689,7 +704,7 @@ static int do_dentry_open(struct file *f, f->f_mode = FMODE_PATH; path_get(&f->f_path); - inode = f->f_path.dentry->d_inode; + inode = f->f_inode = f->f_path.dentry->d_inode; if (f->f_mode & FMODE_WRITE) { error = __get_file_write_access(inode, f->f_path.mnt); if (error) @@ -699,7 +714,6 @@ static int do_dentry_open(struct file *f, } f->f_mapping = inode->i_mapping; - f->f_pos = 0; file_sb_list_add(f, inode->i_sb); if (unlikely(f->f_mode & FMODE_PATH)) { @@ -753,6 +767,7 @@ cleanup_file: path_put(&f->f_path); f->f_path.mnt = NULL; f->f_path.dentry = NULL; + f->f_inode = NULL; return error; } @@ -810,23 +825,22 @@ struct file *dentry_open(const struct path *path, int flags, /* We must always pass in a valid mount pointer. */ BUG_ON(!path->mnt); - error = -ENFILE; f = get_empty_filp(); - if (f == NULL) - return ERR_PTR(error); - - f->f_flags = flags; - f->f_path = *path; - error = do_dentry_open(f, NULL, cred); - if (!error) { - error = open_check_o_direct(f); - if (error) { - fput(f); + if (!IS_ERR(f)) { + f->f_flags = flags; + f->f_path = *path; + error = do_dentry_open(f, NULL, cred); + if (!error) { + /* from now on we need fput() to dispose of f */ + error = open_check_o_direct(f); + if (error) { + fput(f); + f = ERR_PTR(error); + } + } else { + put_filp(f); f = ERR_PTR(error); } - } else { - put_filp(f); - f = ERR_PTR(error); } return f; } |