]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/socket.c
Merge ../linus
[linux-2.6-omap-h63xx.git] / net / socket.c
index df92e4252749b025503f0f35f85d5fec9d79b64e..4e396312f8d58751d0c23914a056126e79ff72ac 100644 (file)
@@ -77,7 +77,6 @@
 #include <linux/cache.h>
 #include <linux/module.h>
 #include <linux/highmem.h>
-#include <linux/divert.h>
 #include <linux/mount.h>
 #include <linux/security.h>
 #include <linux/syscalls.h>
@@ -110,10 +109,6 @@ static long compat_sock_ioctl(struct file *file,
                              unsigned int cmd, unsigned long arg);
 #endif
 static int sock_fasync(int fd, struct file *filp, int on);
-static ssize_t sock_readv(struct file *file, const struct iovec *vector,
-                         unsigned long count, loff_t *ppos);
-static ssize_t sock_writev(struct file *file, const struct iovec *vector,
-                          unsigned long count, loff_t *ppos);
 static ssize_t sock_sendpage(struct file *file, struct page *page,
                             int offset, size_t size, loff_t *ppos, int more);
 
@@ -136,8 +131,6 @@ static struct file_operations socket_file_ops = {
        .open =         sock_no_open,   /* special open code to disallow open via /proc */
        .release =      sock_close,
        .fasync =       sock_fasync,
-       .readv =        sock_readv,
-       .writev =       sock_writev,
        .sendpage =     sock_sendpage,
        .splice_write = generic_splice_sendpage,
 };
@@ -237,13 +230,13 @@ int move_addr_to_user(void *kaddr, int klen, void __user *uaddr,
 
 #define SOCKFS_MAGIC 0x534F434B
 
-static kmem_cache_t *sock_inode_cachep __read_mostly;
+static struct kmem_cache *sock_inode_cachep __read_mostly;
 
 static struct inode *sock_alloc_inode(struct super_block *sb)
 {
        struct socket_alloc *ei;
 
-       ei = kmem_cache_alloc(sock_inode_cachep, SLAB_KERNEL);
+       ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL);
        if (!ei)
                return NULL;
        init_waitqueue_head(&ei->socket.wait);
@@ -264,7 +257,7 @@ static void sock_destroy_inode(struct inode *inode)
                        container_of(inode, struct socket_alloc, vfs_inode));
 }
 
-static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
+static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
 {
        struct socket_alloc *ei = (struct socket_alloc *)foo;
 
@@ -312,7 +305,14 @@ static struct file_system_type sock_fs_type = {
 
 static int sockfs_delete_dentry(struct dentry *dentry)
 {
-       return 1;
+       /*
+        * At creation time, we pretended this dentry was hashed
+        * (by clearing DCACHE_UNHASHED bit in d_flags)
+        * At delete time, we restore the truth : not hashed.
+        * (so that dput() can proceed correctly)
+        */
+       dentry->d_flags |= DCACHE_UNHASHED;
+       return 0;
 }
 static struct dentry_operations sockfs_dentry_operations = {
        .d_delete = sockfs_delete_dentry,
@@ -360,16 +360,22 @@ static int sock_attach_fd(struct socket *sock, struct file *file)
 
        this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
        this.name = name;
-       this.hash = SOCK_INODE(sock)->i_ino;
+       this.hash = 0;
 
-       file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
-       if (unlikely(!file->f_dentry))
+       file->f_path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
+       if (unlikely(!file->f_path.dentry))
                return -ENOMEM;
 
-       file->f_dentry->d_op = &sockfs_dentry_operations;
-       d_add(file->f_dentry, SOCK_INODE(sock));
-       file->f_vfsmnt = mntget(sock_mnt);
-       file->f_mapping = file->f_dentry->d_inode->i_mapping;
+       file->f_path.dentry->d_op = &sockfs_dentry_operations;
+       /*
+        * We dont want to push this dentry into global dentry hash table.
+        * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
+        * This permits a working /proc/$pid/fd/XXX on sockets
+        */
+       file->f_path.dentry->d_flags &= ~DCACHE_UNHASHED;
+       d_instantiate(file->f_path.dentry, SOCK_INODE(sock));
+       file->f_path.mnt = mntget(sock_mnt);
+       file->f_mapping = file->f_path.dentry->d_inode->i_mapping;
 
        sock->file = file;
        file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;
@@ -407,7 +413,7 @@ static struct socket *sock_from_file(struct file *file, int *err)
        if (file->f_op == &socket_file_ops)
                return file->private_data;      /* set in sock_map_fd */
 
-       inode = file->f_dentry->d_inode;
+       inode = file->f_path.dentry->d_inode;
        if (!S_ISSOCK(inode->i_mode)) {
                *err = -ENOTSOCK;
                return NULL;
@@ -700,23 +706,6 @@ static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb,
        return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags);
 }
 
-static ssize_t sock_readv(struct file *file, const struct iovec *iov,
-                         unsigned long nr_segs, loff_t *ppos)
-{
-       struct kiocb iocb;
-       struct sock_iocb siocb;
-       struct msghdr msg;
-       int ret;
-
-       init_sync_kiocb(&iocb, NULL);
-       iocb.private = &siocb;
-
-       ret = do_sock_read(&msg, &iocb, file, iov, nr_segs);
-       if (-EIOCBQUEUED == ret)
-               ret = wait_on_sync_kiocb(&iocb);
-       return ret;
-}
-
 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
                                unsigned long nr_segs, loff_t pos)
 {
@@ -759,23 +748,6 @@ static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
        return __sock_sendmsg(iocb, sock, msg, size);
 }
 
-static ssize_t sock_writev(struct file *file, const struct iovec *iov,
-                          unsigned long nr_segs, loff_t *ppos)
-{
-       struct msghdr msg;
-       struct kiocb iocb;
-       struct sock_iocb siocb;
-       int ret;
-
-       init_sync_kiocb(&iocb, NULL);
-       iocb.private = &siocb;
-
-       ret = do_sock_write(&msg, &iocb, file, iov, nr_segs);
-       if (-EIOCBQUEUED == ret)
-               ret = wait_on_sync_kiocb(&iocb);
-       return ret;
-}
-
 static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,
                          unsigned long nr_segs, loff_t pos)
 {
@@ -865,7 +837,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
                        break;
                case FIOGETOWN:
                case SIOCGPGRP:
-                       err = put_user(sock->file->f_owner.pid,
+                       err = put_user(f_getown(sock->file),
                                       (int __user *)argp);
                        break;
                case SIOCGIFBR:
@@ -892,11 +864,6 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
                                err = vlan_ioctl_hook(argp);
                        mutex_unlock(&vlan_ioctl_mutex);
                        break;
-               case SIOCGIFDIVERT:
-               case SIOCSIFDIVERT:
-                       /* Convert this to call through a hook */
-                       err = divert_ioctl(cmd, argp);
-                       break;
                case SIOCADDDLCI:
                case SIOCDELDLCI:
                        err = -ENOPKG;