mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
Code to map tdb locks onto POSIX. Mainly placeholder code at the moment,
but the structure is done enough so that Andrew can look it over and give a yea/nay decision. Jeremy.
This commit is contained in:
parent
5086e6425f
commit
db96f83e34
@ -1357,6 +1357,7 @@ BOOL lp_map_hidden(int );
|
||||
BOOL lp_map_archive(int );
|
||||
BOOL lp_locking(int );
|
||||
BOOL lp_strict_locking(int );
|
||||
BOOL lp_posix_locking(int );
|
||||
BOOL lp_utmp(int );
|
||||
BOOL lp_share_modes(int );
|
||||
BOOL lp_oplocks(int );
|
||||
|
@ -482,12 +482,13 @@ typedef struct files_struct
|
||||
mode_t mode;
|
||||
uint16 vuid;
|
||||
write_bmpx_struct *wbmpx_ptr;
|
||||
write_cache *wcp;
|
||||
write_cache *wcp;
|
||||
struct timeval open_time;
|
||||
int share_mode;
|
||||
int share_mode;
|
||||
time_t pending_modtime;
|
||||
int oplock_type;
|
||||
int sent_oplock_break;
|
||||
int oplock_type;
|
||||
int sent_oplock_break;
|
||||
unsigned int num_posix_locks;
|
||||
BOOL open;
|
||||
BOOL can_lock;
|
||||
BOOL can_read;
|
||||
|
@ -40,27 +40,134 @@ static TDB_CONTEXT *tdb;
|
||||
|
||||
int global_smbpid;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
remove any locks on this fd
|
||||
Remove any locks on this fd.
|
||||
****************************************************************************/
|
||||
|
||||
void locking_close_file(files_struct *fsp)
|
||||
{
|
||||
if (!lp_locking(SNUM(fsp->conn))) return;
|
||||
if (!lp_locking(SNUM(fsp->conn)))
|
||||
return;
|
||||
|
||||
brl_close(fsp->dev, fsp->inode,
|
||||
getpid(), fsp->conn->cnum, fsp->fnum);
|
||||
if(lp_posix_locking(SNUM(fsp->conn))) {
|
||||
/*
|
||||
* We need to release all POSIX locks we have on this
|
||||
* fd.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Now release all the tdb locks.
|
||||
*/
|
||||
|
||||
brl_close(fsp->dev, fsp->inode, getpid(), fsp->conn->cnum, fsp->fnum);
|
||||
|
||||
/*
|
||||
* We now need to search our open file list for any other
|
||||
* fd open on this file with outstanding POSIX locks. If we
|
||||
* don't find one, great, just return. If we do find one then
|
||||
* we have to add this file descriptor to the 'pending close'
|
||||
* list of that fd, to stop the POSIX problem where the locks
|
||||
* on *that* fd will get lost when we close this one. POSIX
|
||||
* braindamage... JRA.
|
||||
*/
|
||||
|
||||
/* Placeholder for code here.... */
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Debugging aid :-).
|
||||
****************************************************************************/
|
||||
|
||||
static const char *lock_type_name(enum brl_type lock_type)
|
||||
{
|
||||
return (lock_type == READ_LOCK) ? "READ" : "WRITE";
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Check to see if the given unsigned lock range is within the possible POSIX
|
||||
range. Modifies the given args to be in range if possible, just returns
|
||||
False if not.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL posix_lock_in_range(SMB_OFF_T *p_offset, SMB_OFF_T *p_count)
|
||||
{
|
||||
/* Placeholder. */
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
POSIX function to see if a file region is locked. Returns True if the
|
||||
lock could be granted, False if not.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL posix_locktest(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type)
|
||||
{
|
||||
SMB_OFF_T offset = (SMB_OFF_T)u_offset;
|
||||
SMB_OFF_T count = (SMB_OFF_T)u_count;
|
||||
|
||||
DEBUG(10,("posix_locktest: File %s, offset = %.0f, count = %.0f, type = %s\n",
|
||||
fsp->fsp_name, (double)offset, (double)count, lock_type_name(lock_type) ));
|
||||
|
||||
if(!posix_lock_in_range(&offset, &count))
|
||||
return True;
|
||||
|
||||
/* Placeholder - for now always return that the lock could be granted. */
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
POSIX function to acquire a lock. Returns True if the
|
||||
lock could be granted, False if not.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL get_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type)
|
||||
{
|
||||
SMB_OFF_T offset = (SMB_OFF_T)u_offset;
|
||||
SMB_OFF_T count = (SMB_OFF_T)u_count;
|
||||
|
||||
DEBUG(10,("get_posix_lock: File %s, offset = %.0f, count = %.0f, type = %s\n",
|
||||
fsp->fsp_name, (double)offset, (double)count, lock_type_name(lock_type) ));
|
||||
|
||||
if(!posix_lock_in_range(&offset, &count))
|
||||
return True;
|
||||
|
||||
/* Placeholder - for now always return that the lock could be granted. */
|
||||
fsp->num_posix_locks++;
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
POSIX function to release a lock. Returns True if the
|
||||
lock could be granted, False if not.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count)
|
||||
{
|
||||
SMB_OFF_T offset = (SMB_OFF_T)u_offset;
|
||||
SMB_OFF_T count = (SMB_OFF_T)u_count;
|
||||
|
||||
DEBUG(10,("release_posix_lock: File %s, offset = %.0f, count = %.0f\n",
|
||||
fsp->fsp_name, (double)offset, (double)count ));
|
||||
|
||||
if(!posix_lock_in_range(&offset, &count))
|
||||
return True;
|
||||
|
||||
/* Placeholder - for now always return that the lock could be granted. */
|
||||
fsp->num_posix_locks--;
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Utility function called to see if a file region is locked.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL is_locked(files_struct *fsp,connection_struct *conn,
|
||||
SMB_BIG_UINT count,SMB_BIG_UINT offset,
|
||||
enum brl_type lock_type)
|
||||
{
|
||||
int snum = SNUM(conn);
|
||||
BOOL ret;
|
||||
|
||||
if (count == 0)
|
||||
return(False);
|
||||
@ -68,15 +175,28 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
|
||||
if (!lp_locking(snum) || !lp_strict_locking(snum))
|
||||
return(False);
|
||||
|
||||
return !brl_locktest(fsp->dev, fsp->inode,
|
||||
ret = !brl_locktest(fsp->dev, fsp->inode,
|
||||
global_smbpid, getpid(), conn->cnum,
|
||||
offset, count, lock_type);
|
||||
}
|
||||
|
||||
/*
|
||||
* There is no lock held by an SMB daemon, check to
|
||||
* see if there is a POSIX lock from a UNIX or NFS process.
|
||||
* Note that as an optimisation we only bother to
|
||||
* check this if the file is not exclusively
|
||||
* oplocked. JRA.
|
||||
*/
|
||||
|
||||
if(!ret && !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && lp_posix_locking(snum))
|
||||
ret = !posix_locktest(fsp, offset, count, lock_type);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Utility function called by locking requests.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL do_lock(files_struct *fsp,connection_struct *conn,
|
||||
SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type,
|
||||
int *eclass,uint32 *ecode)
|
||||
@ -92,14 +212,33 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn,
|
||||
return False;
|
||||
}
|
||||
|
||||
DEBUG(10,("do_lock: lock type %d start=%.0f len=%.0f requested for file %s\n",
|
||||
lock_type, (double)offset, (double)count, fsp->fsp_name ));
|
||||
DEBUG(10,("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n",
|
||||
lock_type_name(lock_type), (double)offset, (double)count, fsp->fsp_name ));
|
||||
|
||||
if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
|
||||
ok = brl_lock(fsp->dev, fsp->inode, fsp->fnum,
|
||||
global_smbpid, getpid(), conn->cnum,
|
||||
offset, count,
|
||||
lock_type);
|
||||
|
||||
if(ok && lp_posix_locking(SNUM(conn))) {
|
||||
|
||||
/*
|
||||
* Try and get a POSIX lock on this range.
|
||||
*/
|
||||
|
||||
ok = get_posix_lock(fsp, offset, count, lock_type);
|
||||
|
||||
if(!ok) {
|
||||
/*
|
||||
* We failed to map - we must now remove the brl
|
||||
* lock entry.
|
||||
*/
|
||||
(void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
|
||||
global_smbpid, getpid(), conn->cnum,
|
||||
offset, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
@ -130,6 +269,15 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn,
|
||||
ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
|
||||
global_smbpid, getpid(), conn->cnum,
|
||||
offset, count);
|
||||
|
||||
if(ok && lp_posix_locking(SNUM(conn))) {
|
||||
|
||||
/*
|
||||
* Release the POSIX lock on this range.
|
||||
*/
|
||||
|
||||
(void)release_posix_lock(fsp, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
|
@ -342,6 +342,7 @@ typedef struct
|
||||
BOOL bMap_archive;
|
||||
BOOL bLocking;
|
||||
BOOL bStrictLocking;
|
||||
BOOL bPosixLocking;
|
||||
#ifdef WITH_UTMP
|
||||
BOOL bUtmp;
|
||||
#endif
|
||||
@ -454,6 +455,7 @@ static service sDefault =
|
||||
True, /* bMap_archive */
|
||||
True, /* bLocking */
|
||||
False, /* bStrictLocking */
|
||||
True, /* bPosixLocking */
|
||||
#ifdef WITH_UTMP
|
||||
False, /* bUtmp */
|
||||
#endif
|
||||
@ -814,6 +816,7 @@ static struct parm_struct parm_table[] =
|
||||
{"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
|
||||
{"oplock break wait time",P_INTEGER,P_GLOBAL,&Globals.oplock_break_wait_time,NULL,NULL,FLAG_GLOBAL},
|
||||
{"oplock contention limit",P_INTEGER,P_LOCAL,&sDefault.iOplockContentionLimit,NULL,NULL,FLAG_SHARE|FLAG_GLOBAL},
|
||||
{"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
|
||||
{"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
|
||||
{"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
|
||||
|
||||
@ -1420,6 +1423,7 @@ FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
|
||||
FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
|
||||
FN_LOCAL_BOOL(lp_locking,bLocking)
|
||||
FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
|
||||
FN_LOCAL_BOOL(lp_posix_locking,bPosixLocking)
|
||||
#ifdef WITH_UTMP
|
||||
FN_LOCAL_BOOL(lp_utmp,bUtmp)
|
||||
#endif
|
||||
|
@ -165,6 +165,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
|
||||
fsp->modified = False;
|
||||
fsp->oplock_type = NO_OPLOCK;
|
||||
fsp->sent_oplock_break = NO_BREAK_SENT;
|
||||
fsp->num_posix_locks = 0;
|
||||
fsp->is_directory = False;
|
||||
fsp->stat_open = False;
|
||||
fsp->directory_delete_on_close = False;
|
||||
@ -738,6 +739,7 @@ int open_file_stat(files_struct *fsp,connection_struct *conn,
|
||||
fsp->modified = False;
|
||||
fsp->oplock_type = NO_OPLOCK;
|
||||
fsp->sent_oplock_break = NO_BREAK_SENT;
|
||||
fsp->num_posix_locks = 0;
|
||||
fsp->is_directory = False;
|
||||
fsp->stat_open = True;
|
||||
fsp->directory_delete_on_close = False;
|
||||
@ -851,6 +853,7 @@ int open_directory(files_struct *fsp,connection_struct *conn,
|
||||
fsp->modified = False;
|
||||
fsp->oplock_type = NO_OPLOCK;
|
||||
fsp->sent_oplock_break = NO_BREAK_SENT;
|
||||
fsp->num_posix_locks = 0;
|
||||
fsp->is_directory = True;
|
||||
fsp->directory_delete_on_close = False;
|
||||
fsp->conn = conn;
|
||||
|
Loading…
Reference in New Issue
Block a user