staticbool io_openat_force_async(struct io_open *open)
{ /* * Don't bother trying for O_TRUNC, O_CREAT, or O_TMPFILE open, * it'll always -EAGAIN. Note that we test for __O_TMPFILE because * O_TMPFILE includes O_DIRECTORY, which isn't a flag we need to force * async for.
*/ return open->how.flags & (O_TRUNC | O_CREAT | __O_TMPFILE);
}
if (!fixed) {
ret = __get_unused_fd_flags(open->how.flags, open->nofile); if (ret < 0) goto err;
}
file = do_filp_open(open->dfd, open->filename, &op); if (IS_ERR(file)) { /* * We could hang on to this 'fd' on retrying, but seems like * marginal gain for something that is now known to be a slower * path. So just put it, and we'll get a new one when we retry.
*/ if (!fixed)
put_unused_fd(ret);
ret = PTR_ERR(file); /* only retry if RESOLVE_CACHED wasn't already set by application */ if (ret == -EAGAIN &&
(!resolve_nonblock && (issue_flags & IO_URING_F_NONBLOCK))) return -EAGAIN; goto err;
}
if ((issue_flags & IO_URING_F_NONBLOCK) && !nonblock_set)
file->f_flags &= ~O_NONBLOCK;
if (!fixed)
fd_install(ret, file); else
ret = io_fixed_fd_install(req, issue_flags, file,
open->file_slot);
err:
putname(open->filename);
req->flags &= ~REQ_F_NEED_CLEANUP; if (ret < 0)
req_set_fail(req);
io_req_set_res(req, ret, 0); return IOU_COMPLETE;
}
/* if the file has a flush method, be safe and punt to async */ if (file->f_op->flush && (issue_flags & IO_URING_F_NONBLOCK)) {
spin_unlock(&files->file_lock); return -EAGAIN;
}
file = file_close_fd_locked(files, close->fd);
spin_unlock(&files->file_lock); if (!file) goto err;
/* No ->flush() or already async, safely close from here */
ret = filp_close(file, current->files);
err: if (ret < 0)
req_set_fail(req);
io_req_set_res(req, ret, 0); return IOU_COMPLETE;
}
/* must be a fixed file */ if (!(req->flags & REQ_F_FIXED_FILE)) return -EBADF;
flags = READ_ONCE(sqe->install_fd_flags); if (flags & ~IORING_FIXED_FD_NO_CLOEXEC) return -EINVAL;
/* ensure the task's creds are used when installing/receiving fds */ if (req->flags & REQ_F_CREDS) return -EPERM;
/* default to O_CLOEXEC, disable if IORING_FIXED_FD_NO_CLOEXEC is set */
ifi = io_kiocb_to_cmd(req, struct io_fixed_install);
ifi->o_flags = O_CLOEXEC; if (flags & IORING_FIXED_FD_NO_CLOEXEC)
ifi->o_flags = 0;
return 0;
}
int io_install_fixed_fd(struct io_kiocb *req, unsignedint issue_flags)
{ struct io_fixed_install *ifi; int ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.