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;
int oplock_type;
int sent_oplock_break;
unsigned long file_id;
BOOL can_lock;
BOOL can_read;
BOOL can_write;
@ -557,13 +558,15 @@ struct interface
};
/* struct returned by get_share_modes */
typedef struct
{
pid_t pid;
uint16 op_port;
uint16 op_type;
int share_mode;
struct timeval time;
typedef struct {
pid_t pid;
uint16 op_port;
uint16 op_type;
int share_mode;
struct timeval time;
SMB_DEV_T dev;
SMB_INO_T inode;
unsigned long share_file_id;
} share_mode_entry;
@ -1409,19 +1412,18 @@ extern int chain_size;
*
* The form of this is :
*
* 0 2 6 10 14 14+devsize 14+devsize+inodesize
* +----+--------+--------+--------+-------+--------+
* | cmd| pid | sec | usec | dev | inode |
* +----+--------+--------+--------+-------+--------+
* 0 2 2+pid 2+pid+dev 2+pid+dev+ino
* +----+--------+-------+--------+---------+
* | cmd| pid | dev | inode | fileid |
* +----+--------+-------+--------+---------+
*/
#define OPLOCK_BREAK_CMD 0x1
#define OPLOCK_BREAK_PID_OFFSET 2
#define OPLOCK_BREAK_SEC_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_DEV_OFFSET (OPLOCK_BREAK_PID_OFFSET + sizeof(pid_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 LEVEL_II_OPLOCK_BREAK_CMD 0x3
@ -1438,13 +1440,14 @@ extern int chain_size;
* Form of this is :
*
* 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_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
@ -1453,7 +1456,7 @@ struct kernel_oplocks {
BOOL (*receive_message)(fd_set *fds, char *buffer, int buffer_len);
BOOL (*set_oplock)(files_struct *fsp, int oplock_type);
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);
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 */
if(userinfo->passwrd)
PUTWORD(p,strnlen(userinfo->passwrd, RAP_UPASSWD_LEN));
PUTWORD(p,MIN(strlen(userinfo->passwrd), RAP_UPASSWD_LEN));
else
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);
}
#ifndef LOCK_SHARE_ENTRY_SPIN_COUNT
#define LOCK_SHARE_ENTRY_SPIN_COUNT 100
#endif
/*******************************************************************
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_type = op_type;
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)
{
#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 &&
(e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) &&
e1->time.tv_sec == e2->time.tv_sec &&
e1->time.tv_usec == e2->time.tv_usec );
e1->dev == e2->dev &&
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;
/****************************************************************************
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)
{
int i;
@ -90,6 +104,8 @@ files_struct *file_new(connection_struct *conn)
ZERO_STRUCTP(fsp);
fsp->fd = -1;
fsp->conn = conn;
fsp->file_id = get_gen_count();
GetTimeOfDay(&fsp->open_time);
first_file = (i+1) % real_max_open_files;
@ -109,10 +125,10 @@ files_struct *file_new(connection_struct *conn)
return fsp;
}
/****************************************************************************
close all open files for a connection
Close all open files for a connection.
****************************************************************************/
void file_close_conn(connection_struct *conn)
{
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
@ -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);
}
/****************************************************************************
close files open by a specified vuid
Close files open by a specified vuid.
****************************************************************************/
void file_close_user(int vuid)
{
files_struct *fsp, *next;
@ -178,13 +194,32 @@ void file_close_user(int vuid)
}
}
/****************************************************************************
Find a fsp given a device, inode and timevalue
If this is from a kernel oplock break request then tval may be NULL.
Find a fsp given a file descriptor.
****************************************************************************/
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;
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 &&
fsp->dev == dev &&
fsp->inode == inode &&
(tval ? (fsp->open_time.tv_sec == tval->tv_sec) : True ) &&
(tval ? (fsp->open_time.tv_usec == tval->tv_usec) : True )) {
fsp->file_id == file_id ) {
if (count > 10) {
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 *fsp;
@ -271,10 +306,10 @@ files_struct *file_find_print(void)
return NULL;
}
/****************************************************************************
sync open files on a connection
Sync open files on a connection.
****************************************************************************/
void file_sync_all(connection_struct *conn)
{
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)
{
DLIST_REMOVE(Files, fsp);
@ -312,16 +347,17 @@ void file_free(files_struct *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)
{
int fnum, count=0;
files_struct *fsp;
if (chain_fsp) return chain_fsp;
if (chain_fsp)
return chain_fsp;
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)
@ -358,6 +394,7 @@ void file_chain_save(void)
/****************************************************************************
Restore the chained fsp - done after an oplock break.
****************************************************************************/
void file_chain_restore(void)
{
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->inode = psbuf->st_ino;
fsp->dev = psbuf->st_dev;
GetTimeOfDay(&fsp->open_time);
fsp->vuid = current_user.vuid;
fsp->size = psbuf->st_size;
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. */
unlock_share_entry(conn, dev, inode);
opb_ret = request_oplock_break(share_entry, dev, inode);
opb_ret = request_oplock_break(share_entry);
/* Now relock. */
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.
*/
fsp->fd = -1;
fsp->mode = psbuf->st_mode;
fsp->inode = psbuf->st_ino;
fsp->dev = psbuf->st_dev;
GetTimeOfDay(&fsp->open_time);
fsp->size = psbuf->st_size;
fsp->vuid = current_user.vuid;
fsp->pos = -1;
@ -1110,11 +1107,9 @@ files_struct *open_directory(connection_struct *conn, char *fname,
* Setup the files_struct for it.
*/
fsp->fd = -1;
fsp->mode = psbuf->st_mode;
fsp->inode = psbuf->st_ino;
fsp->dev = psbuf->st_dev;
GetTimeOfDay(&fsp->open_time);
fsp->size = psbuf->st_size;
fsp->vuid = current_user.vuid;
fsp->pos = -1;
@ -1230,7 +1225,7 @@ dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (doub
/* Oplock break.... */
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, \
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;
/****************************************************************************
test to see if IRIX kernel oplocks work
Test to see if IRIX kernel oplocks work.
****************************************************************************/
static BOOL irix_oplocks_available(void)
{
int fd;
@ -81,106 +82,113 @@ Disabling kernel oplock support.\n", strerror(errno) ));
return True;
}
/****************************************************************************
* Deal with the IRIX kernel <--> smbd
* oplock break protocol.
****************************************************************************/
static BOOL irix_oplock_receive_message(fd_set *fds, char *buffer, int buffer_len)
{
extern int smb_read_error;
oplock_stat_t os;
SMB_DEV_T dev;
SMB_INO_T inode;
char dummy;
oplock_stat_t os;
char dummy;
files_struct *fsp;
/*
* Read one byte of zero to clear the
* kernel break notify message.
*/
/*
* Read one byte of zero to clear the
* kernel break notify message.
*/
if(read(oplock_pipe_read, &dummy, 1) != 1) {
DEBUG(0,("receive_local_message: read of kernel notification failed. \
if(read(oplock_pipe_read, &dummy, 1) != 1) {
DEBUG(0,("receive_local_message: read of kernel notification failed. \
Error was %s.\n", strerror(errno) ));
smb_read_error = READ_ERROR;
return False;
}
smb_read_error = READ_ERROR;
return False;
}
/*
* Do a query to get the
* device and inode of the file that has the break
* request outstanding.
*/
/*
* Do a query to get the
* device and inode of the file that has the break
* request outstanding.
*/
if(fcntl(oplock_pipe_read, F_OPLKSTAT, &os) < 0) {
DEBUG(0,("receive_local_message: fcntl of kernel notification failed. \
if(fcntl(oplock_pipe_read, F_OPLKSTAT, &os) < 0) {
DEBUG(0,("receive_local_message: fcntl of kernel notification failed. \
Error was %s.\n", strerror(errno) ));
if(errno == EAGAIN) {
/*
* Duplicate kernel break message - ignore.
*/
memset(buffer, '\0', KERNEL_OPLOCK_BREAK_MSG_LEN);
return True;
}
smb_read_error = READ_ERROR;
return False;
}
if(errno == EAGAIN) {
/*
* Duplicate kernel break message - ignore.
*/
memset(buffer, '\0', KERNEL_OPLOCK_BREAK_MSG_LEN);
return True;
}
smb_read_error = READ_ERROR;
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.
*/
DEBUG(5,("receive_local_message: kernel oplock break request received for \
dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
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;
}
/*
* Create a kernel oplock break message.
*/
DEBUG(5,("receive_local_message: kernel oplock break request received for \
dev = %x, inode = %.0f\n, file_id = %ul", (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id ));
/* Setup the message header */
SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,KERNEL_OPLOCK_BREAK_MSG_LEN);
SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,0);
/*
* Create a kernel oplock break message.
*/
buffer += OPBRK_CMD_HEADER_LEN;
/* Setup the message header */
SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,KERNEL_OPLOCK_BREAK_MSG_LEN);
SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,0);
SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
buffer += OPBRK_CMD_HEADER_LEN;
memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&dev, sizeof(dev));
memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&inode, sizeof(inode));
SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
return True;
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));
memcpy(buffer + KERNEL_OPLOCK_BREAK_FILEID_OFFSET, (char *)&fsp->file_id, sizeof(fsp->file_id));
return True;
}
/****************************************************************************
Attempt to set an kernel oplock on a file.
****************************************************************************/
static BOOL irix_set_kernel_oplock(files_struct *fsp, int oplock_type)
{
if (fcntl(fsp->fd, F_OPLKREG, oplock_pipe_write) == -1) {
if(errno != EAGAIN) {
DEBUG(0,("set_file_oplock: Unable to get kernel oplock on file %s, dev = %x, \
inode = %.0f. Error was %s\n",
fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode,
inode = %.0f, file_id = %ul. Error was %s\n",
fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id,
strerror(errno) ));
} else {
DEBUG(5,("set_file_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
inode = %.0f. Another process had the file open.\n",
fsp->fsp_name, fsp->fd, (unsigned int)fsp->dev, (double)fsp->inode ));
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->file_id ));
}
return False;
}
DEBUG(10,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f\n",
fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode));
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->file_id));
return True;
}
/****************************************************************************
Release a kernel oplock on a file.
****************************************************************************/
static void irix_release_kernel_oplock(files_struct *fsp)
{
if (DEBUGLVL(10)) {
@ -189,9 +197,9 @@ static void irix_release_kernel_oplock(files_struct *fsp)
* oplock state of this file.
*/
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,
(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( DEBUGLVL( 0 )) {
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,
(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. */
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;
}
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 *)inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(*inode));
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",
(unsigned int)*dev, (double)*inode));
DEBUG(5,("kernel oplock break request for file dev = %x, inode = %.0f, file_id = %ul\n",
(unsigned int)*dev, (double)*inode, *file_id));
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)
{
if (oplock_pipe_read == -1) return False;
if (oplock_pipe_read == -1)
return False;
return FD_ISSET(oplock_pipe_read,fds);
}
/****************************************************************************
setup kernel oplocks
Setup kernel oplocks.
****************************************************************************/
struct kernel_oplocks *irix_init_kernel_oplocks(void)
{
int pfd[2];
static struct kernel_oplocks koplocks;
if (!irix_oplocks_available()) return NULL;
if (!irix_oplocks_available())
return NULL;
if(pipe(pfd) != 0) {
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;
}
#else
void oplock_irix_dummy(void) {}
#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
/****************************************************************************
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)
{
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)
{
#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
try again
Call SETLEASE. If we get EACCES then we try setting up the right capability and
try again
****************************************************************************/
static int linux_setlease(int fd, int leasetype)
{
int ret;
@ -116,31 +118,27 @@ static int linux_setlease(int fd, int leasetype)
return ret;
}
/****************************************************************************
* Deal with the Linux kernel <--> smbd
* oplock break protocol.
****************************************************************************/
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;
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));
ret = False;
goto out;
}
dev = sbuf.st_dev;
inode = sbuf.st_ino;
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.
@ -154,8 +152,9 @@ dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
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_INODE_OFFSET, (char *)&inode, sizeof(inode));
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));
memcpy(buffer + KERNEL_OPLOCK_BREAK_FILEID_OFFSET, (char *)&fsp->file_id, sizeof(fsp->file_id));
out:
/* now we can receive more signals */
@ -166,10 +165,10 @@ dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
return ret;
}
/****************************************************************************
Attempt to set an kernel oplock on a file.
****************************************************************************/
static BOOL linux_set_kernel_oplock(files_struct *fsp, int oplock_type)
{
if (linux_setlease(fsp->fd, F_WRLCK) == -1) {
@ -180,16 +179,16 @@ inode = %.0f. (%s)\n",
return False;
}
DEBUG(3,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f\n",
fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode));
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->file_id));
return True;
}
/****************************************************************************
Release a kernel oplock on a file.
****************************************************************************/
static void linux_release_kernel_oplock(files_struct *fsp)
{
if (DEBUGLVL(10)) {
@ -198,9 +197,9 @@ static void linux_release_kernel_oplock(files_struct *fsp)
* oplock state of this file.
*/
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,
(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 (DEBUGLVL(0)) {
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,
(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. */
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;
}
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 *)inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(*inode));
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",
(unsigned int)*dev, (double)*inode));
DEBUG(3,("kernel oplock break request for file dev = %x, inode = %.0f, file_id = %ul\n",
(unsigned int)*dev, (double)*inode, *file_id));
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)
{
return signals_processed != signals_received;
}
/****************************************************************************
see if the kernel supports oplocks
See if the kernel supports oplocks.
****************************************************************************/
static BOOL linux_oplocks_available(void)
{
int fd, ret;
fd = open("/dev/null", O_RDONLY);
if (fd == -1) return False; /* uggh! */
if (fd == -1)
return False; /* uggh! */
ret = fcntl(fd, F_GETLEASE, 0);
close(fd);
return ret == F_UNLCK;
}
/****************************************************************************
setup kernel oplocks
Setup kernel oplocks.
****************************************************************************/
struct kernel_oplocks *linux_init_kernel_oplocks(void)
{
static struct kernel_oplocks koplocks;
@ -274,13 +277,13 @@ struct kernel_oplocks *linux_init_kernel_oplocks(void)
return NULL;
}
act.sa_handler = NULL;
act.sa_sigaction = signal_handler;
act.sa_flags = SA_SIGINFO;
if (sigaction(RT_SIGNAL_LEASE, &act, NULL) != 0) {
act.sa_handler = NULL;
act.sa_sigaction = signal_handler;
act.sa_flags = SA_SIGINFO;
if (sigaction(RT_SIGNAL_LEASE, &act, NULL) != 0) {
DEBUG(0,("Failed to setup RT_SIGNAL_LEASE handler\n"));
return NULL;
}
}
koplocks.receive_message = linux_oplock_receive_message;
koplocks.set_oplock = linux_set_kernel_oplock;
@ -293,9 +296,6 @@ struct kernel_oplocks *linux_init_kernel_oplocks(void)
return &koplocks;
}
#else
void oplock_linux_dummy(void) {}
#endif /* HAVE_KERNEL_OPLOCKS_LINUX */