diff options
author | Kent Overstreet <koverstreet@google.com> | 2013-05-07 19:18:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-07 21:38:28 -0400 |
commit | 1d98ebfccc15aeea87a7c48d50d7343e1ce8daae (patch) | |
tree | fd38e32b9629b7988569d4b28c50c462bb6f13c3 /fs/aio.c | |
parent | caf4167aa73bef20f5ce994b776ecb2e44226e5e (diff) |
aio: do fget() after aio_get_req()
aio_get_req() will fail if we have the maximum number of requests
outstanding, which depending on the application may not be uncommon. So
avoid doing an unnecessary fget().
Signed-off-by: Kent Overstreet <koverstreet@google.com>
Cc: Zach Brown <zab@redhat.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Asai Thambi S P <asamymuthupa@micron.com>
Cc: Selvan Mani <smani@micron.com>
Cc: Sam Bradshaw <sbradshaw@micron.com>
Acked-by: Jeff Moyer <jmoyer@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Benjamin LaHaise <bcrl@kvack.org>
Reviewed-by: "Theodore Ts'o" <tytso@mit.edu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/aio.c')
-rw-r--r-- | fs/aio.c | 22 |
1 files changed, 9 insertions, 13 deletions
@@ -587,6 +587,8 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req) | |||
587 | { | 587 | { |
588 | assert_spin_locked(&ctx->ctx_lock); | 588 | assert_spin_locked(&ctx->ctx_lock); |
589 | 589 | ||
590 | if (req->ki_filp) | ||
591 | fput(req->ki_filp); | ||
590 | if (req->ki_eventfd != NULL) | 592 | if (req->ki_eventfd != NULL) |
591 | eventfd_ctx_put(req->ki_eventfd); | 593 | eventfd_ctx_put(req->ki_eventfd); |
592 | if (req->ki_dtor) | 594 | if (req->ki_dtor) |
@@ -605,9 +607,6 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req) | |||
605 | */ | 607 | */ |
606 | static void __aio_put_req(struct kioctx *ctx, struct kiocb *req) | 608 | static void __aio_put_req(struct kioctx *ctx, struct kiocb *req) |
607 | { | 609 | { |
608 | pr_debug("(%p): f_count=%ld\n", | ||
609 | req, atomic_long_read(&req->ki_filp->f_count)); | ||
610 | |||
611 | assert_spin_locked(&ctx->ctx_lock); | 610 | assert_spin_locked(&ctx->ctx_lock); |
612 | 611 | ||
613 | req->ki_users--; | 612 | req->ki_users--; |
@@ -618,8 +617,6 @@ static void __aio_put_req(struct kioctx *ctx, struct kiocb *req) | |||
618 | req->ki_cancel = NULL; | 617 | req->ki_cancel = NULL; |
619 | req->ki_retry = NULL; | 618 | req->ki_retry = NULL; |
620 | 619 | ||
621 | fput(req->ki_filp); | ||
622 | req->ki_filp = NULL; | ||
623 | really_put_req(ctx, req); | 620 | really_put_req(ctx, req); |
624 | } | 621 | } |
625 | 622 | ||
@@ -1270,7 +1267,6 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1270 | bool compat) | 1267 | bool compat) |
1271 | { | 1268 | { |
1272 | struct kiocb *req; | 1269 | struct kiocb *req; |
1273 | struct file *file; | ||
1274 | ssize_t ret; | 1270 | ssize_t ret; |
1275 | 1271 | ||
1276 | /* enforce forwards compatibility on users */ | 1272 | /* enforce forwards compatibility on users */ |
@@ -1289,16 +1285,16 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1289 | return -EINVAL; | 1285 | return -EINVAL; |
1290 | } | 1286 | } |
1291 | 1287 | ||
1292 | file = fget(iocb->aio_fildes); | ||
1293 | if (unlikely(!file)) | ||
1294 | return -EBADF; | ||
1295 | |||
1296 | req = aio_get_req(ctx, batch); /* returns with 2 references to req */ | 1288 | req = aio_get_req(ctx, batch); /* returns with 2 references to req */ |
1297 | if (unlikely(!req)) { | 1289 | if (unlikely(!req)) |
1298 | fput(file); | ||
1299 | return -EAGAIN; | 1290 | return -EAGAIN; |
1291 | |||
1292 | req->ki_filp = fget(iocb->aio_fildes); | ||
1293 | if (unlikely(!req->ki_filp)) { | ||
1294 | ret = -EBADF; | ||
1295 | goto out_put_req; | ||
1300 | } | 1296 | } |
1301 | req->ki_filp = file; | 1297 | |
1302 | if (iocb->aio_flags & IOCB_FLAG_RESFD) { | 1298 | if (iocb->aio_flags & IOCB_FLAG_RESFD) { |
1303 | /* | 1299 | /* |
1304 | * If the IOCB_FLAG_RESFD flag of aio_flags is set, get an | 1300 | * If the IOCB_FLAG_RESFD flag of aio_flags is set, get an |