From: Linus Torvalds Date: Wed, 3 Oct 2012 03:25:04 +0000 (-0700) Subject: Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs X-Git-Tag: MMI-PSA29.97-13-9~15859 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=aab174f0df5d72d31caccf281af5f614fa254578;p=GitHub%2FMotorolaMobilityLLC%2Fkernel-slsi.git Merge branch 'for-linus' of git://git./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() ... --- aab174f0df5d72d31caccf281af5f614fa254578 diff --cc drivers/staging/android/binder.c index b1937ca13575,f71d624995ea..7b0ba92e7e46 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@@ -362,14 -362,9 +362,9 @@@ struct binder_transaction static void binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer); - /* - * copied from get_unused_fd_flags - */ -int task_get_unused_fd_flags(struct binder_proc *proc, int 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; diff --cc include/linux/net.h index 99276c3dc89a,c8a9708d4d66..6ab31cabef7c --- a/include/linux/net.h +++ b/include/linux/net.h @@@ -246,7 -247,7 +247,7 @@@ extern int sock_sendmsg(struct size_t len); extern int sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, int flags); - extern int sock_map_fd(struct socket *sock, int flags); -extern struct file *sock_alloc_file(struct socket *sock, int flags); ++extern struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname); extern struct socket *sockfd_lookup(int fd, int *err); extern struct socket *sock_from_file(struct file *file, int *err); #define sockfd_put(sock) fput(sock->file) diff --cc net/9p/trans_fd.c index 505f0ce3f10b,8c4e0b538a8a..15656b8573f3 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@@ -800,8 -801,8 +801,8 @@@ static int p9_socket_open(struct p9_cli return -ENOMEM; csocket->sk->sk_allocation = GFP_NOIO; - fd = sock_map_fd(csocket, 0); - if (fd < 0) { - file = sock_alloc_file(csocket, 0); ++ file = sock_alloc_file(csocket, 0, NULL); + if (IS_ERR(file)) { pr_err("%s (%d): failed to map fd\n", __func__, task_pid_nr(current)); sock_release(csocket); diff --cc net/sctp/socket.c index d37d24ff197f,fb5931ca50d0..59d16ea927f0 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@@ -4311,6 -4297,13 +4313,13 @@@ static int sctp_getsockopt_peeloff(stru goto out; } - newfile = sock_alloc_file(newsock, 0); ++ newfile = sock_alloc_file(newsock, 0, NULL); + if (unlikely(IS_ERR(newfile))) { + put_unused_fd(retval); + sock_release(newsock); + return PTR_ERR(newfile); + } + SCTP_DEBUG_PRINTK("%s: sk: %p newsk: %p sd: %d\n", __func__, sk, newsock->sk, retval); diff --cc net/socket.c index 80dc7e84b046,38a14311f3a6..d92c490e66fa --- a/net/socket.c +++ b/net/socket.c @@@ -347,30 -346,15 +347,22 @@@ static struct file_system_type sock_fs_ * but we take care of internal coherence yet. */ - static int sock_alloc_file(struct socket *sock, struct file **f, int flags, - const char *dname) -struct file *sock_alloc_file(struct socket *sock, int flags) ++struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname) { struct qstr name = { .name = "" }; struct path path; struct file *file; - int fd; - - fd = get_unused_fd_flags(flags); - if (unlikely(fd < 0)) - return fd; + if (dname) { + name.name = dname; + name.len = strlen(name.name); + } else if (sock->sk) { + name.name = sock->sk->sk_prot_creator->name; + name.len = strlen(name.name); + } path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name); - if (unlikely(!path.dentry)) { - put_unused_fd(fd); - return -ENOMEM; - } + if (unlikely(!path.dentry)) + return ERR_PTR(-ENOMEM); path.mnt = mntget(sock_mnt); d_instantiate(path.dentry, SOCK_INODE(sock)); @@@ -390,22 -373,26 +381,26 @@@ file->f_flags = O_RDWR | (flags & O_NONBLOCK); file->f_pos = 0; file->private_data = sock; - - *f = file; - return fd; + return file; } + EXPORT_SYMBOL(sock_alloc_file); - int sock_map_fd(struct socket *sock, int flags) + static int sock_map_fd(struct socket *sock, int flags) { struct file *newfile; - int fd = sock_alloc_file(sock, &newfile, flags, NULL); + int fd = get_unused_fd_flags(flags); + if (unlikely(fd < 0)) + return fd; - if (likely(fd >= 0)) - newfile = sock_alloc_file(sock, flags); ++ newfile = sock_alloc_file(sock, flags, NULL); + if (likely(!IS_ERR(newfile))) { fd_install(fd, newfile); + return fd; + } - return fd; + put_unused_fd(fd); + return PTR_ERR(newfile); } - EXPORT_SYMBOL(sock_map_fd); struct socket *sock_from_file(struct file *file, int *err) { @@@ -1471,12 -1395,27 +1466,27 @@@ SYSCALL_DEFINE4(socketpair, int, family err = fd1; goto out_release_both; } - - fd2 = sock_alloc_file(sock2, &newfile2, flags, NULL); + fd2 = get_unused_fd_flags(flags); if (unlikely(fd2 < 0)) { err = fd2; + put_unused_fd(fd1); + goto out_release_both; + } + - newfile1 = sock_alloc_file(sock1, flags); ++ newfile1 = sock_alloc_file(sock1, flags, NULL); + if (unlikely(IS_ERR(newfile1))) { + err = PTR_ERR(newfile1); + put_unused_fd(fd1); + put_unused_fd(fd2); + goto out_release_both; + } + - newfile2 = sock_alloc_file(sock2, flags); ++ newfile2 = sock_alloc_file(sock2, flags, NULL); + if (IS_ERR(newfile2)) { + err = PTR_ERR(newfile2); fput(newfile1); put_unused_fd(fd1); + put_unused_fd(fd2); sock_release(sock2); goto out; } @@@ -1615,6 -1553,13 +1624,13 @@@ SYSCALL_DEFINE4(accept4, int, fd, struc sock_release(newsock); goto out_put; } - newfile = sock_alloc_file(newsock, flags); ++ newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name); + if (unlikely(IS_ERR(newfile))) { + err = PTR_ERR(newfile); + put_unused_fd(newfd); + sock_release(newsock); + goto out_put; + } err = security_socket_accept(sock, newsock); if (err)