summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2000-09-29 20:18:14 +0000
committerJeremy Allison <jra@samba.org>2000-09-29 20:18:14 +0000
commitb8b683de77810c315f1984a68d128908347dc409 (patch)
tree7f70ee72d53ddbf71e699d9a0ee91e13829c95cc
parent08e04b8267705b3e2f34e6bcd86ce77f2a3e7b53 (diff)
downloadsamba-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.h13
-rw-r--r--source/include/proto.h4
-rw-r--r--source/lib/system.c14
-rw-r--r--source/libsmb/clifile.c96
-rw-r--r--source/smbd/reply.c2
-rw-r--r--source/utils/locktest.c38
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);
}