You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs update from Al Viro:
- big one - consolidation of descriptor-related logics; almost all of
that is moved to fs/file.c
(BTW, I'm seriously tempted to rename the result to fd.c. As it is,
we have a situation when file_table.c is about handling of struct
file and file.c is about handling of descriptor tables; the reasons
are historical - file_table.c used to be about a static array of
struct file we used to have way back).
A lot of stray ends got cleaned up and converted to saner primitives,
disgusting mess in android/binder.c is still disgusting, but at least
doesn't poke so much in descriptor table guts anymore. A bunch of
relatively minor races got fixed in process, plus an ext4 struct file
leak.
- related thing - fget_light() partially unuglified; see fdget() in
there (and yes, it generates the code as good as we used to have).
- also related - bits of Cyrill's procfs stuff that got entangled into
that work; _not_ all of it, just the initial move to fs/proc/fd.c and
switch of fdinfo to seq_file.
- Alex's fs/coredump.c spiltoff - the same story, had been easier to
take that commit than mess with conflicts. The rest is a separate
pile, this was just a mechanical code movement.
- a few misc patches all over the place. Not all for this cycle,
there'll be more (and quite a few currently sit in akpm's tree)."
Fix up trivial conflicts in the android binder driver, and some fairly
simple conflicts due to two different changes to the sock_alloc_file()
interface ("take descriptor handling from sock_alloc_file() to callers"
vs "net: Providing protocol type via system.sockprotoname xattr of
/proc/PID/fd entries" adding a dentry name to the socket)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (72 commits)
MAX_LFS_FILESIZE should be a loff_t
compat: fs: Generic compat_sys_sendfile implementation
fs: push rcu_barrier() from deactivate_locked_super() to filesystems
btrfs: reada_extent doesn't need kref for refcount
coredump: move core dump functionality into its own file
coredump: prevent double-free on an error path in core dumper
usb/gadget: fix misannotations
fcntl: fix misannotations
ceph: don't abuse d_delete() on failure exits
hypfs: ->d_parent is never NULL or negative
vfs: delete surplus inode NULL check
switch simple cases of fget_light to fdget
new helpers: fdget()/fdput()
switch o2hb_region_dev_write() to fget_light()
proc_map_files_readdir(): don't bother with grabbing files
make get_file() return its argument
vhost_set_vring(): turn pollstart/pollstop into bool
switch prctl_set_mm_exe_file() to fget_light()
switch xfs_find_handle() to fget_light()
switch xfs_swapext() to fget_light()
...
This commit is contained in:
@@ -145,27 +145,24 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
|
||||
long __user *, basep)
|
||||
{
|
||||
int error;
|
||||
struct file *file;
|
||||
struct fd arg = fdget(fd);
|
||||
struct osf_dirent_callback buf;
|
||||
|
||||
error = -EBADF;
|
||||
file = fget(fd);
|
||||
if (!file)
|
||||
goto out;
|
||||
if (!arg.file)
|
||||
return -EBADF;
|
||||
|
||||
buf.dirent = dirent;
|
||||
buf.basep = basep;
|
||||
buf.count = count;
|
||||
buf.error = 0;
|
||||
|
||||
error = vfs_readdir(file, osf_filldir, &buf);
|
||||
error = vfs_readdir(arg.file, osf_filldir, &buf);
|
||||
if (error >= 0)
|
||||
error = buf.error;
|
||||
if (count != buf.count)
|
||||
error = count - buf.count;
|
||||
|
||||
fput(file);
|
||||
out:
|
||||
fdput(arg);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -2306,7 +2306,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
|
||||
* partially initialize the vma for the sampling buffer
|
||||
*/
|
||||
vma->vm_mm = mm;
|
||||
vma->vm_file = filp;
|
||||
vma->vm_file = get_file(filp);
|
||||
vma->vm_flags = VM_READ| VM_MAYREAD |VM_RESERVED;
|
||||
vma->vm_page_prot = PAGE_READONLY; /* XXX may need to change */
|
||||
|
||||
@@ -2345,8 +2345,6 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
|
||||
goto error;
|
||||
}
|
||||
|
||||
get_file(filp);
|
||||
|
||||
/*
|
||||
* now insert the vma in the vm list for the process, must be
|
||||
* done with mmap lock held
|
||||
@@ -4782,7 +4780,7 @@ recheck:
|
||||
asmlinkage long
|
||||
sys_perfmonctl (int fd, int cmd, void __user *arg, int count)
|
||||
{
|
||||
struct file *file = NULL;
|
||||
struct fd f = {NULL, 0};
|
||||
pfm_context_t *ctx = NULL;
|
||||
unsigned long flags = 0UL;
|
||||
void *args_k = NULL;
|
||||
@@ -4879,17 +4877,17 @@ restart_args:
|
||||
|
||||
ret = -EBADF;
|
||||
|
||||
file = fget(fd);
|
||||
if (unlikely(file == NULL)) {
|
||||
f = fdget(fd);
|
||||
if (unlikely(f.file == NULL)) {
|
||||
DPRINT(("invalid fd %d\n", fd));
|
||||
goto error_args;
|
||||
}
|
||||
if (unlikely(PFM_IS_FILE(file) == 0)) {
|
||||
if (unlikely(PFM_IS_FILE(f.file) == 0)) {
|
||||
DPRINT(("fd %d not related to perfmon\n", fd));
|
||||
goto error_args;
|
||||
}
|
||||
|
||||
ctx = file->private_data;
|
||||
ctx = f.file->private_data;
|
||||
if (unlikely(ctx == NULL)) {
|
||||
DPRINT(("no context for fd %d\n", fd));
|
||||
goto error_args;
|
||||
@@ -4919,8 +4917,8 @@ abort_locked:
|
||||
if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT;
|
||||
|
||||
error_args:
|
||||
if (file)
|
||||
fput(file);
|
||||
if (f.file)
|
||||
fdput(f);
|
||||
|
||||
kfree(args_k);
|
||||
|
||||
|
||||
@@ -109,33 +109,32 @@ Efault:
|
||||
|
||||
int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned int count)
|
||||
{
|
||||
struct file * file;
|
||||
struct fd arg;
|
||||
struct hpux_dirent __user * lastdirent;
|
||||
struct getdents_callback buf;
|
||||
int error = -EBADF;
|
||||
int error;
|
||||
|
||||
file = fget(fd);
|
||||
if (!file)
|
||||
goto out;
|
||||
arg = fdget(fd);
|
||||
if (!arg.file)
|
||||
return -EBADF;
|
||||
|
||||
buf.current_dir = dirent;
|
||||
buf.previous = NULL;
|
||||
buf.count = count;
|
||||
buf.error = 0;
|
||||
|
||||
error = vfs_readdir(file, filldir, &buf);
|
||||
error = vfs_readdir(arg.file, filldir, &buf);
|
||||
if (error >= 0)
|
||||
error = buf.error;
|
||||
lastdirent = buf.previous;
|
||||
if (lastdirent) {
|
||||
if (put_user(file->f_pos, &lastdirent->d_off))
|
||||
if (put_user(arg.file->f_pos, &lastdirent->d_off))
|
||||
error = -EFAULT;
|
||||
else
|
||||
error = count - buf.count;
|
||||
}
|
||||
|
||||
fput(file);
|
||||
out:
|
||||
fdput(arg);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@ SYSCALL_SPU(getcwd)
|
||||
SYSCALL_SPU(capget)
|
||||
SYSCALL_SPU(capset)
|
||||
COMPAT_SYS(sigaltstack)
|
||||
SYSX_SPU(sys_sendfile64,compat_sys_sendfile,sys_sendfile)
|
||||
SYSX_SPU(sys_sendfile,compat_sys_sendfile_wrapper,sys_sendfile)
|
||||
SYSCALL(ni_syscall)
|
||||
SYSCALL(ni_syscall)
|
||||
PPC_SYS(vfork)
|
||||
@@ -229,7 +229,7 @@ COMPAT_SYS_SPU(sched_setaffinity)
|
||||
COMPAT_SYS_SPU(sched_getaffinity)
|
||||
SYSCALL(ni_syscall)
|
||||
SYSCALL(ni_syscall)
|
||||
SYS32ONLY(sendfile64)
|
||||
SYSX(sys_ni_syscall,compat_sys_sendfile64_wrapper,sys_sendfile64)
|
||||
COMPAT_SYS_SPU(io_setup)
|
||||
SYSCALL_SPU(io_destroy)
|
||||
COMPAT_SYS_SPU(io_getevents)
|
||||
|
||||
@@ -419,6 +419,7 @@
|
||||
#define __ARCH_WANT_COMPAT_SYS_TIME
|
||||
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
|
||||
#define __ARCH_WANT_SYS_NEWFSTATAT
|
||||
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -143,48 +143,17 @@ long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t pt
|
||||
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
|
||||
* and the register representation of a signed int (msr in 64-bit mode) is performed.
|
||||
*/
|
||||
asmlinkage long compat_sys_sendfile(u32 out_fd, u32 in_fd, compat_off_t __user * offset, u32 count)
|
||||
asmlinkage long compat_sys_sendfile_wrapper(u32 out_fd, u32 in_fd,
|
||||
compat_off_t __user *offset, u32 count)
|
||||
{
|
||||
mm_segment_t old_fs = get_fs();
|
||||
int ret;
|
||||
off_t of;
|
||||
off_t __user *up;
|
||||
|
||||
if (offset && get_user(of, offset))
|
||||
return -EFAULT;
|
||||
|
||||
/* The __user pointer cast is valid because of the set_fs() */
|
||||
set_fs(KERNEL_DS);
|
||||
up = offset ? (off_t __user *) &of : NULL;
|
||||
ret = sys_sendfile((int)out_fd, (int)in_fd, up, count);
|
||||
set_fs(old_fs);
|
||||
|
||||
if (offset && put_user(of, offset))
|
||||
return -EFAULT;
|
||||
|
||||
return ret;
|
||||
return compat_sys_sendfile((int)out_fd, (int)in_fd, offset, count);
|
||||
}
|
||||
|
||||
asmlinkage int compat_sys_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count)
|
||||
asmlinkage long compat_sys_sendfile64_wrapper(u32 out_fd, u32 in_fd,
|
||||
compat_loff_t __user *offset, u32 count)
|
||||
{
|
||||
mm_segment_t old_fs = get_fs();
|
||||
int ret;
|
||||
loff_t lof;
|
||||
loff_t __user *up;
|
||||
|
||||
if (offset && get_user(lof, offset))
|
||||
return -EFAULT;
|
||||
|
||||
/* The __user pointer cast is valid because of the set_fs() */
|
||||
set_fs(KERNEL_DS);
|
||||
up = offset ? (loff_t __user *) &lof : NULL;
|
||||
ret = sys_sendfile64(out_fd, in_fd, up, count);
|
||||
set_fs(old_fs);
|
||||
|
||||
if (offset && put_user(lof, offset))
|
||||
return -EFAULT;
|
||||
|
||||
return ret;
|
||||
return sys_sendfile((int)out_fd, (int)in_fd,
|
||||
(off_t __user *)offset, count);
|
||||
}
|
||||
|
||||
long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
|
||||
|
||||
@@ -69,8 +69,6 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
|
||||
umode_t, mode, int, neighbor_fd)
|
||||
{
|
||||
long ret;
|
||||
struct file *neighbor;
|
||||
int fput_needed;
|
||||
struct spufs_calls *calls;
|
||||
|
||||
calls = spufs_calls_get();
|
||||
@@ -78,11 +76,11 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
|
||||
return -ENOSYS;
|
||||
|
||||
if (flags & SPU_CREATE_AFFINITY_SPU) {
|
||||
struct fd neighbor = fdget(neighbor_fd);
|
||||
ret = -EBADF;
|
||||
neighbor = fget_light(neighbor_fd, &fput_needed);
|
||||
if (neighbor) {
|
||||
ret = calls->create_thread(name, flags, mode, neighbor);
|
||||
fput_light(neighbor, fput_needed);
|
||||
if (neighbor.file) {
|
||||
ret = calls->create_thread(name, flags, mode, neighbor.file);
|
||||
fdput(neighbor);
|
||||
}
|
||||
} else
|
||||
ret = calls->create_thread(name, flags, mode, NULL);
|
||||
@@ -94,8 +92,7 @@ SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
|
||||
asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
|
||||
{
|
||||
long ret;
|
||||
struct file *filp;
|
||||
int fput_needed;
|
||||
struct fd arg;
|
||||
struct spufs_calls *calls;
|
||||
|
||||
calls = spufs_calls_get();
|
||||
@@ -103,10 +100,10 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
|
||||
return -ENOSYS;
|
||||
|
||||
ret = -EBADF;
|
||||
filp = fget_light(fd, &fput_needed);
|
||||
if (filp) {
|
||||
ret = calls->spu_run(filp, unpc, ustatus);
|
||||
fput_light(filp, fput_needed);
|
||||
arg = fdget(fd);
|
||||
if (arg.file) {
|
||||
ret = calls->spu_run(arg.file, unpc, ustatus);
|
||||
fdput(arg);
|
||||
}
|
||||
|
||||
spufs_calls_put(calls);
|
||||
|
||||
@@ -106,6 +106,17 @@ static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
|
||||
return total;
|
||||
}
|
||||
|
||||
static int match_context(const void *v, struct file *file, unsigned fd)
|
||||
{
|
||||
struct spu_context *ctx;
|
||||
if (file->f_op != &spufs_context_fops)
|
||||
return 0;
|
||||
ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
|
||||
if (ctx->flags & SPU_CREATE_NOSCHED)
|
||||
return 0;
|
||||
return fd + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The additional architecture-specific notes for Cell are various
|
||||
* context files in the spu context.
|
||||
@@ -115,29 +126,18 @@ static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
|
||||
* internal functionality to dump them without needing to actually
|
||||
* open the files.
|
||||
*/
|
||||
/*
|
||||
* descriptor table is not shared, so files can't change or go away.
|
||||
*/
|
||||
static struct spu_context *coredump_next_context(int *fd)
|
||||
{
|
||||
struct fdtable *fdt = files_fdtable(current->files);
|
||||
struct file *file;
|
||||
struct spu_context *ctx = NULL;
|
||||
|
||||
for (; *fd < fdt->max_fds; (*fd)++) {
|
||||
if (!fd_is_open(*fd, fdt))
|
||||
continue;
|
||||
|
||||
file = fcheck(*fd);
|
||||
|
||||
if (!file || file->f_op != &spufs_context_fops)
|
||||
continue;
|
||||
|
||||
ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
|
||||
if (ctx->flags & SPU_CREATE_NOSCHED)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
int n = iterate_fd(current->files, *fd, match_context, NULL);
|
||||
if (!n)
|
||||
return NULL;
|
||||
*fd = n - 1;
|
||||
file = fcheck(*fd);
|
||||
return SPUFS_I(file->f_dentry->d_inode)->i_ctx;
|
||||
}
|
||||
|
||||
int spufs_coredump_extra_notes_size(void)
|
||||
|
||||
@@ -72,8 +72,6 @@ static void hypfs_remove(struct dentry *dentry)
|
||||
struct dentry *parent;
|
||||
|
||||
parent = dentry->d_parent;
|
||||
if (!parent || !parent->d_inode)
|
||||
return;
|
||||
mutex_lock(&parent->d_inode->i_mutex);
|
||||
if (hypfs_positive(dentry)) {
|
||||
if (S_ISDIR(dentry->d_inode->i_mode))
|
||||
|
||||
@@ -447,6 +447,7 @@
|
||||
#else
|
||||
#define __ARCH_WANT_COMPAT_SYS_TIME
|
||||
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
|
||||
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -90,7 +90,7 @@ SIGN1(sys32_mkdir, sys_mkdir, %o1)
|
||||
SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5)
|
||||
SIGN1(sys32_sysfs, compat_sys_sysfs, %o0)
|
||||
SIGN2(sys32_sendfile, compat_sys_sendfile, %o0, %o1)
|
||||
SIGN2(sys32_sendfile64, compat_sys_sendfile64, %o0, %o1)
|
||||
SIGN2(sys32_sendfile64, sys_sendfile, %o0, %o1)
|
||||
SIGN1(sys32_prctl, sys_prctl, %o0)
|
||||
SIGN1(sys32_sched_rr_get_interval, compat_sys_sched_rr_get_interval, %o0)
|
||||
SIGN2(sys32_waitpid, sys_waitpid, %o0, %o2)
|
||||
|
||||
@@ -506,52 +506,6 @@ long compat_sys_fadvise64_64(int fd,
|
||||
advice);
|
||||
}
|
||||
|
||||
asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
|
||||
compat_off_t __user *offset,
|
||||
compat_size_t count)
|
||||
{
|
||||
mm_segment_t old_fs = get_fs();
|
||||
int ret;
|
||||
off_t of;
|
||||
|
||||
if (offset && get_user(of, offset))
|
||||
return -EFAULT;
|
||||
|
||||
set_fs(KERNEL_DS);
|
||||
ret = sys_sendfile(out_fd, in_fd,
|
||||
offset ? (off_t __user *) &of : NULL,
|
||||
count);
|
||||
set_fs(old_fs);
|
||||
|
||||
if (offset && put_user(of, offset))
|
||||
return -EFAULT;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd,
|
||||
compat_loff_t __user *offset,
|
||||
compat_size_t count)
|
||||
{
|
||||
mm_segment_t old_fs = get_fs();
|
||||
int ret;
|
||||
loff_t lof;
|
||||
|
||||
if (offset && get_user(lof, offset))
|
||||
return -EFAULT;
|
||||
|
||||
set_fs(KERNEL_DS);
|
||||
ret = sys_sendfile64(out_fd, in_fd,
|
||||
offset ? (loff_t __user *) &lof : NULL,
|
||||
count);
|
||||
set_fs(old_fs);
|
||||
|
||||
if (offset && put_user(lof, offset))
|
||||
return -EFAULT;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This is just a version for 32-bit applications which does
|
||||
* not force O_LARGEFILE on.
|
||||
*/
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
#include <linux/un.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/file.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/switch_to.h>
|
||||
|
||||
@@ -118,18 +121,14 @@ void mconsole_log(struct mc_request *req)
|
||||
mconsole_reply(req, "", 0, 0);
|
||||
}
|
||||
|
||||
/* This is a more convoluted version of mconsole_proc, which has some stability
|
||||
* problems; however, we need it fixed, because it is expected that UML users
|
||||
* mount HPPFS instead of procfs on /proc. And we want mconsole_proc to still
|
||||
* show the real procfs content, not the ones from hppfs.*/
|
||||
#if 0
|
||||
void mconsole_proc(struct mc_request *req)
|
||||
{
|
||||
struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt;
|
||||
char *buf;
|
||||
int len;
|
||||
struct file *file;
|
||||
int n;
|
||||
char *ptr = req->request.data, *buf;
|
||||
mm_segment_t old_fs = get_fs();
|
||||
int first_chunk = 1;
|
||||
char *ptr = req->request.data;
|
||||
|
||||
ptr += strlen("proc");
|
||||
ptr = skip_spaces(ptr);
|
||||
@@ -137,6 +136,7 @@ void mconsole_proc(struct mc_request *req)
|
||||
file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
|
||||
if (IS_ERR(file)) {
|
||||
mconsole_reply(req, "Failed to open file", 1, 0);
|
||||
printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -146,62 +146,13 @@ void mconsole_proc(struct mc_request *req)
|
||||
goto out_fput;
|
||||
}
|
||||
|
||||
if (file->f_op->read) {
|
||||
do {
|
||||
loff_t pos;
|
||||
set_fs(KERNEL_DS);
|
||||
n = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
|
||||
file_pos_write(file, pos);
|
||||
set_fs(old_fs);
|
||||
if (n >= 0) {
|
||||
buf[n] = '\0';
|
||||
mconsole_reply(req, buf, 0, (n > 0));
|
||||
}
|
||||
else {
|
||||
mconsole_reply(req, "Read of file failed",
|
||||
1, 0);
|
||||
goto out_free;
|
||||
}
|
||||
} while (n > 0);
|
||||
}
|
||||
else mconsole_reply(req, "", 0, 0);
|
||||
|
||||
out_free:
|
||||
kfree(buf);
|
||||
out_fput:
|
||||
fput(file);
|
||||
out: ;
|
||||
}
|
||||
#endif
|
||||
|
||||
void mconsole_proc(struct mc_request *req)
|
||||
{
|
||||
char path[64];
|
||||
char *buf;
|
||||
int len;
|
||||
int fd;
|
||||
int first_chunk = 1;
|
||||
char *ptr = req->request.data;
|
||||
|
||||
ptr += strlen("proc");
|
||||
ptr = skip_spaces(ptr);
|
||||
snprintf(path, sizeof(path), "/proc/%s", ptr);
|
||||
|
||||
fd = sys_open(path, 0, 0);
|
||||
if (fd < 0) {
|
||||
mconsole_reply(req, "Failed to open file", 1, 0);
|
||||
printk(KERN_ERR "open %s: %d\n",path,fd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (buf == NULL) {
|
||||
mconsole_reply(req, "Failed to allocate buffer", 1, 0);
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
len = sys_read(fd, buf, PAGE_SIZE-1);
|
||||
do {
|
||||
loff_t pos;
|
||||
mm_segment_t old_fs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
len = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
|
||||
set_fs(old_fs);
|
||||
file->f_pos = pos;
|
||||
if (len < 0) {
|
||||
mconsole_reply(req, "Read of file failed", 1, 0);
|
||||
goto out_free;
|
||||
@@ -211,22 +162,14 @@ void mconsole_proc(struct mc_request *req)
|
||||
mconsole_reply(req, "\n", 0, 1);
|
||||
first_chunk = 0;
|
||||
}
|
||||
if (len == PAGE_SIZE-1) {
|
||||
buf[len] = '\0';
|
||||
mconsole_reply(req, buf, 0, 1);
|
||||
} else {
|
||||
buf[len] = '\0';
|
||||
mconsole_reply(req, buf, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buf[len] = '\0';
|
||||
mconsole_reply(req, buf, 0, (len > 0));
|
||||
} while (len > 0);
|
||||
out_free:
|
||||
kfree(buf);
|
||||
out_close:
|
||||
sys_close(fd);
|
||||
out:
|
||||
/* nothing */;
|
||||
out_fput:
|
||||
fput(file);
|
||||
out: ;
|
||||
}
|
||||
|
||||
#define UML_MCONSOLE_HELPTEXT \
|
||||
|
||||
@@ -460,8 +460,7 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
|
||||
if (vma->vm_file)
|
||||
fput(vma->vm_file);
|
||||
|
||||
vma->vm_file = dmabuf->file;
|
||||
get_file(vma->vm_file);
|
||||
vma->vm_file = get_file(dmabuf->file);
|
||||
|
||||
vma->vm_pgoff = pgoff;
|
||||
|
||||
|
||||
@@ -1183,7 +1183,7 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
|
||||
struct rdma_ucm_migrate_id cmd;
|
||||
struct rdma_ucm_migrate_resp resp;
|
||||
struct ucma_context *ctx;
|
||||
struct file *filp;
|
||||
struct fd f;
|
||||
struct ucma_file *cur_file;
|
||||
int ret = 0;
|
||||
|
||||
@@ -1191,12 +1191,12 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
|
||||
return -EFAULT;
|
||||
|
||||
/* Get current fd to protect against it being closed */
|
||||
filp = fget(cmd.fd);
|
||||
if (!filp)
|
||||
f = fdget(cmd.fd);
|
||||
if (!f.file)
|
||||
return -ENOENT;
|
||||
|
||||
/* Validate current fd and prevent destruction of id. */
|
||||
ctx = ucma_get_ctx(filp->private_data, cmd.id);
|
||||
ctx = ucma_get_ctx(f.file->private_data, cmd.id);
|
||||
if (IS_ERR(ctx)) {
|
||||
ret = PTR_ERR(ctx);
|
||||
goto file_put;
|
||||
@@ -1230,7 +1230,7 @@ response:
|
||||
|
||||
ucma_put_ctx(ctx);
|
||||
file_put:
|
||||
fput(filp);
|
||||
fdput(f);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -705,7 +705,7 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
|
||||
struct ib_udata udata;
|
||||
struct ib_uxrcd_object *obj;
|
||||
struct ib_xrcd *xrcd = NULL;
|
||||
struct file *f = NULL;
|
||||
struct fd f = {NULL, 0};
|
||||
struct inode *inode = NULL;
|
||||
int ret = 0;
|
||||
int new_xrcd = 0;
|
||||
@@ -724,18 +724,13 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
|
||||
|
||||
if (cmd.fd != -1) {
|
||||
/* search for file descriptor */
|
||||
f = fget(cmd.fd);
|
||||
if (!f) {
|
||||
ret = -EBADF;
|
||||
goto err_tree_mutex_unlock;
|
||||
}
|
||||
|
||||
inode = f->f_dentry->d_inode;
|
||||
if (!inode) {
|
||||
f = fdget(cmd.fd);
|
||||
if (!f.file) {
|
||||
ret = -EBADF;
|
||||
goto err_tree_mutex_unlock;
|
||||
}
|
||||
|
||||
inode = f.file->f_path.dentry->d_inode;
|
||||
xrcd = find_xrcd(file->device, inode);
|
||||
if (!xrcd && !(cmd.oflags & O_CREAT)) {
|
||||
/* no file descriptor. Need CREATE flag */
|
||||
@@ -800,8 +795,8 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
|
||||
goto err_copy;
|
||||
}
|
||||
|
||||
if (f)
|
||||
fput(f);
|
||||
if (f.file)
|
||||
fdput(f);
|
||||
|
||||
mutex_lock(&file->mutex);
|
||||
list_add_tail(&obj->uobject.list, &file->ucontext->xrcd_list);
|
||||
@@ -830,8 +825,8 @@ err:
|
||||
put_uobj_write(&obj->uobject);
|
||||
|
||||
err_tree_mutex_unlock:
|
||||
if (f)
|
||||
fput(f);
|
||||
if (f.file)
|
||||
fdput(f);
|
||||
|
||||
mutex_unlock(&file->device->xrcd_tree_mutex);
|
||||
|
||||
|
||||
@@ -541,16 +541,15 @@ struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
|
||||
struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd)
|
||||
{
|
||||
struct ib_uverbs_event_file *ev_file = NULL;
|
||||
struct file *filp;
|
||||
struct fd f = fdget(fd);
|
||||
|
||||
filp = fget(fd);
|
||||
if (!filp)
|
||||
if (!f.file)
|
||||
return NULL;
|
||||
|
||||
if (filp->f_op != &uverbs_event_fops)
|
||||
if (f.file->f_op != &uverbs_event_fops)
|
||||
goto out;
|
||||
|
||||
ev_file = filp->private_data;
|
||||
ev_file = f.file->private_data;
|
||||
if (ev_file->is_async) {
|
||||
ev_file = NULL;
|
||||
goto out;
|
||||
@@ -559,7 +558,7 @@ struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd)
|
||||
kref_get(&ev_file->ref);
|
||||
|
||||
out:
|
||||
fput(filp);
|
||||
fdput(f);
|
||||
return ev_file;
|
||||
}
|
||||
|
||||
|
||||
@@ -362,71 +362,22 @@ struct binder_transaction {
|
||||
static void
|
||||
binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer);
|
||||
|
||||
/*
|
||||
* copied from get_unused_fd_flags
|
||||
*/
|
||||
static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
|
||||
{
|
||||
struct files_struct *files = proc->files;
|
||||
int fd, error;
|
||||
struct fdtable *fdt;
|
||||
unsigned long rlim_cur;
|
||||
unsigned long irqs;
|
||||
|
||||
if (files == NULL)
|
||||
return -ESRCH;
|
||||
|
||||
error = -EMFILE;
|
||||
spin_lock(&files->file_lock);
|
||||
if (!lock_task_sighand(proc->tsk, &irqs))
|
||||
return -EMFILE;
|
||||
|
||||
repeat:
|
||||
fdt = files_fdtable(files);
|
||||
fd = find_next_zero_bit(fdt->open_fds, fdt->max_fds, files->next_fd);
|
||||
rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE);
|
||||
unlock_task_sighand(proc->tsk, &irqs);
|
||||
|
||||
/*
|
||||
* N.B. For clone tasks sharing a files structure, this test
|
||||
* will limit the total number of files that can be opened.
|
||||
*/
|
||||
rlim_cur = 0;
|
||||
if (lock_task_sighand(proc->tsk, &irqs)) {
|
||||
rlim_cur = proc->tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur;
|
||||
unlock_task_sighand(proc->tsk, &irqs);
|
||||
}
|
||||
if (fd >= rlim_cur)
|
||||
goto out;
|
||||
|
||||
/* Do we need to expand the fd array or fd set? */
|
||||
error = expand_files(files, fd);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
if (error) {
|
||||
/*
|
||||
* If we needed to expand the fs array we
|
||||
* might have blocked - try again.
|
||||
*/
|
||||
error = -EMFILE;
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
__set_open_fd(fd, fdt);
|
||||
if (flags & O_CLOEXEC)
|
||||
__set_close_on_exec(fd, fdt);
|
||||
else
|
||||
__clear_close_on_exec(fd, fdt);
|
||||
files->next_fd = fd + 1;
|
||||
|
||||
/* Sanity check */
|
||||
if (fdt->fd[fd] != NULL) {
|
||||
pr_warn("get_unused_fd: slot %d not NULL!\n", fd);
|
||||
fdt->fd[fd] = NULL;
|
||||
}
|
||||
|
||||
error = fd;
|
||||
|
||||
out:
|
||||
spin_unlock(&files->file_lock);
|
||||
return error;
|
||||
return __alloc_fd(files, 0, rlim_cur, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -435,28 +386,8 @@ out:
|
||||
static void task_fd_install(
|
||||
struct binder_proc *proc, unsigned int fd, struct file *file)
|
||||
{
|
||||
struct files_struct *files = proc->files;
|
||||
struct fdtable *fdt;
|
||||
|
||||
if (files == NULL)
|
||||
return;
|
||||
|
||||
spin_lock(&files->file_lock);
|
||||
fdt = files_fdtable(files);
|
||||
BUG_ON(fdt->fd[fd] != NULL);
|
||||
rcu_assign_pointer(fdt->fd[fd], file);
|
||||
spin_unlock(&files->file_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* copied from __put_unused_fd in open.c
|
||||
*/
|
||||
static void __put_unused_fd(struct files_struct *files, unsigned int fd)
|
||||
{
|
||||
struct fdtable *fdt = files_fdtable(files);
|
||||
__clear_open_fd(fd, fdt);
|
||||
if (fd < files->next_fd)
|
||||
files->next_fd = fd;
|
||||
if (proc->files)
|
||||
__fd_install(proc->files, fd, file);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -464,27 +395,12 @@ static void __put_unused_fd(struct files_struct *files, unsigned int fd)
|
||||
*/
|
||||
static long task_close_fd(struct binder_proc *proc, unsigned int fd)
|
||||
{
|
||||
struct file *filp;
|
||||
struct files_struct *files = proc->files;
|
||||
struct fdtable *fdt;
|
||||
int retval;
|
||||
|
||||
if (files == NULL)
|
||||
if (proc->files == NULL)
|
||||
return -ESRCH;
|
||||
|
||||
spin_lock(&files->file_lock);
|
||||
fdt = files_fdtable(files);
|
||||
if (fd >= fdt->max_fds)
|
||||
goto out_unlock;
|
||||
filp = fdt->fd[fd];
|
||||
if (!filp)
|
||||
goto out_unlock;
|
||||
rcu_assign_pointer(fdt->fd[fd], NULL);
|
||||
__clear_close_on_exec(fd, fdt);
|
||||
__put_unused_fd(files, fd);
|
||||
spin_unlock(&files->file_lock);
|
||||
retval = filp_close(filp, files);
|
||||
|
||||
retval = __close_fd(proc->files, fd);
|
||||
/* can't restart close syscall because file table entry was cleared */
|
||||
if (unlikely(retval == -ERESTARTSYS ||
|
||||
retval == -ERESTARTNOINTR ||
|
||||
@@ -493,10 +409,6 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd)
|
||||
retval = -EINTR;
|
||||
|
||||
return retval;
|
||||
|
||||
out_unlock:
|
||||
spin_unlock(&files->file_lock);
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
static void binder_set_nice(long nice)
|
||||
@@ -2793,6 +2705,9 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
const char *failure_string;
|
||||
struct binder_buffer *buffer;
|
||||
|
||||
if (proc->tsk != current)
|
||||
return -EINVAL;
|
||||
|
||||
if ((vma->vm_end - vma->vm_start) > SZ_4M)
|
||||
vma->vm_end = vma->vm_start + SZ_4M;
|
||||
|
||||
@@ -2857,7 +2772,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
binder_insert_free_buffer(proc, buffer);
|
||||
proc->free_async_space = proc->buffer_size / 2;
|
||||
barrier();
|
||||
proc->files = get_files_struct(proc->tsk);
|
||||
proc->files = get_files_struct(current);
|
||||
proc->vma = vma;
|
||||
proc->vma_vm_mm = vma->vm_mm;
|
||||
|
||||
|
||||
@@ -592,9 +592,8 @@ int omap_gem_mmap_obj(struct drm_gem_object *obj,
|
||||
* in particular in the case of mmap'd dmabufs)
|
||||
*/
|
||||
fput(vma->vm_file);
|
||||
get_file(obj->filp);
|
||||
vma->vm_pgoff = 0;
|
||||
vma->vm_file = obj->filp;
|
||||
vma->vm_file = get_file(obj->filp);
|
||||
|
||||
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
|
||||
}
|
||||
|
||||
+16
-29
@@ -1166,10 +1166,8 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf,
|
||||
struct file *p = NULL;
|
||||
|
||||
spin_lock(&redirect_lock);
|
||||
if (redirect) {
|
||||
get_file(redirect);
|
||||
p = redirect;
|
||||
}
|
||||
if (redirect)
|
||||
p = get_file(redirect);
|
||||
spin_unlock(&redirect_lock);
|
||||
|
||||
if (p) {
|
||||
@@ -2264,8 +2262,7 @@ static int tioccons(struct file *file)
|
||||
spin_unlock(&redirect_lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
get_file(file);
|
||||
redirect = file;
|
||||
redirect = get_file(file);
|
||||
spin_unlock(&redirect_lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -2809,6 +2806,13 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
}
|
||||
#endif
|
||||
|
||||
static int this_tty(const void *t, struct file *file, unsigned fd)
|
||||
{
|
||||
if (likely(file->f_op->read != tty_read))
|
||||
return 0;
|
||||
return file_tty(file) != t ? 0 : fd + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This implements the "Secure Attention Key" --- the idea is to
|
||||
* prevent trojan horses by killing all processes associated with this
|
||||
@@ -2836,8 +2840,6 @@ void __do_SAK(struct tty_struct *tty)
|
||||
struct task_struct *g, *p;
|
||||
struct pid *session;
|
||||
int i;
|
||||
struct file *filp;
|
||||
struct fdtable *fdt;
|
||||
|
||||
if (!tty)
|
||||
return;
|
||||
@@ -2867,27 +2869,12 @@ void __do_SAK(struct tty_struct *tty)
|
||||
continue;
|
||||
}
|
||||
task_lock(p);
|
||||
if (p->files) {
|
||||
/*
|
||||
* We don't take a ref to the file, so we must
|
||||
* hold ->file_lock instead.
|
||||
*/
|
||||
spin_lock(&p->files->file_lock);
|
||||
fdt = files_fdtable(p->files);
|
||||
for (i = 0; i < fdt->max_fds; i++) {
|
||||
filp = fcheck_files(p->files, i);
|
||||
if (!filp)
|
||||
continue;
|
||||
if (filp->f_op->read == tty_read &&
|
||||
file_tty(filp) == tty) {
|
||||
printk(KERN_NOTICE "SAK: killed process %d"
|
||||
" (%s): fd#%d opened to the tty\n",
|
||||
task_pid_nr(p), p->comm, i);
|
||||
force_sig(SIGKILL, p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&p->files->file_lock);
|
||||
i = iterate_fd(p->files, 0, this_tty, tty);
|
||||
if (i != 0) {
|
||||
printk(KERN_NOTICE "SAK: killed process %d"
|
||||
" (%s): fd#%d opened to the tty\n",
|
||||
task_pid_nr(p), p->comm, i - 1);
|
||||
force_sig(SIGKILL, p);
|
||||
}
|
||||
task_unlock(p);
|
||||
} while_each_thread(g, p);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user