From 496ad9aa8ef448058e36ca7a787c61f2e63f0f54 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 23 Jan 2013 17:07:38 -0500 Subject: new helper: file_inode(file) Signed-off-by: Al Viro --- fs/open.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'fs/open.c') diff --git a/fs/open.c b/fs/open.c index 9b33c0cbfac..e08643feb57 100644 --- a/fs/open.c +++ b/fs/open.c @@ -228,7 +228,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 +426,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 +689,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 = file_inode(f); if (f->f_mode & FMODE_WRITE) { error = __get_file_write_access(inode, f->f_path.mnt); if (error) -- cgit v1.2.3-70-g09d2 From 1afc99beaf0fca3767d9b67789a7ae91c4f7a9c9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 14 Feb 2013 20:41:04 -0500 Subject: propagate error from get_empty_filp() to its callers Based on parts from Anatol's patch (the rest is the next commit). Signed-off-by: Al Viro --- fs/file_table.c | 27 +++++++++++++-------------- fs/namei.c | 4 ++-- fs/open.c | 27 +++++++++++++-------------- 3 files changed, 28 insertions(+), 30 deletions(-) (limited to 'fs/open.c') diff --git a/fs/file_table.c b/fs/file_table.c index 0f607ce89ac..cd76d4fdf4a 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -94,8 +94,8 @@ int proc_nr_files(ctl_table *table, int write, #endif /* Find an unused file structure and return a pointer to it. - * Returns NULL, if there are no more free file structures or - * we run out of memory. + * Returns an error pointer if some error happend e.g. we over file + * structures limit, run out of memory or operation is not permitted. * * Be very careful using this. You are responsible for * getting write access to any mount that you might assign @@ -107,7 +107,8 @@ struct file *get_empty_filp(void) { const struct cred *cred = current_cred(); static long old_max; - struct file * f; + struct file *f; + int error; /* * Privileged users can go above max_files @@ -122,13 +123,16 @@ struct file *get_empty_filp(void) } f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); - if (f == NULL) - goto fail; + if (unlikely(!f)) + return ERR_PTR(-ENOMEM); percpu_counter_inc(&nr_files); f->f_cred = get_cred(cred); - if (security_file_alloc(f)) - goto fail_sec; + error = security_file_alloc(f); + if (unlikely(error)) { + file_free(f); + return ERR_PTR(error); + } INIT_LIST_HEAD(&f->f_u.fu_list); atomic_long_set(&f->f_count, 1); @@ -144,12 +148,7 @@ over: pr_info("VFS: file-max limit %lu reached\n", get_max_files()); old_max = get_nr_files(); } - goto fail; - -fail_sec: - file_free(f); -fail: - return NULL; + return ERR_PTR(-ENFILE); } /** @@ -173,7 +172,7 @@ struct file *alloc_file(struct path *path, fmode_t mode, struct file *file; file = get_empty_filp(); - if (!file) + if (IS_ERR(file)) return NULL; file->f_path = *path; diff --git a/fs/namei.c b/fs/namei.c index df00b754631..e0a33f598cd 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2941,8 +2941,8 @@ static struct file *path_openat(int dfd, struct filename *pathname, int error; file = get_empty_filp(); - if (!file) - return ERR_PTR(-ENFILE); + if (IS_ERR(file)) + return file; file->f_flags = op->open_flag; diff --git a/fs/open.c b/fs/open.c index e08643feb57..97a237f67b7 100644 --- a/fs/open.c +++ b/fs/open.c @@ -810,23 +810,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; } -- cgit v1.2.3-70-g09d2 From 21d206819a6f111c77f0a9e920f5efca06dc65fd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 23 Feb 2013 17:36:01 -0500 Subject: get_empty_filp()/alloc_file() leave both ->f_pos and ->f_version zero Signed-off-by: Al Viro --- fs/anon_inodes.c | 2 -- fs/open.c | 1 - net/socket.c | 1 - 3 files changed, 4 deletions(-) (limited to 'fs/open.c') diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index a14eb0c1cd8..47a65df8c87 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c @@ -164,9 +164,7 @@ struct file *anon_inode_getfile(const char *name, goto err_dput; file->f_mapping = anon_inode_inode->i_mapping; - file->f_pos = 0; file->f_flags = flags & (O_ACCMODE | O_NONBLOCK); - file->f_version = 0; file->private_data = priv; return file; diff --git a/fs/open.c b/fs/open.c index 97a237f67b7..62f907e3bc3 100644 --- a/fs/open.c +++ b/fs/open.c @@ -699,7 +699,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)) { diff --git a/net/socket.c b/net/socket.c index f4a8c5a0b8d..b6ca6896dec 100644 --- a/net/socket.c +++ b/net/socket.c @@ -379,7 +379,6 @@ struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname) sock->file = file; file->f_flags = O_RDWR | (flags & O_NONBLOCK); - file->f_pos = 0; file->private_data = sock; return file; } -- cgit v1.2.3-70-g09d2