summaryrefslogtreecommitdiff
path: root/source/locking/locking.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/locking/locking.c')
-rw-r--r--source/locking/locking.c653
1 files changed, 209 insertions, 444 deletions
diff --git a/source/locking/locking.c b/source/locking/locking.c
index abda5d39d47..461ad5aef0b 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -46,7 +46,7 @@ BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset)
return(False);
return(fcntl_lock(Files[fnum].fd_ptr->fd,F_GETLK,offset,count,
- (Files[fnum].can_write?F_WRLCK:F_RDLCK)));
+ (Files[fnum].can_write?F_WRLCK:F_RDLCK)));
}
@@ -68,7 +68,7 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ec
if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count,
- (Files[fnum].can_write?F_WRLCK:F_RDLCK));
+ (Files[fnum].can_write?F_WRLCK:F_RDLCK));
if (!ok) {
*eclass = ERRDOS;
@@ -182,37 +182,37 @@ int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode,
file_prev_p = file_scanner_p;
while(file_scanner_p)
{
- if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
- {
- found = True;
- break;
- }
- else
- {
- file_prev_p = file_scanner_p ;
- file_scanner_p = (share_mode_record *)smb_shm_offset2addr(
- file_scanner_p->next_offset);
- }
+ if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
+ {
+ found = True;
+ break;
+ }
+ else
+ {
+ file_prev_p = file_scanner_p ;
+ file_scanner_p = (share_mode_record *)smb_shm_offset2addr(
+ file_scanner_p->next_offset);
+ }
}
if(!found)
{
- DEBUG(5,("get_share_modes (FAST_SHARE_MODES): no entry for \
+ DEBUG(5,("get_share_modes (FAST_SHARE_MODES): no entry for \
file dev = %d, ino = %d in hash_bucket %d\n", dev, inode, hash_entry));
- return (0);
+ return (0);
}
if(file_scanner_p->locking_version != LOCKING_VERSION)
{
- DEBUG(0,("ERROR:get_share_modes (FAST_SHARE_MODES): Deleting old share mode \
+ DEBUG(0,("ERROR:get_share_modes (FAST_SHARE_MODES): Deleting old share mode \
record due to old locking version %d for file dev = %d, inode = %d in hash \
-bucket %d\n", file_scanner_p->locking_version, dev, inode, hash_entry));
- if(file_prev_p == file_scanner_p)
- mode_array[hash_entry] = file_scanner_p->next_offset;
- else
- file_prev_p->next_offset = file_scanner_p->next_offset;
- smb_shm_free(smb_shm_addr2offset(file_scanner_p));
- return (0);
+bucket %d\n",file_scanner_p->locking_version, dev, inode, hash_entry));
+ if(file_prev_p == file_scanner_p)
+ mode_array[hash_entry] = file_scanner_p->next_offset;
+ else
+ file_prev_p->next_offset = file_scanner_p->next_offset;
+ smb_shm_free(smb_shm_addr2offset(file_scanner_p));
+ return (0);
}
/* Allocate the old_shares array */
@@ -241,6 +241,7 @@ bucket %d\n", file_scanner_p->locking_version, dev, inode, hash_entry));
{
/* Delete this share mode entry */
share_mode_entry *delete_entry_p = entry_scanner_p;
+ int share_mode = entry_scanner_p->share_mode;
if(entry_prev_p == entry_scanner_p)
{
@@ -271,7 +272,7 @@ for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries
DEBUG(0,("get_share_modes (FAST_SHARE_MODES): process %d no longer exists and \
it left a share mode entry with mode 0x%X for file dev = %d, ino = %d in hash \
bucket %d (number of entries now = %d)\n",
- pid, entry_scanner_p->share_mode, dev, inode, hash_entry,
+ pid, share_mode, dev, inode, hash_entry,
file_scanner_p->num_share_mode_entries));
smb_shm_free(smb_shm_addr2offset(delete_entry_p));
@@ -283,10 +284,6 @@ bucket %d (number of entries now = %d)\n",
*/
share_array[num_entries_copied].pid = entry_scanner_p->pid;
share_array[num_entries_copied].share_mode = entry_scanner_p->share_mode;
-#ifdef USE_OPLOCKS
- share_array[num_entries_copied].op_port = entry_scanner_p->op_port;
- share_array[num_entries_copied].op_type = entry_scanner_p->op_type;
-#endif /* USE_OPLOCKS */
memcpy(&share_array[num_entries_copied].time, &entry_scanner_p->time,
sizeof(struct timeval));
num_entries_copied++;
@@ -316,7 +313,8 @@ hash bucket %d has a share mode record but no entries - deleting\n",
}
DEBUG(5,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \
-hash bucket %d returning %d entries\n", dev, inode, hash_entry, num_entries_copied));
+hash bucket %d returning %d entries\n", dev, inode, hash_entry,
+ num_entries_copied));
return(num_entries_copied);
}
@@ -364,17 +362,17 @@ void del_share_mode(share_lock_token token, int fnum)
while(file_scanner_p)
{
- if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
- {
- found = True;
- break;
- }
- else
- {
- file_prev_p = file_scanner_p ;
- file_scanner_p = (share_mode_record *)
- smb_shm_offset2addr(file_scanner_p->next_offset);
- }
+ if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
+ {
+ found = True;
+ break;
+ }
+ else
+ {
+ file_prev_p = file_scanner_p ;
+ file_scanner_p = (share_mode_record *)
+ smb_shm_offset2addr(file_scanner_p->next_offset);
+ }
}
if(!found)
@@ -386,20 +384,20 @@ inode %d in hash bucket %d\n", dev, inode, hash_entry));
if(file_scanner_p->locking_version != LOCKING_VERSION)
{
- DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): Deleting old share mode \
+ DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): Deleting old share mode \
record due to old locking version %d for file dev %d, inode %d hash bucket %d\n",
file_scanner_p->locking_version, dev, inode, hash_entry ));
- if(file_prev_p == file_scanner_p)
- mode_array[hash_entry] = file_scanner_p->next_offset;
- else
- file_prev_p->next_offset = file_scanner_p->next_offset;
- smb_shm_free(smb_shm_addr2offset(file_scanner_p));
- return;
+ if(file_prev_p == file_scanner_p)
+ mode_array[hash_entry] = file_scanner_p->next_offset;
+ else
+ file_prev_p->next_offset = file_scanner_p->next_offset;
+ smb_shm_free(smb_shm_addr2offset(file_scanner_p));
+ return;
}
found = False;
entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr(
- file_scanner_p->share_mode_entries);
+ file_scanner_p->share_mode_entries);
entry_prev_p = entry_scanner_p;
while(entry_scanner_p)
{
@@ -444,15 +442,15 @@ for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries
/* If we deleted the last share mode entry then remove the share mode record. */
if(file_scanner_p->num_share_mode_entries == 0)
- {
+ {
DEBUG(2,("del_share_modes (FAST_SHARE_MODES): num entries = 0, deleting share_mode \
record dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry));
if(file_prev_p == file_scanner_p)
- mode_array[hash_entry] = file_scanner_p->next_offset;
+ mode_array[hash_entry] = file_scanner_p->next_offset;
else
- file_prev_p->next_offset = file_scanner_p->next_offset;
+ file_prev_p->next_offset = file_scanner_p->next_offset;
smb_shm_free(smb_shm_addr2offset(file_scanner_p));
- }
+ }
}
else
{
@@ -464,7 +462,7 @@ dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry));
/*******************************************************************
set the share mode of a file. Return False on fail, True on success.
********************************************************************/
-BOOL set_share_mode(share_lock_token token, int fnum, uint16 port, uint16 op_type)
+BOOL set_share_mode(share_lock_token token, int fnum)
{
files_struct *fs_p = &Files[fnum];
int32 dev, inode;
@@ -496,17 +494,17 @@ BOOL set_share_mode(share_lock_token token, int fnum, uint16 port, uint16 op_typ
while(file_scanner_p)
{
- if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
- {
- found = True;
- break;
- }
- else
- {
- file_prev_p = file_scanner_p ;
- file_scanner_p = (share_mode_record *)
- smb_shm_offset2addr(file_scanner_p->next_offset);
- }
+ if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
+ {
+ found = True;
+ break;
+ }
+ else
+ {
+ file_prev_p = file_scanner_p ;
+ file_scanner_p = (share_mode_record *)
+ smb_shm_offset2addr(file_scanner_p->next_offset);
+ }
}
if(!found)
@@ -555,10 +553,6 @@ inode %d in hash bucket %d\n", fs_p->name, dev, inode, hash_entry));
new_entry_p->pid = getpid();
new_entry_p->share_mode = fs_p->share_mode;
-#ifdef USE_OPLOCKS
- new_entry_p->op_port = port;
- new_entry_p->op_type = op_type;
-#endif /* USE_OPLOCKS */
memcpy( (char *)&new_entry_p->time, (char *)&fs_p->open_time, sizeof(struct timeval));
/* Chain onto the share_mode_record */
@@ -584,121 +578,6 @@ for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries
return(True);
}
-/*******************************************************************
-Remove an oplock port and mode entry from a share mode.
-********************************************************************/
-BOOL remove_share_oplock(int fnum, share_lock_token token)
-{
-#ifdef USE_OPLOCKS
- uint32 dev, inode;
- smb_shm_offset_t *mode_array;
- unsigned int hash_entry;
- share_mode_record *file_scanner_p;
- share_mode_record *file_prev_p;
- share_mode_entry *entry_scanner_p;
- share_mode_entry *entry_prev_p;
- BOOL found = False;
- int pid = getpid();
-
- dev = Files[fnum].fd_ptr->dev;
- inode = Files[fnum].fd_ptr->inode;
-
- hash_entry = HASH_ENTRY(dev, inode);
-
- if(hash_entry > lp_shmem_hash_size() )
- {
- DEBUG(0,
- ("PANIC ERROR:remove_share_oplock (FAST_SHARE_MODES): hash_entry %d too large \
-(max = %d)\n",
- hash_entry, lp_shmem_hash_size() ));
- return False;
- }
-
- mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
-
- if(mode_array[hash_entry] == NULL_OFFSET)
- {
- DEBUG(0,("PANIC ERROR:remove_share_oplock (FAST_SHARE_MODES): hash bucket %d empty\n",
- hash_entry));
- return False;
- }
-
- file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]);
- file_prev_p = file_scanner_p;
-
- while(file_scanner_p)
- {
- if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
- {
- found = True;
- break;
- }
- else
- {
- file_prev_p = file_scanner_p ;
- file_scanner_p = (share_mode_record *)
- smb_shm_offset2addr(file_scanner_p->next_offset);
- }
- }
-
- if(!found)
- {
- DEBUG(0,("ERROR:remove_share_oplock (FAST_SHARE_MODES): no entry found for dev %d, \
-inode %d in hash bucket %d\n", dev, inode, hash_entry));
- return False;
- }
-
- if(file_scanner_p->locking_version != LOCKING_VERSION)
- {
- DEBUG(0,("ERROR: remove_share_oplock (FAST_SHARE_MODES): Deleting old share mode \
-record due to old locking version %d for file dev %d, inode %d hash bucket %d\n",
- file_scanner_p->locking_version, dev, inode, hash_entry ));
- if(file_prev_p == file_scanner_p)
- mode_array[hash_entry] = file_scanner_p->next_offset;
- else
- file_prev_p->next_offset = file_scanner_p->next_offset;
- smb_shm_free(smb_shm_addr2offset(file_scanner_p));
- return False;
- }
-
- found = False;
- entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr(
- file_scanner_p->share_mode_entries);
- entry_prev_p = entry_scanner_p;
- while(entry_scanner_p)
- {
- if( (pid == entry_scanner_p->pid) &&
- (entry_scanner_p->share_mode == Files[fnum].share_mode) &&
- (memcmp(&entry_scanner_p->time,
- &Files[fnum].open_time,sizeof(struct timeval)) == 0) )
- {
- /* Delete the oplock info. */
- entry_scanner_p->op_port = 0;
- entry_scanner_p->op_type = 0;
- found = True;
- break;
- }
- else
- {
- entry_prev_p = entry_scanner_p;
- entry_scanner_p = (share_mode_entry *)
- smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry);
- }
- }
-
- if(!found)
- {
- DEBUG(0,("ERROR: remove_share_oplock (FAST_SHARE_MODES): No oplock granted share \
-mode record found dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry));
- return False;
- }
-
- return True;
-#else /* USE_OPLOCKS */
- return False;
-#endif /* USE_OPLOCKS */
-}
-
#else /* FAST_SHARE_MODES */
/* SHARE MODE LOCKS USING SLOW DESCRIPTION FILES */
@@ -725,50 +604,88 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok
{
pstring fname;
int fd;
+ int ret = True;
*ptok = (share_lock_token)-1;
if(!share_name(cnum, dev, inode, fname))
return False;
+ /* we need to do this as root */
+ become_root(0);
+
{
int old_umask;
- unbecome_user();
+ BOOL gotlock = False;
old_umask = umask(0);
+
+ /*
+ * There was a race condition in the original slow share mode code.
+ * A smbd could open a share mode file, and before getting
+ * the lock, another smbd could delete the last entry for
+ * the share mode file and delete the file entry from the
+ * directory. Thus this smbd would be left with a locked
+ * share mode fd attached to a file that no longer had a
+ * directory entry. Thus another smbd would think that
+ * there were no outstanding opens on the file. To fix
+ * this we now check we can do a stat() call on the filename
+ * before allowing the lock to proceed, and back out completely
+ * and try the open again if we cannot.
+ * Jeremy Allison (jallison@whistle.com).
+ */
+
+ do
+ {
+ struct stat dummy_stat;
#ifdef SECURE_SHARE_MODES
- fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0600);
+ fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0600);
#else /* SECURE_SHARE_MODES */
- fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0666);
+ fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0666);
#endif /* SECURE_SHARE_MODES */
+
+ if(fd < 0)
+ {
+ DEBUG(0,("ERROR lock_share_entry: failed to open share file %s. Error was %s\n",
+ fname, strerror(errno)));
+ ret = False;
+ break;
+ }
+
+ /* At this point we have an open fd to the share mode file.
+ Lock the first byte exclusively to signify a lock. */
+ if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False)
+ {
+ DEBUG(0,("ERROR lock_share_entry: fcntl_lock failed with %s\n",
+ strerror(errno)));
+ close(fd);
+ ret = False;
+ break;
+ }
+
+ /*
+ * If we cannot stat the filename, the file was deleted between
+ * the open and the lock call. Back out and try again.
+ */
+
+ if(stat(fname, &dummy_stat)!=0)
+ {
+ DEBUG(2,("lock_share_entry: Re-issuing open on %s to fix race. Error was %s\n",
+ fname, strerror(errno)));
+ close(fd);
+ }
+ else
+ gotlock = True;
+ } while(!gotlock);
+
umask(old_umask);
- if(!become_user(cnum,Connections[cnum].vuid))
- {
- DEBUG(0,("lock_share_entry: Can't become connected user!\n"));
- close(fd);
- return False;
- }
- /* We need to change directory back to the connection root. */
- if (ChDir(Connections[cnum].connectpath) != 0)
- {
- DEBUG(0,("lock_share_entry: Can't change directory to %s (%s)\n",
- Connections[cnum].connectpath, strerror(errno)));
- close(fd);
- return False;
- }
}
- /* At this point we have an open fd to the share mode file.
- Lock the first byte exclusively to signify a lock. */
- if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False)
- {
- DEBUG(0,("ERROR lock_share_entry: fcntl_lock failed with %s\n",
- strerror(errno)));
- close(fd);
- return False;
- }
+ *ptok = (share_lock_token)fd;
- *ptok = (share_lock_token)fd;
- return True;
+ /* return to our previous privilage level */
+ unbecome_root(0);
+
+ return ret;
}
/*******************************************************************
@@ -795,31 +712,21 @@ BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token tok
/*******************************************************************
Force a share file to be deleted.
********************************************************************/
-
static int delete_share_file( int cnum, char *fname )
{
- unbecome_user();
- if(unlink(fname) != 0)
- {
- DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n",
- fname, strerror(errno)));
- }
-
- DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
-
- if(!become_user(cnum,Connections[cnum].vuid))
- {
- DEBUG(0,("delete_share_file: Can't become connected user!\n"));
- return -1;
- }
- /* We need to change directory back to the connection root. */
- if (ChDir(Connections[cnum].connectpath) != 0)
- {
- DEBUG(0,("delete_share_file: Can't change directory to %s (%s)\n",
- Connections[cnum].connectpath, strerror(errno)));
- return -1;
- }
- return 0;
+ /* the share file could be owned by anyone, so do this as root */
+ become_root(0);
+
+ if(unlink(fname) != 0) {
+ DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n",
+ fname, strerror(errno)));
+ } else {
+ DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
+ }
+
+ unbecome_root(0);
+
+ return 0;
}
/*******************************************************************
@@ -873,11 +780,10 @@ for share file %s (%s)\n", fname, strerror(errno)));
return -1;
}
- if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) {
+ if (IVAL(buf,0) != LOCKING_VERSION) {
DEBUG(0,("ERROR: read_share_file: share file %s has incorrect \
-locking version (was %d, should be %d).\n",fname,
- IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION));
- if(buf)
+locking version (was %d, should be %d).\n",fname, IVAL(buf,0), LOCKING_VERSION));
+ if(buf)
free(buf);
delete_share_file(cnum, fname);
return -1;
@@ -885,13 +791,13 @@ locking version (was %d, should be %d).\n",fname,
/* Sanity check for file contents */
size = sb.st_size;
- size -= SMF_HEADER_LENGTH; /* Remove the header */
+ size -= 10; /* Remove the header */
/* Remove the filename component. */
- size -= SVAL(buf, SMF_FILENAME_LEN_OFFSET);
+ size -= SVAL(buf, 8);
- /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
- if((size % SMF_ENTRY_LENGTH) != 0)
+ /* The remaining size must be a multiple of 16 - error if not. */
+ if((size % 16) != 0)
{
DEBUG(0,("ERROR: read_share_file: share file %s is an incorrect length - \
deleting it.\n", fname));
@@ -936,7 +842,7 @@ int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode,
4 - tv_usec
8 - share_mode
12 - pid
- 16 - oplock port (if oplocks in use) - 2 bytes.
+
*/
share_name(cnum, dev, inode, fname);
@@ -951,7 +857,7 @@ int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode,
if(new_file == True)
return 0;
- num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
+ num_entries = IVAL(buf,4);
DEBUG(5,("get_share_modes: share file %s has %d share mode entries.\n",
fname, num_entries));
@@ -986,30 +892,26 @@ for share file %d\n", num_entries, fname));
}
num_entries_copied = 0;
- base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
+ base = buf + 10 + SVAL(buf,8);
for( i = 0; i < num_entries; i++)
{
int pid;
- char *p = base + (i*SMF_ENTRY_LENGTH);
+ char *p = base + (i*16);
- pid = IVAL(p,SME_PID_OFFSET);
+ pid = IVAL(p,12);
if(!process_exists(pid))
{
DEBUG(0,("get_share_modes: process %d no longer exists and \
it left a share mode entry with mode 0x%X in share file %s\n",
- pid, IVAL(p,SME_SHAREMODE_OFFSET), fname));
+ pid, IVAL(p,8), fname));
continue;
}
- share_array[num_entries_copied].time.tv_sec = IVAL(p,SME_SEC_OFFSET);
- share_array[num_entries_copied].time.tv_usec = IVAL(p,SME_USEC_OFFSET);
- share_array[num_entries_copied].share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
+ share_array[num_entries_copied].time.tv_sec = IVAL(p,0);
+ share_array[num_entries_copied].time.tv_usec = IVAL(p,4);
+ share_array[num_entries_copied].share_mode = IVAL(p,8);
share_array[num_entries_copied].pid = pid;
-#ifdef USE_OPLOCKS
- share_array[num_entries_copied].op_port = SVAL(p,SME_PORT_OFFSET);
- share_array[num_entries_copied].op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
-#endif /* USE_OPLOCKS */
num_entries_copied++;
}
@@ -1045,22 +947,18 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
return 0;
}
- SIVAL(buf, SMF_NUM_ENTRIES_OFFSET, num_entries_copied);
+ SIVAL(buf, 4, num_entries_copied);
for( i = 0; i < num_entries_copied; i++)
{
- char *p = base + (i*SMF_ENTRY_LENGTH);
-
- SIVAL(p,SME_PID_OFFSET,share_array[i].pid);
- SIVAL(p,SME_SHAREMODE_OFFSET,share_array[i].share_mode);
- SIVAL(p,SME_SEC_OFFSET,share_array[i].time.tv_sec);
- SIVAL(p,SME_USEC_OFFSET,share_array[i].time.tv_usec);
-#ifdef USE_OPLOCKS
- SSVAL(p,SME_PORT_OFFSET,share_array[i].op_port);
- SSVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type);
-#endif /* USE_OPLOCKS */
+ char *p = base + (i*16);
+
+ SIVAL(p,12,share_array[i].pid);
+ SIVAL(p,8,share_array[i].share_mode);
+ SIVAL(p,0,share_array[i].time.tv_sec);
+ SIVAL(p,4,share_array[i].time.tv_usec);
}
- newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries_copied);
+ newsize = (base - buf) + (16*num_entries_copied);
if(write(fd, buf, newsize) != newsize)
{
DEBUG(0,("ERROR: get_share_modes: failed to re-write share \
@@ -1130,7 +1028,7 @@ void del_share_mode(share_lock_token token, int fnum)
return;
}
- num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
+ num_entries = IVAL(buf,4);
DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n",
fname, num_entries));
@@ -1160,16 +1058,14 @@ for share file %d\n", num_entries, fname));
we have set - delete it.
*/
- base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
+ base = buf + 10 + SVAL(buf,8);
for(i = 0; i < num_entries; i++)
{
- char *p = base + (i*SMF_ENTRY_LENGTH);
+ char *p = base + (i*16);
- if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) ||
- (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) ||
- (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) ||
- (IVAL(p,SME_PID_OFFSET) != pid))
+ if((IVAL(p,0) != fs_p->open_time.tv_sec) || (IVAL(p,4) != fs_p->open_time.tv_usec) ||
+ (IVAL(p,8) != fs_p->share_mode) || (IVAL(p,12) != pid))
continue;
DEBUG(5,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n",
@@ -1177,7 +1073,7 @@ for share file %d\n", num_entries, fname));
/* Remove this entry. */
if(i != num_entries - 1)
- memcpy(p, p + SMF_ENTRY_LENGTH, (num_entries - i - 1)*SMF_ENTRY_LENGTH);
+ memcpy(p, p + 16, (num_entries - i - 1)*16);
deleted = True;
break;
@@ -1192,7 +1088,7 @@ for share file %d\n", num_entries, fname));
}
num_entries--;
- SIVAL(buf,SMF_NUM_ENTRIES_OFFSET, num_entries);
+ SIVAL(buf,4, num_entries);
if(num_entries == 0)
{
@@ -1207,23 +1103,23 @@ for share file %d\n", num_entries, fname));
/* Re-write the file - and truncate it at the correct point. */
if(lseek(fd, 0, SEEK_SET) != 0)
- {
- DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \
+ {
+ DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \
position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return;
- }
+ if(buf)
+ free(buf);
+ return;
+ }
- newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
+ newsize = (base - buf) + (16*num_entries);
if(write(fd, buf, newsize) != newsize)
- {
- DEBUG(0,("ERROR: del_share_mode: failed to re-write share \
+ {
+ DEBUG(0,("ERROR: del_share_mode: failed to re-write share \
mode file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return;
- }
+ if(buf)
+ free(buf);
+ return;
+ }
/* Now truncate the file at this point. */
if(ftruncate(fd, newsize) != 0)
{
@@ -1238,7 +1134,7 @@ mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
/*******************************************************************
set the share mode of a file
********************************************************************/
-BOOL set_share_mode(share_lock_token token,int fnum, uint16 port, uint16 op_type)
+BOOL set_share_mode(share_lock_token token,int fnum)
{
files_struct *fs_p = &Files[fnum];
pstring fname;
@@ -1266,10 +1162,9 @@ BOOL set_share_mode(share_lock_token token,int fnum, uint16 port, uint16 op_type
int size = sb.st_size;
/* Allocate space for the file plus one extra entry */
- if((buf = (char *)malloc(sb.st_size + SMF_ENTRY_LENGTH)) == NULL)
+ if((buf = (char *)malloc(sb.st_size + 16)) == NULL)
{
- DEBUG(0,("set_share_mode: malloc for file size %d fail !\n",
- sb.st_size + SMF_ENTRY_LENGTH));
+ DEBUG(0,("set_share_mode: malloc for file size %d fail !\n", sb.st_size + 16));
return False;
}
@@ -1291,21 +1186,20 @@ to 0 for share file %s (%s)\n", fname, strerror(errno)));
return False;
}
- if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION)
+ if (IVAL(buf,0) != LOCKING_VERSION)
{
DEBUG(0,("ERROR: set_share_mode: share file %s has incorrect \
-locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET),
- LOCKING_VERSION));
+locking version (was %d, should be %d).\n",fname, IVAL(buf,0), LOCKING_VERSION));
if(buf)
free(buf);
delete_share_file(fs_p->cnum, fname);
return False;
}
- size -= (SMF_HEADER_LENGTH + SVAL(buf, SMF_FILENAME_LEN_OFFSET)); /* Remove the header */
+ size -= (10 + SVAL(buf, 8)); /* Remove the header */
- /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
- if((size % SMF_ENTRY_LENGTH) != 0)
+ /* The remaining size must be a multiple of 16 - error if not. */
+ if((size % 16) != 0)
{
DEBUG(0,("ERROR: set_share_mode: share file %s is an incorrect length - \
deleting it.\n", fname));
@@ -1319,33 +1213,28 @@ deleting it.\n", fname));
else
{
/* New file - just use a single_entry. */
- if((buf = (char *)malloc(SMF_HEADER_LENGTH +
- strlen(fs_p->name) + 1 + SMF_ENTRY_LENGTH)) == NULL)
+ if((buf = (char *)malloc(10 + strlen(fs_p->name) + 1 + 16)) == NULL)
{
DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n"));
return False;
}
- SIVAL(buf,SMF_VERSION_OFFSET,LOCKING_VERSION);
- SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,0);
- SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fs_p->name) + 1);
- strcpy(buf + SMF_HEADER_LENGTH, fs_p->name);
+ SIVAL(buf,0,LOCKING_VERSION);
+ SIVAL(buf,4,0);
+ SSVAL(buf,8,strlen(fs_p->name) + 1);
+ strcpy(buf + 10, fs_p->name);
}
- num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
- header_size = SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
- p = buf + header_size + (num_entries * SMF_ENTRY_LENGTH);
- SIVAL(p,SME_SEC_OFFSET,fs_p->open_time.tv_sec);
- SIVAL(p,SME_USEC_OFFSET,fs_p->open_time.tv_usec);
- SIVAL(p,SME_SHAREMODE_OFFSET,fs_p->share_mode);
- SIVAL(p,SME_PID_OFFSET,pid);
-#ifdef USE_OPLOCKS
- SSVAL(p,SME_PORT_OFFSET,port);
- SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type);
-#endif /* USE_OPLOCKS */
+ num_entries = IVAL(buf,4);
+ header_size = 10 + SVAL(buf,8);
+ p = buf + header_size + (num_entries * 16);
+ SIVAL(p,0,fs_p->open_time.tv_sec);
+ SIVAL(p,4,fs_p->open_time.tv_usec);
+ SIVAL(p,8,fs_p->share_mode);
+ SIVAL(p,12,pid);
num_entries++;
- SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,num_entries);
+ SIVAL(buf,4,num_entries);
if(lseek(fd, 0, SEEK_SET) != 0)
{
@@ -1356,8 +1245,7 @@ deleting it.\n", fname));
return False;
}
- if (write(fd,buf,header_size + (num_entries*SMF_ENTRY_LENGTH)) !=
- (header_size + (num_entries*SMF_ENTRY_LENGTH)))
+ if (write(fd,buf,header_size + (num_entries*16)) != (header_size + (num_entries*16)))
{
DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \
deleting it (%s).\n",fname, strerror(errno)));
@@ -1368,11 +1256,10 @@ deleting it (%s).\n",fname, strerror(errno)));
}
/* Now truncate the file at this point - just for safety. */
- if(ftruncate(fd, header_size + (SMF_ENTRY_LENGTH*num_entries))!= 0)
+ if(ftruncate(fd, header_size + (16*num_entries))!= 0)
{
DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \
-mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entries),
- strerror(errno)));
+mode file %s to size %d (%s)\n", fname, header_size + (16*num_entries), strerror(errno)));
if(buf)
free(buf);
return False;
@@ -1386,126 +1273,4 @@ mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid));
return True;
}
-
-/*******************************************************************
-Remove an oplock port and mode entry from a share mode.
-********************************************************************/
-BOOL remove_share_oplock(int fnum, share_lock_token token)
-{
-#ifdef USE_OPLOCKS
- pstring fname;
- int fd = (int)token;
- char *buf = 0;
- char *base = 0;
- int num_entries;
- int fsize;
- int i;
- files_struct *fs_p = &Files[fnum];
- int pid;
- BOOL found = False;
- BOOL new_file;
-
- share_name(fs_p->cnum, fs_p->fd_ptr->dev,
- fs_p->fd_ptr->inode, fname);
-
- if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0)
- {
- DEBUG(0,("ERROR: remove_share_oplock: 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), \
-deleting it.\n", fname));
- delete_share_file(fs_p->cnum, fname);
- return False;
- }
-
- num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
-
- DEBUG(5,("remove_share_oplock: 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) \
-for share file %d\n", num_entries, fname));
- return False;
- }
-
- 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",
- fname));
- if(buf)
- free(buf);
- delete_share_file(fs_p->cnum, fname);
- return False;
- }
-
- 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++)
- {
- char *p = base + (i*SMF_ENTRY_LENGTH);
-
- if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) ||
- (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) ||
- (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) ||
- (IVAL(p,SME_PID_OFFSET) != pid))
- continue;
-
- DEBUG(5,("remove_share_oplock: clearing oplock on 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);
- found = True;
- break;
- }
-
- if(!found)
- {
- DEBUG(0,("remove_share_oplock: entry not found in share file %s\n", fname));
- if(buf)
- free(buf);
- return False;
- }
-
- /* Re-write the file - and truncate it at the correct point. */
- if(lseek(fd, 0, SEEK_SET) != 0)
- {
- DEBUG(0,("ERROR: remove_share_oplock: lseek failed to reset to \
-position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return False;
- }
-
- 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 \
-mode file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return False;
- }
-
- return True;
-
-#else /* USE_OPLOCKS */
- return False;
-#endif /* USE_OPLOCKS */
-}
#endif /* FAST_SHARE_MODES */