.. | .. |
---|
21 | 21 | struct kiocb iocb; |
---|
22 | 22 | refcount_t ref; |
---|
23 | 23 | struct kiocb *orig_iocb; |
---|
24 | | - struct fd fd; |
---|
25 | 24 | }; |
---|
26 | 25 | |
---|
27 | 26 | static struct kmem_cache *ovl_aio_request_cachep; |
---|
.. | .. |
---|
247 | 246 | static inline void ovl_aio_put(struct ovl_aio_req *aio_req) |
---|
248 | 247 | { |
---|
249 | 248 | if (refcount_dec_and_test(&aio_req->ref)) { |
---|
250 | | - fdput(aio_req->fd); |
---|
| 249 | + fput(aio_req->iocb.ki_filp); |
---|
251 | 250 | kmem_cache_free(ovl_aio_request_cachep, aio_req); |
---|
252 | 251 | } |
---|
253 | 252 | } |
---|
.. | .. |
---|
314 | 313 | if (!aio_req) |
---|
315 | 314 | goto out; |
---|
316 | 315 | |
---|
317 | | - aio_req->fd = real; |
---|
318 | 316 | real.flags = 0; |
---|
319 | 317 | aio_req->orig_iocb = iocb; |
---|
320 | | - kiocb_clone(&aio_req->iocb, iocb, real.file); |
---|
| 318 | + kiocb_clone(&aio_req->iocb, iocb, get_file(real.file)); |
---|
321 | 319 | aio_req->iocb.ki_complete = ovl_aio_rw_complete; |
---|
322 | 320 | refcount_set(&aio_req->ref, 2); |
---|
323 | 321 | ret = vfs_iocb_iter_read(real.file, &aio_req->iocb, iter); |
---|
.. | .. |
---|
387 | 385 | /* Pacify lockdep, same trick as done in aio_write() */ |
---|
388 | 386 | __sb_writers_release(file_inode(real.file)->i_sb, |
---|
389 | 387 | SB_FREEZE_WRITE); |
---|
390 | | - aio_req->fd = real; |
---|
391 | 388 | real.flags = 0; |
---|
392 | 389 | aio_req->orig_iocb = iocb; |
---|
393 | | - kiocb_clone(&aio_req->iocb, iocb, real.file); |
---|
| 390 | + kiocb_clone(&aio_req->iocb, iocb, get_file(real.file)); |
---|
394 | 391 | aio_req->iocb.ki_flags = ifl; |
---|
395 | 392 | aio_req->iocb.ki_complete = ovl_aio_rw_complete; |
---|
396 | 393 | refcount_set(&aio_req->ref, 2); |
---|
.. | .. |
---|
519 | 516 | const struct cred *old_cred; |
---|
520 | 517 | int ret; |
---|
521 | 518 | |
---|
| 519 | + inode_lock(inode); |
---|
| 520 | + /* Update mode */ |
---|
| 521 | + ovl_copyattr(ovl_inode_real(inode), inode); |
---|
| 522 | + ret = file_remove_privs(file); |
---|
| 523 | + if (ret) |
---|
| 524 | + goto out_unlock; |
---|
| 525 | + |
---|
522 | 526 | ret = ovl_real_fdget(file, &real); |
---|
523 | 527 | if (ret) |
---|
524 | | - return ret; |
---|
| 528 | + goto out_unlock; |
---|
525 | 529 | |
---|
526 | 530 | old_cred = ovl_override_creds(file_inode(file)->i_sb); |
---|
527 | 531 | ret = vfs_fallocate(real.file, mode, offset, len); |
---|
.. | .. |
---|
531 | 535 | ovl_copyattr(ovl_inode_real(inode), inode); |
---|
532 | 536 | |
---|
533 | 537 | fdput(real); |
---|
| 538 | + |
---|
| 539 | +out_unlock: |
---|
| 540 | + inode_unlock(inode); |
---|
534 | 541 | |
---|
535 | 542 | return ret; |
---|
536 | 543 | } |
---|
.. | .. |
---|
675 | 682 | const struct cred *old_cred; |
---|
676 | 683 | loff_t ret; |
---|
677 | 684 | |
---|
| 685 | + inode_lock(inode_out); |
---|
| 686 | + if (op != OVL_DEDUPE) { |
---|
| 687 | + /* Update mode */ |
---|
| 688 | + ovl_copyattr(ovl_inode_real(inode_out), inode_out); |
---|
| 689 | + ret = file_remove_privs(file_out); |
---|
| 690 | + if (ret) |
---|
| 691 | + goto out_unlock; |
---|
| 692 | + } |
---|
| 693 | + |
---|
678 | 694 | ret = ovl_real_fdget(file_out, &real_out); |
---|
679 | 695 | if (ret) |
---|
680 | | - return ret; |
---|
| 696 | + goto out_unlock; |
---|
681 | 697 | |
---|
682 | 698 | ret = ovl_real_fdget(file_in, &real_in); |
---|
683 | 699 | if (ret) { |
---|
684 | 700 | fdput(real_out); |
---|
685 | | - return ret; |
---|
| 701 | + goto out_unlock; |
---|
686 | 702 | } |
---|
687 | 703 | |
---|
688 | 704 | old_cred = ovl_override_creds(file_inode(file_out)->i_sb); |
---|
.. | .. |
---|
711 | 727 | fdput(real_in); |
---|
712 | 728 | fdput(real_out); |
---|
713 | 729 | |
---|
| 730 | +out_unlock: |
---|
| 731 | + inode_unlock(inode_out); |
---|
| 732 | + |
---|
714 | 733 | return ret; |
---|
715 | 734 | } |
---|
716 | 735 | |
---|