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:
@ -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;
|
||||
};
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Reference in New Issue
Block a user