mirror of
https://github.com/samba-team/samba.git
synced 2025-03-03 12:58:35 +03:00
s3: Fix strict locking with chained reads
Move the strict lock/unlock code down a level for reads to avoid calling chain_reply before the unlock.
This commit is contained in:
parent
5aefb44bf0
commit
c60bb39df3
@ -3352,12 +3352,22 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
|
|||||||
{
|
{
|
||||||
SMB_STRUCT_STAT sbuf;
|
SMB_STRUCT_STAT sbuf;
|
||||||
ssize_t nread = -1;
|
ssize_t nread = -1;
|
||||||
|
struct lock_struct lock;
|
||||||
|
|
||||||
if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
|
if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
|
||||||
reply_unixerror(req, ERRDOS, ERRnoaccess);
|
reply_unixerror(req, ERRDOS, ERRnoaccess);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init_strict_lock_struct(fsp, (uint32)req->smbpid,
|
||||||
|
(uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
|
||||||
|
&lock);
|
||||||
|
|
||||||
|
if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
|
||||||
|
reply_doserror(req, ERRDOS, ERRlock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!S_ISREG(sbuf.st_mode) || (startpos > sbuf.st_size)
|
if (!S_ISREG(sbuf.st_mode) || (startpos > sbuf.st_size)
|
||||||
|| (smb_maxcnt > (sbuf.st_size - startpos))) {
|
|| (smb_maxcnt > (sbuf.st_size - startpos))) {
|
||||||
/*
|
/*
|
||||||
@ -3419,8 +3429,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
|
|||||||
DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
|
DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
|
||||||
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
|
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
|
||||||
/* No outbuf here means successful sendfile. */
|
/* No outbuf here means successful sendfile. */
|
||||||
TALLOC_FREE(req->outbuf);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
|
DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
|
||||||
@ -3447,12 +3456,10 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
|
|||||||
if (nread != smb_maxcnt + sizeof(headerbuf)) {
|
if (nread != smb_maxcnt + sizeof(headerbuf)) {
|
||||||
sendfile_short_send(fsp, nread, sizeof(headerbuf), smb_maxcnt);
|
sendfile_short_send(fsp, nread, sizeof(headerbuf), smb_maxcnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No outbuf here means successful sendfile. */
|
/* No outbuf here means successful sendfile. */
|
||||||
TALLOC_FREE(req->outbuf);
|
|
||||||
SMB_PERFCOUNT_SET_MSGLEN_OUT(&req->pcd, nread);
|
SMB_PERFCOUNT_SET_MSGLEN_OUT(&req->pcd, nread);
|
||||||
SMB_PERFCOUNT_END(&req->pcd);
|
SMB_PERFCOUNT_END(&req->pcd);
|
||||||
return;
|
goto strict_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
normal_read:
|
normal_read:
|
||||||
@ -3478,8 +3485,7 @@ normal_read:
|
|||||||
fsp->fsp_name, strerror(errno) ));
|
fsp->fsp_name, strerror(errno) ));
|
||||||
exit_server_cleanly("send_file_readX: fake_sendfile failed");
|
exit_server_cleanly("send_file_readX: fake_sendfile failed");
|
||||||
}
|
}
|
||||||
TALLOC_FREE(req->outbuf);
|
goto strict_unlock;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nosendfile_read:
|
nosendfile_read:
|
||||||
@ -3487,6 +3493,9 @@ nosendfile_read:
|
|||||||
reply_outbuf(req, 12, smb_maxcnt);
|
reply_outbuf(req, 12, smb_maxcnt);
|
||||||
|
|
||||||
nread = read_file(fsp, smb_buf(req->outbuf), startpos, smb_maxcnt);
|
nread = read_file(fsp, smb_buf(req->outbuf), startpos, smb_maxcnt);
|
||||||
|
|
||||||
|
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
|
||||||
|
|
||||||
if (nread < 0) {
|
if (nread < 0) {
|
||||||
reply_unixerror(req, ERRDOS, ERRnoaccess);
|
reply_unixerror(req, ERRDOS, ERRnoaccess);
|
||||||
return;
|
return;
|
||||||
@ -3498,6 +3507,12 @@ nosendfile_read:
|
|||||||
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
|
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
|
||||||
|
|
||||||
chain_reply(req);
|
chain_reply(req);
|
||||||
|
return;
|
||||||
|
|
||||||
|
strict_unlock:
|
||||||
|
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
|
||||||
|
TALLOC_FREE(req->outbuf);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -3510,7 +3525,6 @@ void reply_read_and_X(struct smb_request *req)
|
|||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
SMB_OFF_T startpos;
|
SMB_OFF_T startpos;
|
||||||
size_t smb_maxcnt;
|
size_t smb_maxcnt;
|
||||||
struct lock_struct lock;
|
|
||||||
bool big_readX = False;
|
bool big_readX = False;
|
||||||
#if 0
|
#if 0
|
||||||
size_t smb_mincnt = SVAL(req->vwv+6, 0);
|
size_t smb_mincnt = SVAL(req->vwv+6, 0);
|
||||||
@ -3599,26 +3613,14 @@ void reply_read_and_X(struct smb_request *req)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init_strict_lock_struct(fsp, (uint32)req->smbpid,
|
|
||||||
(uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
|
|
||||||
&lock);
|
|
||||||
|
|
||||||
if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
|
|
||||||
END_PROFILE(SMBreadX);
|
|
||||||
reply_doserror(req, ERRDOS, ERRlock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!big_readX &&
|
if (!big_readX &&
|
||||||
schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
|
schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
|
||||||
goto strict_unlock;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
|
send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
|
||||||
|
|
||||||
strict_unlock:
|
out:
|
||||||
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
|
|
||||||
|
|
||||||
END_PROFILE(SMBreadX);
|
END_PROFILE(SMBreadX);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user