.. | .. |
---|
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) |
---|