1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-04 08:22:08 +03:00

Move from timestamp to gen count file id's for finding oplocked files

in a tdb.
Jeremy.
(This used to be commit 058ae6b58f)
This commit is contained in:
Jeremy Allison
2001-10-20 21:59:34 +00:00
parent e5868e1f57
commit 88b55f47b4
8 changed files with 900 additions and 894 deletions

View File

@ -408,6 +408,7 @@ typedef struct files_struct
time_t pending_modtime; time_t pending_modtime;
int oplock_type; int oplock_type;
int sent_oplock_break; int sent_oplock_break;
unsigned long file_id;
BOOL can_lock; BOOL can_lock;
BOOL can_read; BOOL can_read;
BOOL can_write; BOOL can_write;
@ -557,13 +558,15 @@ struct interface
}; };
/* struct returned by get_share_modes */ /* struct returned by get_share_modes */
typedef struct typedef struct {
{ pid_t pid;
pid_t pid; uint16 op_port;
uint16 op_port; uint16 op_type;
uint16 op_type; int share_mode;
int share_mode; struct timeval time;
struct timeval time; SMB_DEV_T dev;
SMB_INO_T inode;
unsigned long share_file_id;
} share_mode_entry; } share_mode_entry;
@ -1409,19 +1412,18 @@ extern int chain_size;
* *
* The form of this is : * The form of this is :
* *
* 0 2 6 10 14 14+devsize 14+devsize+inodesize * 0 2 2+pid 2+pid+dev 2+pid+dev+ino
* +----+--------+--------+--------+-------+--------+ * +----+--------+-------+--------+---------+
* | cmd| pid | sec | usec | dev | inode | * | cmd| pid | dev | inode | fileid |
* +----+--------+--------+--------+-------+--------+ * +----+--------+-------+--------+---------+
*/ */
#define OPLOCK_BREAK_CMD 0x1 #define OPLOCK_BREAK_CMD 0x1
#define OPLOCK_BREAK_PID_OFFSET 2 #define OPLOCK_BREAK_PID_OFFSET 2
#define OPLOCK_BREAK_SEC_OFFSET (OPLOCK_BREAK_PID_OFFSET + sizeof(pid_t)) #define OPLOCK_BREAK_DEV_OFFSET (OPLOCK_BREAK_PID_OFFSET + sizeof(pid_t))
#define OPLOCK_BREAK_USEC_OFFSET (OPLOCK_BREAK_SEC_OFFSET + sizeof(time_t))
#define OPLOCK_BREAK_DEV_OFFSET (OPLOCK_BREAK_USEC_OFFSET + sizeof(long))
#define OPLOCK_BREAK_INODE_OFFSET (OPLOCK_BREAK_DEV_OFFSET + sizeof(SMB_DEV_T)) #define OPLOCK_BREAK_INODE_OFFSET (OPLOCK_BREAK_DEV_OFFSET + sizeof(SMB_DEV_T))
#define OPLOCK_BREAK_MSG_LEN (OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T)) #define OPLOCK_BREAK_FILEID_OFFSET (OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T))
#define OPLOCK_BREAK_MSG_LEN (OPLOCK_BREAK_FILEID_OFFSET + sizeof(unsigned long))
#define KERNEL_OPLOCK_BREAK_CMD 0x2 #define KERNEL_OPLOCK_BREAK_CMD 0x2
#define LEVEL_II_OPLOCK_BREAK_CMD 0x3 #define LEVEL_II_OPLOCK_BREAK_CMD 0x3
@ -1438,13 +1440,14 @@ extern int chain_size;
* Form of this is : * Form of this is :
* *
* 0 2 2+devsize 2+devsize+inodesize * 0 2 2+devsize 2+devsize+inodesize
* +----+--------+--------+ * +----+--------+--------+----------+
* | cmd| dev | inode | * | cmd| dev | inode | fileid |
* +----+--------+--------+ * +----+--------+--------+----------+
*/ */
#define KERNEL_OPLOCK_BREAK_DEV_OFFSET 2 #define KERNEL_OPLOCK_BREAK_DEV_OFFSET 2
#define KERNEL_OPLOCK_BREAK_INODE_OFFSET (KERNEL_OPLOCK_BREAK_DEV_OFFSET + sizeof(SMB_DEV_T)) #define KERNEL_OPLOCK_BREAK_INODE_OFFSET (KERNEL_OPLOCK_BREAK_DEV_OFFSET + sizeof(SMB_DEV_T))
#define KERNEL_OPLOCK_BREAK_MSG_LEN (KERNEL_OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T)) #define KERNEL_OPLOCK_BREAK_FILEID_OFFSET (KERNEL_OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T))
#define KERNEL_OPLOCK_BREAK_MSG_LEN (KERNEL_OPLOCK_BREAK_FILEID_OFFSET + sizeof(unsigned long))
/* if a kernel does support oplocks then a structure of the following /* if a kernel does support oplocks then a structure of the following
@ -1453,7 +1456,7 @@ struct kernel_oplocks {
BOOL (*receive_message)(fd_set *fds, char *buffer, int buffer_len); BOOL (*receive_message)(fd_set *fds, char *buffer, int buffer_len);
BOOL (*set_oplock)(files_struct *fsp, int oplock_type); BOOL (*set_oplock)(files_struct *fsp, int oplock_type);
void (*release_oplock)(files_struct *fsp); void (*release_oplock)(files_struct *fsp);
BOOL (*parse_message)(char *msg_start, int msg_len, SMB_INO_T *inode, SMB_DEV_T *dev); BOOL (*parse_message)(char *msg_start, int msg_len, SMB_INO_T *inode, SMB_DEV_T *dev, unsigned long *file_id);
BOOL (*msg_waiting)(fd_set *fds); BOOL (*msg_waiting)(fd_set *fds);
int notification_fd; int notification_fd;
}; };

View File

@ -586,7 +586,7 @@ int cli_NetUserAdd(struct cli_state *cli, RAP_USER_INFO_1 * userinfo )
PUTWORD(p, 0); /* pwencrypt */ PUTWORD(p, 0); /* pwencrypt */
if(userinfo->passwrd) if(userinfo->passwrd)
PUTWORD(p,strnlen(userinfo->passwrd, RAP_UPASSWD_LEN)); PUTWORD(p,MIN(strlen(userinfo->passwrd), RAP_UPASSWD_LEN));
else else
PUTWORD(p, 0); /* password length */ PUTWORD(p, 0); /* password length */

View File

@ -349,10 +349,6 @@ static TDB_DATA locking_key_fsp(files_struct *fsp)
return locking_key(fsp->dev, fsp->inode); return locking_key(fsp->dev, fsp->inode);
} }
#ifndef LOCK_SHARE_ENTRY_SPIN_COUNT
#define LOCK_SHARE_ENTRY_SPIN_COUNT 100
#endif
/******************************************************************* /*******************************************************************
Lock a hash bucket entry. Lock a hash bucket entry.
******************************************************************/ ******************************************************************/
@ -436,6 +432,9 @@ static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_t
e->op_port = port; e->op_port = port;
e->op_type = op_type; e->op_type = op_type;
memcpy(x, &fsp->open_time, sizeof(struct timeval)); memcpy(x, &fsp->open_time, sizeof(struct timeval));
e->share_file_id = fsp->file_id;
e->dev = fsp->dev;
e->inode = fsp->inode;
} }
/******************************************************************* /*******************************************************************
@ -445,10 +444,24 @@ static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_t
BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2) BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2)
{ {
#if 1 /* JRA PARANOIA TEST - REMOVE LATER */
if (e1->pid == e2->pid &&
e1->share_file_id == e2->share_file_id &&
e1->dev == e2->dev &&
e1->inode == e2->inode &&
(e1->share_mode & ~DELETE_ON_CLOSE_FLAG) != (e2->share_mode & ~DELETE_ON_CLOSE_FLAG)) {
DEBUG(0,("PANIC: share_modes_identical: share_mode missmatch (e1 = %u, e2 = %u). Logic error.\n",
(unsigned int)(e1->share_mode & ~DELETE_ON_CLOSE_FLAG),
(unsigned int)(e2->share_mode & ~DELETE_ON_CLOSE_FLAG) ));
smb_panic("PANIC: share_modes_identical logic error.\n");
}
#endif
return (e1->pid == e2->pid && return (e1->pid == e2->pid &&
(e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) && (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) &&
e1->time.tv_sec == e2->time.tv_sec && e1->dev == e2->dev &&
e1->time.tv_usec == e2->time.tv_usec ); e1->inode == e2->inode &&
e1->share_file_id == e2->share_file_id );
} }
/******************************************************************* /*******************************************************************

View File

@ -39,8 +39,22 @@ static files_struct *oplock_save_chain_fsp = NULL;
static int files_used; static int files_used;
/**************************************************************************** /****************************************************************************
find first available file slot Return a unique number identifying this fsp over the life of this pid.
****************************************************************************/ ****************************************************************************/
static unsigned long get_gen_count(void)
{
static unsigned long file_gen_counter;
if ((++file_gen_counter) == 0)
return ++file_gen_counter;
return file_gen_counter;
}
/****************************************************************************
Find first available file slot.
****************************************************************************/
files_struct *file_new(connection_struct *conn) files_struct *file_new(connection_struct *conn)
{ {
int i; int i;
@ -90,6 +104,8 @@ files_struct *file_new(connection_struct *conn)
ZERO_STRUCTP(fsp); ZERO_STRUCTP(fsp);
fsp->fd = -1; fsp->fd = -1;
fsp->conn = conn; fsp->conn = conn;
fsp->file_id = get_gen_count();
GetTimeOfDay(&fsp->open_time);
first_file = (i+1) % real_max_open_files; first_file = (i+1) % real_max_open_files;
@ -109,10 +125,10 @@ files_struct *file_new(connection_struct *conn)
return fsp; return fsp;
} }
/**************************************************************************** /****************************************************************************
close all open files for a connection Close all open files for a connection.
****************************************************************************/ ****************************************************************************/
void file_close_conn(connection_struct *conn) void file_close_conn(connection_struct *conn)
{ {
files_struct *fsp, *next; files_struct *fsp, *next;
@ -126,7 +142,7 @@ void file_close_conn(connection_struct *conn)
} }
/**************************************************************************** /****************************************************************************
initialise file structures Initialise file structures.
****************************************************************************/ ****************************************************************************/
#define MAX_OPEN_FUDGEFACTOR 10 #define MAX_OPEN_FUDGEFACTOR 10
@ -162,10 +178,10 @@ open files, %d are available.\n", request_max_open_files, real_max_open_files));
set_pipe_handle_offset(real_max_open_files); set_pipe_handle_offset(real_max_open_files);
} }
/**************************************************************************** /****************************************************************************
close files open by a specified vuid Close files open by a specified vuid.
****************************************************************************/ ****************************************************************************/
void file_close_user(int vuid) void file_close_user(int vuid)
{ {
files_struct *fsp, *next; files_struct *fsp, *next;
@ -178,13 +194,32 @@ void file_close_user(int vuid)
} }
} }
/**************************************************************************** /****************************************************************************
Find a fsp given a device, inode and timevalue Find a fsp given a file descriptor.
If this is from a kernel oplock break request then tval may be NULL.
****************************************************************************/ ****************************************************************************/
files_struct *file_find_dit(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval) files_struct *file_find_fd(int fd)
{
int count=0;
files_struct *fsp;
for (fsp=Files;fsp;fsp=fsp->next,count++) {
if (fsp->fd == fd) {
if (count > 10) {
DLIST_PROMOTE(Files, fsp);
}
return fsp;
}
}
return NULL;
}
/****************************************************************************
Find a fsp given a device, inode and file_id.
****************************************************************************/
files_struct *file_find_dif(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id)
{ {
int count=0; int count=0;
files_struct *fsp; files_struct *fsp;
@ -193,8 +228,7 @@ files_struct *file_find_dit(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval
if (fsp->fd != -1 && if (fsp->fd != -1 &&
fsp->dev == dev && fsp->dev == dev &&
fsp->inode == inode && fsp->inode == inode &&
(tval ? (fsp->open_time.tv_sec == tval->tv_sec) : True ) && fsp->file_id == file_id ) {
(tval ? (fsp->open_time.tv_usec == tval->tv_usec) : True )) {
if (count > 10) { if (count > 10) {
DLIST_PROMOTE(Files, fsp); DLIST_PROMOTE(Files, fsp);
} }
@ -258,8 +292,9 @@ files_struct *file_find_di_next(files_struct *start_fsp)
} }
/**************************************************************************** /****************************************************************************
find a fsp that is open for printing Find a fsp that is open for printing.
****************************************************************************/ ****************************************************************************/
files_struct *file_find_print(void) files_struct *file_find_print(void)
{ {
files_struct *fsp; files_struct *fsp;
@ -271,10 +306,10 @@ files_struct *file_find_print(void)
return NULL; return NULL;
} }
/**************************************************************************** /****************************************************************************
sync open files on a connection Sync open files on a connection.
****************************************************************************/ ****************************************************************************/
void file_sync_all(connection_struct *conn) void file_sync_all(connection_struct *conn)
{ {
files_struct *fsp, *next; files_struct *fsp, *next;
@ -287,10 +322,10 @@ void file_sync_all(connection_struct *conn)
} }
} }
/**************************************************************************** /****************************************************************************
free up a fsp Free up a fsp.
****************************************************************************/ ****************************************************************************/
void file_free(files_struct *fsp) void file_free(files_struct *fsp)
{ {
DLIST_REMOVE(Files, fsp); DLIST_REMOVE(Files, fsp);
@ -312,16 +347,17 @@ void file_free(files_struct *fsp)
SAFE_FREE(fsp); SAFE_FREE(fsp);
} }
/**************************************************************************** /****************************************************************************
get a fsp from a packet given the offset of a 16 bit fnum Get a fsp from a packet given the offset of a 16 bit fnum.
****************************************************************************/ ****************************************************************************/
files_struct *file_fsp(char *buf, int where) files_struct *file_fsp(char *buf, int where)
{ {
int fnum, count=0; int fnum, count=0;
files_struct *fsp; files_struct *fsp;
if (chain_fsp) return chain_fsp; if (chain_fsp)
return chain_fsp;
fnum = SVAL(buf, where); fnum = SVAL(buf, where);
@ -338,7 +374,7 @@ files_struct *file_fsp(char *buf, int where)
} }
/**************************************************************************** /****************************************************************************
Reset the chained fsp - done at the start of a packet reply Reset the chained fsp - done at the start of a packet reply.
****************************************************************************/ ****************************************************************************/
void file_chain_reset(void) void file_chain_reset(void)
@ -358,6 +394,7 @@ void file_chain_save(void)
/**************************************************************************** /****************************************************************************
Restore the chained fsp - done after an oplock break. Restore the chained fsp - done after an oplock break.
****************************************************************************/ ****************************************************************************/
void file_chain_restore(void) void file_chain_restore(void)
{ {
chain_fsp = oplock_save_chain_fsp; chain_fsp = oplock_save_chain_fsp;

View File

@ -181,7 +181,6 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
fsp->mode = psbuf->st_mode; fsp->mode = psbuf->st_mode;
fsp->inode = psbuf->st_ino; fsp->inode = psbuf->st_ino;
fsp->dev = psbuf->st_dev; fsp->dev = psbuf->st_dev;
GetTimeOfDay(&fsp->open_time);
fsp->vuid = current_user.vuid; fsp->vuid = current_user.vuid;
fsp->size = psbuf->st_size; fsp->size = psbuf->st_size;
fsp->pos = -1; fsp->pos = -1;
@ -489,7 +488,7 @@ dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsi
/* Oplock break - unlock to request it. */ /* Oplock break - unlock to request it. */
unlock_share_entry(conn, dev, inode); unlock_share_entry(conn, dev, inode);
opb_ret = request_oplock_break(share_entry, dev, inode); opb_ret = request_oplock_break(share_entry);
/* Now relock. */ /* Now relock. */
lock_share_entry(conn, dev, inode); lock_share_entry(conn, dev, inode);
@ -946,11 +945,9 @@ files_struct *open_file_stat(connection_struct *conn, char *fname,
* Setup the files_struct for it. * Setup the files_struct for it.
*/ */
fsp->fd = -1;
fsp->mode = psbuf->st_mode; fsp->mode = psbuf->st_mode;
fsp->inode = psbuf->st_ino; fsp->inode = psbuf->st_ino;
fsp->dev = psbuf->st_dev; fsp->dev = psbuf->st_dev;
GetTimeOfDay(&fsp->open_time);
fsp->size = psbuf->st_size; fsp->size = psbuf->st_size;
fsp->vuid = current_user.vuid; fsp->vuid = current_user.vuid;
fsp->pos = -1; fsp->pos = -1;
@ -1110,11 +1107,9 @@ files_struct *open_directory(connection_struct *conn, char *fname,
* Setup the files_struct for it. * Setup the files_struct for it.
*/ */
fsp->fd = -1;
fsp->mode = psbuf->st_mode; fsp->mode = psbuf->st_mode;
fsp->inode = psbuf->st_ino; fsp->inode = psbuf->st_ino;
fsp->dev = psbuf->st_dev; fsp->dev = psbuf->st_dev;
GetTimeOfDay(&fsp->open_time);
fsp->size = psbuf->st_size; fsp->size = psbuf->st_size;
fsp->vuid = current_user.vuid; fsp->vuid = current_user.vuid;
fsp->pos = -1; fsp->pos = -1;
@ -1230,7 +1225,7 @@ dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (doub
/* Oplock break.... */ /* Oplock break.... */
unlock_share_entry(conn, dev, inode); unlock_share_entry(conn, dev, inode);
if(request_oplock_break(share_entry, dev, inode) == False) if(request_oplock_break(share_entry) == False)
{ {
DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \ DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode)); dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));

File diff suppressed because it is too large Load Diff

View File

@ -27,8 +27,9 @@ static int oplock_pipe_write = -1;
static int oplock_pipe_read = -1; static int oplock_pipe_read = -1;
/**************************************************************************** /****************************************************************************
test to see if IRIX kernel oplocks work Test to see if IRIX kernel oplocks work.
****************************************************************************/ ****************************************************************************/
static BOOL irix_oplocks_available(void) static BOOL irix_oplocks_available(void)
{ {
int fd; int fd;
@ -81,106 +82,113 @@ Disabling kernel oplock support.\n", strerror(errno) ));
return True; return True;
} }
/**************************************************************************** /****************************************************************************
* Deal with the IRIX kernel <--> smbd * Deal with the IRIX kernel <--> smbd
* oplock break protocol. * oplock break protocol.
****************************************************************************/ ****************************************************************************/
static BOOL irix_oplock_receive_message(fd_set *fds, char *buffer, int buffer_len) static BOOL irix_oplock_receive_message(fd_set *fds, char *buffer, int buffer_len)
{ {
extern int smb_read_error; extern int smb_read_error;
oplock_stat_t os; oplock_stat_t os;
SMB_DEV_T dev; char dummy;
SMB_INO_T inode; files_struct *fsp;
char dummy;
/* /*
* Read one byte of zero to clear the * Read one byte of zero to clear the
* kernel break notify message. * kernel break notify message.
*/ */
if(read(oplock_pipe_read, &dummy, 1) != 1) { if(read(oplock_pipe_read, &dummy, 1) != 1) {
DEBUG(0,("receive_local_message: read of kernel notification failed. \ DEBUG(0,("receive_local_message: read of kernel notification failed. \
Error was %s.\n", strerror(errno) )); Error was %s.\n", strerror(errno) ));
smb_read_error = READ_ERROR; smb_read_error = READ_ERROR;
return False; return False;
} }
/* /*
* Do a query to get the * Do a query to get the
* device and inode of the file that has the break * device and inode of the file that has the break
* request outstanding. * request outstanding.
*/ */
if(fcntl(oplock_pipe_read, F_OPLKSTAT, &os) < 0) { if(fcntl(oplock_pipe_read, F_OPLKSTAT, &os) < 0) {
DEBUG(0,("receive_local_message: fcntl of kernel notification failed. \ DEBUG(0,("receive_local_message: fcntl of kernel notification failed. \
Error was %s.\n", strerror(errno) )); Error was %s.\n", strerror(errno) ));
if(errno == EAGAIN) { if(errno == EAGAIN) {
/* /*
* Duplicate kernel break message - ignore. * Duplicate kernel break message - ignore.
*/ */
memset(buffer, '\0', KERNEL_OPLOCK_BREAK_MSG_LEN); memset(buffer, '\0', KERNEL_OPLOCK_BREAK_MSG_LEN);
return True; return True;
} }
smb_read_error = READ_ERROR; smb_read_error = READ_ERROR;
return False; return False;
} }
dev = (SMB_DEV_T)os.os_dev; /*
inode = (SMB_INO_T)os.os_ino; * We only have device and inode info here - we have to guess that this
* is the first fsp open with this dev,ino pair.
*/
if ((fsp = file_find_di_first((SMB_DEV_T)os.os_dev, (SMB_INO_T)os.os_ino)) == NULL) {
DEBUG(0,("receive_local_message: unable to find open file with dev = %x, inode = %.0f\n",
(unsigned int)os.os_dev, (double)os.os_ino ));
return False;
}
DEBUG(5,("receive_local_message: kernel oplock break request received for \ DEBUG(5,("receive_local_message: kernel oplock break request received for \
dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode )); dev = %x, inode = %.0f\n, file_id = %ul", (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id ));
/* /*
* Create a kernel oplock break message. * Create a kernel oplock break message.
*/ */
/* Setup the message header */
SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,KERNEL_OPLOCK_BREAK_MSG_LEN);
SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,0);
buffer += OPBRK_CMD_HEADER_LEN;
/* Setup the message header */ SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,KERNEL_OPLOCK_BREAK_MSG_LEN);
SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,0); memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&fsp->dev, sizeof(fsp->dev));
memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&fsp->inode, sizeof(fsp->inode));
buffer += OPBRK_CMD_HEADER_LEN; memcpy(buffer + KERNEL_OPLOCK_BREAK_FILEID_OFFSET, (char *)&fsp->file_id, sizeof(fsp->file_id));
SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD); return True;
memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&dev, sizeof(dev));
memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&inode, sizeof(inode));
return True;
} }
/**************************************************************************** /****************************************************************************
Attempt to set an kernel oplock on a file. Attempt to set an kernel oplock on a file.
****************************************************************************/ ****************************************************************************/
static BOOL irix_set_kernel_oplock(files_struct *fsp, int oplock_type) static BOOL irix_set_kernel_oplock(files_struct *fsp, int oplock_type)
{ {
if (fcntl(fsp->fd, F_OPLKREG, oplock_pipe_write) == -1) { if (fcntl(fsp->fd, F_OPLKREG, oplock_pipe_write) == -1) {
if(errno != EAGAIN) { if(errno != EAGAIN) {
DEBUG(0,("set_file_oplock: Unable to get kernel oplock on file %s, dev = %x, \ DEBUG(0,("set_file_oplock: Unable to get kernel oplock on file %s, dev = %x, \
inode = %.0f. Error was %s\n", inode = %.0f, file_id = %ul. Error was %s\n",
fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id,
strerror(errno) )); strerror(errno) ));
} else { } else {
DEBUG(5,("set_file_oplock: Refused oplock on file %s, fd = %d, dev = %x, \ DEBUG(5,("set_file_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
inode = %.0f. Another process had the file open.\n", inode = %.0f, file_id = %ul. Another process had the file open.\n",
fsp->fsp_name, fsp->fd, (unsigned int)fsp->dev, (double)fsp->inode )); fsp->fsp_name, fsp->fd, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id ));
} }
return False; return False;
} }
DEBUG(10,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f\n", DEBUG(10,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f, file_id = %ul\n",
fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode)); fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id));
return True; return True;
} }
/**************************************************************************** /****************************************************************************
Release a kernel oplock on a file. Release a kernel oplock on a file.
****************************************************************************/ ****************************************************************************/
static void irix_release_kernel_oplock(files_struct *fsp) static void irix_release_kernel_oplock(files_struct *fsp)
{ {
if (DEBUGLVL(10)) { if (DEBUGLVL(10)) {
@ -189,9 +197,9 @@ static void irix_release_kernel_oplock(files_struct *fsp)
* oplock state of this file. * oplock state of this file.
*/ */
int state = fcntl(fsp->fd, F_OPLKACK, -1); int state = fcntl(fsp->fd, F_OPLKACK, -1);
dbgtext("release_kernel_oplock: file %s, dev = %x, inode = %.0f has kernel \ dbgtext("release_kernel_oplock: file %s, dev = %x, inode = %.0f file_id = %ul, has kernel \
oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev, oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
(double)fsp->inode, state ); (double)fsp->inode, fsp->file_id, state );
} }
/* /*
@ -200,18 +208,19 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
if(fcntl(fsp->fd, F_OPLKACK, OP_REVOKE) < 0) { if(fcntl(fsp->fd, F_OPLKACK, OP_REVOKE) < 0) {
if( DEBUGLVL( 0 )) { if( DEBUGLVL( 0 )) {
dbgtext("release_kernel_oplock: Error when removing kernel oplock on file " ); dbgtext("release_kernel_oplock: Error when removing kernel oplock on file " );
dbgtext("%s, dev = %x, inode = %.0f. Error was %s\n", dbgtext("%s, dev = %x, inode = %.0f, file_id = %ul. Error was %s\n",
fsp->fsp_name, (unsigned int)fsp->dev, fsp->fsp_name, (unsigned int)fsp->dev,
(double)fsp->inode, strerror(errno) ); (double)fsp->inode, fsp->file_id, strerror(errno) );
} }
} }
} }
/**************************************************************************** /****************************************************************************
parse a kernel oplock message Parse a kernel oplock message.
****************************************************************************/ ****************************************************************************/
static BOOL irix_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *inode, SMB_DEV_T *dev)
static BOOL irix_kernel_oplock_parse(char *msg_start, int msg_len,
SMB_INO_T *inode, SMB_DEV_T *dev, unsigned long *file_id)
{ {
/* Ensure that the msg length is correct. */ /* Ensure that the msg length is correct. */
if(msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN) { if(msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN) {
@ -220,36 +229,39 @@ static BOOL irix_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *in
return False; return False;
} }
memcpy((char *)inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(*inode)); memcpy((char *)inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(*inode));
memcpy((char *)dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(*dev)); memcpy((char *)dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(*dev));
memcpy((char *)file_id, msg_start+KERNEL_OPLOCK_BREAK_FILEID_OFFSET, sizeof(*file_id));
DEBUG(5,("kernel oplock break request for file dev = %x, inode = %.0f\n", DEBUG(5,("kernel oplock break request for file dev = %x, inode = %.0f, file_id = %ul\n",
(unsigned int)*dev, (double)*inode)); (unsigned int)*dev, (double)*inode, *file_id));
return True; return True;
} }
/**************************************************************************** /****************************************************************************
set *maxfd to include oplock read pipe Set *maxfd to include oplock read pipe.
****************************************************************************/ ****************************************************************************/
static BOOL irix_oplock_msg_waiting(fd_set *fds) static BOOL irix_oplock_msg_waiting(fd_set *fds)
{ {
if (oplock_pipe_read == -1) return False; if (oplock_pipe_read == -1)
return False;
return FD_ISSET(oplock_pipe_read,fds); return FD_ISSET(oplock_pipe_read,fds);
} }
/**************************************************************************** /****************************************************************************
setup kernel oplocks Setup kernel oplocks.
****************************************************************************/ ****************************************************************************/
struct kernel_oplocks *irix_init_kernel_oplocks(void) struct kernel_oplocks *irix_init_kernel_oplocks(void)
{ {
int pfd[2]; int pfd[2];
static struct kernel_oplocks koplocks; static struct kernel_oplocks koplocks;
if (!irix_oplocks_available()) return NULL; if (!irix_oplocks_available())
return NULL;
if(pipe(pfd) != 0) { if(pipe(pfd) != 0) {
DEBUG(0,("setup_kernel_oplock_pipe: Unable to create pipe. Error was %s\n", DEBUG(0,("setup_kernel_oplock_pipe: Unable to create pipe. Error was %s\n",
@ -269,9 +281,6 @@ struct kernel_oplocks *irix_init_kernel_oplocks(void)
return &koplocks; return &koplocks;
} }
#else #else
void oplock_irix_dummy(void) {} void oplock_irix_dummy(void) {}
#endif /* HAVE_KERNEL_OPLOCKS_IRIX */ #endif /* HAVE_KERNEL_OPLOCKS_IRIX */

View File

@ -48,8 +48,9 @@ static VOLATILE sig_atomic_t fd_pending; /* the fd of the current pending signal
#endif #endif
/**************************************************************************** /****************************************************************************
handle a LEASE signal, incrementing the signals_received and blocking the signal Handle a LEASE signal, incrementing the signals_received and blocking the signal.
****************************************************************************/ ****************************************************************************/
static void signal_handler(int sig, siginfo_t *info, void *unused) static void signal_handler(int sig, siginfo_t *info, void *unused)
{ {
BlockSignals(True, sig); BlockSignals(True, sig);
@ -59,8 +60,9 @@ static void signal_handler(int sig, siginfo_t *info, void *unused)
} }
/**************************************************************************** /****************************************************************************
try to gain a linux capability Try to gain a linux capability.
****************************************************************************/ ****************************************************************************/
static void set_capability(unsigned capability) static void set_capability(unsigned capability)
{ {
#ifndef _LINUX_CAPABILITY_VERSION #ifndef _LINUX_CAPABILITY_VERSION
@ -93,11 +95,11 @@ static void set_capability(unsigned capability)
} }
} }
/**************************************************************************** /****************************************************************************
call SETLEASE. If we get EACCES then we try setting up the right capability and Call SETLEASE. If we get EACCES then we try setting up the right capability and
try again try again
****************************************************************************/ ****************************************************************************/
static int linux_setlease(int fd, int leasetype) static int linux_setlease(int fd, int leasetype)
{ {
int ret; int ret;
@ -116,31 +118,27 @@ static int linux_setlease(int fd, int leasetype)
return ret; return ret;
} }
/**************************************************************************** /****************************************************************************
* Deal with the Linux kernel <--> smbd * Deal with the Linux kernel <--> smbd
* oplock break protocol. * oplock break protocol.
****************************************************************************/ ****************************************************************************/
static BOOL linux_oplock_receive_message(fd_set *fds, char *buffer, int buffer_len) static BOOL linux_oplock_receive_message(fd_set *fds, char *buffer, int buffer_len)
{ {
SMB_DEV_T dev;
SMB_INO_T inode;
SMB_STRUCT_STAT sbuf;
BOOL ret = True; BOOL ret = True;
struct files_struct *fsp;
if (signals_received == signals_processed) return False; if (signals_received == signals_processed)
return False;
if (sys_fstat((int)fd_pending,&sbuf) == -1) { if ((fsp = file_find_fd(fd_pending)) == NULL) {
DEBUG(0,("Invalid file descriptor %d in kernel oplock break!\n", (int)fd_pending)); DEBUG(0,("Invalid file descriptor %d in kernel oplock break!\n", (int)fd_pending));
ret = False; ret = False;
goto out; goto out;
} }
dev = sbuf.st_dev;
inode = sbuf.st_ino;
DEBUG(3,("receive_local_message: kernel oplock break request received for \ DEBUG(3,("receive_local_message: kernel oplock break request received for \
dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode )); dev = %x, inode = %.0f\n", (unsigned int)fsp->dev, (double)fsp->inode ));
/* /*
* Create a kernel oplock break message. * Create a kernel oplock break message.
@ -154,8 +152,9 @@ dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD); SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&dev, sizeof(dev)); memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&fsp->dev, sizeof(fsp->dev));
memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&inode, sizeof(inode)); memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&fsp->inode, sizeof(fsp->inode));
memcpy(buffer + KERNEL_OPLOCK_BREAK_FILEID_OFFSET, (char *)&fsp->file_id, sizeof(fsp->file_id));
out: out:
/* now we can receive more signals */ /* now we can receive more signals */
@ -166,10 +165,10 @@ dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
return ret; return ret;
} }
/**************************************************************************** /****************************************************************************
Attempt to set an kernel oplock on a file. Attempt to set an kernel oplock on a file.
****************************************************************************/ ****************************************************************************/
static BOOL linux_set_kernel_oplock(files_struct *fsp, int oplock_type) static BOOL linux_set_kernel_oplock(files_struct *fsp, int oplock_type)
{ {
if (linux_setlease(fsp->fd, F_WRLCK) == -1) { if (linux_setlease(fsp->fd, F_WRLCK) == -1) {
@ -180,16 +179,16 @@ inode = %.0f. (%s)\n",
return False; return False;
} }
DEBUG(3,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f\n", DEBUG(3,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f, file_id = %ul\n",
fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode)); fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id));
return True; return True;
} }
/**************************************************************************** /****************************************************************************
Release a kernel oplock on a file. Release a kernel oplock on a file.
****************************************************************************/ ****************************************************************************/
static void linux_release_kernel_oplock(files_struct *fsp) static void linux_release_kernel_oplock(files_struct *fsp)
{ {
if (DEBUGLVL(10)) { if (DEBUGLVL(10)) {
@ -198,9 +197,9 @@ static void linux_release_kernel_oplock(files_struct *fsp)
* oplock state of this file. * oplock state of this file.
*/ */
int state = fcntl(fsp->fd, F_GETLEASE, 0); int state = fcntl(fsp->fd, F_GETLEASE, 0);
dbgtext("release_kernel_oplock: file %s, dev = %x, inode = %.0f has kernel \ dbgtext("release_kernel_oplock: file %s, dev = %x, inode = %.0f file_id = %ul has kernel \
oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev, oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
(double)fsp->inode, state ); (double)fsp->inode, fsp->file_id, state );
} }
/* /*
@ -209,18 +208,19 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
if (linux_setlease(fsp->fd, F_UNLCK) == -1) { if (linux_setlease(fsp->fd, F_UNLCK) == -1) {
if (DEBUGLVL(0)) { if (DEBUGLVL(0)) {
dbgtext("release_kernel_oplock: Error when removing kernel oplock on file " ); dbgtext("release_kernel_oplock: Error when removing kernel oplock on file " );
dbgtext("%s, dev = %x, inode = %.0f. Error was %s\n", dbgtext("%s, dev = %x, inode = %.0f, file_id = %ul. Error was %s\n",
fsp->fsp_name, (unsigned int)fsp->dev, fsp->fsp_name, (unsigned int)fsp->dev,
(double)fsp->inode, strerror(errno) ); (double)fsp->inode, fsp->file_id, strerror(errno) );
} }
} }
} }
/**************************************************************************** /****************************************************************************
parse a kernel oplock message Parse a kernel oplock message.
****************************************************************************/ ****************************************************************************/
static BOOL linux_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *inode, SMB_DEV_T *dev)
static BOOL linux_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *inode,
SMB_DEV_T *dev, unsigned long *file_id)
{ {
/* Ensure that the msg length is correct. */ /* Ensure that the msg length is correct. */
if (msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN) { if (msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN) {
@ -229,41 +229,44 @@ static BOOL linux_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *i
return False; return False;
} }
memcpy((char *)inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(*inode)); memcpy((char *)inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(*inode));
memcpy((char *)dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(*dev)); memcpy((char *)dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(*dev));
memcpy((char *)file_id, msg_start+KERNEL_OPLOCK_BREAK_FILEID_OFFSET, sizeof(*file_id));
DEBUG(3,("kernel oplock break request for file dev = %x, inode = %.0f\n", DEBUG(3,("kernel oplock break request for file dev = %x, inode = %.0f, file_id = %ul\n",
(unsigned int)*dev, (double)*inode)); (unsigned int)*dev, (double)*inode, *file_id));
return True; return True;
} }
/**************************************************************************** /****************************************************************************
see if a oplock message is waiting See if a oplock message is waiting.
****************************************************************************/ ****************************************************************************/
static BOOL linux_oplock_msg_waiting(fd_set *fds) static BOOL linux_oplock_msg_waiting(fd_set *fds)
{ {
return signals_processed != signals_received; return signals_processed != signals_received;
} }
/**************************************************************************** /****************************************************************************
see if the kernel supports oplocks See if the kernel supports oplocks.
****************************************************************************/ ****************************************************************************/
static BOOL linux_oplocks_available(void) static BOOL linux_oplocks_available(void)
{ {
int fd, ret; int fd, ret;
fd = open("/dev/null", O_RDONLY); fd = open("/dev/null", O_RDONLY);
if (fd == -1) return False; /* uggh! */ if (fd == -1)
return False; /* uggh! */
ret = fcntl(fd, F_GETLEASE, 0); ret = fcntl(fd, F_GETLEASE, 0);
close(fd); close(fd);
return ret == F_UNLCK; return ret == F_UNLCK;
} }
/**************************************************************************** /****************************************************************************
setup kernel oplocks Setup kernel oplocks.
****************************************************************************/ ****************************************************************************/
struct kernel_oplocks *linux_init_kernel_oplocks(void) struct kernel_oplocks *linux_init_kernel_oplocks(void)
{ {
static struct kernel_oplocks koplocks; static struct kernel_oplocks koplocks;
@ -274,13 +277,13 @@ struct kernel_oplocks *linux_init_kernel_oplocks(void)
return NULL; return NULL;
} }
act.sa_handler = NULL; act.sa_handler = NULL;
act.sa_sigaction = signal_handler; act.sa_sigaction = signal_handler;
act.sa_flags = SA_SIGINFO; act.sa_flags = SA_SIGINFO;
if (sigaction(RT_SIGNAL_LEASE, &act, NULL) != 0) { if (sigaction(RT_SIGNAL_LEASE, &act, NULL) != 0) {
DEBUG(0,("Failed to setup RT_SIGNAL_LEASE handler\n")); DEBUG(0,("Failed to setup RT_SIGNAL_LEASE handler\n"));
return NULL; return NULL;
} }
koplocks.receive_message = linux_oplock_receive_message; koplocks.receive_message = linux_oplock_receive_message;
koplocks.set_oplock = linux_set_kernel_oplock; koplocks.set_oplock = linux_set_kernel_oplock;
@ -293,9 +296,6 @@ struct kernel_oplocks *linux_init_kernel_oplocks(void)
return &koplocks; return &koplocks;
} }
#else #else
void oplock_linux_dummy(void) {} void oplock_linux_dummy(void) {}
#endif /* HAVE_KERNEL_OPLOCKS_LINUX */ #endif /* HAVE_KERNEL_OPLOCKS_LINUX */