Commit 27738039 authored by Jens Axboe's avatar Jens Axboe
Browse files

Merge branch 'for-5.19/io_uring-socket' into for-5.19/io_uring-net

* for-5.19/io_uring-socket: (73 commits)
  io_uring: use the text representation of ops in trace
  io_uring: rename op -> opcode
  io_uring: add io_uring_get_opcode
  io_uring: add type to op enum
  io_uring: add socket(2) support
  net: add __sys_socket_file()
  io_uring: fix trace for reduced sqe padding
  io_uring: add fgetxattr and getxattr support
  io_uring: add fsetxattr and setxattr support
  fs: split off do_getxattr from getxattr
  fs: split off setxattr_copy and do_setxattr function from setxattr
  io_uring: return an error when cqe is dropped
  io_uring: use constants for cq_overflow bitfield
  io_uring: rework io_uring_enter to simplify return value
  io_uring: trace cqe overflows
  io_uring: add trace support for CQE overflow
  io_uring: allow re-poll if we made progress
  io_uring: support MSG_WAITALL for IORING_OP_SEND(MSG)
  io_uring: add support for IORING_ASYNC_CANCEL_ANY
  io_uring: allow IORING_OP_ASYNC_CANCEL with 'fd' key
  ...
parents 8013d1d3 033b87d2
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -191,3 +191,32 @@ long splice_file_to_pipe(struct file *in,
			 struct pipe_inode_info *opipe,
			 loff_t *offset,
			 size_t len, unsigned int flags);

/*
 * fs/xattr.c:
 */
struct xattr_name {
	char name[XATTR_NAME_MAX + 1];
};

struct xattr_ctx {
	/* Value of attribute */
	union {
		const void __user *cvalue;
		void __user *value;
	};
	void *kvalue;
	size_t size;
	/* Attribute name */
	struct xattr_name *kname;
	unsigned int flags;
};


ssize_t do_getxattr(struct user_namespace *mnt_userns,
		    struct dentry *d,
		    struct xattr_ctx *ctx);

int setxattr_copy(const char __user *name, struct xattr_ctx *ctx);
int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
		struct xattr_ctx *ctx);
+1 −0
Original line number Diff line number Diff line
@@ -155,6 +155,7 @@ struct io_wq_work_node *wq_stack_extract(struct io_wq_work_node *stack)
struct io_wq_work {
	struct io_wq_work_node list;
	unsigned flags;
	int cancel_seq;
};

static inline struct io_wq_work *wq_next_work(struct io_wq_work *work)
+1368 −697

File changed.

Preview size limit exceeded, changes collapsed.

+97 −46
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@

#include <linux/uaccess.h>

#include "internal.h"

static const char *
strcmp_prefix(const char *a, const char *a_prefix)
{
@@ -539,44 +541,76 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
/*
 * Extended attribute SET operations
 */
static long
setxattr(struct user_namespace *mnt_userns, struct dentry *d,
	 const char __user *name, const void __user *value, size_t size,
	 int flags)

int setxattr_copy(const char __user *name, struct xattr_ctx *ctx)
{
	int error;
	void *kvalue = NULL;
	char kname[XATTR_NAME_MAX + 1];

	if (flags & ~(XATTR_CREATE|XATTR_REPLACE))
	if (ctx->flags & ~(XATTR_CREATE|XATTR_REPLACE))
		return -EINVAL;

	error = strncpy_from_user(kname, name, sizeof(kname));
	if (error == 0 || error == sizeof(kname))
		error = -ERANGE;
	error = strncpy_from_user(ctx->kname->name, name,
				sizeof(ctx->kname->name));
	if (error == 0 || error == sizeof(ctx->kname->name))
		return  -ERANGE;
	if (error < 0)
		return error;

	if (size) {
		if (size > XATTR_SIZE_MAX)
	error = 0;
	if (ctx->size) {
		if (ctx->size > XATTR_SIZE_MAX)
			return -E2BIG;
		kvalue = kvmalloc(size, GFP_KERNEL);
		if (!kvalue)
			return -ENOMEM;
		if (copy_from_user(kvalue, value, size)) {
			error = -EFAULT;
			goto out;

		ctx->kvalue = vmemdup_user(ctx->cvalue, ctx->size);
		if (IS_ERR(ctx->kvalue)) {
			error = PTR_ERR(ctx->kvalue);
			ctx->kvalue = NULL;
		}
		if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
		    (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
	}

	return error;
}

static void setxattr_convert(struct user_namespace *mnt_userns,
			     struct dentry *d, struct xattr_ctx *ctx)
{
	if (ctx->size &&
		((strcmp(ctx->kname->name, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
		(strcmp(ctx->kname->name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)))
		posix_acl_fix_xattr_from_user(mnt_userns, d_inode(d),
						      kvalue, size);
						ctx->kvalue, ctx->size);
}

	error = vfs_setxattr(mnt_userns, d, kname, kvalue, size, flags);
out:
	kvfree(kvalue);
int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry,
		struct xattr_ctx *ctx)
{
	setxattr_convert(mnt_userns, dentry, ctx);
	return vfs_setxattr(mnt_userns, dentry, ctx->kname->name,
			ctx->kvalue, ctx->size, ctx->flags);
}

static long
setxattr(struct user_namespace *mnt_userns, struct dentry *d,
	const char __user *name, const void __user *value, size_t size,
	int flags)
{
	struct xattr_name kname;
	struct xattr_ctx ctx = {
		.cvalue   = value,
		.kvalue   = NULL,
		.size     = size,
		.kname    = &kname,
		.flags    = flags,
	};
	int error;

	error = setxattr_copy(name, &ctx);
	if (error)
		return error;

	error = do_setxattr(mnt_userns, d, &ctx);

	kvfree(ctx.kvalue);
	return error;
}

@@ -642,44 +676,61 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
/*
 * Extended attribute GET operations
 */
static ssize_t
getxattr(struct user_namespace *mnt_userns, struct dentry *d,
	 const char __user *name, void __user *value, size_t size)
ssize_t
do_getxattr(struct user_namespace *mnt_userns, struct dentry *d,
	struct xattr_ctx *ctx)
{
	ssize_t error;
	void *kvalue = NULL;
	char kname[XATTR_NAME_MAX + 1];
	char *kname = ctx->kname->name;

	error = strncpy_from_user(kname, name, sizeof(kname));
	if (error == 0 || error == sizeof(kname))
		error = -ERANGE;
	if (error < 0)
		return error;

	if (size) {
		if (size > XATTR_SIZE_MAX)
			size = XATTR_SIZE_MAX;
		kvalue = kvzalloc(size, GFP_KERNEL);
		if (!kvalue)
	if (ctx->size) {
		if (ctx->size > XATTR_SIZE_MAX)
			ctx->size = XATTR_SIZE_MAX;
		ctx->kvalue = kvzalloc(ctx->size, GFP_KERNEL);
		if (!ctx->kvalue)
			return -ENOMEM;
	}

	error = vfs_getxattr(mnt_userns, d, kname, kvalue, size);
	error = vfs_getxattr(mnt_userns, d, kname, ctx->kvalue, ctx->size);
	if (error > 0) {
		if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
		    (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
			posix_acl_fix_xattr_to_user(mnt_userns, d_inode(d),
						    kvalue, error);
		if (size && copy_to_user(value, kvalue, error))
							ctx->kvalue, error);
		if (ctx->size && copy_to_user(ctx->value, ctx->kvalue, error))
			error = -EFAULT;
	} else if (error == -ERANGE && size >= XATTR_SIZE_MAX) {
	} else if (error == -ERANGE && ctx->size >= XATTR_SIZE_MAX) {
		/* The file system tried to returned a value bigger
		   than XATTR_SIZE_MAX bytes. Not possible. */
		error = -E2BIG;
	}

	kvfree(kvalue);
	return error;
}

static ssize_t
getxattr(struct user_namespace *mnt_userns, struct dentry *d,
	 const char __user *name, void __user *value, size_t size)
{
	ssize_t error;
	struct xattr_name kname;
	struct xattr_ctx ctx = {
		.value    = value,
		.kvalue   = NULL,
		.size     = size,
		.kname    = &kname,
		.flags    = 0,
	};

	error = strncpy_from_user(kname.name, name, sizeof(kname.name));
	if (error == 0 || error == sizeof(kname.name))
		error = -ERANGE;
	if (error < 0)
		return error;

	error =  do_getxattr(mnt_userns, d, &ctx);

	kvfree(ctx.kvalue);
	return error;
}

+5 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ struct sock *io_uring_get_socket(struct file *file);
void __io_uring_cancel(bool cancel_all);
void __io_uring_free(struct task_struct *tsk);
void io_uring_unreg_ringfd(void);
const char *io_uring_get_opcode(u8 opcode);

static inline void io_uring_files_cancel(void)
{
@@ -42,6 +43,10 @@ static inline void io_uring_files_cancel(void)
static inline void io_uring_free(struct task_struct *tsk)
{
}
static inline const char *io_uring_get_opcode(u8 opcode)
{
	return "";
}
#endif

#endif
Loading