| .. | .. |
|---|
| 386 | 386 | |
|---|
| 387 | 387 | uni_mode = use_unicode(inode); |
|---|
| 388 | 388 | attr = use_attributes(inode); |
|---|
| 389 | | - ret = -ENXIO; |
|---|
| 390 | | - vc = vcs_vc(inode, &viewed); |
|---|
| 391 | | - if (!vc) |
|---|
| 392 | | - goto unlock_out; |
|---|
| 393 | 389 | |
|---|
| 394 | 390 | ret = -EINVAL; |
|---|
| 395 | 391 | if (pos < 0) |
|---|
| .. | .. |
|---|
| 407 | 403 | unsigned int this_round, skip = 0; |
|---|
| 408 | 404 | int size; |
|---|
| 409 | 405 | |
|---|
| 406 | + vc = vcs_vc(inode, &viewed); |
|---|
| 407 | + if (!vc) { |
|---|
| 408 | + ret = -ENXIO; |
|---|
| 409 | + break; |
|---|
| 410 | + } |
|---|
| 411 | + |
|---|
| 410 | 412 | /* Check whether we are above size each round, |
|---|
| 411 | 413 | * as copy_to_user at the end of this loop |
|---|
| 412 | 414 | * could sleep. |
|---|
| 413 | 415 | */ |
|---|
| 414 | 416 | size = vcs_size(vc, attr, uni_mode); |
|---|
| 415 | 417 | if (size < 0) { |
|---|
| 416 | | - if (read) |
|---|
| 417 | | - break; |
|---|
| 418 | 418 | ret = size; |
|---|
| 419 | | - goto unlock_out; |
|---|
| 419 | + break; |
|---|
| 420 | 420 | } |
|---|
| 421 | 421 | if (pos >= size) |
|---|
| 422 | 422 | break; |
|---|
| .. | .. |
|---|
| 656 | 656 | } |
|---|
| 657 | 657 | } |
|---|
| 658 | 658 | |
|---|
| 659 | | - /* The vcs_size might have changed while we slept to grab |
|---|
| 660 | | - * the user buffer, so recheck. |
|---|
| 659 | + /* The vc might have been freed or vcs_size might have changed |
|---|
| 660 | + * while we slept to grab the user buffer, so recheck. |
|---|
| 661 | 661 | * Return data written up to now on failure. |
|---|
| 662 | 662 | */ |
|---|
| 663 | + vc = vcs_vc(inode, &viewed); |
|---|
| 664 | + if (!vc) { |
|---|
| 665 | + if (written) |
|---|
| 666 | + break; |
|---|
| 667 | + ret = -ENXIO; |
|---|
| 668 | + goto unlock_out; |
|---|
| 669 | + } |
|---|
| 663 | 670 | size = vcs_size(vc, attr, false); |
|---|
| 664 | 671 | if (size < 0) { |
|---|
| 665 | 672 | if (written) |
|---|