int smb_write(struct smb_share *ssp, u_int16_t fid, struct uio *uio, struct smb_cred *scred) { int error = 0; size_t len, tsize, resid; int wx = (SMB_CAPS(SSTOVC(ssp)) & SMB_CAP_LARGE_WRITEX); resid = 0; /* XXX gcc */ tsize = uio->uio_resid; while (tsize > 0) { len = tsize; if (wx) error = smb_smb_writex(ssp, fid, &len, &resid, uio, scred); else error = smb_smb_write(ssp, fid, &len, &resid, uio, scred); if (error) break; if (resid < len) { error = EIO; break; } tsize -= resid; } return error; }
int smb_write(struct smb_share *ssp, u_int16_t fid, struct uio *uio, struct smb_cred *scred) { int error = 0, len, resid; struct uio olduio; olduio = *uio; while (uio->uio_resid > 0) { if (uio->uio_resid > INT_MAX) len = INT_MAX; else len = (int)uio->uio_resid; error = smb_smb_write(ssp, fid, &len, &resid, uio, scred); if (error) break; if (resid < len) { error = EIO; break; } } if (error) { /* * Errors can happen on the copyin, the rpc, etc. So they * imply resid is unreliable. The only safe thing is * to pretend zero bytes made it. We needn't restore the * iovs because callers don't depend on them in error * paths - uio_resid and uio_offset are what matter. */ *uio = olduio; } return error; }
int smb_write(struct smb_share *ssp, u_int16_t fid, struct uio *uio, struct smb_cred *scred) { int error = 0, len, tsize, resid; struct uio olduio; /* * review: manage iov more precisely */ if (uio->uio_iovcnt != 1) { SMBERROR("can't handle iovcnt > 1\n"); return EIO; } tsize = uio->uio_resid; olduio = *uio; while (tsize > 0) { len = tsize; error = smb_smb_write(ssp, fid, &len, &resid, uio, scred); if (error) break; if (resid < len) { error = EIO; break; } tsize -= resid; } if (error) { *uio = olduio; } return error; }