diff options
author | Jeremy Allison <jra@samba.org> | 2000-09-29 20:18:14 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2000-09-29 20:18:14 +0000 |
commit | b8b683de77810c315f1984a68d128908347dc409 (patch) | |
tree | 7f70ee72d53ddbf71e699d9a0ee91e13829c95cc | |
parent | 08e04b8267705b3e2f34e6bcd86ce77f2a3e7b53 (diff) | |
download | samba-b8b683de77810c315f1984a68d128908347dc409.tar.gz |
Adnrew's 64 bit locking fixes for RedHat 7.0.... (sigh). They don't
seem to peturb much.
Jeremy.
-rw-r--r-- | source/include/includes.h | 13 | ||||
-rw-r--r-- | source/include/proto.h | 4 | ||||
-rw-r--r-- | source/lib/system.c | 14 | ||||
-rw-r--r-- | source/libsmb/clifile.c | 96 | ||||
-rw-r--r-- | source/smbd/reply.c | 2 | ||||
-rw-r--r-- | source/utils/locktest.c | 38 |
6 files changed, 147 insertions, 20 deletions
diff --git a/source/include/includes.h b/source/include/includes.h index a18c8b6d5cb..da16ae16320 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -951,5 +951,18 @@ extern int DEBUGLEVEL; #define MAX_SEC_CTX_DEPTH 8 /* Maximum number of security contexts */ + +#ifdef GLIBC_HACK_FCNTL64 +/* this is a gross hack. 64 bit locking is completely screwed up on + i386 Linux in glibc 2.1.95 (which ships with RedHat 7.0). This hack + "fixes" the problem with the current 2.4.0test kernels +*/ +#define fcntl fcntl64 +#undef F_SETLKW +#undef F_SETLK +#define F_SETLK 13 +#define F_SETLKW 14 +#endif + #endif /* _INCLUDES_H */ diff --git a/source/include/proto.h b/source/include/proto.h index c901e9bf719..9b1a293c62e 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -279,6 +279,7 @@ pid_t sys_fork(void); pid_t sys_getpid(void); int sys_popen(const char *command); int sys_pclose(int fd); +int fcntl64(int fd, int cmd, struct flock * lock); /*The following definitions come from lib/talloc.c */ @@ -677,6 +678,9 @@ BOOL cli_close(struct cli_state *cli, int fnum); BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout, enum brl_type lock_type); BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len); +BOOL cli_lock64(struct cli_state *cli, int fnum, + SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type lock_type); +BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len); BOOL cli_getattrE(struct cli_state *cli, int fd, uint16 *attr, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time); diff --git a/source/lib/system.c b/source/lib/system.c index 479bce19659..e846e4755ec 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -1013,3 +1013,17 @@ int sys_pclose(int fd) return -1; return wstatus; } + + + +#if GLIBC_HACK_FCNTL64 +#include <asm/unistd.h> +/* this is a gross hack. 64 bit locking is completely screwed up on + i386 Linux in glibc 2.1.95 (which ships with RedHat 7.0). This hack + "fixes" the problem with the current 2.4.0test kernels +*/ +int fcntl64(int fd, int cmd, struct flock * lock) +{ + return syscall(__NR_fcntl64, fd, cmd, lock); +} +#endif /* HACK_FCNTL64 */ diff --git a/source/libsmb/clifile.c b/source/libsmb/clifile.c index 214c30d930a..63f6f8cc6c6 100644 --- a/source/libsmb/clifile.c +++ b/source/libsmb/clifile.c @@ -409,6 +409,102 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) } +/**************************************************************************** + lock a file with 64 bit offsets +****************************************************************************/ +BOOL cli_lock64(struct cli_state *cli, int fnum, + SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type lock_type) +{ + char *p; + int saved_timeout = cli->timeout; + int ltype; + + ltype = (lock_type == READ_LOCK? 1 : 0); + ltype |= LOCKING_ANDX_LARGE_FILES; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0', smb_size); + + set_message(cli->outbuf,8,20,True); + + CVAL(cli->outbuf,smb_com) = SMBlockingX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + CVAL(cli->outbuf,smb_vwv3) = ltype; + SIVALS(cli->outbuf, smb_vwv4, timeout); + SSVAL(cli->outbuf,smb_vwv6,0); + SSVAL(cli->outbuf,smb_vwv7,1); + + p = smb_buf(cli->outbuf); + SIVAL(p, 0, cli->pid); + SIVAL(p, 4, (offset>>32)); + SIVAL(p, 8, (offset&0xffffffff)); + SIVAL(p, 12, (len>>32)); + SIVAL(p, 16, (len&0xffffffff)); + cli_send_smb(cli); + + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); + + if (!cli_receive_smb(cli)) { + cli->timeout = saved_timeout; + return False; + } + + cli->timeout = saved_timeout; + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + +/**************************************************************************** + unlock a file with 64 bit offsets +****************************************************************************/ +BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,8,20,True); + + CVAL(cli->outbuf,smb_com) = SMBlockingX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + CVAL(cli->outbuf,smb_vwv3) = LOCKING_ANDX_LARGE_FILES; + SIVALS(cli->outbuf, smb_vwv4, 0); + SSVAL(cli->outbuf,smb_vwv6,1); + SSVAL(cli->outbuf,smb_vwv7,0); + + p = smb_buf(cli->outbuf); + SIVAL(p, 0, cli->pid); + SIVAL(p, 4, (offset>>32)); + SIVAL(p, 8, (offset&0xffffffff)); + SIVAL(p, 12, (len>>32)); + SIVAL(p, 16, (len&0xffffffff)); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + + diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 8624bdb9b4a..96a43b48c82 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -4025,7 +4025,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length, char *data; uint32 ecode=0, dummy2; int eclass=0, dummy1; - BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); + BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False; BOOL err; CHECK_FSP(fsp,conn); diff --git a/source/utils/locktest.c b/source/utils/locktest.c index c5d04724207..80dbba1e37e 100644 --- a/source/utils/locktest.c +++ b/source/utils/locktest.c @@ -33,8 +33,8 @@ static BOOL hide_unlock_fails; static BOOL use_oplocks; #define FILENAME "\\locktest.dat" -#define LOCKRANGE 100 -#define LOCKBASE 0 +#define LOCKRANGE 1000 +#define LOCKBASE 0; /* #define LOCKBASE (0x40000000 - 50) @@ -55,7 +55,7 @@ static BOOL use_oplocks; struct record { char r1, r2; char conn, f; - unsigned start, len; + SMB_BIG_UINT start, len; char needed; }; @@ -236,8 +236,8 @@ static BOOL test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS], { unsigned conn = rec->conn; unsigned f = rec->f; - unsigned start = rec->start; - unsigned len = rec->len; + SMB_BIG_UINT start = rec->start; + SMB_BIG_UINT len = rec->len; unsigned r1 = rec->r1; unsigned r2 = rec->r2; unsigned op; @@ -253,14 +253,14 @@ static BOOL test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS], if (r2 < LOCK_PCT) { /* set a lock */ for (server=0;server<NSERVERS;server++) { - ret[server] = cli_lock(cli[server][conn], - fnum[server][conn][f], - start, len, LOCK_TIMEOUT, op); + ret[server] = cli_lock64(cli[server][conn], + fnum[server][conn][f], + start, len, LOCK_TIMEOUT, op); } if (showall || ret[0] != ret[1]) { - printf("lock conn=%u f=%u range=%u:%u(%u) op=%s -> %u:%u\n", + printf("lock conn=%u f=%u range=%.0f:%.0f(%.0f) op=%s -> %u:%u\n", conn, f, - start, start+len-1, len, + (double)start, (double)start+len-1, (double)len, op==READ_LOCK?"READ_LOCK":"WRITE_LOCK", ret[0], ret[1]); } @@ -269,14 +269,14 @@ static BOOL test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS], } else if (r2 < LOCK_PCT+UNLOCK_PCT) { /* unset a lock */ for (server=0;server<NSERVERS;server++) { - ret[server] = cli_unlock(cli[server][conn], - fnum[server][conn][f], - start, len); + ret[server] = cli_unlock64(cli[server][conn], + fnum[server][conn][f], + start, len); } if (showall || (!hide_unlock_fails && (ret[0] != ret[1]))) { - printf("unlock conn=%u f=%u range=%u:%u(%u) -> %u:%u\n", + printf("unlock conn=%u f=%u range=%.0f:%.0f(%.0f) -> %u:%u\n", conn, f, - start, start+len-1, len, + (double)start, (double)start+len-1, (double)len, ret[0], ret[1]); } if (showall || ret[0] != ret[1]) show_locks(); @@ -442,13 +442,13 @@ static void test_locks(char *share[NSERVERS]) close_files(cli, fnum); for (i=0;i<n;i++) { - printf("{%u, %u, %u, %u, %u, %u, %u},\n", + printf("{%u, %u, %u, %u, %.0f, %.0f, %u},\n", recorded[i].r1, recorded[i].r2, recorded[i].conn, recorded[i].f, - recorded[i].start, - recorded[i].len, + (double)recorded[i].start, + (double)recorded[i].len, recorded[i].needed); } } @@ -488,7 +488,7 @@ static void usage(void) dbf = stderr; - if (argv[1][0] == '-' || argc < 3) { + if (argc < 3 || argv[1][0] == '-') { usage(); exit(1); } |