static const struct file_operations socket_file_ops = {
.owner =
THIS_MODULE,
.llseek =
no_llseek,
.read_iter =
sock_read_iter,
.write_iter =
sock_write_iter,
.poll =
sock_poll,
.unlocked_ioctl = sock_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_sock_ioctl,
#endif
.mmap =
sock_mmap,
.release =
sock_close,
.fasync =
sock_fasync,
.sendpage =
sock_sendpage,
.splice_write = generic_splice_sendpage,
.splice_read =
sock_splice_read,
};
/*
*
Obtains the first available file descriptor and sets it up for use.
*
*
These functions create file structures and maps them to fd space
*
of the current process. On success it returns file descriptor
*
and file struct implicitly stored in sock->file.
*
Note that another thread may close file descriptor before we return
*
from this function. We use the fact that now we do not refer
*
to socket after mapping. If one day we will need it, this
*
function will increment ref. count on file by 1.
*
*
In any case returned fd MAY BE not valid!
*
This race condition is unavoidable
*
with shared fd spaces, we cannot solve it inside kernel,
*
but we take care of internal coherence yet.
*/
struct file *
sock_alloc_file(struct socket *sock, int flags, const char *dname)
{
struct qstr name = { .name = "" };
struct path path;
struct file *file;
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))
return ERR_PTR(-ENOMEM);
path.mnt = mntget(sock_mnt);
d_instantiate(path.dentry, SOCK_INODE(sock));
file = alloc_file(&path, FMODE_READ | FMODE_WRITE,
&socket_file_ops);
if (IS_ERR(file)) {
/* drop dentry, keep inode */
ihold(d_inode(path.dentry));
path_put(&path);
return file;
}
sock->file = file;
file->f_flags = O_RDWR | (flags & O_NONBLOCK);
file->private_data = sock;
return file;
}
转载请注明原文地址: https://ju.6miu.com/read-37326.html