summaryrefslogtreecommitdiff
path: root/source3/locking
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1998-10-23 03:34:50 +0000
committerJeremy Allison <jra@samba.org>1998-10-23 03:34:50 +0000
commit9bb7ac81b6e4d33e1be49447dbdbbb8d24259f53 (patch)
tree0bffe55dcb3dee8574d89546af83bd44cd476491 /source3/locking
parent1e60cc49f5ecb864ab965a6e7ab9287e1204d1d6 (diff)
downloadsamba-9bb7ac81b6e4d33e1be49447dbdbbb8d24259f53.tar.gz
samba-9bb7ac81b6e4d33e1be49447dbdbbb8d24259f53.tar.bz2
samba-9bb7ac81b6e4d33e1be49447dbdbbb8d24259f53.zip
Reasonably large change to give us *exactly* correct NT delete on close semantics.
This was trickier than it looks :-). Check out the new DELETE_ON_CLOSE flag in the share modes and the new code that iterates through all open files on the same device and inode in files.c and trans2.c Also changed the code that modifies share mode entries to take generic function pointers rather than doing a specific thing so this sort of change should be easier in the future. Jeremy. (This used to be commit 5e6a7cd99d29d1cf068fc517272559c1cf47ea3a)
Diffstat (limited to 'source3/locking')
-rw-r--r--source3/locking/locking.c45
-rw-r--r--source3/locking/locking_shm.c29
-rw-r--r--source3/locking/locking_slow.c59
3 files changed, 102 insertions, 31 deletions
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index f088720e0a..b71b775524 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -230,11 +230,52 @@ BOOL set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type)
}
/*******************************************************************
+ Static function that actually does the work for the generic function
+ below.
+********************************************************************/
+
+static void remove_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode,
+ void *param)
+{
+ DEBUG(10,("remove_share_oplock_fn: removing oplock info for entry dev=%x ino=%.0f\n",
+ (unsigned int)dev, (double)inode ));
+ /* Delete the oplock info. */
+ entry->op_port = 0;
+ entry->op_type = 0;
+}
+
+/*******************************************************************
Remove an oplock port and mode entry from a share mode.
********************************************************************/
-BOOL remove_share_oplock(files_struct *fsp, int token)
+
+BOOL remove_share_oplock(int token, files_struct *fsp)
+{
+ return share_ops->mod_entry(token, fsp, remove_share_oplock_fn, NULL);
+}
+
+/*******************************************************************
+ Static function that actually does the work for the generic function
+ below.
+********************************************************************/
+
+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;
+}
+
+/*******************************************************************
+ Modify a share mode on a file. Used by the delete open file code.
+ Return False on fail, True on success.
+********************************************************************/
+
+BOOL modify_share_mode(int token, files_struct *fsp, int new_mode)
{
- return share_ops->remove_oplock(fsp, token);
+ return share_ops->mod_entry(token, fsp, modify_share_mode_fn, (void *)&new_mode);
}
/*******************************************************************
diff --git a/source3/locking/locking_shm.c b/source3/locking/locking_shm.c
index 1077cf23eb..375a8b7f10 100644
--- a/source3/locking/locking_shm.c
+++ b/source3/locking/locking_shm.c
@@ -495,9 +495,12 @@ static BOOL shm_set_share_mode(int token, files_struct *fsp, uint16 port, uint16
}
/*******************************************************************
-Remove an oplock port and mode entry from a share mode.
+ Call a generic modify function for a share mode entry.
********************************************************************/
-static BOOL shm_remove_share_oplock(files_struct *fsp, int token)
+
+static BOOL shm_mod_share_entry(int token, files_struct *fsp,
+ void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
+ void *param)
{
SMB_DEV_T dev;
SMB_INO_T inode;
@@ -518,7 +521,7 @@ static BOOL shm_remove_share_oplock(files_struct *fsp, int token)
if(mode_array[hash_entry] == 0)
{
- DEBUG(0,("PANIC ERROR:remove_share_oplock: hash bucket %d empty\n",
+ DEBUG(0,("PANIC ERROR:modify_share_entry: hash bucket %d empty\n",
hash_entry));
return False;
}
@@ -543,14 +546,14 @@ static BOOL shm_remove_share_oplock(files_struct *fsp, int token)
if(!found)
{
- DEBUG(0,("ERROR:remove_share_oplock: no entry found for dev=%x ino=%.0f\n",
+ DEBUG(0,("ERROR:modify_share_entry: no entry found for dev=%x ino=%.0f\n",
(unsigned int)dev, (double)inode));
return False;
}
if(file_scanner_p->locking_version != LOCKING_VERSION)
{
- DEBUG(0,("ERROR: remove_share_oplock: Deleting old share mode v1=%d dev=%x ino=%.0f\n",
+ DEBUG(0,("ERROR: modify_share_entry: Deleting old share mode v1=%d dev=%x ino=%.0f\n",
file_scanner_p->locking_version, (unsigned int)dev, (double)inode));
if(file_prev_p == file_scanner_p)
@@ -571,9 +574,14 @@ static BOOL shm_remove_share_oplock(files_struct *fsp, int token)
(memcmp(&entry_scanner_p->e.time,
&fsp->open_time,sizeof(struct timeval)) == 0) )
{
- /* Delete the oplock info. */
- entry_scanner_p->e.op_port = 0;
- entry_scanner_p->e.op_type = 0;
+ /*
+ * Call the generic function with the given parameter.
+ */
+
+ DEBUG(5,("modify_share_entry: Calling generic function to modify entry for dev=%x ino=%.0f\n",
+ (unsigned int)dev, (double)inode));
+
+ (*mod_fn)( &entry_scanner_p->e, dev, inode, param);
found = True;
break;
}
@@ -586,7 +594,7 @@ static BOOL shm_remove_share_oplock(files_struct *fsp, int token)
if(!found)
{
- DEBUG(0,("ERROR: remove_share_oplock: No oplock granted. dev=%x ino=%.0f\n",
+ DEBUG(0,("ERROR: modify_share_entry: No entry found for dev=%x ino=%.0f\n",
(unsigned int)dev, (double)inode));
return False;
}
@@ -594,7 +602,6 @@ static BOOL shm_remove_share_oplock(files_struct *fsp, int token)
return True;
}
-
/*******************************************************************
call the specified function on each entry under management by the
share mode system
@@ -670,7 +677,7 @@ static struct share_ops share_ops = {
shm_get_share_modes,
shm_del_share_mode,
shm_set_share_mode,
- shm_remove_share_oplock,
+ shm_mod_share_entry,
shm_share_forall,
shm_share_status,
};
diff --git a/source3/locking/locking_slow.c b/source3/locking/locking_slow.c
index f2c2d3e9d9..f1e0fa2149 100644
--- a/source3/locking/locking_slow.c
+++ b/source3/locking/locking_slow.c
@@ -827,9 +827,12 @@ mode 0x%X pid=%d\n",fname,fsp->share_mode,pid));
}
/*******************************************************************
-Remove an oplock port and mode entry from a share mode.
+ Call a generic modify function for a share mode entry.
********************************************************************/
-static BOOL slow_remove_share_oplock(files_struct *fsp, int token)
+
+static BOOL slow_mod_share_entry(int token, files_struct *fsp,
+ void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
+ void *param)
{
pstring fname;
int fd = (int)token;
@@ -841,20 +844,21 @@ static BOOL slow_remove_share_oplock(files_struct *fsp, int token)
int pid;
BOOL found = False;
BOOL new_file;
+ share_mode_entry entry;
share_name(fsp->conn, fsp->fd_ptr->dev,
fsp->fd_ptr->inode, fname);
if(read_share_file( fsp->conn, fd, fname, &buf, &new_file) != 0)
{
- DEBUG(0,("ERROR: remove_share_oplock: Failed to read share file %s\n",
+ DEBUG(0,("ERROR: slow_mod_share_entry: Failed to read share file %s\n",
fname));
return False;
}
if(new_file == True)
{
- DEBUG(0,("ERROR: remove_share_oplock: share file %s is new (size zero), \
+ DEBUG(0,("ERROR: slow_mod_share_entry: share file %s is new (size zero), \
deleting it.\n", fname));
delete_share_file(fsp->conn, fname);
return False;
@@ -862,13 +866,13 @@ deleting it.\n", fname));
num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
- DEBUG(5,("remove_share_oplock: share file %s has %d share mode entries.\n",
+ DEBUG(5,("slow_mod_share_entry: share file %s has %d share mode entries.\n",
fname, num_entries));
/* PARANOIA TEST */
if(num_entries < 0)
{
- DEBUG(0,("PANIC ERROR:remove_share_oplock: num_share_mode_entries < 0 (%d) \
+ DEBUG(0,("PANIC ERROR:slow_mod_share_entry: num_share_mode_entries < 0 (%d) \
for share file %s\n", num_entries, fname));
return False;
}
@@ -876,7 +880,7 @@ for share file %s\n", num_entries, fname));
if(num_entries == 0)
{
/* No entries - just delete the file. */
- DEBUG(0,("remove_share_oplock: share file %s has no share mode entries - deleting.\n",
+ DEBUG(0,("slow_mod_share_entry: share file %s has no share mode entries - deleting.\n",
fname));
if(buf)
free(buf);
@@ -886,10 +890,6 @@ for share file %s\n", num_entries, fname));
pid = getpid();
- /* Go through the entries looking for the particular one
- we have set - remove the oplock settings on it.
- */
-
base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
for(i = 0; i < num_entries; i++)
@@ -902,18 +902,41 @@ for share file %s\n", num_entries, fname));
(IVAL(p,SME_PID_OFFSET) != pid))
continue;
- DEBUG(5,("remove_share_oplock: clearing oplock on entry number %d (of %d) \
+ DEBUG(5,("slow_mod_share_entry: Calling generic function to modify entry number %d (of %d) \
from the share file %s\n", i, num_entries, fname));
- SSVAL(p,SME_PORT_OFFSET,0);
- SSVAL(p,SME_OPLOCK_TYPE_OFFSET,0);
+ /*
+ * Copy into the share_mode_entry structure and then call
+ * the generic function with the given parameter.
+ */
+
+ entry.pid = IVAL(p,SME_PID_OFFSET);
+ entry.op_port = SVAL(p,SME_PORT_OFFSET);
+ entry.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
+ entry.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
+ entry.time.tv_sec = IVAL(p,SME_SEC_OFFSET)
+ entry.time.tv_sec = IVAL(p,SME_USEC_OFFSET);
+
+ (*mod_fn)( &entry, fsp->fd_ptr->dev, fsp->fd_ptr->inode, param);
+
+ /*
+ * Now copy any changes the function made back into the buffer.
+ */
+
+ SIVAL(p,SME_PID_OFFSET, entry.pid)
+ SSVAL(p,SME_PORT_OFFSET,entry.op_port);
+ SSVAL(p,SME_OPLOCK_TYPE_OFFSET,entry.op_type);
+ SIVAL(p,SME_SHAREMODE_OFFSET,entry.share_mode);
+ SIVAL(p,SME_SEC_OFFSET,entry.time.tv_sec)
+ SIVAL(p,SME_USEC_OFFSET,entry.time.tv_sec);
+
found = True;
break;
}
if(!found)
{
- DEBUG(0,("remove_share_oplock: entry not found in share file %s\n", fname));
+ DEBUG(0,("slow_mod_share_entry: entry not found in share file %s\n", fname));
if(buf)
free(buf);
return False;
@@ -922,7 +945,7 @@ from the share file %s\n", i, num_entries, fname));
/* Re-write the file - and truncate it at the correct point. */
if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
{
- DEBUG(0,("ERROR: remove_share_oplock: lseek failed to reset to \
+ DEBUG(0,("ERROR: slow_mod_share_entry: lseek failed to reset to \
position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
if(buf)
free(buf);
@@ -932,7 +955,7 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
fsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
if(write(fd, buf, fsize) != fsize)
{
- DEBUG(0,("ERROR: remove_share_oplock: failed to re-write share \
+ DEBUG(0,("ERROR: slow_mod_share_entry: failed to re-write share \
mode file %s (%s)\n", fname, strerror(errno)));
if(buf)
free(buf);
@@ -1048,7 +1071,7 @@ static struct share_ops share_ops = {
slow_get_share_modes,
slow_del_share_mode,
slow_set_share_mode,
- slow_remove_share_oplock,
+ slow_mod_share_entry,
slow_share_forall,
slow_share_status,
};