650 /*
651 * Note: in_xoff is relative to the beginning of the "token"
652 * (a range of the source file tn1_off, tn1_eof). Make sure
653 * in_xoff is within the range represented by this token.
654 */
655 src_offset = tn1->tn1_off + args->in_xoff;
656 if (src_offset >= tn1->tn1_eof ||
657 src_offset < tn1->tn1_off) {
658 status = NT_STATUS_INVALID_PARAMETER;
659 goto out;
660 }
661
662 /*
663 * Get a buffer used for copying, always
664 * smb2_odx_buf_size (1M)
665 *
666 * Rather than sleep for this relatively large allocation,
667 * allow the allocation to fail and return an error.
668 * The client should then fall back to normal copy.
669 */
670 buffer = kmem_alloc(bufsize, KM_NOSLEEP | KM_NORMALPRI);
671 if (buffer == NULL) {
672 status = NT_STATUS_INSUFF_SERVER_RESOURCES;
673 goto out;
674 }
675
676 /*
677 * Copy src to dst for xlen
678 */
679 resid = xlen;
680 status = smb2_sparse_copy(sr, src_ofile, dst_ofile,
681 src_offset, args->in_dstoff, &resid, buffer, bufsize);
682
683 /*
684 * If the result was a partial copy, round down the
685 * reported transfer size to a block boundary.
686 */
687 if (resid != 0) {
688 xlen -= resid;
689 xlen &= ~OFFMASK;
690 args->out_xlen = xlen;
|
650 /*
651 * Note: in_xoff is relative to the beginning of the "token"
652 * (a range of the source file tn1_off, tn1_eof). Make sure
653 * in_xoff is within the range represented by this token.
654 */
655 src_offset = tn1->tn1_off + args->in_xoff;
656 if (src_offset >= tn1->tn1_eof ||
657 src_offset < tn1->tn1_off) {
658 status = NT_STATUS_INVALID_PARAMETER;
659 goto out;
660 }
661
662 /*
663 * Get a buffer used for copying, always
664 * smb2_odx_buf_size (1M)
665 *
666 * Rather than sleep for this relatively large allocation,
667 * allow the allocation to fail and return an error.
668 * The client should then fall back to normal copy.
669 */
670 buffer = kmem_alloc(bufsize, KM_NOSLEEP_LAZY);
671 if (buffer == NULL) {
672 status = NT_STATUS_INSUFF_SERVER_RESOURCES;
673 goto out;
674 }
675
676 /*
677 * Copy src to dst for xlen
678 */
679 resid = xlen;
680 status = smb2_sparse_copy(sr, src_ofile, dst_ofile,
681 src_offset, args->in_dstoff, &resid, buffer, bufsize);
682
683 /*
684 * If the result was a partial copy, round down the
685 * reported transfer size to a block boundary.
686 */
687 if (resid != 0) {
688 xlen -= resid;
689 xlen &= ~OFFMASK;
690 args->out_xlen = xlen;
|