diff options
Diffstat (limited to 'source/locking/locking.c')
-rw-r--r-- | source/locking/locking.c | 84 |
1 files changed, 62 insertions, 22 deletions
diff --git a/source/locking/locking.c b/source/locking/locking.c index fdc39d00407..012d954e501 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -87,8 +87,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, * fd. So we don't need to use map_lock_type here. */ - return(conn->vfs_ops.lock(fsp->fd_ptr->fd,SMB_F_GETLK,offset,count, - lock_type)); + return(fcntl_lock(fsp->fd_ptr->fd,SMB_F_GETLK,offset,count,lock_type)); } @@ -114,8 +113,8 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, lock_type, (double)offset, (double)count, fsp->fsp_name )); if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) - ok = conn->vfs_ops.lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count, - map_lock_type(fsp,lock_type)); + ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count, + map_lock_type(fsp,lock_type)); if (!ok) { *eclass = ERRDOS; @@ -141,7 +140,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, (double)offset, (double)count, fsp->fsp_name )); if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) - ok = conn->vfs_ops.lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK); + ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK); if (!ok) { *eclass = ERRDOS; @@ -157,21 +156,26 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, BOOL locking_init(int read_only) { - if (share_ops) - return True; + if (share_ops) + return True; #ifdef FAST_SHARE_MODES - share_ops = locking_shm_init(read_only); + share_ops = locking_shm_init(read_only); + if (!share_ops && read_only && (getuid() == 0)) { + /* this may be the first time the share modes code has + been run. Initialise it now by running it read-write */ + share_ops = locking_shm_init(0); + } #else - share_ops = locking_slow_init(read_only); + share_ops = locking_slow_init(read_only); #endif - if (!share_ops) { - DEBUG(0,("ERROR: Failed to initialise share modes!\n")); - return False; - } + if (!share_ops) { + DEBUG(0,("ERROR: Failed to initialise share modes\n")); + return False; + } - return True; + return True; } /******************************************************************* @@ -242,7 +246,7 @@ static void remove_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_I (unsigned int)dev, (double)inode )); /* Delete the oplock info. */ entry->op_port = 0; - entry->op_type = 0; + entry->op_type = NO_OPLOCK; } /******************************************************************* @@ -259,14 +263,45 @@ BOOL remove_share_oplock(int token, files_struct *fsp) below. ********************************************************************/ +static void downgrade_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode, + void *param) +{ + DEBUG(10,("downgrade_share_oplock_fn: downgrading oplock info for entry dev=%x ino=%.0f\n", + (unsigned int)dev, (double)inode )); + entry->op_type = LEVEL_II_OPLOCK; +} + +/******************************************************************* + Downgrade a oplock type from exclusive to level II. +********************************************************************/ + +BOOL downgrade_share_oplock(int token, files_struct *fsp) +{ + return share_ops->mod_entry(token, fsp, downgrade_share_oplock_fn, NULL); +} + +/******************************************************************* + Static function that actually does the work for the generic function + below. +********************************************************************/ + +struct mod_val { + int new_share_mode; + uint16 new_oplock; +}; + static void modify_share_mode_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode, void *param) { - int new_share_mode = *(int *)param; - DEBUG(10,("modify_share_mode_fn: changing share mode info from %x to %x for entry dev=%x ino=%.0f\n", - entry->share_mode, new_share_mode, (unsigned int)dev, (double)inode )); - /* Change the share mode info. */ - entry->share_mode = new_share_mode; + struct mod_val *mvp = (struct mod_val *)param; + + DEBUG(10,("modify_share_mode_fn: changing share mode info from %x to %x for entry dev=%x ino=%.0f\n", + entry->share_mode, mvp->new_share_mode, (unsigned int)dev, (double)inode )); + DEBUG(10,("modify_share_mode_fn: changing oplock state from %x to %x for entry dev=%x ino=%.0f\n", + entry->op_type, (int)mvp->new_oplock, (unsigned int)dev, (double)inode )); + /* Change the share mode info. */ + entry->share_mode = mvp->new_share_mode; + entry->op_type = mvp->new_oplock; } /******************************************************************* @@ -274,9 +309,14 @@ static void modify_share_mode_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO Return False on fail, True on success. ********************************************************************/ -BOOL modify_share_mode(int token, files_struct *fsp, int new_mode) +BOOL modify_share_mode(int token, files_struct *fsp, int new_mode, uint16 new_oplock) { - return share_ops->mod_entry(token, fsp, modify_share_mode_fn, (void *)&new_mode); + struct mod_val mv; + + mv.new_share_mode = new_mode; + mv.new_oplock = new_oplock; + + return share_ops->mod_entry(token, fsp, modify_share_mode_fn, (void *)&mv); } /******************************************************************* |