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