From 0e8fd3398771da2f016d72830179507f3edda51b Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Sat, 4 May 1996 07:50:46 +0000 Subject: Initial version imported to CVS (This used to be commit 291551d80711daab7b7581720bcd9a08d6096517) --- source3/locking/locking.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 source3/locking/locking.c (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c new file mode 100644 index 0000000000..6ff3ab5d12 --- /dev/null +++ b/source3/locking/locking.c @@ -0,0 +1,330 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Locking functions + Copyright (C) Andrew Tridgell 1992-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "loadparm.h" +extern int DEBUGLEVEL; +extern connection_struct Connections[]; +extern files_struct Files[]; + +pstring share_del_pending=""; + + +/**************************************************************************** + utility function called to see if a file region is locked +****************************************************************************/ +BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset) +{ + int snum = SNUM(cnum); + + if (count == 0) + return(False); + + if (!lp_locking(snum) || !lp_strict_locking(snum)) + return(False); + + return(fcntl_lock(Files[fnum].fd,F_GETLK,offset,count, + (Files[fnum].can_write?F_WRLCK:F_RDLCK))); +} + + +/**************************************************************************** + utility function called by locking requests +****************************************************************************/ +BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode) +{ + BOOL ok = False; + + if (!lp_locking(SNUM(cnum))) + return(True); + + if (count == 0) { + *eclass = ERRDOS; + *ecode = ERRnoaccess; + return False; + } + + if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum)) + ok = fcntl_lock(Files[fnum].fd,F_SETLK,offset,count, + (Files[fnum].can_write?F_WRLCK:F_RDLCK)); + + if (!ok) { + *eclass = ERRDOS; + *ecode = ERRlock; + return False; + } + return True; /* Got lock */ +} + + +/**************************************************************************** + utility function called by unlocking requests +****************************************************************************/ +BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode) +{ + BOOL ok = False; + + if (!lp_locking(SNUM(cnum))) + return(True); + + if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum)) + ok = fcntl_lock(Files[fnum].fd,F_SETLK,offset,count,F_UNLCK); + + if (!ok) { + *eclass = ERRDOS; + *ecode = ERRlock; + return False; + } + return True; /* Did unlock */ +} + +/******************************************************************* + name a share file + ******************************************************************/ +static BOOL share_name(int cnum,struct stat *st,char *name) +{ + strcpy(name,lp_lockdir()); + standard_sub(cnum,name); + trim_string(name,"","/"); + if (!*name) return(False); + name += strlen(name); + + sprintf(name,"/share.%d.%d",(int)st->st_dev,(int)st->st_ino); + return(True); +} + +/******************************************************************* + use the fnum to get the share file name + ******************************************************************/ +static BOOL share_name_fnum(int fnum,char *name) +{ + struct stat st; + if (fstat(Files[fnum].fd,&st) != 0) return(False); + return(share_name(Files[fnum].cnum,&st,name)); +} + + +/******************************************************************* + get the share mode of a file using the fnum + ******************************************************************/ +int get_share_mode_by_fnum(int cnum,int fnum,int *pid) +{ + struct stat sbuf; + if (fstat(Files[fnum].fd,&sbuf) == -1) return(0); + return(get_share_mode(cnum,&sbuf,pid)); +} + +/******************************************************************* + get the share mode of a file using the files name + ******************************************************************/ +int get_share_mode_byname(int cnum,char *fname,int *pid) +{ + struct stat sbuf; + if (stat(fname,&sbuf) == -1) return(0); + return(get_share_mode(cnum,&sbuf,pid)); +} + + +/******************************************************************* +get the share mode of a file +********************************************************************/ +int get_share_mode(int cnum,struct stat *sbuf,int *pid) +{ + pstring fname; + int fd2; + char buf[16]; + int ret; + time_t t; + + *pid = 0; + + if (!share_name(cnum,sbuf,fname)) return(0); + + fd2 = open(fname,O_RDONLY,0); + if (fd2 < 0) return(0); + + if (read(fd2,buf,16) != 16) { + close(fd2); + unlink(fname); + return(0); + } + close(fd2); + + t = IVAL(buf,0); + ret = IVAL(buf,4); + *pid = IVAL(buf,8); + + if (IVAL(buf,12) != LOCKING_VERSION) { + if (!unlink(fname)) DEBUG(2,("Deleted old locking file %s",fname)); + *pid = 0; + return(0); + } + + if (*pid && !process_exists(*pid)) { + ret=0; + *pid = 0; + } + + if (! *pid) unlink(fname); /* XXXXX race, race */ + + if (*pid) + DEBUG(5,("Read share file %s mode 0x%X pid=%d\n",fname,ret,*pid)); + + return(ret); +} + + +/******************************************************************* +del the share mode of a file, if we set it last +********************************************************************/ +void del_share_mode(int fnum) +{ + pstring fname; + int fd2; + char buf[16]; + time_t t=0; + int pid=0; + BOOL del = False; + + if (!share_name_fnum(fnum,fname)) return; + + fd2 = open(fname,O_RDONLY,0); + if (fd2 < 0) return; + if (read(fd2,buf,16) != 16) + del = True; + close(fd2); + + if (!del) { + t = IVAL(buf,0); + pid = IVAL(buf,8); + } + + if (!del) + if (IVAL(buf,12) != LOCKING_VERSION || !pid || !process_exists(pid)) + del = True; + + if (!del && t == Files[fnum].open_time && pid==(int)getpid()) + del = True; + + if (del) { + if (!unlink(fname)) + DEBUG(2,("Deleted share file %s\n",fname)); + else { + DEBUG(3,("Pending delete share file %s\n",fname)); + if (*share_del_pending) DEBUG(0,("Share del clash!\n")); + strcpy(share_del_pending,fname); + } + } +} + + +/******************************************************************* +set the share mode of a file +********************************************************************/ +BOOL set_share_mode(int fnum,int mode) +{ + pstring fname; + int fd2; + char buf[16]; + int pid = (int)getpid(); + + if (!share_name_fnum(fnum,fname)) return(False); + + { + int old_umask = umask(0); + fd2 = open(fname,O_WRONLY|O_CREAT|O_TRUNC,0644); + umask(old_umask); + } + if (fd2 < 0) { + DEBUG(2,("Failed to create share file %s\n",fname)); + return(False); + } + + SIVAL(buf,0,Files[fnum].open_time); + SIVAL(buf,4,mode); + SIVAL(buf,8,pid); + SIVAL(buf,12,LOCKING_VERSION); + + if (write(fd2,buf,16) != 16) { + close(fd2); + unlink(fname); + return(False); + } + + write(fd2,Files[fnum].name,strlen(Files[fnum].name)+1); + + close(fd2); + + DEBUG(3,("Created share file %s with mode 0x%X pid=%d\n",fname,mode,pid)); + + return(True); +} + + +/******************************************************************* +cleanup any stale share files +********************************************************************/ +void clean_share_files(void) +{ + char *lockdir = lp_lockdir(); + void *dir; + char *s; + + if (!*lockdir) return; + + dir = opendir(lockdir); + if (!dir) return; + + while ((s=readdirname(dir))) { + char buf[16]; + int pid; + int fd; + pstring lname; + int dev,inode; + + if (sscanf(s,"share.%d.%d",&dev,&inode)!=2) continue; + + strcpy(lname,lp_lockdir()); + trim_string(lname,NULL,"/"); + strcat(lname,"/"); + strcat(lname,s); + + fd = open(lname,O_RDONLY,0); + if (fd < 0) continue; + + if (read(fd,buf,16) != 16) { + close(fd); + if (!unlink(lname)) + printf("Deleted corrupt share file %s\n",s); + continue; + } + close(fd); + + pid = IVAL(buf,8); + + if (IVAL(buf,12) != LOCKING_VERSION || !process_exists(pid)) { + if (!unlink(lname)) + printf("Deleted stale share file %s\n",s); + } + } + + closedir(dir); +} -- cgit From de411c701ed79c02875807dc60ef035d8d08334d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jun 1996 03:39:58 +0000 Subject: moved some more locking routines to locking.c, and moved replacement routines for broken OSes from util.c to replace.c. (This used to be commit 3ee9d45426a9b3b584d1ffb9f81af26790a83b4c) --- source3/locking/locking.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 6ff3ab5d12..9ece771266 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -28,6 +28,137 @@ extern files_struct Files[]; pstring share_del_pending=""; +/**************************************************************************** +routine to do file locking +****************************************************************************/ +BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type) +{ +#if HAVE_FCNTL_LOCK + struct flock lock; + int ret; + +#if 1 + uint32 mask = 0xC0000000; + + /* make sure the count is reasonable, we might kill the lockd otherwise */ + count &= ~mask; + + /* the offset is often strange - remove 2 of its bits if either of + the top two bits are set. Shift the top ones by two bits. This + still allows OLE2 apps to operate, but should stop lockd from + dieing */ + if ((offset & mask) != 0) + offset = (offset & ~mask) | ((offset & mask) >> 2); +#else + unsigned long mask = ((unsigned)1<<31); + + /* interpret negative counts as large numbers */ + if (count < 0) + count &= ~mask; + + /* no negative offsets */ + offset &= ~mask; + + /* count + offset must be in range */ + while ((offset < 0 || (offset + count < 0)) && mask) + { + offset &= ~mask; + mask = mask >> 1; + } +#endif + + + DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type)); + + lock.l_type = type; + lock.l_whence = SEEK_SET; + lock.l_start = (int)offset; + lock.l_len = (int)count; + lock.l_pid = 0; + + errno = 0; + + ret = fcntl(fd,op,&lock); + + if (errno != 0) + DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno))); + + /* a lock query */ + if (op == F_GETLK) + { + if ((ret != -1) && + (lock.l_type != F_UNLCK) && + (lock.l_pid != 0) && + (lock.l_pid != getpid())) + { + DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid)); + return(True); + } + + /* it must be not locked or locked by me */ + return(False); + } + + /* a lock set or unset */ + if (ret == -1) + { + DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n", + offset,count,op,type,strerror(errno))); + + /* perhaps it doesn't support this sort of locking?? */ + if (errno == EINVAL) + { + DEBUG(3,("locking not supported? returning True\n")); + return(True); + } + + return(False); + } + + /* everything went OK */ + DEBUG(5,("Lock call successful\n")); + + return(True); +#else + return(False); +#endif +} + +/******************************************************************* +lock a file - returning a open file descriptor or -1 on failure +The timeout is in seconds. 0 means no timeout +********************************************************************/ +int file_lock(char *name,int timeout) +{ + int fd = open(name,O_RDWR|O_CREAT,0666); + time_t t=0; + if (fd < 0) return(-1); + +#if HAVE_FCNTL_LOCK + if (timeout) t = time(NULL); + while (!timeout || (time(NULL)-t < timeout)) { + if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd); + msleep(LOCK_RETRY_TIMEOUT); + } + return(-1); +#else + return(fd); +#endif +} + +/******************************************************************* +unlock a file locked by file_lock +********************************************************************/ +void file_unlock(int fd) +{ + if (fd<0) return; +#if HAVE_FCNTL_LOCK + fcntl_lock(fd,F_SETLK,0,1,F_UNLCK); +#endif + close(fd); +} + + /**************************************************************************** utility function called to see if a file region is locked ****************************************************************************/ -- cgit From 7e3b4a1c0df1434eb3d02f93c736ce065f9898d8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jun 1996 04:38:24 +0000 Subject: got rid of a lot of redundent header files as we now globally generate prototypes automatically using "make proto". This is much less prone to error than the old method of manually adding prototypes (This used to be commit b551dc98f7cc194a5fc2e67a4ebae7fd67a01bbc) --- source3/locking/locking.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 9ece771266..e81e1125e8 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -20,7 +20,6 @@ */ #include "includes.h" -#include "loadparm.h" extern int DEBUGLEVEL; extern connection_struct Connections[]; extern files_struct Files[]; -- cgit From dc38599c5a01211f20b9685dd440df82cd25c5cc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Jun 1996 12:23:54 +0000 Subject: - change date as a demo for john - modified plp printing parser to work on my system (This used to be commit 9408f91e1b9a2482af96afe9df08e0a5fba60cdb) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e81e1125e8..78661d6970 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. Locking functions - Copyright (C) Andrew Tridgell 1992-1995 + Copyright (C) Andrew Tridgell 1992-1996 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From ebc96b7309dbce110ae63bcb91dd8ad5a2cadbbf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 14 Aug 1996 15:02:28 +0000 Subject: changed "unsigned long" to "uint32" in several places (for IP addresses) to keep 64 bit machines happy. (This used to be commit b4aaec504ae66dc6a0f05d12529100cb62d47afd) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 78661d6970..8f76ce43da 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -49,7 +49,7 @@ BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type) if ((offset & mask) != 0) offset = (offset & ~mask) | ((offset & mask) >> 2); #else - unsigned long mask = ((unsigned)1<<31); + uint32 mask = ((unsigned)1<<31); /* interpret negative counts as large numbers */ if (count < 0) -- cgit From 47673b32ed4a907b380b70d5f4f366ba8be301d2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 15 Aug 1996 15:11:34 +0000 Subject: - added FAST_SHARE_MODES code - added some named pipe code from Jim (This used to be commit c94866e9e44ea1eb72da06bc65ef1c032ae8e0c9) --- source3/locking/locking.c | 246 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 245 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 8f76ce43da..60428f2e98 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -17,6 +17,11 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Revision History: + + 12 aug 96: Erik.Devriendt@te6.siemens.be + added support for shared memory implementation of share mode locking */ #include "includes.h" @@ -226,6 +231,34 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 * return True; /* Did unlock */ } +#ifdef FAST_SHARE_MODES +/******************************************************************* + initialize the shared memory for share_mode management + ******************************************************************/ +BOOL start_share_mode_mgmt(void) +{ + pstring shmem_file_name; + + strcpy(shmem_file_name,lp_lockdir()); + trim_string(shmem_file_name,"","/"); + if (!*shmem_file_name) return(False); + strcat(shmem_file_name, "/SHARE_MEM_FILE"); + return shm_open(shmem_file_name, SHMEM_SIZE); +} + + +/******************************************************************* + deinitialize the shared memory for share_mode management + ******************************************************************/ +BOOL stop_share_mode_mgmt(void) +{ + return shm_close(); +} + +#else + +/* SHARE MODE LOCKS USING SLOW DESCRIPTION FILES */ + /******************************************************************* name a share file ******************************************************************/ @@ -251,6 +284,7 @@ static BOOL share_name_fnum(int fnum,char *name) return(share_name(Files[fnum].cnum,&st,name)); } +#endif /******************************************************************* get the share mode of a file using the fnum @@ -278,6 +312,78 @@ get the share mode of a file ********************************************************************/ int get_share_mode(int cnum,struct stat *sbuf,int *pid) { +#ifdef FAST_SHARE_MODES + share_mode_record *scanner_p; + share_mode_record *prev_p; + int ret; + BOOL found = False; + + *pid = 0; + + if(!shm_lock()) return (0); + + scanner_p = (share_mode_record *)shm_offset2addr(shm_get_userdef_off()); + prev_p = scanner_p; + while(scanner_p) + { + if( (scanner_p->st_dev == sbuf->st_dev) && (scanner_p->st_ino == sbuf->st_ino) ) + { + found = True; + break; + } + else + { + prev_p = scanner_p ; + scanner_p = (share_mode_record *)shm_offset2addr(scanner_p->next_offset); + } + } + + if(!found) + { + shm_unlock(); + return (0); + } + + if(scanner_p->locking_version != LOCKING_VERSION) + { + DEBUG(2,("Deleting old share mode record due to old locking version %d",scanner_p->locking_version)); + if(prev_p == scanner_p) + shm_set_userdef_off(scanner_p->next_offset); + else + prev_p->next_offset = scanner_p->next_offset; + shm_free(shm_addr2offset(scanner_p)); + *pid = 0; + + shm_unlock(); + return (0); + } + + *pid = scanner_p->pid; + ret = scanner_p->share_mode; + + if (*pid && !process_exists(*pid)) + { + ret = 0; + *pid = 0; + } + + if (! *pid) + { + if(prev_p == scanner_p) + shm_set_userdef_off(scanner_p->next_offset); + else + prev_p->next_offset = scanner_p->next_offset; + shm_free(shm_addr2offset(scanner_p)); + } + + if (*pid) + DEBUG(5,("Read share mode record mode 0x%X pid=%d\n",ret,*pid)); + + if(!shm_unlock()) return (0); + + return(ret); + +#else pstring fname; int fd2; char buf[16]; @@ -319,6 +425,7 @@ int get_share_mode(int cnum,struct stat *sbuf,int *pid) DEBUG(5,("Read share file %s mode 0x%X pid=%d\n",fname,ret,*pid)); return(ret); +#endif } @@ -327,6 +434,67 @@ del the share mode of a file, if we set it last ********************************************************************/ void del_share_mode(int fnum) { +#ifdef FAST_SHARE_MODES + struct stat st; + time_t t=0; + int pid=0; + BOOL del = False; + share_mode_record *scanner_p; + share_mode_record *prev_p; + BOOL found = False; + + + + if (fstat(Files[fnum].fd,&st) != 0) return; + + if (!shm_lock()) return; + + scanner_p = (share_mode_record *)shm_offset2addr(shm_get_userdef_off()); + prev_p = scanner_p; + while(scanner_p) + { + if( (scanner_p->st_dev == st.st_dev) && (scanner_p->st_ino == st.st_ino) ) + { + found = True; + break; + } + else + { + prev_p = scanner_p ; + scanner_p = (share_mode_record *)shm_offset2addr(scanner_p->next_offset); + } + } + + if(!found) + { + shm_unlock(); + return; + } + + t = scanner_p->time; + pid = scanner_p->pid; + + if( (scanner_p->locking_version != LOCKING_VERSION) || !pid || !process_exists(pid)) + del = True; + + if (!del && t == Files[fnum].open_time && pid==(int)getpid()) + del = True; + + if (del) + { + DEBUG(2,("Deleting share mode record\n")); + if(prev_p == scanner_p) + shm_set_userdef_off(scanner_p->next_offset); + else + prev_p->next_offset = scanner_p->next_offset; + shm_free(shm_addr2offset(scanner_p)); + + } + + shm_unlock(); + return; + +#else pstring fname; int fd2; char buf[16]; @@ -363,6 +531,7 @@ void del_share_mode(int fnum) strcpy(share_del_pending,fname); } } +#endif } @@ -371,6 +540,36 @@ set the share mode of a file ********************************************************************/ BOOL set_share_mode(int fnum,int mode) { +#ifdef FAST_SHARE_MODES + int pid = (int)getpid(); + struct stat st; + shm_offset_t new_off; + share_mode_record *new_p; + + + if (fstat(Files[fnum].fd,&st) != 0) return(False); + + if (!shm_lock()) return (False); + new_off = shm_alloc(sizeof(share_mode_record) + strlen(Files[fnum].name) ); + if (new_off == NULL_OFFSET) return (False); + new_p = (share_mode_record *)shm_offset2addr(new_off); + new_p->locking_version = LOCKING_VERSION; + new_p->share_mode = mode; + new_p->time = Files[fnum].open_time; + new_p->pid = pid; + new_p->st_dev = st.st_dev; + new_p->st_ino = st.st_ino; + strcpy(new_p->file_name,Files[fnum].name); + new_p->next_offset = shm_get_userdef_off(); + shm_set_userdef_off(new_off); + + + DEBUG(3,("Created share record for %s with mode 0x%X pid=%d\n",Files[fnum].name,mode,pid)); + + if (!shm_unlock()) return (False); + return(True); + +#else pstring fname; int fd2; char buf[16]; @@ -406,14 +605,58 @@ BOOL set_share_mode(int fnum,int mode) DEBUG(3,("Created share file %s with mode 0x%X pid=%d\n",fname,mode,pid)); return(True); +#endif } /******************************************************************* cleanup any stale share files ********************************************************************/ -void clean_share_files(void) +void clean_share_modes(void) { +#ifdef USE_SHMEM + share_mode_record *scanner_p; + share_mode_record *prev_p; + int pid; + + if (!shm_lock()) return; + + scanner_p = (share_mode_record *)shm_offset2addr(shm_get_userdef_off()); + prev_p = scanner_p; + while(scanner_p) + { + pid = scanner_p->pid; + + if( (scanner_p->locking_version != LOCKING_VERSION) || !process_exists(pid)) + { + DEBUG(2,("Deleting stale share mode record")); + if(prev_p == scanner_p) + { + shm_set_userdef_off(scanner_p->next_offset); + shm_free(shm_addr2offset(scanner_p)); + scanner_p = (share_mode_record *)shm_offset2addr(shm_get_userdef_off()); + prev_p = scanner_p; + } + else + { + prev_p->next_offset = scanner_p->next_offset; + shm_free(shm_addr2offset(scanner_p)); + scanner_p = (share_mode_record *)shm_offset2addr(prev_p->next_offset); + } + + } + else + { + prev_p = scanner_p ; + scanner_p = (share_mode_record *)shm_offset2addr(scanner_p->next_offset); + } + } + + + shm_unlock(); + return; + +#else char *lockdir = lp_lockdir(); void *dir; char *s; @@ -457,4 +700,5 @@ void clean_share_files(void) } closedir(dir); +#endif } -- cgit From efb8113d00a4513c1115640004c0905465d3b673 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 17 Aug 1996 14:27:12 +0000 Subject: - made FAST_SHARE_MODES standard for Linux - you can now press enter after a password prompt with "smbclient -L hostname" and it will use a blank username and password, the same as if you used -U% - changed the wins.dat store code to not go via a string variable (just use fprintf instead) - removed a "unsigned long" that luke put back in, changing it to uint32 to keep 64 bit machines happy. Naughtly luke! - allow guest non-connnected print queue listings so ms client 3 can work (This used to be commit 917160dee69bbc198985b6f3232ca2dcda809d8a) --- source3/locking/locking.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 60428f2e98..966bb2253b 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -231,7 +231,7 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 * return True; /* Did unlock */ } -#ifdef FAST_SHARE_MODES +#if FAST_SHARE_MODES /******************************************************************* initialize the shared memory for share_mode management ******************************************************************/ @@ -312,7 +312,7 @@ get the share mode of a file ********************************************************************/ int get_share_mode(int cnum,struct stat *sbuf,int *pid) { -#ifdef FAST_SHARE_MODES +#if FAST_SHARE_MODES share_mode_record *scanner_p; share_mode_record *prev_p; int ret; @@ -434,7 +434,7 @@ del the share mode of a file, if we set it last ********************************************************************/ void del_share_mode(int fnum) { -#ifdef FAST_SHARE_MODES +#if FAST_SHARE_MODES struct stat st; time_t t=0; int pid=0; @@ -540,7 +540,7 @@ set the share mode of a file ********************************************************************/ BOOL set_share_mode(int fnum,int mode) { -#ifdef FAST_SHARE_MODES +#if FAST_SHARE_MODES int pid = (int)getpid(); struct stat st; shm_offset_t new_off; -- cgit From 0c33046a0aa0461a5e932dd7b0b6e38ab9708867 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Aug 1996 11:17:29 +0000 Subject: - added "netbios name" option in smb.conf to make controlling the name that samba uses possible - added "socket address" option to allow virtual SMB servers (on systems with IP aliasing line Linux) - disabled FAST_SHARE_MODES by default in Linux as older Linux boxes can't do shared writeable mappings. We really need autoconf ... - added new option types in loadparm so a string type can be specified ot be uppercase only, this is used for the workgroup and netbios name options - auto-create the lock directory if it doesn't exist in shared mem startup - get rid of announce_backup() - change a few comments in nmbd code - rewrote the chaining code completely. Hopefully it will handle any depth chains now. - added LPRng support (This used to be commit e9eac6cd49c352349580ddb13d720cb201aecc48) --- source3/locking/locking.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 966bb2253b..04f4a4b197 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -240,6 +240,8 @@ BOOL start_share_mode_mgmt(void) pstring shmem_file_name; strcpy(shmem_file_name,lp_lockdir()); + if (!directory_exist(shmem_file_name,NULL)) + mkdir(shmem_file_name,0755); trim_string(shmem_file_name,"","/"); if (!*shmem_file_name) return(False); strcat(shmem_file_name, "/SHARE_MEM_FILE"); -- cgit From 75e3bbc651187754fa7b0c9fb5df921c31738d65 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 10 Dec 1996 17:53:00 +0000 Subject: Moved fcntl locking code into util.c to allow it to be called from nmbd code. jra@cygnus.com (This used to be commit d718f4fd30423fea957b14e141289739506656cb) --- source3/locking/locking.c | 131 ---------------------------------------------- 1 file changed, 131 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 04f4a4b197..dde9477e23 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -32,137 +32,6 @@ extern files_struct Files[]; pstring share_del_pending=""; -/**************************************************************************** -routine to do file locking -****************************************************************************/ -BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type) -{ -#if HAVE_FCNTL_LOCK - struct flock lock; - int ret; - -#if 1 - uint32 mask = 0xC0000000; - - /* make sure the count is reasonable, we might kill the lockd otherwise */ - count &= ~mask; - - /* the offset is often strange - remove 2 of its bits if either of - the top two bits are set. Shift the top ones by two bits. This - still allows OLE2 apps to operate, but should stop lockd from - dieing */ - if ((offset & mask) != 0) - offset = (offset & ~mask) | ((offset & mask) >> 2); -#else - uint32 mask = ((unsigned)1<<31); - - /* interpret negative counts as large numbers */ - if (count < 0) - count &= ~mask; - - /* no negative offsets */ - offset &= ~mask; - - /* count + offset must be in range */ - while ((offset < 0 || (offset + count < 0)) && mask) - { - offset &= ~mask; - mask = mask >> 1; - } -#endif - - - DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type)); - - lock.l_type = type; - lock.l_whence = SEEK_SET; - lock.l_start = (int)offset; - lock.l_len = (int)count; - lock.l_pid = 0; - - errno = 0; - - ret = fcntl(fd,op,&lock); - - if (errno != 0) - DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno))); - - /* a lock query */ - if (op == F_GETLK) - { - if ((ret != -1) && - (lock.l_type != F_UNLCK) && - (lock.l_pid != 0) && - (lock.l_pid != getpid())) - { - DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid)); - return(True); - } - - /* it must be not locked or locked by me */ - return(False); - } - - /* a lock set or unset */ - if (ret == -1) - { - DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n", - offset,count,op,type,strerror(errno))); - - /* perhaps it doesn't support this sort of locking?? */ - if (errno == EINVAL) - { - DEBUG(3,("locking not supported? returning True\n")); - return(True); - } - - return(False); - } - - /* everything went OK */ - DEBUG(5,("Lock call successful\n")); - - return(True); -#else - return(False); -#endif -} - -/******************************************************************* -lock a file - returning a open file descriptor or -1 on failure -The timeout is in seconds. 0 means no timeout -********************************************************************/ -int file_lock(char *name,int timeout) -{ - int fd = open(name,O_RDWR|O_CREAT,0666); - time_t t=0; - if (fd < 0) return(-1); - -#if HAVE_FCNTL_LOCK - if (timeout) t = time(NULL); - while (!timeout || (time(NULL)-t < timeout)) { - if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd); - msleep(LOCK_RETRY_TIMEOUT); - } - return(-1); -#else - return(fd); -#endif -} - -/******************************************************************* -unlock a file locked by file_lock -********************************************************************/ -void file_unlock(int fd) -{ - if (fd<0) return; -#if HAVE_FCNTL_LOCK - fcntl_lock(fd,F_SETLK,0,1,F_UNLCK); -#endif - close(fd); -} - - /**************************************************************************** utility function called to see if a file region is locked ****************************************************************************/ -- cgit From 8bc7d6bebd4fcf8c95cb6d58da14404a5e46de91 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 9 Jan 1997 18:02:17 +0000 Subject: Makefile: Changes to split Solaris into Solaris2.3 and previous, and 2.4 and after from Paul Eggert. Makefile: Added AMIGA changes from Rask Ingemann Lambertsen . charset.c: Patch for Western European Languages from Josef Hinteregger charset.h: Patch for Western European Languages from Josef Hinteregger clitar.c: Patch to re-sync after read fail from (lost contributor name, sorry). includes.h: Patch for AMIGA from Rask Ingemann Lambertsen includes.h: Patch for SunOS atexit by Jeremy (jra@cygnus.com) interface.c: Patch for AMIGA from Rask Ingemann Lambertsen kanji.h: Patch for Western European Languages from Josef Hinteregger locking.c: Patch to fix file locking from Jeremy (jra@cygnus.com) locking.c: Patch to add granularity of lock files to usec by Jeremy (jra@cygnus.com) pipes.c: Patch to fix file locking from Jeremy (jra@cygnus.com) proto.h: Patch to fix file locking from Jeremy (jra@cygnus.com) reply.c: Patch to fix file locking from Jeremy (jra@cygnus.com) server.c: Patch to fix file locking from Jeremy (jra@cygnus.com) server.c: Patch for FAST_SHARE_MODE fix from (lost contributor name, sorry). smb.h: Patch to fix file locking from Jeremy (jra@cygnus.com) smb.h: Patch to add granularity of lock files to usec by Jeremy (jra@cygnus.com) status.c: Patch to fix file locking from Jeremy (jra@cygnus.com) statuc.c: Patch to add granularity of lock files to usec by Jeremy (jra@cygnus.com) system.c: Patch for Western European Languages from Josef Hinteregger trans2.c: Patch to fix file locking from Jeremy (jra@cygnus.com) trans2.c: Patch to fix volume name reported to Win95 from Jeremy (jra@cygnus.com) util.c: Patch for Western European Languages from Josef Hinteregger util.c: Patch to fix client_name from continuously returning UNKNOWN (from various contributors). version.h: Update to 1.9.16p10. (This used to be commit 03d28fa32eb094affa33133ebe2602fdb70f6361) --- source3/locking/locking.c | 64 ++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 29 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index dde9477e23..d94cc9c35f 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -45,7 +45,7 @@ BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset) if (!lp_locking(snum) || !lp_strict_locking(snum)) return(False); - return(fcntl_lock(Files[fnum].fd,F_GETLK,offset,count, + return(fcntl_lock(Files[fnum].fd_ptr->fd,F_GETLK,offset,count, (Files[fnum].can_write?F_WRLCK:F_RDLCK))); } @@ -67,7 +67,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,F_SETLK,offset,count, + ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count, (Files[fnum].can_write?F_WRLCK:F_RDLCK)); if (!ok) { @@ -90,7 +90,7 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 * return(True); if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum)) - ok = fcntl_lock(Files[fnum].fd,F_SETLK,offset,count,F_UNLCK); + ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count,F_UNLCK); if (!ok) { *eclass = ERRDOS; @@ -151,7 +151,7 @@ static BOOL share_name(int cnum,struct stat *st,char *name) static BOOL share_name_fnum(int fnum,char *name) { struct stat st; - if (fstat(Files[fnum].fd,&st) != 0) return(False); + if (fstat(Files[fnum].fd_ptr->fd,&st) != 0) return(False); return(share_name(Files[fnum].cnum,&st,name)); } @@ -163,7 +163,7 @@ static BOOL share_name_fnum(int fnum,char *name) int get_share_mode_by_fnum(int cnum,int fnum,int *pid) { struct stat sbuf; - if (fstat(Files[fnum].fd,&sbuf) == -1) return(0); + if (fstat(Files[fnum].fd_ptr->fd,&sbuf) == -1) return(0); return(get_share_mode(cnum,&sbuf,pid)); } @@ -257,9 +257,9 @@ int get_share_mode(int cnum,struct stat *sbuf,int *pid) #else pstring fname; int fd2; - char buf[16]; + char buf[20]; int ret; - time_t t; + struct timeval t; *pid = 0; @@ -268,18 +268,20 @@ int get_share_mode(int cnum,struct stat *sbuf,int *pid) fd2 = open(fname,O_RDONLY,0); if (fd2 < 0) return(0); - if (read(fd2,buf,16) != 16) { + if (read(fd2,buf,20) != 20) { + DEBUG(2,("Failed to read share file %s\n",fname)); close(fd2); unlink(fname); return(0); } close(fd2); - t = IVAL(buf,0); - ret = IVAL(buf,4); - *pid = IVAL(buf,8); + t.tv_sec = IVAL(buf,4); + t.tv_usec = IVAL(buf,8); + ret = IVAL(buf,12); + *pid = IVAL(buf,16); - if (IVAL(buf,12) != LOCKING_VERSION) { + if (IVAL(buf,0) != LOCKING_VERSION) { if (!unlink(fname)) DEBUG(2,("Deleted old locking file %s",fname)); *pid = 0; return(0); @@ -368,29 +370,31 @@ void del_share_mode(int fnum) #else pstring fname; int fd2; - char buf[16]; - time_t t=0; + char buf[20]; + struct timeval t; int pid=0; BOOL del = False; + t.tv_sec = t.tv_usec = 0; if (!share_name_fnum(fnum,fname)) return; fd2 = open(fname,O_RDONLY,0); if (fd2 < 0) return; - if (read(fd2,buf,16) != 16) + if (read(fd2,buf,20) != 20) del = True; close(fd2); if (!del) { - t = IVAL(buf,0); - pid = IVAL(buf,8); + t.tv_sec = IVAL(buf,4); + t.tv_usec = IVAL(buf,8); + pid = IVAL(buf,16); } if (!del) - if (IVAL(buf,12) != LOCKING_VERSION || !pid || !process_exists(pid)) + if (IVAL(buf,0) != LOCKING_VERSION || !pid || !process_exists(pid)) del = True; - if (!del && t == Files[fnum].open_time && pid==(int)getpid()) + if (!del && (memcmp(&t,&Files[fnum].open_time,sizeof(t)) == 0) && (pid==(int)getpid())) del = True; if (del) { @@ -443,7 +447,7 @@ BOOL set_share_mode(int fnum,int mode) #else pstring fname; int fd2; - char buf[16]; + char buf[20]; int pid = (int)getpid(); if (!share_name_fnum(fnum,fname)) return(False); @@ -458,12 +462,14 @@ BOOL set_share_mode(int fnum,int mode) return(False); } - SIVAL(buf,0,Files[fnum].open_time); - SIVAL(buf,4,mode); - SIVAL(buf,8,pid); - SIVAL(buf,12,LOCKING_VERSION); + SIVAL(buf,0,LOCKING_VERSION); + SIVAL(buf,4,Files[fnum].open_time.tv_sec); + SIVAL(buf,8,Files[fnum].open_time.tv_usec); + SIVAL(buf,12,mode); + SIVAL(buf,16,pid); - if (write(fd2,buf,16) != 16) { + if (write(fd2,buf,20) != 20) { + DEBUG(2,("Failed to write share file %s\n",fname)); close(fd2); unlink(fname); return(False); @@ -538,7 +544,7 @@ void clean_share_modes(void) if (!dir) return; while ((s=readdirname(dir))) { - char buf[16]; + char buf[20]; int pid; int fd; pstring lname; @@ -554,7 +560,7 @@ void clean_share_modes(void) fd = open(lname,O_RDONLY,0); if (fd < 0) continue; - if (read(fd,buf,16) != 16) { + if (read(fd,buf,20) != 20) { close(fd); if (!unlink(lname)) printf("Deleted corrupt share file %s\n",s); @@ -562,9 +568,9 @@ void clean_share_modes(void) } close(fd); - pid = IVAL(buf,8); + pid = IVAL(buf,16); - if (IVAL(buf,12) != LOCKING_VERSION || !process_exists(pid)) { + if (IVAL(buf,0) != LOCKING_VERSION || !process_exists(pid)) { if (!unlink(lname)) printf("Deleted stale share file %s\n",s); } -- cgit From 869f24e0b1915ec8d3e14f8850417474200e687e Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Wed, 15 Jan 1997 01:53:25 +0000 Subject: locking.c proto.h shmem.c smb.h status.c : Changed shm_ prefixes to smb_shm_ prefixes as shm_ is a POSIX.4 prefix. Updated fd code in FAST_SHARE_MODE code to work with new fd indirection. quotas.c: Fixed #ifdef not on position zero. Jeremy. (jra@cygnus.com). (This used to be commit c9a9d56642cc34369a42f48a28116e466240d303) --- source3/locking/locking.c | 87 ++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 42 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d94cc9c35f..ce96aa01cf 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -114,7 +114,7 @@ BOOL start_share_mode_mgmt(void) trim_string(shmem_file_name,"","/"); if (!*shmem_file_name) return(False); strcat(shmem_file_name, "/SHARE_MEM_FILE"); - return shm_open(shmem_file_name, SHMEM_SIZE); + return smb_shm_open(shmem_file_name, SHMEM_SIZE); } @@ -123,7 +123,7 @@ BOOL start_share_mode_mgmt(void) ******************************************************************/ BOOL stop_share_mode_mgmt(void) { - return shm_close(); + return smb_shm_close(); } #else @@ -191,9 +191,9 @@ int get_share_mode(int cnum,struct stat *sbuf,int *pid) *pid = 0; - if(!shm_lock()) return (0); + if(!smb_shm_lock()) return (0); - scanner_p = (share_mode_record *)shm_offset2addr(shm_get_userdef_off()); + scanner_p = (share_mode_record *)smb_shm_offset2addr(smb_shm_get_userdef_off()); prev_p = scanner_p; while(scanner_p) { @@ -205,13 +205,13 @@ int get_share_mode(int cnum,struct stat *sbuf,int *pid) else { prev_p = scanner_p ; - scanner_p = (share_mode_record *)shm_offset2addr(scanner_p->next_offset); + scanner_p = (share_mode_record *)smb_shm_offset2addr(scanner_p->next_offset); } } if(!found) { - shm_unlock(); + smb_shm_unlock(); return (0); } @@ -219,13 +219,13 @@ int get_share_mode(int cnum,struct stat *sbuf,int *pid) { DEBUG(2,("Deleting old share mode record due to old locking version %d",scanner_p->locking_version)); if(prev_p == scanner_p) - shm_set_userdef_off(scanner_p->next_offset); + smb_shm_set_userdef_off(scanner_p->next_offset); else prev_p->next_offset = scanner_p->next_offset; - shm_free(shm_addr2offset(scanner_p)); + smb_shm_free(smb_shm_addr2offset(scanner_p)); *pid = 0; - shm_unlock(); + smb_shm_unlock(); return (0); } @@ -241,16 +241,16 @@ int get_share_mode(int cnum,struct stat *sbuf,int *pid) if (! *pid) { if(prev_p == scanner_p) - shm_set_userdef_off(scanner_p->next_offset); + smb_shm_set_userdef_off(scanner_p->next_offset); else prev_p->next_offset = scanner_p->next_offset; - shm_free(shm_addr2offset(scanner_p)); + smb_shm_free(smb_shm_addr2offset(scanner_p)); } if (*pid) DEBUG(5,("Read share mode record mode 0x%X pid=%d\n",ret,*pid)); - if(!shm_unlock()) return (0); + if(!smb_shm_unlock()) return (0); return(ret); @@ -309,20 +309,20 @@ void del_share_mode(int fnum) { #if FAST_SHARE_MODES struct stat st; - time_t t=0; + struct timeval t; int pid=0; BOOL del = False; share_mode_record *scanner_p; share_mode_record *prev_p; BOOL found = False; + t.tv_sec = t.tv_usec = 0; + if (fstat(Files[fnum].fd_ptr->fd,&st) != 0) return; - if (fstat(Files[fnum].fd,&st) != 0) return; - - if (!shm_lock()) return; + if (!smb_shm_lock()) return; - scanner_p = (share_mode_record *)shm_offset2addr(shm_get_userdef_off()); + scanner_p = (share_mode_record *)smb_shm_offset2addr(smb_shm_get_userdef_off()); prev_p = scanner_p; while(scanner_p) { @@ -334,37 +334,39 @@ void del_share_mode(int fnum) else { prev_p = scanner_p ; - scanner_p = (share_mode_record *)shm_offset2addr(scanner_p->next_offset); + scanner_p = (share_mode_record *)smb_shm_offset2addr(scanner_p->next_offset); } } if(!found) { - shm_unlock(); + smb_shm_unlock(); return; } - t = scanner_p->time; + t.tv_sec = scanner_p->time.tv_sec; + t.tv_usec = scanner_p->time.tv_usec; pid = scanner_p->pid; if( (scanner_p->locking_version != LOCKING_VERSION) || !pid || !process_exists(pid)) del = True; - if (!del && t == Files[fnum].open_time && pid==(int)getpid()) + if (!del && (memcmp(&t,&Files[fnum].open_time,sizeof(t)) == 0) + && pid==(int)getpid()) del = True; if (del) { DEBUG(2,("Deleting share mode record\n")); if(prev_p == scanner_p) - shm_set_userdef_off(scanner_p->next_offset); + smb_shm_set_userdef_off(scanner_p->next_offset); else prev_p->next_offset = scanner_p->next_offset; - shm_free(shm_addr2offset(scanner_p)); + smb_shm_free(smb_shm_addr2offset(scanner_p)); } - shm_unlock(); + smb_shm_unlock(); return; #else @@ -418,30 +420,31 @@ BOOL set_share_mode(int fnum,int mode) #if FAST_SHARE_MODES int pid = (int)getpid(); struct stat st; - shm_offset_t new_off; + smb_shm_offset_t new_off; share_mode_record *new_p; - if (fstat(Files[fnum].fd,&st) != 0) return(False); + if (fstat(Files[fnum].fd_ptr->fd,&st) != 0) return(False); - if (!shm_lock()) return (False); - new_off = shm_alloc(sizeof(share_mode_record) + strlen(Files[fnum].name) ); + if (!smb_shm_lock()) return (False); + new_off = smb_shm_alloc(sizeof(share_mode_record) + strlen(Files[fnum].name) ); if (new_off == NULL_OFFSET) return (False); - new_p = (share_mode_record *)shm_offset2addr(new_off); + new_p = (share_mode_record *)smb_shm_offset2addr(new_off); new_p->locking_version = LOCKING_VERSION; new_p->share_mode = mode; - new_p->time = Files[fnum].open_time; + new_p->time.tv_sec = Files[fnum].open_time.tv_sec; + new_p->time.tv_usec = Files[fnum].open_time.tv_usec; new_p->pid = pid; new_p->st_dev = st.st_dev; new_p->st_ino = st.st_ino; strcpy(new_p->file_name,Files[fnum].name); - new_p->next_offset = shm_get_userdef_off(); - shm_set_userdef_off(new_off); + new_p->next_offset = smb_shm_get_userdef_off(); + smb_shm_set_userdef_off(new_off); DEBUG(3,("Created share record for %s with mode 0x%X pid=%d\n",Files[fnum].name,mode,pid)); - if (!shm_unlock()) return (False); + if (!smb_shm_unlock()) return (False); return(True); #else @@ -496,9 +499,9 @@ void clean_share_modes(void) share_mode_record *prev_p; int pid; - if (!shm_lock()) return; + if (!smb_shm_lock()) return; - scanner_p = (share_mode_record *)shm_offset2addr(shm_get_userdef_off()); + scanner_p = (share_mode_record *)smb_shm_offset2addr(smb_shm_get_userdef_off()); prev_p = scanner_p; while(scanner_p) { @@ -509,28 +512,28 @@ void clean_share_modes(void) DEBUG(2,("Deleting stale share mode record")); if(prev_p == scanner_p) { - shm_set_userdef_off(scanner_p->next_offset); - shm_free(shm_addr2offset(scanner_p)); - scanner_p = (share_mode_record *)shm_offset2addr(shm_get_userdef_off()); + smb_shm_set_userdef_off(scanner_p->next_offset); + smb_shm_free(smb_shm_addr2offset(scanner_p)); + scanner_p = (share_mode_record *)smb_shm_offset2addr(smb_shm_get_userdef_off()); prev_p = scanner_p; } else { prev_p->next_offset = scanner_p->next_offset; - shm_free(shm_addr2offset(scanner_p)); - scanner_p = (share_mode_record *)shm_offset2addr(prev_p->next_offset); + smb_shm_free(smb_shm_addr2offset(scanner_p)); + scanner_p = (share_mode_record *)smb_shm_offset2addr(prev_p->next_offset); } } else { prev_p = scanner_p ; - scanner_p = (share_mode_record *)shm_offset2addr(scanner_p->next_offset); + scanner_p = (share_mode_record *)smb_shm_offset2addr(scanner_p->next_offset); } } - shm_unlock(); + smb_shm_unlock(); return; #else -- cgit From 0f1f0ceb9519368188f695e18e2341ccfd1b2d15 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 8 May 1997 01:14:17 +0000 Subject: 'The mother of all checkins' :-). Jeremy Allison (jallison@whistle.com) Wed May 7 1997: Update for 1.9.17alpha1 release - 'browsefix release' designed to make browsing across subnets work. byteorder.h: Updated copyright to 1997. charcnv.c: Updated copyright to 1997. charset.c Updated copyright to 1997. charset.h Updated copyright to 1997. client.c Updated copyright to 1997. clientutil.c Updated copyright to 1997. dir.c Updated copyright to 1997. fault.c Updated copyright to 1997. includes.h Updated copyright to 1997. interface.c Updated copyright to 1997. ipc.c Updated copyright to 1997. kanji.c Updated copyright to 1997. kanji.h Updated copyright to 1997. loadparm.c Updated copyright to 1997. locking.c Updated copyright to 1997. mangle.c Updated copyright to 1997. message.c Updated copyright to 1997. nameannounce.c Made use of WINS subnet explicit. Added reset_announce_timer() so announcement can be made immediately when we become a master. Expanded code to do sync with dmb. namebrowse.c Removed redundent checks for AM_MASTER in sync code. Made use of WINS subnet explicit. namedbname.c Made use of WINS subnet explicit. namedbresp.c Made use of WINS subnet explicit. namedbserver.c Made use of WINS subnet explicit. namedbsubnet.c Explicitly add workgroup to WINS subnet when we become a dmb. Made use of WINS subnet explicit. namedbwork.c Made use of WINS subnet explicit. Removed redundent check_work_servertype() function. nameelect.c Explicitly add workgroup to WINS subnet when we become a master browser. Made use of WINS subnet explicit. namelogon.c Updated copyright to 1997. namepacket.c Updated copyright to 1997. namequery.c Updated copyright to 1997. nameresp.c Made use of WINS subnet explicit. Made nmbd fail if configured as master browser and one exists already. nameserv.c Made use of WINS subnet explicit. Remove redundent logon server and domain master code. nameserv.h Add emumerate subnet macros. nameservreply.c Made use of WINS subnet explicit. nameservresp.c Updated copyright to 1997. namework.c Made use of WINS subnet explicit. Updated code to add sync browser entries to add subnet parameter. nmbd.c Added sanity check for misconfigured nmbd. nmblib.c Updated copyright to 1997. nmblookup.c Updated copyright to 1997. nmbsync.c Removed redundent AM_ANY_MASTER check. params.c Updated copyright to 1997. password.c Updated copyright to 1997. pipes.c Updated copyright to 1997. predict.c Updated copyright to 1997. printing.c Updated copyright to 1997. proto.h Changed protos for new nmbd code. quotas.c Updated copyright to 1997. replace.c Updated copyright to 1997. reply.c Updated copyright to 1997. server.c Updated copyright to 1997. shmem.c Updated copyright to 1997. smb.h Updated copyright to 1997. smbencrypt.c Updated copyright to 1997. smbpasswd.c Updated copyright to 1997. smbrun.c Updated copyright to 1997. status.c Updated copyright to 1997. system.c Updated copyright to 1997. testparm.c Updated copyright to 1997. testprns.c Updated copyright to 1997. time.c Updated copyright to 1997. trans2.c Updated copyright to 1997. trans2.h Updated copyright to 1997. uid.c Updated copyright to 1997. username.c Updated copyright to 1997. util.c Updated copyright to 1997. version.h Changed to 1.9.17alpha1. (This used to be commit cf23a155a1315f50d488794a2caf88402bf3e3e6) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index ce96aa01cf..7c23e5b3ca 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. Locking functions - Copyright (C) Andrew Tridgell 1992-1996 + Copyright (C) Andrew Tridgell 1992-1997 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From aa864415c5183c948fe9ae221023d40265c38013 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 20 May 1997 00:32:51 +0000 Subject: dir.c: Fixed double slash issue. includes.h: Changed to ifdef FAST_SHARE_MODES. ipc.c: Changed lp_workgroup() to myworkgroup. loadparm.c: Added new shared mem parameters. Added Luke's fix. locking.c: Rewrite to do share modes better (both fast and slow modes). nameannounce.c: Changed lp_workgroup() to myworkgroup. Added Luke's fix. nameconf.c: Changed lp_workgroup() to myworkgroup. namedbname.c: Improved debug. namedbserver.c: Changed lp_workgroup() to myworkgroup. namedbsubnet.c: Added Luke's fix - rewritten somewhat. namedbwork.c: Changed lp_workgroup() to myworkgroup. nameelect.c: Added Luke's fix - rewritten somewhat. nameresp.c: Stoped shadowing global. nameserv.c: Added Luke's fix - Improved debug. nameservreply.c: Improved debug. namework.c: Changed lp_workgroup() to myworkgroup. nmbd.c: Added Luke's fix - Changed lp_workgroup() to myworkgroup. pipes.c: Changed lp_workgroup() to myworkgroup. proto.h: Added Luke's fix, added smb_shm_ proto's. reply.c: Changed lp_workgroup() to myworkgroup. server.c: Rewrite to do share modes better (both fast and slow modes). shmem.c: Rewrite to do share modes better (both fast and slow modes). smb.h: Rewrite to do share modes better (both fast and slow modes). status.c: Rewrite to do share modes better (both fast and slow modes). trans2.c: Fixed double slash issue. util.c: Tidied up, created myworkgroup. Jeremy Allison (jallison@whistle.com). (This used to be commit 2a1711eaaf08bb6776770cd3c96b3010f431a677) --- source3/locking/locking.c | 1323 +++++++++++++++++++++++++++++++++------------ 1 file changed, 991 insertions(+), 332 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 7c23e5b3ca..e63e347a26 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -22,6 +22,9 @@ 12 aug 96: Erik.Devriendt@te6.siemens.be added support for shared memory implementation of share mode locking + + May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode + locking to deal with multiple share modes per open file. */ #include "includes.h" @@ -29,9 +32,6 @@ extern int DEBUGLEVEL; extern connection_struct Connections[]; extern files_struct Files[]; -pstring share_del_pending=""; - - /**************************************************************************** utility function called to see if a file region is locked ****************************************************************************/ @@ -100,7 +100,7 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 * return True; /* Did unlock */ } -#if FAST_SHARE_MODES +#ifdef FAST_SHARE_MODES /******************************************************************* initialize the shared memory for share_mode management ******************************************************************/ @@ -114,7 +114,7 @@ BOOL start_share_mode_mgmt(void) trim_string(shmem_file_name,"","/"); if (!*shmem_file_name) return(False); strcat(shmem_file_name, "/SHARE_MEM_FILE"); - return smb_shm_open(shmem_file_name, SHMEM_SIZE); + return smb_shm_open(shmem_file_name, lp_shmem_size()); } @@ -126,459 +126,1118 @@ BOOL stop_share_mode_mgmt(void) return smb_shm_close(); } -#else - -/* SHARE MODE LOCKS USING SLOW DESCRIPTION FILES */ - -/******************************************************************* - name a share file - ******************************************************************/ -static BOOL share_name(int cnum,struct stat *st,char *name) -{ - strcpy(name,lp_lockdir()); - standard_sub(cnum,name); - trim_string(name,"","/"); - if (!*name) return(False); - name += strlen(name); - - sprintf(name,"/share.%d.%d",(int)st->st_dev,(int)st->st_ino); - return(True); -} - /******************************************************************* - use the fnum to get the share file name + lock a hash bucket entry in shared memory for share_mode management ******************************************************************/ -static BOOL share_name_fnum(int fnum,char *name) +BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok) { - struct stat st; - if (fstat(Files[fnum].fd_ptr->fd,&st) != 0) return(False); - return(share_name(Files[fnum].cnum,&st,name)); + return smb_shm_lock_hash_entry(HASH_ENTRY(dev, inode)); } -#endif - /******************************************************************* - get the share mode of a file using the fnum + unlock a hash bucket entry in shared memory for share_mode management ******************************************************************/ -int get_share_mode_by_fnum(int cnum,int fnum,int *pid) +BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token) { - struct stat sbuf; - if (fstat(Files[fnum].fd_ptr->fd,&sbuf) == -1) return(0); - return(get_share_mode(cnum,&sbuf,pid)); + return smb_shm_unlock_hash_entry(HASH_ENTRY(dev, inode)); } /******************************************************************* - get the share mode of a file using the files name - ******************************************************************/ -int get_share_mode_byname(int cnum,char *fname,int *pid) -{ - struct stat sbuf; - if (stat(fname,&sbuf) == -1) return(0); - return(get_share_mode(cnum,&sbuf,pid)); -} - - -/******************************************************************* -get the share mode of a file +get all share mode entries in shared memory for a dev/inode pair. ********************************************************************/ -int get_share_mode(int cnum,struct stat *sbuf,int *pid) +int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, + min_share_mode_entry **old_shares) { -#if FAST_SHARE_MODES - share_mode_record *scanner_p; - share_mode_record *prev_p; - int ret; + smb_shm_offset_t *mode_array; + unsigned int hash_entry = HASH_ENTRY(dev, inode); + share_mode_record *file_scanner_p; + share_mode_record *file_prev_p; + share_mode_entry *entry_scanner_p; + share_mode_entry *entry_prev_p; + int num_entries; + int num_entries_copied; BOOL found = False; + min_share_mode_entry *share_array = (min_share_mode_entry *)0; - *pid = 0; + *old_shares = 0; - if(!smb_shm_lock()) return (0); + if(hash_entry > lp_shmem_hash_size() ) + { + DEBUG(0, + ("PANIC ERROR : get_share_modes (FAST_SHARE_MODES): hash_entry %d too large \ +(max = %d)\n", + hash_entry, lp_shmem_hash_size() )); + abort(); + } - scanner_p = (share_mode_record *)smb_shm_offset2addr(smb_shm_get_userdef_off()); - prev_p = scanner_p; - while(scanner_p) + mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off()); + + if(mode_array[hash_entry] == NULL_OFFSET) { - if( (scanner_p->st_dev == sbuf->st_dev) && (scanner_p->st_ino == sbuf->st_ino) ) + DEBUG(5,("get_share_modes (FAST_SHARE_MODES): hash bucket %d empty\n", hash_entry)); + return 0; + } + + 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 { - prev_p = scanner_p ; - scanner_p = (share_mode_record *)smb_shm_offset2addr(scanner_p->next_offset); + file_prev_p = file_scanner_p ; + file_scanner_p = (share_mode_record *)smb_shm_offset2addr( + file_scanner_p->next_offset); } } if(!found) { - smb_shm_unlock(); + 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); } - if(scanner_p->locking_version != LOCKING_VERSION) + if(file_scanner_p->locking_version != LOCKING_VERSION) { - DEBUG(2,("Deleting old share mode record due to old locking version %d",scanner_p->locking_version)); - if(prev_p == scanner_p) - smb_shm_set_userdef_off(scanner_p->next_offset); + 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",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 - prev_p->next_offset = scanner_p->next_offset; - smb_shm_free(smb_shm_addr2offset(scanner_p)); - *pid = 0; - - smb_shm_unlock(); + file_prev_p->next_offset = file_scanner_p->next_offset; + smb_shm_free(smb_shm_addr2offset(file_scanner_p)); return (0); } - - *pid = scanner_p->pid; - ret = scanner_p->share_mode; - if (*pid && !process_exists(*pid)) + /* Allocate the old_shares array */ + num_entries = file_scanner_p->num_share_mode_entries; + if(num_entries) { - ret = 0; - *pid = 0; + *old_shares = share_array = (min_share_mode_entry *) + malloc(num_entries * sizeof(min_share_mode_entry)); + if(*old_shares == 0) + { + DEBUG(0,("get_share_modes (FAST_SHARE_MODES): malloc fail !\n")); + return 0; + } } + + num_entries_copied = 0; - if (! *pid) + 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(prev_p == scanner_p) - smb_shm_set_userdef_off(scanner_p->next_offset); - else - prev_p->next_offset = scanner_p->next_offset; - smb_shm_free(smb_shm_addr2offset(scanner_p)); + int pid = entry_scanner_p->pid; + + if (pid && !process_exists(pid)) + { + /* Delete this share mode entry */ + share_mode_entry *delete_entry_p = entry_scanner_p; + + if(entry_prev_p == entry_scanner_p) + { + /* We are at start of list */ + file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry; + entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr( + file_scanner_p->share_mode_entries); + entry_prev_p = entry_scanner_p; + } + else + { + entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry; + entry_scanner_p = (share_mode_entry*) + smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry); + } + /* Decrement the number of share mode entries on this share mode record */ + file_scanner_p->num_share_mode_entries -= 1; + + /* PARANOIA TEST */ + if(file_scanner_p->num_share_mode_entries < 0) + { + DEBUG(0,("PANIC ERROR:get_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \ +for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries, + dev, inode, hash_entry)); + abort(); + } + + 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 (number of entries now = %d)\n", + pid, entry_scanner_p->share_mode, dev, inode, hash_entry, + file_scanner_p->num_share_mode_entries)); + + smb_shm_free(smb_shm_addr2offset(delete_entry_p)); + } + else + { + /* This is a valid share mode entry and the process that + created it still exists. Copy it into the output array. + */ + share_array[num_entries_copied].pid = entry_scanner_p->pid; + share_array[num_entries_copied].share_mode = entry_scanner_p->share_mode; + memcpy(&share_array[num_entries_copied].time, &entry_scanner_p->time, + sizeof(struct timeval)); + num_entries_copied++; + DEBUG(5,("get_share_modes (FAST_SHARE_MODES): Read share mode \ +record mode 0x%X pid=%d\n", entry_scanner_p->share_mode, entry_scanner_p->pid)); + entry_prev_p = entry_scanner_p; + entry_scanner_p = (share_mode_entry *) + smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry); + } } - if (*pid) - DEBUG(5,("Read share mode record mode 0x%X pid=%d\n",ret,*pid)); + /* If no valid share mode entries were found then this record shouldn't exist ! */ + if(num_entries_copied == 0) + { + DEBUG(0,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \ +hash bucket %d has a share mode record but no entries - deleting\n", + dev, inode, hash_entry)); + if(*old_shares) + free((char *)old_shares); + *old_shares = 0; + + 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)); + } - if(!smb_shm_unlock()) return (0); - - return(ret); - -#else - pstring fname; - int fd2; - char buf[20]; - int ret; - struct timeval t; + 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)); + + return(num_entries_copied); +} - *pid = 0; +/******************************************************************* +del the share mode of a file. +********************************************************************/ +void del_share_mode(share_lock_token token, int fnum) +{ + 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(); - if (!share_name(cnum,sbuf,fname)) return(0); + dev = Files[fnum].fd_ptr->dev; + inode = Files[fnum].fd_ptr->inode; - fd2 = open(fname,O_RDONLY,0); - if (fd2 < 0) return(0); + hash_entry = HASH_ENTRY(dev, inode); - if (read(fd2,buf,20) != 20) { - DEBUG(2,("Failed to read share file %s\n",fname)); - close(fd2); - unlink(fname); - return(0); + if(hash_entry > lp_shmem_hash_size() ) + { + DEBUG(0, + ("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): hash_entry %d too large \ +(max = %d)\n", + hash_entry, lp_shmem_hash_size() )); + abort(); } - close(fd2); - t.tv_sec = IVAL(buf,4); - t.tv_usec = IVAL(buf,8); - ret = IVAL(buf,12); - *pid = IVAL(buf,16); + 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:del_share_mode (FAST_SHARE_MODES): hash bucket %d empty\n", + hash_entry)); + abort(); + } - if (IVAL(buf,0) != LOCKING_VERSION) { - if (!unlink(fname)) DEBUG(2,("Deleted old locking file %s",fname)); - *pid = 0; - return(0); - } + file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]); + file_prev_p = file_scanner_p; - if (*pid && !process_exists(*pid)) { - ret=0; - *pid = 0; + 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:del_share_mode (FAST_SHARE_MODES): no entry found for dev %d, \ +inode %d in hash bucket %d\n", dev, inode, hash_entry)); + return; + } + + if(file_scanner_p->locking_version != LOCKING_VERSION) + { + 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 (! *pid) unlink(fname); /* XXXXX race, race */ + 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) && + (memcmp(&entry_scanner_p->time, + &Files[fnum].open_time,sizeof(struct timeval)) == 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 (*pid) - DEBUG(5,("Read share file %s mode 0x%X pid=%d\n",fname,ret,*pid)); + if (found) + { + /* Decrement the number of entries in the record. */ + file_scanner_p->num_share_mode_entries -= 1; + + DEBUG(2,("del_share_modes (FAST_SHARE_MODES): \ +Deleting share mode entry dev = %d, inode = %d in hash bucket %d (num entries now = %d)\n", + dev, inode, hash_entry, file_scanner_p->num_share_mode_entries)); + if(entry_prev_p == entry_scanner_p) + /* We are at start of list */ + file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry; + else + entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry; + smb_shm_free(smb_shm_addr2offset(entry_scanner_p)); + + /* PARANOIA TEST */ + if(file_scanner_p->num_share_mode_entries < 0) + { + DEBUG(0,("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \ +for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries, + dev, inode, hash_entry)); + abort(); + } - return(ret); -#endif + /* 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; + else + file_prev_p->next_offset = file_scanner_p->next_offset; + smb_shm_free(smb_shm_addr2offset(file_scanner_p)); + } + } + else + { + DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): No share mode record found \ +dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry)); + } } - /******************************************************************* -del the share mode of a file, if we set it last +set the share mode of a file. Return False on fail, True on success. ********************************************************************/ -void del_share_mode(int fnum) +BOOL set_share_mode(share_lock_token token, int fnum) { -#if FAST_SHARE_MODES - struct stat st; - struct timeval t; - int pid=0; - BOOL del = False; - share_mode_record *scanner_p; - share_mode_record *prev_p; + files_struct *fs_p = &Files[fnum]; + int32 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 *new_entry_p; + smb_shm_offset_t new_entry_offset; BOOL found = False; - t.tv_sec = t.tv_usec = 0; - - if (fstat(Files[fnum].fd_ptr->fd,&st) != 0) return; - - if (!smb_shm_lock()) return; + dev = fs_p->fd_ptr->dev; + inode = fs_p->fd_ptr->inode; + + hash_entry = HASH_ENTRY(dev, inode); + if(hash_entry > lp_shmem_hash_size() ) + { + DEBUG(0, + ("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): hash_entry %d too large \ +(max = %d)\n", + hash_entry, lp_shmem_hash_size() )); + abort(); + } + + mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off()); + + file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]); + file_prev_p = file_scanner_p; - scanner_p = (share_mode_record *)smb_shm_offset2addr(smb_shm_get_userdef_off()); - prev_p = scanner_p; - while(scanner_p) + while(file_scanner_p) { - if( (scanner_p->st_dev == st.st_dev) && (scanner_p->st_ino == st.st_ino) ) + if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) ) { - found = True; - break; + found = True; + break; } else { - prev_p = scanner_p ; - scanner_p = (share_mode_record *)smb_shm_offset2addr(scanner_p->next_offset); + file_prev_p = file_scanner_p ; + file_scanner_p = (share_mode_record *) + smb_shm_offset2addr(file_scanner_p->next_offset); } } - + if(!found) { - smb_shm_unlock(); - return; + /* We must create a share_mode_record */ + share_mode_record *new_mode_p = NULL; + smb_shm_offset_t new_offset = smb_shm_alloc( sizeof(share_mode_record) + + strlen(fs_p->name) + 1); + if(new_offset == NULL_OFFSET) + { + DEBUG(0,("ERROR:set_share_mode (FAST_SHARE_MODES): smb_shm_alloc fail !\n")); + return False; + } + new_mode_p = smb_shm_offset2addr(new_offset); + new_mode_p->locking_version = LOCKING_VERSION; + new_mode_p->st_dev = dev; + new_mode_p->st_ino = inode; + new_mode_p->num_share_mode_entries = 0; + new_mode_p->share_mode_entries = NULL_OFFSET; + strcpy(new_mode_p->file_name, fs_p->name); + + /* Chain onto the start of the hash chain (in the hope we will be used first). */ + new_mode_p->next_offset = mode_array[hash_entry]; + mode_array[hash_entry] = new_offset; + + file_scanner_p = new_mode_p; + + DEBUG(3,("set_share_mode (FAST_SHARE_MODES): Created share record for %s (dev %d \ +inode %d in hash bucket %d\n", fs_p->name, dev, inode, hash_entry)); + } + + /* Now create the share mode entry */ + new_entry_offset = smb_shm_alloc( sizeof(share_mode_entry)); + if(new_entry_offset == NULL_OFFSET) + { + smb_shm_offset_t delete_offset = mode_array[hash_entry]; + DEBUG(0,("ERROR:set_share_mode (FAST_SHARE_MODES): smb_shm_alloc fail 1!\n")); + /* Unlink the damaged record */ + mode_array[hash_entry] = file_scanner_p->next_offset; + /* And delete it */ + smb_shm_free( delete_offset ); + return False; } - - t.tv_sec = scanner_p->time.tv_sec; - t.tv_usec = scanner_p->time.tv_usec; - pid = scanner_p->pid; - - if( (scanner_p->locking_version != LOCKING_VERSION) || !pid || !process_exists(pid)) - del = True; - if (!del && (memcmp(&t,&Files[fnum].open_time,sizeof(t)) == 0) - && pid==(int)getpid()) - del = True; + new_entry_p = smb_shm_offset2addr(new_entry_offset); - if (del) + new_entry_p->pid = getpid(); + new_entry_p->share_mode = fs_p->share_mode; + memcpy( (char *)&new_entry_p->time, (char *)&fs_p->open_time, sizeof(struct timeval)); + + /* Chain onto the share_mode_record */ + new_entry_p->next_share_mode_entry = file_scanner_p->share_mode_entries; + file_scanner_p->share_mode_entries = new_entry_offset; + + /* PARANOIA TEST */ + if(file_scanner_p->num_share_mode_entries < 0) { - DEBUG(2,("Deleting share mode record\n")); - if(prev_p == scanner_p) - smb_shm_set_userdef_off(scanner_p->next_offset); - else - prev_p->next_offset = scanner_p->next_offset; - smb_shm_free(smb_shm_addr2offset(scanner_p)); - + DEBUG(0,("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \ +for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries, + dev, inode, hash_entry)); + abort(); } - smb_shm_unlock(); - return; + /* Increment the share_mode_entries counter */ + file_scanner_p->num_share_mode_entries += 1; + + DEBUG(3,("set_share_mode (FAST_SHARE_MODES): Created share entry for %s with mode \ +0x%X pid=%d (num_entries now = %d)\n",fs_p->name, fs_p->share_mode, new_entry_p->pid, + file_scanner_p->num_share_mode_entries)); + + return(True); +} + +#else /* FAST_SHARE_MODES */ + +/* SHARE MODE LOCKS USING SLOW DESCRIPTION FILES */ -#else +/******************************************************************* + name a share file + ******************************************************************/ +static BOOL share_name(int cnum, uint32 dev, uint32 inode, char *name) +{ + strcpy(name,lp_lockdir()); + standard_sub(cnum,name); + trim_string(name,"","/"); + if (!*name) return(False); + name += strlen(name); + + sprintf(name,"/share.%u.%u",dev,inode); + return(True); +} + +/******************************************************************* + lock a share mode file. + ******************************************************************/ +BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok) +{ pstring fname; - int fd2; - char buf[20]; - struct timeval t; - int pid=0; - BOOL del = False; - - t.tv_sec = t.tv_usec = 0; - if (!share_name_fnum(fnum,fname)) return; - - fd2 = open(fname,O_RDONLY,0); - if (fd2 < 0) return; - if (read(fd2,buf,20) != 20) - del = True; - close(fd2); - - if (!del) { - t.tv_sec = IVAL(buf,4); - t.tv_usec = IVAL(buf,8); - pid = IVAL(buf,16); - } - - if (!del) - if (IVAL(buf,0) != LOCKING_VERSION || !pid || !process_exists(pid)) - del = True; - - if (!del && (memcmp(&t,&Files[fnum].open_time,sizeof(t)) == 0) && (pid==(int)getpid())) - del = True; - - if (del) { - if (!unlink(fname)) - DEBUG(2,("Deleted share file %s\n",fname)); - else { - DEBUG(3,("Pending delete share file %s\n",fname)); - if (*share_del_pending) DEBUG(0,("Share del clash!\n")); - strcpy(share_del_pending,fname); + int fd; + + *ptok = (share_lock_token)-1; + + if(!share_name(cnum, dev, inode, fname)) + return False; + + { + int old_umask; + unbecome_user(); + old_umask = umask(0); +#ifdef SECURE_SHARE_MODES + 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,0644); +#endif /* SECURE_SHARE_MODES */ + 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; } } -#endif + + /* 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; + return True; } - /******************************************************************* -set the share mode of a file + unlock a share mode file. + ******************************************************************/ +BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token) +{ + int fd = (int)token; + int ret = True; + + /* token is the fd of the open share mode file. */ + /* Unlock the first byte. */ + if(fcntl_lock(fd, F_SETLKW, 0, 1, F_UNLCK) == False) + { + DEBUG(0,("ERROR unlock_share_entry: fcntl_lock failed with %s\n", + strerror(errno))); + ret = False; + } + + close((int)token); + return ret; +} + +/******************************************************************* +Force a share file to be deleted. ********************************************************************/ -BOOL set_share_mode(int fnum,int mode) + +static int delete_share_file( int cnum, char *fname ) { -#if FAST_SHARE_MODES - int pid = (int)getpid(); - struct stat st; - smb_shm_offset_t new_off; - share_mode_record *new_p; + 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; +} + +/******************************************************************* +Read a share file into a buffer. +********************************************************************/ + +static int read_share_file(int cnum, int fd, char *fname, char **out, BOOL *p_new_file) +{ + struct stat sb; + char *buf; + int size; + + *out = 0; + *p_new_file = False; + + if(fstat(fd, &sb) != 0) + { + DEBUG(0,("ERROR: read_share_file: Failed to do stat on share file %s (%s)\n", + fname, strerror(errno))); + return -1; + } + + if(sb.st_size == 0) + { + *p_new_file = True; + return 0; + } + + /* Allocate space for the file */ + if((buf = (char *)malloc(sb.st_size)) == NULL) + { + DEBUG(0,("read_share_file: malloc for file size %d fail !\n", sb.st_size)); + return -1; + } + if(lseek(fd, 0, SEEK_SET) != 0) + { + DEBUG(0,("ERROR: read_share_file: Failed to reset position to 0 \ +for share file %s (%s)\n", fname, strerror(errno))); + if(buf) + free(buf); + return -1; + } - if (fstat(Files[fnum].fd_ptr->fd,&st) != 0) return(False); + if (read(fd,buf,sb.st_size) != sb.st_size) + { + DEBUG(0,("ERROR: read_share_file: Failed to read share file %s (%s)\n", + fname, strerror(errno))); + if(buf) + free(buf); + return -1; + } - if (!smb_shm_lock()) return (False); - new_off = smb_shm_alloc(sizeof(share_mode_record) + strlen(Files[fnum].name) ); - if (new_off == NULL_OFFSET) return (False); - new_p = (share_mode_record *)smb_shm_offset2addr(new_off); - new_p->locking_version = LOCKING_VERSION; - new_p->share_mode = mode; - new_p->time.tv_sec = Files[fnum].open_time.tv_sec; - new_p->time.tv_usec = Files[fnum].open_time.tv_usec; - new_p->pid = pid; - new_p->st_dev = st.st_dev; - new_p->st_ino = st.st_ino; - strcpy(new_p->file_name,Files[fnum].name); - new_p->next_offset = smb_shm_get_userdef_off(); - smb_shm_set_userdef_off(new_off); - - - DEBUG(3,("Created share record for %s with mode 0x%X pid=%d\n",Files[fnum].name,mode,pid)); - - if (!smb_shm_unlock()) return (False); - return(True); + 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,0), LOCKING_VERSION)); + if(buf) + free(buf); + delete_share_file(cnum, fname); + return -1; + } + + /* Sanity check for file contents */ + size = sb.st_size; + size -= 10; /* Remove the header */ + + /* Remove the filename component. */ + size -= SVAL(buf, 8); + + /* 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)); + if(buf) + free(buf); + delete_share_file(cnum, fname); + return -1; + } -#else + *out = buf; + return 0; +} + +/******************************************************************* +get all share mode entries in a share file for a dev/inode pair. +********************************************************************/ +int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, + min_share_mode_entry **old_shares) +{ + int fd = (int)token; pstring fname; - int fd2; - char buf[20]; - int pid = (int)getpid(); + int i; + int num_entries; + int num_entries_copied; + int newsize; + min_share_mode_entry *share_array; + char *buf = 0; + char *base = 0; + BOOL new_file; + + *old_shares = 0; + + /* Read the share file header - this is of the form: + 0 - locking version. + 4 - number of share mode entries. + 8 - 2 byte name length + [n bytes] file name (zero terminated). - if (!share_name_fnum(fnum,fname)) return(False); + Followed by share mode entries of the form : + 0 - tv_sec + 4 - tv_usec + 8 - share_mode + 12 - pid + + */ + + share_name(cnum, dev, inode, fname); + + if(read_share_file( cnum, fd, fname, &buf, &new_file) != 0) { - int old_umask = umask(0); - fd2 = open(fname,O_WRONLY|O_CREAT|O_TRUNC,0644); - umask(old_umask); + DEBUG(0,("ERROR: get_share_modes: Failed to read share file %s\n", + fname)); + return 0; } - if (fd2 < 0) { - DEBUG(2,("Failed to create share file %s\n",fname)); - return(False); + + if(new_file == True) + return 0; + + num_entries = IVAL(buf,4); + + DEBUG(5,("get_share_modes: share file %s has %d share mode entries.\n", + fname, num_entries)); + + /* PARANOIA TEST */ + if(num_entries < 0) + { + DEBUG(0,("PANIC ERROR:get_share_mode: num_share_mode_entries < 0 (%d) \ +for share file %d\n", num_entries, fname)); + abort(); } - SIVAL(buf,0,LOCKING_VERSION); - SIVAL(buf,4,Files[fnum].open_time.tv_sec); - SIVAL(buf,8,Files[fnum].open_time.tv_usec); - SIVAL(buf,12,mode); - SIVAL(buf,16,pid); + if(num_entries) + { + *old_shares = share_array = (min_share_mode_entry *) + malloc(num_entries * sizeof(min_share_mode_entry)); + if(*old_shares == 0) + { + DEBUG(0,("get_share_modes: malloc fail !\n")); + return 0; + } + } + else + { + /* No entries - just delete the file. */ + DEBUG(0,("get_share_modes: share file %s has no share mode entries - deleting.\n", + fname)); + if(buf) + free(buf); + delete_share_file(cnum, fname); + return 0; + } - if (write(fd2,buf,20) != 20) { - DEBUG(2,("Failed to write share file %s\n",fname)); - close(fd2); - unlink(fname); - return(False); + num_entries_copied = 0; + base = buf + 10 + SVAL(buf,8); + + for( i = 0; i < num_entries; i++) + { + int pid; + char *p = base + (i*16); + + 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,8), fname)); + continue; + } + 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; + + num_entries_copied++; } - write(fd2,Files[fnum].name,strlen(Files[fnum].name)+1); + if(num_entries_copied == 0) + { + /* Delete the whole file. */ + DEBUG(0,("get_share_modes: share file %s had no valid entries - deleting it !\n", + fname)); + if(*old_shares) + free((char *)old_shares); + if(buf) + free(buf); + delete_share_file(cnum, fname); + return 0; + } - close(fd2); + /* If we deleted some entries we need to re-write the whole number of + share mode entries back into the file. */ - DEBUG(3,("Created share file %s with mode 0x%X pid=%d\n",fname,mode,pid)); + if(num_entries_copied != num_entries) + { + if(lseek(fd, 0, SEEK_SET) != 0) + { + DEBUG(0,("ERROR: get_share_modes: lseek failed to reset to \ +position 0 for share mode file %s (%s)\n", fname, strerror(errno))); + if(*old_shares) + free((char *)old_shares); + if(buf) + free(buf); + return 0; + } - return(True); -#endif + SIVAL(buf, 4, num_entries_copied); + for( i = 0; i < num_entries_copied; i++) + { + 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) + (16*num_entries_copied); + if(write(fd, buf, newsize) != newsize) + { + DEBUG(0,("ERROR: get_share_modes: failed to re-write share \ +mode file %s (%s)\n", fname, strerror(errno))); + if(*old_shares) + free((char *)old_shares); + if(buf) + free(buf); + return 0; + } + /* Now truncate the file at this point. */ + if(ftruncate(fd, newsize)!= 0) + { + DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \ +mode file %s to size %d (%s)\n", fname, newsize, strerror(errno))); + if(*old_shares) + free((char *)old_shares); + if(buf) + free(buf); + return 0; + } + } + + if(buf) + free(buf); + + DEBUG(5,("get_share_modes: Read share file %s returning %d entries\n",fname, + num_entries_copied)); + + return num_entries_copied; } - /******************************************************************* -cleanup any stale share files +del a share mode from a share mode file. ********************************************************************/ -void clean_share_modes(void) +void del_share_mode(share_lock_token token, int fnum) { -#ifdef USE_SHMEM - share_mode_record *scanner_p; - share_mode_record *prev_p; + pstring fname; + int fd = (int)token; + char *buf = 0; + char *base = 0; + int num_entries; + int newsize; + int i; + files_struct *fs_p = &Files[fnum]; int pid; - - if (!smb_shm_lock()) return; - - scanner_p = (share_mode_record *)smb_shm_offset2addr(smb_shm_get_userdef_off()); - prev_p = scanner_p; - while(scanner_p) + BOOL deleted = 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) { - pid = scanner_p->pid; - - if( (scanner_p->locking_version != LOCKING_VERSION) || !process_exists(pid)) - { - DEBUG(2,("Deleting stale share mode record")); - if(prev_p == scanner_p) - { - smb_shm_set_userdef_off(scanner_p->next_offset); - smb_shm_free(smb_shm_addr2offset(scanner_p)); - scanner_p = (share_mode_record *)smb_shm_offset2addr(smb_shm_get_userdef_off()); - prev_p = scanner_p; - } - else - { - prev_p->next_offset = scanner_p->next_offset; - smb_shm_free(smb_shm_addr2offset(scanner_p)); - scanner_p = (share_mode_record *)smb_shm_offset2addr(prev_p->next_offset); - } - - } - else - { - prev_p = scanner_p ; - scanner_p = (share_mode_record *)smb_shm_offset2addr(scanner_p->next_offset); - } + DEBUG(0,("ERROR: del_share_mode: Failed to read share file %s\n", + fname)); + return; } - - smb_shm_unlock(); - return; - -#else - char *lockdir = lp_lockdir(); - void *dir; - char *s; + if(new_file == True) + { + DEBUG(0,("ERROR:del_share_mode: share file %s is new (size zero), deleting it.\n", + fname)); + delete_share_file(fs_p->cnum, fname); + return; + } - if (!*lockdir) return; + num_entries = IVAL(buf,4); - dir = opendir(lockdir); - if (!dir) return; + DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n", + fname, num_entries)); - while ((s=readdirname(dir))) { - char buf[20]; - int pid; - int fd; - pstring lname; - int dev,inode; + /* PARANOIA TEST */ + if(num_entries < 0) + { + DEBUG(0,("PANIC ERROR:del_share_mode: num_share_mode_entries < 0 (%d) \ +for share file %d\n", num_entries, fname)); + abort(); + } - if (sscanf(s,"share.%d.%d",&dev,&inode)!=2) continue; + if(num_entries == 0) + { + /* No entries - just delete the file. */ + DEBUG(0,("del_share_mode: share file %s has no share mode entries - deleting.\n", + fname)); + if(buf) + free(buf); + delete_share_file(fs_p->cnum, fname); + return; + } - strcpy(lname,lp_lockdir()); - trim_string(lname,NULL,"/"); - strcat(lname,"/"); - strcat(lname,s); + pid = getpid(); - fd = open(lname,O_RDONLY,0); - if (fd < 0) continue; + /* Go through the entries looking for the particular one + we have set - delete it. + */ - if (read(fd,buf,20) != 20) { - close(fd); - if (!unlink(lname)) - printf("Deleted corrupt share file %s\n",s); + base = buf + 10 + SVAL(buf,8); + + for(i = 0; i < num_entries; i++) + { + char *p = base + (i*16); + + 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", + i, num_entries, fname)); + + /* Remove this entry. */ + if(i != num_entries - 1) + memcpy(p, p + 16, (num_entries - i - 1)*16); + + deleted = True; + break; + } + + if(!deleted) + { + DEBUG(0,("del_share_mode: entry not found in share file %s\n", fname)); + if(buf) + free(buf); + return; + } + + num_entries--; + SIVAL(buf,4, num_entries); + + if(num_entries == 0) + { + /* Deleted the last entry - remove the file. */ + DEBUG(5,("del_share_mode: removed last entry in share file - deleting share file %s\n", + fname)); + if(buf) + free(buf); + delete_share_file(fs_p->cnum,fname); + return; + } + + /* 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 \ +position 0 for share mode file %s (%s)\n", fname, strerror(errno))); + if(buf) + free(buf); + return; } - close(fd); - pid = IVAL(buf,16); + newsize = (base - buf) + (16*num_entries); + if(write(fd, buf, newsize) != newsize) + { + DEBUG(0,("ERROR: del_share_mode: failed to re-write share \ +mode file %s (%s)\n", fname, strerror(errno))); + if(buf) + free(buf); + return; + } + /* Now truncate the file at this point. */ + if(ftruncate(fd, newsize) != 0) + { + DEBUG(0,("ERROR: del_share_mode: failed to ftruncate share \ +mode file %s to size %d (%s)\n", fname, newsize, strerror(errno))); + if(buf) + free(buf); + return; + } +} + +/******************************************************************* +set the share mode of a file +********************************************************************/ +BOOL set_share_mode(share_lock_token token,int fnum) +{ + files_struct *fs_p = &Files[fnum]; + pstring fname; + int fd = (int)token; + int pid = (int)getpid(); + struct stat sb; + char *buf; + int num_entries; + int header_size; + char *p; + + share_name(fs_p->cnum, fs_p->fd_ptr->dev, + fs_p->fd_ptr->inode, fname); + + if(fstat(fd, &sb) != 0) + { + DEBUG(0,("ERROR: set_share_mode: Failed to do stat on share file %s\n", + fname)); + return False; + } - if (IVAL(buf,0) != LOCKING_VERSION || !process_exists(pid)) { - if (!unlink(lname)) - printf("Deleted stale share file %s\n",s); + /* Sanity check for file contents (if it's not a new share file). */ + if(sb.st_size != 0) + { + int size = sb.st_size; + + /* Allocate space for the file plus one extra entry */ + if((buf = (char *)malloc(sb.st_size + 16)) == NULL) + { + DEBUG(0,("set_share_mode: malloc for file size %d fail !\n", sb.st_size + 16)); + return False; + } + + if(lseek(fd, 0, SEEK_SET) != 0) + { + DEBUG(0,("ERROR: set_share_mode: Failed to reset position \ +to 0 for share file %s (%s)\n", fname, strerror(errno))); + if(buf) + free(buf); + return False; } + + if (read(fd,buf,sb.st_size) != sb.st_size) + { + DEBUG(0,("ERROR: set_share_mode: Failed to read share file %s (%s)\n", + fname, strerror(errno))); + if(buf) + free(buf); + return False; + } + + 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,0), LOCKING_VERSION)); + if(buf) + free(buf); + delete_share_file(fs_p->cnum, fname); + return False; + } + + size -= (10 + SVAL(buf, 8)); /* Remove the header */ + + /* 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)); + if(buf) + free(buf); + delete_share_file(fs_p->cnum, fname); + return False; + } + } + else + { + /* New file - just use a single_entry. */ + 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,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,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,4,num_entries); + + if(lseek(fd, 0, SEEK_SET) != 0) + { + DEBUG(0,("ERROR: set_share_mode: (1) Failed to reset position to \ +0 for share file %s (%s)\n", fname, strerror(errno))); + if(buf) + free(buf); + return False; + } + + 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))); + delete_share_file(fs_p->cnum, fname); + if(buf) + free(buf); + return False; + } + + /* Now truncate the file at this point - just for safety. */ + 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 + (16*num_entries), strerror(errno))); + if(buf) + free(buf); + return False; + } + + if(buf) + free(buf); + + DEBUG(3,("set_share_mode: Created share file %s with \ +mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid)); - closedir(dir); -#endif + return True; } +#endif /* FAST_SHARE_MODES */ -- cgit From ccf4314fe73fb035f6941f00ce952ba3a308c2da Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 27 May 1997 20:28:45 +0000 Subject: loadparm.c: Ensure printer services cannot be read only and don't use share mode locking. locking.c: Changed aborts to returns so not so drastic on PANIC errors. proto.h: Removed definition of open_file as this is now never externally called. reply.c: Changed reply_mknew, reply_ctemp, reply_printopen to go through open_file_shared. server.c: Modified open_file_shared to be more robust and be useful for printer & temp files. Removed truncate option from open_file (now all truncates are done in open_file_shared). util.c: Added EAGAIN to errors checked in open_socket_out(). version.h: Updated to 1.9.17alpha2. jallison@whistle.com (This used to be commit d8471909b79fd591be2b789485b65d2e636d4745) --- source3/locking/locking.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e63e347a26..2c392e924d 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -167,7 +167,7 @@ int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, ("PANIC ERROR : get_share_modes (FAST_SHARE_MODES): hash_entry %d too large \ (max = %d)\n", hash_entry, lp_shmem_hash_size() )); - abort(); + return 0; } mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off()); @@ -265,7 +265,7 @@ bucket %d",file_scanner_p->locking_version, dev, inode, hash_entry)); DEBUG(0,("PANIC ERROR:get_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \ for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries, dev, inode, hash_entry)); - abort(); + return 0; } DEBUG(0,("get_share_modes (FAST_SHARE_MODES): process %d no longer exists and \ @@ -344,7 +344,7 @@ void del_share_mode(share_lock_token token, int fnum) ("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): hash_entry %d too large \ (max = %d)\n", hash_entry, lp_shmem_hash_size() )); - abort(); + return; } mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off()); @@ -353,7 +353,7 @@ void del_share_mode(share_lock_token token, int fnum) { DEBUG(0,("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): hash bucket %d empty\n", hash_entry)); - abort(); + return; } file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]); @@ -436,7 +436,7 @@ Deleting share mode entry dev = %d, inode = %d in hash bucket %d (num entries no DEBUG(0,("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \ for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries, dev, inode, hash_entry)); - abort(); + return; } /* If we deleted the last share mode entry then remove the share mode record. */ @@ -483,7 +483,7 @@ BOOL set_share_mode(share_lock_token token, int fnum) ("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): hash_entry %d too large \ (max = %d)\n", hash_entry, lp_shmem_hash_size() )); - abort(); + return False; } mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off()); @@ -564,7 +564,7 @@ inode %d in hash bucket %d\n", fs_p->name, dev, inode, hash_entry)); DEBUG(0,("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \ for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries, dev, inode, hash_entry)); - abort(); + return False; } /* Increment the share_mode_entries counter */ @@ -838,7 +838,7 @@ int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, { DEBUG(0,("PANIC ERROR:get_share_mode: num_share_mode_entries < 0 (%d) \ for share file %d\n", num_entries, fname)); - abort(); + return 0; } if(num_entries) @@ -1005,7 +1005,7 @@ void del_share_mode(share_lock_token token, int fnum) { DEBUG(0,("PANIC ERROR:del_share_mode: num_share_mode_entries < 0 (%d) \ for share file %d\n", num_entries, fname)); - abort(); + return; } if(num_entries == 0) -- cgit From fb1429c1970bc123e191f0cb7cc764faf4b86998 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 1 Jul 1997 01:19:13 +0000 Subject: client.c: New print queue query code from Jeff C. Foster " ipc.c: Added code for returning restricted lists of servers. loadparm.c: Changed default for force create mode to 000. Changed default maxmux to 50 to comply with NT. locking.c: Fixed silly crash bug with slow share mode code. nameannounce.c: Added code for returning restricted lists of servers. namedbserver.c: Added code for returning restricted lists of servers. nameelect.c: Added code for returning restricted lists of servers. namework.c: Added code for returning restricted lists of servers. nmbsync.c: Added code for returning restricted lists of servers. server.c: Added quota fix Albrecht Gebhardt smb.h: Added define for COPYBUF_SIZE. system.c: Rename across filesystems Patch from Warren Birnbaum util.c: Minor fix for warning. (This used to be commit 1c6e433caa22813a699c9766847886eb59755f8b) --- source3/locking/locking.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 2c392e924d..64dc207cb7 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -893,7 +893,8 @@ it left a share mode entry with mode 0x%X in share file %s\n", DEBUG(0,("get_share_modes: share file %s had no valid entries - deleting it !\n", fname)); if(*old_shares) - free((char *)old_shares); + free((char *)*old_shares); + *old_shares = 0; if(buf) free(buf); delete_share_file(cnum, fname); @@ -910,7 +911,8 @@ it left a share mode entry with mode 0x%X in share file %s\n", DEBUG(0,("ERROR: get_share_modes: lseek failed to reset to \ position 0 for share mode file %s (%s)\n", fname, strerror(errno))); if(*old_shares) - free((char *)old_shares); + free((char *)*old_shares); + *old_shares = 0; if(buf) free(buf); return 0; @@ -933,7 +935,8 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno))); DEBUG(0,("ERROR: get_share_modes: failed to re-write share \ mode file %s (%s)\n", fname, strerror(errno))); if(*old_shares) - free((char *)old_shares); + free((char *)*old_shares); + *old_shares = 0; if(buf) free(buf); return 0; @@ -944,7 +947,8 @@ mode file %s (%s)\n", fname, strerror(errno))); DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \ mode file %s to size %d (%s)\n", fname, newsize, strerror(errno))); if(*old_shares) - free((char *)old_shares); + free((char *)*old_shares); + *old_shares = 0; if(buf) free(buf); return 0; -- cgit From 6835bd679c414a7d19a50cd6e99a53801cf4475e Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 15 Jul 1997 17:47:43 +0000 Subject: Fix silly crash bug in FAST_SHARE_MODES (same bug as was in SLOW_SHARE_MODES - duh !). Jeremy (jallison@whistle.com) (This used to be commit d38ac4f3a2fb47d3e2ca7d5f788130064502c6eb) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 64dc207cb7..f579a75a0b 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -301,7 +301,7 @@ record mode 0x%X pid=%d\n", entry_scanner_p->share_mode, entry_scanner_p->pid)); hash bucket %d has a share mode record but no entries - deleting\n", dev, inode, hash_entry)); if(*old_shares) - free((char *)old_shares); + free((char *)*old_shares); *old_shares = 0; if(file_prev_p == file_scanner_p) -- cgit From 30416c0b8a0f54f6cc1179c2e00860eaf5f58401 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Sep 1997 20:17:32 +0000 Subject: charcnv.c client.c clitar.c kanji.c kanji.h loadparm.c mangle.c smb.h util.c: Big merge to allow KANJI support to be in the main binary without explicitly compiling with it. locking.c: Fix for smbstatus not being able to read files. namepacket.c: Removed unneccesary debug statement. trans2.c: Added Luke's proposed fix (ifdefed out until further testing). nmblookup.c: Fixed bug where query fails and status is done on bogus IP. Jeremy (jallison@whistle.com) (This used to be commit 9196255022ae8c51b527412747b324819bea2c13) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index f579a75a0b..760d21a05d 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -616,7 +616,7 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok #ifdef SECURE_SHARE_MODES 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,0644); + fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0666); #endif /* SECURE_SHARE_MODES */ umask(old_umask); if(!become_user(cnum,Connections[cnum].vuid)) -- cgit From 6dd6b1383c0ed10c0897dea44f247befc15b03cc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 25 Sep 1997 00:25:44 +0000 Subject: Makefile: Removed earlier errors. includes.h: Added INADDR_LOOPBACK define. locking.c: More code to support oplocks. proto.h: Updated. server.c: More code to support oplocks. Moved processing of an SMB out of process() into a separate function so it is easier to call from an oplock break. smb.h: Added oplock fields. Jeremy (jallison@whistle.com) (This used to be commit f46dbaf08eb8e06a7545d2c19dce9e2dda9dcc78) --- source3/locking/locking.c | 271 +++++++++++++++++++++++++--------------------- 1 file changed, 147 insertions(+), 124 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 760d21a05d..7604676394 100644 --- a/source3/locking/locking.c +++ b/source3/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",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); + 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 */ @@ -283,6 +283,9 @@ bucket (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; +#endif /* USE_OPLOCKS */ memcpy(&share_array[num_entries_copied].time, &entry_scanner_p->time, sizeof(struct timeval)); num_entries_copied++; @@ -361,17 +364,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) @@ -383,20 +386,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) { @@ -441,15 +444,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 { @@ -461,7 +464,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) +BOOL set_share_mode(share_lock_token token, int fnum, uint16 port) { files_struct *fs_p = &Files[fnum]; int32 dev, inode; @@ -493,17 +496,17 @@ BOOL set_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) @@ -552,6 +555,9 @@ 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; +#endif /* USE_OPLOCKS */ memcpy( (char *)&new_entry_p->time, (char *)&fs_p->open_time, sizeof(struct timeval)); /* Chain onto the share_mode_record */ @@ -751,9 +757,10 @@ for share file %s (%s)\n", fname, strerror(errno))); return -1; } - if (IVAL(buf,0) != LOCKING_VERSION) { + if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) { DEBUG(0,("ERROR: read_share_file: share file %s has incorrect \ -locking version (was %d, should be %d).\n",fname, IVAL(buf,0), LOCKING_VERSION)); +locking version (was %d, should be %d).\n",fname, + IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION)); if(buf) free(buf); delete_share_file(cnum, fname); @@ -762,13 +769,13 @@ locking version (was %d, should be %d).\n",fname, IVAL(buf,0), LOCKING_VERSION)) /* Sanity check for file contents */ size = sb.st_size; - size -= 10; /* Remove the header */ + size -= SMF_HEADER_LENGTH; /* Remove the header */ /* Remove the filename component. */ - size -= SVAL(buf, 8); + size -= SVAL(buf, SMF_FILENAME_LEN_OFFSET); - /* The remaining size must be a multiple of 16 - error if not. */ - if((size % 16) != 0) + /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */ + if((size % SMF_ENTRY_LENGTH) != 0) { DEBUG(0,("ERROR: read_share_file: share file %s is an incorrect length - \ deleting it.\n", fname)); @@ -813,7 +820,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); @@ -828,7 +835,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,4); + num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET); DEBUG(5,("get_share_modes: share file %s has %d share mode entries.\n", fname, num_entries)); @@ -863,26 +870,29 @@ for share file %d\n", num_entries, fname)); } num_entries_copied = 0; - base = buf + 10 + SVAL(buf,8); + base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET); for( i = 0; i < num_entries; i++) { int pid; - char *p = base + (i*16); + char *p = base + (i*SMF_ENTRY_LENGTH); - pid = IVAL(p,12); + pid = IVAL(p,SME_PID_OFFSET); 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,8), fname)); + pid, IVAL(p,SME_SHAREMODE_OFFSET), fname)); continue; } - 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].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].pid = pid; +#ifdef USE_OPLOCKS + share_array[num_entries_copied].op_port = SVAL(p,SME_PORT_OFFSET); +#endif /* USE_OPLOCKS */ num_entries_copied++; } @@ -918,18 +928,21 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno))); return 0; } - SIVAL(buf, 4, num_entries_copied); + SIVAL(buf, SMF_NUM_ENTRIES_OFFSET, num_entries_copied); for( i = 0; i < num_entries_copied; i++) { - 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); + 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 + SIVAL(p,SME_PORT_OFFSET,share_array[i].op_port); +#endif /* USE_OPLOCKS */ } - newsize = (base - buf) + (16*num_entries_copied); + newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries_copied); if(write(fd, buf, newsize) != newsize) { DEBUG(0,("ERROR: get_share_modes: failed to re-write share \ @@ -999,7 +1012,7 @@ void del_share_mode(share_lock_token token, int fnum) return; } - num_entries = IVAL(buf,4); + num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET); DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n", fname, num_entries)); @@ -1029,14 +1042,16 @@ for share file %d\n", num_entries, fname)); we have set - delete it. */ - base = buf + 10 + SVAL(buf,8); + base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET); for(i = 0; i < num_entries; i++) { - char *p = base + (i*16); + char *p = base + (i*SMF_ENTRY_LENGTH); - 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)) + 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,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n", @@ -1044,7 +1059,7 @@ for share file %d\n", num_entries, fname)); /* Remove this entry. */ if(i != num_entries - 1) - memcpy(p, p + 16, (num_entries - i - 1)*16); + memcpy(p, p + SMF_ENTRY_LENGTH, (num_entries - i - 1)*SMF_ENTRY_LENGTH); deleted = True; break; @@ -1059,7 +1074,7 @@ for share file %d\n", num_entries, fname)); } num_entries--; - SIVAL(buf,4, num_entries); + SIVAL(buf,SMF_NUM_ENTRIES_OFFSET, num_entries); if(num_entries == 0) { @@ -1074,23 +1089,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) + (16*num_entries); + newsize = (base - buf) + (SMF_ENTRY_LENGTH*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) { @@ -1105,7 +1120,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) +BOOL set_share_mode(share_lock_token token,int fnum, uint16 port) { files_struct *fs_p = &Files[fnum]; pstring fname; @@ -1133,9 +1148,10 @@ BOOL set_share_mode(share_lock_token token,int fnum) int size = sb.st_size; /* Allocate space for the file plus one extra entry */ - if((buf = (char *)malloc(sb.st_size + 16)) == NULL) + if((buf = (char *)malloc(sb.st_size + SMF_ENTRY_LENGTH)) == NULL) { - DEBUG(0,("set_share_mode: malloc for file size %d fail !\n", sb.st_size + 16)); + DEBUG(0,("set_share_mode: malloc for file size %d fail !\n", + sb.st_size + SMF_ENTRY_LENGTH)); return False; } @@ -1157,20 +1173,21 @@ to 0 for share file %s (%s)\n", fname, strerror(errno))); return False; } - if (IVAL(buf,0) != LOCKING_VERSION) + if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) { DEBUG(0,("ERROR: set_share_mode: share file %s has incorrect \ -locking version (was %d, should be %d).\n",fname, IVAL(buf,0), LOCKING_VERSION)); +locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET), + LOCKING_VERSION)); if(buf) free(buf); delete_share_file(fs_p->cnum, fname); return False; } - size -= (10 + SVAL(buf, 8)); /* Remove the header */ + size -= (SMF_HEADER_LENGTH + SVAL(buf, SMF_FILENAME_LEN_OFFSET)); /* Remove the header */ - /* The remaining size must be a multiple of 16 - error if not. */ - if((size % 16) != 0) + /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */ + if((size % SMF_ENTRY_LENGTH) != 0) { DEBUG(0,("ERROR: set_share_mode: share file %s is an incorrect length - \ deleting it.\n", fname)); @@ -1184,28 +1201,32 @@ deleting it.\n", fname)); else { /* New file - just use a single_entry. */ - if((buf = (char *)malloc(10 + strlen(fs_p->name) + 1 + 16)) == NULL) + if((buf = (char *)malloc(SMF_HEADER_LENGTH + + strlen(fs_p->name) + 1 + SMF_ENTRY_LENGTH)) == NULL) { DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n")); return False; } - SIVAL(buf,0,LOCKING_VERSION); - SIVAL(buf,4,0); - SSVAL(buf,8,strlen(fs_p->name) + 1); - strcpy(buf + 10, fs_p->name); + 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); } - 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 = 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); +#endif /* USE_OPLOCKS */ num_entries++; - SIVAL(buf,4,num_entries); + SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,num_entries); if(lseek(fd, 0, SEEK_SET) != 0) { @@ -1216,7 +1237,8 @@ deleting it.\n", fname)); return False; } - if (write(fd,buf,header_size + (num_entries*16)) != (header_size + (num_entries*16))) + if (write(fd,buf,header_size + (num_entries*SMF_ENTRY_LENGTH)) != + (header_size + (num_entries*SMF_ENTRY_LENGTH))) { DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \ deleting it (%s).\n",fname, strerror(errno))); @@ -1227,10 +1249,11 @@ deleting it (%s).\n",fname, strerror(errno))); } /* Now truncate the file at this point - just for safety. */ - if(ftruncate(fd, header_size + (16*num_entries))!= 0) + if(ftruncate(fd, header_size + (SMF_ENTRY_LENGTH*num_entries))!= 0) { DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \ -mode file %s to size %d (%s)\n", fname, header_size + (16*num_entries), strerror(errno))); +mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entries), + strerror(errno))); if(buf) free(buf); return False; -- cgit From cef59090bb2fd3f8a9efd1a453cb90264b891d58 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 26 Sep 1997 18:55:29 +0000 Subject: Adding Andrews buffer overflow fixes into the main branch. Jeremy (jallison@whistle.com) (This used to be commit e7eb1f044d3101679dc7a118820ea5efe0cd837c) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 7604676394..64f24fb242 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -108,7 +108,7 @@ BOOL start_share_mode_mgmt(void) { pstring shmem_file_name; - strcpy(shmem_file_name,lp_lockdir()); + pstrcpy(shmem_file_name,lp_lockdir()); if (!directory_exist(shmem_file_name,NULL)) mkdir(shmem_file_name,0755); trim_string(shmem_file_name,"","/"); -- cgit From dff16872ca39c007d32d114af82d3ccd97f9d47a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 26 Sep 1997 19:26:56 +0000 Subject: Syncing up current oplock work in progress. #ifdef'ed out so should have no effect on other work. Jeremy (jallison@whistle.com) (This used to be commit 7e3d4c8b21f63a06d32605d230129e36883ad08c) --- source3/locking/locking.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 64f24fb242..7aa0e7dcf9 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -285,6 +285,7 @@ bucket (number of entries now = %d)\n", 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)); @@ -464,7 +465,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) +BOOL set_share_mode(share_lock_token token, int fnum, uint16 port, uint16 op_type) { files_struct *fs_p = &Files[fnum]; int32 dev, inode; @@ -557,6 +558,7 @@ inode %d in hash bucket %d\n", fs_p->name, dev, inode, hash_entry)); 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)); @@ -892,6 +894,7 @@ it left a share mode entry with mode 0x%X in share file %s\n", 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++; @@ -939,6 +942,7 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno))); SIVAL(p,SME_USEC_OFFSET,share_array[i].time.tv_usec); #ifdef USE_OPLOCKS SIVAL(p,SME_PORT_OFFSET,share_array[i].op_port); + SIVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type); #endif /* USE_OPLOCKS */ } @@ -1120,7 +1124,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) +BOOL set_share_mode(share_lock_token token,int fnum, uint16 port, uint16 op_type) { files_struct *fs_p = &Files[fnum]; pstring fname; @@ -1222,6 +1226,7 @@ deleting it.\n", fname)); 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++; -- cgit From 5864551aef50295addd1c8aa690a52870f70626d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 1 Oct 1997 23:32:22 +0000 Subject: OPLOCK CHECK-IN - oplocks are now *OPERATIONAL* !!!! Yipeee. At least as far as I can check in a short time :-). local.h: Changed OPLOCK_BREAK_TIMEOUT to 30 seconds. locking.c: Big changes to delete oplocks on a share mode entry. proto.h: updated. reply.c: Added oplock break code in lockingX reply & readbraw reply. server.c: Add batch oplock code. Force server shutdown if client fails to respond to oplock break. smb.h: Fix silly slow share mode oplock define bug. status.c: Add oplock status info. Jeremy (jallison@whistle.com) (This used to be commit 4c83d37239f15f855fc10f01d7b4bf4217fb9eda) --- source3/locking/locking.c | 244 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 242 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 7aa0e7dcf9..693beb7432 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -585,6 +585,122 @@ 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->op_port != 0) && + (entry_scanner_p->op_type != 0) && + (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 */ @@ -941,8 +1057,8 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno))); 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 - SIVAL(p,SME_PORT_OFFSET,share_array[i].op_port); - SIVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type); + SSVAL(p,SME_PORT_OFFSET,share_array[i].op_port); + SSVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type); #endif /* USE_OPLOCKS */ } @@ -1272,4 +1388,128 @@ 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) || + (SVAL(p,SME_PORT_OFFSET) == 0) || + (SVAL(p,SME_OPLOCK_TYPE_OFFSET) == 0)) + 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 */ -- cgit From 2f7b04061e61df7dcc1029b71fe12ca4dfca5f10 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 3 Oct 1997 20:36:06 +0000 Subject: locking.c: Fixed incorrect parameter count in debug statements. May explain solaris crashes. reply.c: Added NT specific error code. Put oplock break code in correct place in reply_lockingX. server.c: Removed unneeded error mapping stuff. Fixed race condition in oplock code. trans2.c: Added NT specific error code. util.c: Added paranoia check in interpret_addr. Some core dumps reported here. Upped fcntl debug levels. Andrew. Please check the NT specific error code handling (search for the string "/* Ugly - NT specific hack - but needed (JRA) */", this makes NT and 95 clients behave correctly here - please check your Visual Basic apps with this code. Jeremy (jallison@whistle.com). (This used to be commit 97ee4a5f69bd9cfbbc8710a1a04d80db0ee40104) --- source3/locking/locking.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 693beb7432..834f3e5658 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -206,7 +206,7 @@ file dev = %d, ino = %d in hash_bucket %d\n", dev, inode, hash_entry)); { 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",file_scanner_p->locking_version, dev, inode, hash_entry)); +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 @@ -270,7 +270,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 (number of entries now = %d)\n", +bucket %d (number of entries now = %d)\n", pid, entry_scanner_p->share_mode, dev, inode, hash_entry, file_scanner_p->num_share_mode_entries)); @@ -316,8 +316,7 @@ 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); } @@ -878,8 +877,8 @@ for share file %s (%s)\n", fname, strerror(errno))); if (IVAL(buf,SMF_VERSION_OFFSET) != 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) + IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION)); + if(buf) free(buf); delete_share_file(cnum, fname); return -1; -- cgit From c89eaa20d14c46c70980598345d7aa9394bcd854 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 3 Oct 1997 23:45:34 +0000 Subject: Making it harder for share_mode_entries to be left with non-zero op_type fields. Paranoia code really. Jeremy (jallison@whistle.com) (This used to be commit 21ecb46f56ac0f341803d0552c981e517d0322cb) --- source3/locking/locking.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 834f3e5658..abda5d39d4 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -668,8 +668,7 @@ record due to old locking version %d for file dev %d, inode %d hash bucket %d\n" while(entry_scanner_p) { if( (pid == entry_scanner_p->pid) && - (entry_scanner_p->op_port != 0) && - (entry_scanner_p->op_type != 0) && + (entry_scanner_p->share_mode == Files[fnum].share_mode) && (memcmp(&entry_scanner_p->time, &Files[fnum].open_time,sizeof(struct timeval)) == 0) ) { @@ -1463,9 +1462,7 @@ for share file %d\n", num_entries, fname)); 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) || - (SVAL(p,SME_PORT_OFFSET) == 0) || - (SVAL(p,SME_OPLOCK_TYPE_OFFSET) == 0)) + (IVAL(p,SME_PID_OFFSET) != pid)) continue; DEBUG(5,("remove_share_oplock: clearing oplock on entry number %d (of %d) \ -- cgit From 2e92be3aaf01c574d32d1a10e1359888638b68bc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 6 Oct 1997 17:52:25 +0000 Subject: client.c: Changed shadowed variable. locking.c: Removed USE_OPLOCKS - now the default. params.c: Removed unused variable. proto.h: Updated. reply.c: Removed USE_OPLOCKS - now the default. server.c: Removed USE_OPLOCKS - now the default. smb.h: Removed USE_OPLOCKS - now the default. smbparse.c: Changed shadowed variable. status.c: Removed USE_OPLOCKS - now the default. util.c: Removed USE_OPLOCKS - now the default. Jeremy (jallison@whistle.com) (This used to be commit b93509846d6291771787af457500eec8984ee6bd) --- source3/locking/locking.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index abda5d39d4..f29c1a6105 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -283,10 +283,8 @@ 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++; @@ -555,10 +553,8 @@ 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 */ @@ -589,7 +585,6 @@ 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; @@ -694,9 +689,6 @@ mode record found dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_en } return True; -#else /* USE_OPLOCKS */ - return False; -#endif /* USE_OPLOCKS */ } #else /* FAST_SHARE_MODES */ @@ -1006,10 +998,8 @@ it left a share mode entry with mode 0x%X in share file %s\n", 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].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++; } @@ -1054,10 +1044,8 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno))); 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 */ } newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries_copied); @@ -1338,10 +1326,8 @@ deleting it.\n", fname)); 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++; @@ -1392,7 +1378,6 @@ 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; @@ -1504,8 +1489,5 @@ mode file %s (%s)\n", fname, strerror(errno))); return True; -#else /* USE_OPLOCKS */ - return False; -#endif /* USE_OPLOCKS */ } #endif /* FAST_SHARE_MODES */ -- cgit From 1f7a84bc9c343170ccf06c32d40fc2b07bff271d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 6 Oct 1997 19:50:51 +0000 Subject: Finally ! Found & fixed crash bug with logging message when deleting invalid share mode entries. Thanks to berg@wienrg.aut.alcatel.at (Dietmar Berg) for the stack backtrace. Jeremy (jallison@whistle.com) (This used to be commit db4c2cb50e11d252ff3ba0e0973767e909dd33bd) --- source3/locking/locking.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index f29c1a6105..6e321d0626 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -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)); -- cgit From fb27bc139f8d321e50471c595b65b277ee114801 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Oct 1997 18:46:19 +0000 Subject: locking.c: Added fix for race condition in slow share mode code. lsaparse.c: #ifdef'ed out code so this will compile - LUKE PLEASE CHECK THIS. pipes.c: #ifdef'ed out code so this will compile - LUKE PLEASE CHECK THIS. server.c: Fixed last known oplock race condition. smb.h: Re-removed USE_OPLOCK defines - someone checked in an old version. smbparse.c: #ifdef'ed out code so this will compile - LUKE PLEASE CHECK THIS. Jeremy (jallison@whistle.com) (This used to be commit 1e1366ddc5542283a37debdf830ca139bbade1b0) --- source3/locking/locking.c | 71 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 15 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 6e321d0626..639bc7be0b 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -25,6 +25,10 @@ May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode locking to deal with multiple share modes per open file. + + September 1997. Jeremy Allison (jallison@whistle.com). Added oplock + support. + */ #include "includes.h" @@ -726,13 +730,60 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok { int old_umask; + BOOL gotlock = False; unbecome_user(); 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 */ + + /* 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 on file %s failed with %s\n", + fname, strerror(errno))); + close(fd); + return False; + } + + /* + * 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)) { @@ -750,18 +801,8 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok } } - /* 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; - return True; + *ptok = (share_lock_token)fd; + return True; } /******************************************************************* @@ -781,7 +822,7 @@ BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token tok ret = False; } - close((int)token); + close(fd); return ret; } -- cgit From cdd01aa4dd2660aca01db7b5c22f52a1f506896d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Oct 1997 00:16:37 +0000 Subject: Added fixes for become_user braindamage. Jeremy (jallison@whistle.com) (This used to be commit 08afa51f5c80f3da983781774378bc1646c431d7) --- source3/locking/locking.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 639bc7be0b..4af37fdc47 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -722,6 +722,7 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok { pstring fname; int fd; + ret = True; *ptok = (share_lock_token)-1; @@ -759,6 +760,14 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok 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) @@ -766,7 +775,8 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok DEBUG(0,("ERROR lock_share_entry: fcntl_lock on file %s failed with %s\n", fname, strerror(errno))); close(fd); - return False; + ret = False; + break; } /* @@ -784,12 +794,18 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok gotlock = True; } while(!gotlock); + /* + * We have to come here if any of the above calls fail + * as we don't want to return and leave ourselves running + * as root ! + */ + 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; + ret = False; } /* We need to change directory back to the connection root. */ if (ChDir(Connections[cnum].connectpath) != 0) @@ -797,12 +813,12 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok DEBUG(0,("lock_share_entry: Can't change directory to %s (%s)\n", Connections[cnum].connectpath, strerror(errno))); close(fd); - return False; + ret = False; } } *ptok = (share_lock_token)fd; - return True; + return ret; } /******************************************************************* -- cgit From 9f6a10d173713677a929a2ffe0bc2a7f1a2ed229 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Oct 1997 00:36:57 +0000 Subject: Broke my own rule about checking in uncompiled source :-(. Jeremy. (This used to be commit 9fd056c91196746e09f220a15171f3c97791dcce) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 4af37fdc47..04c198afea 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -722,7 +722,7 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok { pstring fname; int fd; - ret = True; + int ret = True; *ptok = (share_lock_token)-1; -- cgit From 359d42c08d012b3e1c1bc6ac1071f8add706ba35 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Oct 1997 21:53:59 +0000 Subject: ipc.c: Adding Andrews become_root code to the main branch. locking.c: Adding Andrews become_root code to the main branch. pipes.c: Fixing the close_file issue. proto.h: The usual. reply.c: Move smb_pass into NTDOMAIN defined code. Fixing the close_file issue. server.c: Fixing the close_file issue. trans2.c: Fixing the close_file issue. uid.c: Adding Andrews become_root code to the main branch. Jeremy (jallison@whistle.com) (This used to be commit 16fd4337f79ce33f91050c96c4a566221c5d9126) --- source3/locking/locking.c | 45 ++++++++++++++++----------------------------- 1 file changed, 16 insertions(+), 29 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 04c198afea..5071121bed 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -729,10 +729,12 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok if(!share_name(cnum, dev, inode, fname)) return False; + /* we need to do this as root */ + become_root(False); + { int old_umask; BOOL gotlock = False; - unbecome_user(); old_umask = umask(0); /* @@ -801,23 +803,13 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok */ umask(old_umask); - if(!become_user(cnum,Connections[cnum].vuid)) - { - DEBUG(0,("lock_share_entry: Can't become connected user!\n")); - close(fd); - ret = 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); - ret = False; - } } *ptok = (share_lock_token)fd; + + /* return to our previous privilage level */ + unbecome_root(False); + return ret; } @@ -848,27 +840,22 @@ Force a share file to be deleted. static int delete_share_file( int cnum, char *fname ) { - unbecome_user(); + /* the share file could be owned by anyone, so do this as root */ + become_root(False); + 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)); } - DEBUG(5,("delete_share_file: Deleted share file %s\n", fname)); + /* return to our previous privilage level */ + unbecome_root(False); - 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; } -- cgit From c336a2f08183f63031b0a08b2111669bc36a5f30 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Oct 1997 23:08:07 +0000 Subject: .cvsignore: Added make_smbcodepage interface.c: Added is_local_net(). locking.c: Added Fix for zero length share files from Gerald Werner plus a race condition fix for the fix. nameannounce.c: Made function static. namedbresp.c: extern int ClientDGRAM removed - not used. namedbserver.c: extern int ClientDGRAM removed - not used. namedbsubnet.c: Added code to make sockets per subnet. namepacket.c: Added code to read from all sockets & filter. nameresp.c: extern int ClientDGRAM removed - not used. nameserv.c: Indentation tidyup :-). nameserv.h: Added sockets to struct subnet. nameservresp.c: Improved debug message. nmbd.c: Changed to terminte on listen_for_packets exiting. nmbsync.c: extern int ClientDGRAM & ClientNMB removed - not used. proto.h: The usual. util.c: Fixed debug message. Jeremy (jallison@whistle.com) (This used to be commit 6904c2de080b2a9702800e9e4126386ced20569d) --- source3/locking/locking.c | 75 +++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 25 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 5071121bed..bbc0c0033f 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -715,6 +715,31 @@ static BOOL share_name(int cnum, uint32 dev, uint32 inode, char *name) return(True); } +/******************************************************************* +Force a share file to be deleted. +********************************************************************/ + +static int delete_share_file( int cnum, char *fname ) +{ + /* the share file could be owned by anyone, so do this as root */ + become_root(False); + + 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)); + } + + /* return to our previous privilage level */ + unbecome_root(False); + + return 0; +} + /******************************************************************* lock a share mode file. ******************************************************************/ @@ -820,6 +845,31 @@ BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token tok { int fd = (int)token; int ret = True; + struct stat sb; + pstring fname; + + /* Fix for zero length share files from + Gerald Werner */ + + share_name(cnum, dev, inode, fname); + + /* get the share mode file size */ + if(fstat((int)token, &sb) != 0) + { + DEBUG(0,("ERROR: unlock_share_entry: Failed to do stat on share file %s (%s)\n", + fname, strerror(errno))); + sb.st_size = 1; + ret = False; + } + + /* If the file was zero length, we must delete before + doing the unlock to avoid a race condition (see + the code in lock_share_mode_entry for details. + */ + + /* remove the share file if zero length */ + if(sb.st_size == 0) + delete_share_file(cnum, fname); /* token is the fd of the open share mode file. */ /* Unlock the first byte. */ @@ -834,31 +884,6 @@ BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token tok return ret; } -/******************************************************************* -Force a share file to be deleted. -********************************************************************/ - -static int delete_share_file( int cnum, char *fname ) -{ - /* the share file could be owned by anyone, so do this as root */ - become_root(False); - - 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)); - } - - /* return to our previous privilage level */ - unbecome_root(False); - - return 0; -} - /******************************************************************* Read a share file into a buffer. ********************************************************************/ -- cgit From 3e670e4057321911c6674b8abe3c0bdcd684fd09 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Oct 1997 08:46:00 +0000 Subject: a major share modes reorganisation. The shares modes code is now split into separate files. The shared memory implementation is in locking_shm.c. The slow implementation is in locking_slow.c It is all controlled by a struct share_ops structure that has function pointers to the implementation of all the functions needed by a share modes implementation. An initialisation function sets up this structure. This will make adding new implementations easy and clean. This also allowed me to get rid of the ugly code in smbstatus. Now status.c links to the locking code and calls methods in share_ops. I also renamed some things and generally organised things in a much cleaner fashion. Defines and structures specific to each implementation have been moved to the appropriate file and out of smb.h. (This used to be commit 65ab9adaa0d356b8041ed8a507ea52117f2a284e) --- source3/locking/locking.c | 1458 ++------------------------------------------- 1 file changed, 51 insertions(+), 1407 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index bbc0c0033f..c75497c6b9 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -36,6 +36,8 @@ extern int DEBUGLEVEL; extern connection_struct Connections[]; extern files_struct Files[]; +static struct share_ops *share_ops; + /**************************************************************************** utility function called to see if a file region is locked ****************************************************************************/ @@ -104,1460 +106,102 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 * return True; /* Did unlock */ } -#ifdef FAST_SHARE_MODES -/******************************************************************* - initialize the shared memory for share_mode management - ******************************************************************/ -BOOL start_share_mode_mgmt(void) -{ - pstring shmem_file_name; - - pstrcpy(shmem_file_name,lp_lockdir()); - if (!directory_exist(shmem_file_name,NULL)) - mkdir(shmem_file_name,0755); - trim_string(shmem_file_name,"","/"); - if (!*shmem_file_name) return(False); - strcat(shmem_file_name, "/SHARE_MEM_FILE"); - return smb_shm_open(shmem_file_name, lp_shmem_size()); -} -/******************************************************************* - deinitialize the shared memory for share_mode management - ******************************************************************/ -BOOL stop_share_mode_mgmt(void) +/**************************************************************************** + initialise the locking functions +****************************************************************************/ +BOOL locking_init(void) { - return smb_shm_close(); -} +#ifdef FAST_SHARE_MODES + share_ops = locking_shm_init(); + if (!share_ops) { + DEBUG(0,("ERROR: Failed to initialise fast share modes - trying slow code\n")); + } + if (share_ops) return True; +#endif -/******************************************************************* - lock a hash bucket entry in shared memory for share_mode management - ******************************************************************/ -BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok) -{ - return smb_shm_lock_hash_entry(HASH_ENTRY(dev, inode)); + share_ops = locking_slow_init(); + if (!share_ops) { + DEBUG(0,("ERROR: Failed to initialise share modes!\n")); + return False; + } + + return True; } /******************************************************************* - unlock a hash bucket entry in shared memory for share_mode management + deinitialize the share_mode management ******************************************************************/ -BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token) +BOOL locking_end(void) { - return smb_shm_unlock_hash_entry(HASH_ENTRY(dev, inode)); + return share_ops->stop_mgmt(); } -/******************************************************************* -get all share mode entries in shared memory for a dev/inode pair. -********************************************************************/ -int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, - min_share_mode_entry **old_shares) -{ - smb_shm_offset_t *mode_array; - unsigned int hash_entry = HASH_ENTRY(dev, inode); - share_mode_record *file_scanner_p; - share_mode_record *file_prev_p; - share_mode_entry *entry_scanner_p; - share_mode_entry *entry_prev_p; - int num_entries; - int num_entries_copied; - BOOL found = False; - min_share_mode_entry *share_array = (min_share_mode_entry *)0; - - *old_shares = 0; - - if(hash_entry > lp_shmem_hash_size() ) - { - DEBUG(0, - ("PANIC ERROR : get_share_modes (FAST_SHARE_MODES): hash_entry %d too large \ -(max = %d)\n", - hash_entry, lp_shmem_hash_size() )); - return 0; - } - - mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off()); - - if(mode_array[hash_entry] == NULL_OFFSET) - { - DEBUG(5,("get_share_modes (FAST_SHARE_MODES): hash bucket %d empty\n", hash_entry)); - return 0; - } - - 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(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); - } - - if(file_scanner_p->locking_version != LOCKING_VERSION) - { - 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); - } - - /* Allocate the old_shares array */ - num_entries = file_scanner_p->num_share_mode_entries; - if(num_entries) - { - *old_shares = share_array = (min_share_mode_entry *) - malloc(num_entries * sizeof(min_share_mode_entry)); - if(*old_shares == 0) - { - DEBUG(0,("get_share_modes (FAST_SHARE_MODES): malloc fail !\n")); - return 0; - } - } - - num_entries_copied = 0; - - 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) - { - int pid = entry_scanner_p->pid; - - if (pid && !process_exists(pid)) - { - /* 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) - { - /* We are at start of list */ - file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry; - entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr( - file_scanner_p->share_mode_entries); - entry_prev_p = entry_scanner_p; - } - else - { - entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry; - entry_scanner_p = (share_mode_entry*) - smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry); - } - /* Decrement the number of share mode entries on this share mode record */ - file_scanner_p->num_share_mode_entries -= 1; - - /* PARANOIA TEST */ - if(file_scanner_p->num_share_mode_entries < 0) - { - DEBUG(0,("PANIC ERROR:get_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \ -for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries, - dev, inode, hash_entry)); - return 0; - } - - 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, share_mode, dev, inode, hash_entry, - file_scanner_p->num_share_mode_entries)); - - smb_shm_free(smb_shm_addr2offset(delete_entry_p)); - } - else - { - /* This is a valid share mode entry and the process that - created it still exists. Copy it into the output array. - */ - share_array[num_entries_copied].pid = entry_scanner_p->pid; - share_array[num_entries_copied].share_mode = entry_scanner_p->share_mode; - share_array[num_entries_copied].op_port = entry_scanner_p->op_port; - share_array[num_entries_copied].op_type = entry_scanner_p->op_type; - memcpy(&share_array[num_entries_copied].time, &entry_scanner_p->time, - sizeof(struct timeval)); - num_entries_copied++; - DEBUG(5,("get_share_modes (FAST_SHARE_MODES): Read share mode \ -record mode 0x%X pid=%d\n", entry_scanner_p->share_mode, entry_scanner_p->pid)); - entry_prev_p = entry_scanner_p; - entry_scanner_p = (share_mode_entry *) - smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry); - } - } - - /* If no valid share mode entries were found then this record shouldn't exist ! */ - if(num_entries_copied == 0) - { - DEBUG(0,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \ -hash bucket %d has a share mode record but no entries - deleting\n", - dev, inode, hash_entry)); - if(*old_shares) - free((char *)*old_shares); - *old_shares = 0; - - 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)); - } - - 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)); - - return(num_entries_copied); -} /******************************************************************* -del the share mode of a file. -********************************************************************/ -void del_share_mode(share_lock_token token, int fnum) -{ - 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:del_share_mode (FAST_SHARE_MODES): hash_entry %d too large \ -(max = %d)\n", - hash_entry, lp_shmem_hash_size() )); - return; - } - - 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:del_share_mode (FAST_SHARE_MODES): hash bucket %d empty\n", - hash_entry)); - return; - } - - 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:del_share_mode (FAST_SHARE_MODES): no entry found for dev %d, \ -inode %d in hash bucket %d\n", dev, inode, hash_entry)); - return; - } - - if(file_scanner_p->locking_version != LOCKING_VERSION) - { - 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; - } - - 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) && - (memcmp(&entry_scanner_p->time, - &Files[fnum].open_time,sizeof(struct timeval)) == 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) - { - /* Decrement the number of entries in the record. */ - file_scanner_p->num_share_mode_entries -= 1; - - DEBUG(2,("del_share_modes (FAST_SHARE_MODES): \ -Deleting share mode entry dev = %d, inode = %d in hash bucket %d (num entries now = %d)\n", - dev, inode, hash_entry, file_scanner_p->num_share_mode_entries)); - if(entry_prev_p == entry_scanner_p) - /* We are at start of list */ - file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry; - else - entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry; - smb_shm_free(smb_shm_addr2offset(entry_scanner_p)); - - /* PARANOIA TEST */ - if(file_scanner_p->num_share_mode_entries < 0) - { - DEBUG(0,("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \ -for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries, - dev, inode, hash_entry)); - return; - } - - /* 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; - else - file_prev_p->next_offset = file_scanner_p->next_offset; - smb_shm_free(smb_shm_addr2offset(file_scanner_p)); - } - } - else - { - DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): No share mode record found \ -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) -{ - files_struct *fs_p = &Files[fnum]; - int32 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 *new_entry_p; - smb_shm_offset_t new_entry_offset; - BOOL found = False; - - dev = fs_p->fd_ptr->dev; - inode = fs_p->fd_ptr->inode; - - hash_entry = HASH_ENTRY(dev, inode); - if(hash_entry > lp_shmem_hash_size() ) - { - DEBUG(0, - ("PANIC ERROR:set_share_mode (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()); - - 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) - { - /* We must create a share_mode_record */ - share_mode_record *new_mode_p = NULL; - smb_shm_offset_t new_offset = smb_shm_alloc( sizeof(share_mode_record) + - strlen(fs_p->name) + 1); - if(new_offset == NULL_OFFSET) - { - DEBUG(0,("ERROR:set_share_mode (FAST_SHARE_MODES): smb_shm_alloc fail !\n")); - return False; - } - new_mode_p = smb_shm_offset2addr(new_offset); - new_mode_p->locking_version = LOCKING_VERSION; - new_mode_p->st_dev = dev; - new_mode_p->st_ino = inode; - new_mode_p->num_share_mode_entries = 0; - new_mode_p->share_mode_entries = NULL_OFFSET; - strcpy(new_mode_p->file_name, fs_p->name); - - /* Chain onto the start of the hash chain (in the hope we will be used first). */ - new_mode_p->next_offset = mode_array[hash_entry]; - mode_array[hash_entry] = new_offset; - - file_scanner_p = new_mode_p; - - DEBUG(3,("set_share_mode (FAST_SHARE_MODES): Created share record for %s (dev %d \ -inode %d in hash bucket %d\n", fs_p->name, dev, inode, hash_entry)); - } - - /* Now create the share mode entry */ - new_entry_offset = smb_shm_alloc( sizeof(share_mode_entry)); - if(new_entry_offset == NULL_OFFSET) - { - smb_shm_offset_t delete_offset = mode_array[hash_entry]; - DEBUG(0,("ERROR:set_share_mode (FAST_SHARE_MODES): smb_shm_alloc fail 1!\n")); - /* Unlink the damaged record */ - mode_array[hash_entry] = file_scanner_p->next_offset; - /* And delete it */ - smb_shm_free( delete_offset ); - return False; - } - - new_entry_p = smb_shm_offset2addr(new_entry_offset); - - new_entry_p->pid = getpid(); - new_entry_p->share_mode = fs_p->share_mode; - new_entry_p->op_port = port; - new_entry_p->op_type = op_type; - memcpy( (char *)&new_entry_p->time, (char *)&fs_p->open_time, sizeof(struct timeval)); - - /* Chain onto the share_mode_record */ - new_entry_p->next_share_mode_entry = file_scanner_p->share_mode_entries; - file_scanner_p->share_mode_entries = new_entry_offset; - - /* PARANOIA TEST */ - if(file_scanner_p->num_share_mode_entries < 0) - { - DEBUG(0,("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \ -for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries, - dev, inode, hash_entry)); - return False; - } - - /* Increment the share_mode_entries counter */ - file_scanner_p->num_share_mode_entries += 1; - - DEBUG(3,("set_share_mode (FAST_SHARE_MODES): Created share entry for %s with mode \ -0x%X pid=%d (num_entries now = %d)\n",fs_p->name, fs_p->share_mode, new_entry_p->pid, - 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) -{ - 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 /* FAST_SHARE_MODES */ - -/* SHARE MODE LOCKS USING SLOW DESCRIPTION FILES */ - -/******************************************************************* - name a share file + lock a hash bucket entry ******************************************************************/ -static BOOL share_name(int cnum, uint32 dev, uint32 inode, char *name) -{ - strcpy(name,lp_lockdir()); - standard_sub(cnum,name); - trim_string(name,"","/"); - if (!*name) return(False); - name += strlen(name); - - sprintf(name,"/share.%u.%u",dev,inode); - return(True); -} - -/******************************************************************* -Force a share file to be deleted. -********************************************************************/ - -static int delete_share_file( int cnum, char *fname ) +BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok) { - /* the share file could be owned by anyone, so do this as root */ - become_root(False); - - 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)); - } - - /* return to our previous privilage level */ - unbecome_root(False); - - return 0; + return share_ops->lock_entry(cnum, dev, inode, ptok); } /******************************************************************* - lock a share mode file. + unlock a hash bucket entry ******************************************************************/ -BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok) +BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, int token) { - 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(False); - - { - int old_umask; - 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); -#else /* SECURE_SHARE_MODES */ - 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 on file %s failed with %s\n", - fname, 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); - - /* - * We have to come here if any of the above calls fail - * as we don't want to return and leave ourselves running - * as root ! - */ - - umask(old_umask); - } - - *ptok = (share_lock_token)fd; - - /* return to our previous privilage level */ - unbecome_root(False); - - return ret; + return share_ops->unlock_entry(cnum, dev, inode, token); } /******************************************************************* - unlock a share mode file. - ******************************************************************/ -BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token) +get all share mode entries for a dev/inode pair. +********************************************************************/ +int get_share_modes(int cnum, int token, uint32 dev, uint32 inode, + share_mode_entry **shares) { - int fd = (int)token; - int ret = True; - struct stat sb; - pstring fname; - - /* Fix for zero length share files from - Gerald Werner */ - - share_name(cnum, dev, inode, fname); - - /* get the share mode file size */ - if(fstat((int)token, &sb) != 0) - { - DEBUG(0,("ERROR: unlock_share_entry: Failed to do stat on share file %s (%s)\n", - fname, strerror(errno))); - sb.st_size = 1; - ret = False; - } - - /* If the file was zero length, we must delete before - doing the unlock to avoid a race condition (see - the code in lock_share_mode_entry for details. - */ - - /* remove the share file if zero length */ - if(sb.st_size == 0) - delete_share_file(cnum, fname); - - /* token is the fd of the open share mode file. */ - /* Unlock the first byte. */ - if(fcntl_lock(fd, F_SETLKW, 0, 1, F_UNLCK) == False) - { - DEBUG(0,("ERROR unlock_share_entry: fcntl_lock failed with %s\n", - strerror(errno))); - ret = False; - } - - close(fd); - return ret; + return share_ops->get_entries(cnum, token, dev, inode, shares); } /******************************************************************* -Read a share file into a buffer. +del the share mode of a file. ********************************************************************/ - -static int read_share_file(int cnum, int fd, char *fname, char **out, BOOL *p_new_file) +void del_share_mode(int token, int fnum) { - struct stat sb; - char *buf; - int size; - - *out = 0; - *p_new_file = False; - - if(fstat(fd, &sb) != 0) - { - DEBUG(0,("ERROR: read_share_file: Failed to do stat on share file %s (%s)\n", - fname, strerror(errno))); - return -1; - } - - if(sb.st_size == 0) - { - *p_new_file = True; - return 0; - } - - /* Allocate space for the file */ - if((buf = (char *)malloc(sb.st_size)) == NULL) - { - DEBUG(0,("read_share_file: malloc for file size %d fail !\n", sb.st_size)); - return -1; - } - - if(lseek(fd, 0, SEEK_SET) != 0) - { - DEBUG(0,("ERROR: read_share_file: Failed to reset position to 0 \ -for share file %s (%s)\n", fname, strerror(errno))); - if(buf) - free(buf); - return -1; - } - - if (read(fd,buf,sb.st_size) != sb.st_size) - { - DEBUG(0,("ERROR: read_share_file: Failed to read share file %s (%s)\n", - fname, strerror(errno))); - if(buf) - free(buf); - return -1; - } - - if (IVAL(buf,SMF_VERSION_OFFSET) != 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) - free(buf); - delete_share_file(cnum, fname); - return -1; - } - - /* Sanity check for file contents */ - size = sb.st_size; - size -= SMF_HEADER_LENGTH; /* Remove the header */ - - /* Remove the filename component. */ - size -= SVAL(buf, SMF_FILENAME_LEN_OFFSET); - - /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */ - if((size % SMF_ENTRY_LENGTH) != 0) - { - DEBUG(0,("ERROR: read_share_file: share file %s is an incorrect length - \ -deleting it.\n", fname)); - if(buf) - free(buf); - delete_share_file(cnum, fname); - return -1; - } - - *out = buf; - return 0; + share_ops->del_entry(token, fnum); } /******************************************************************* -get all share mode entries in a share file for a dev/inode pair. +set the share mode of a file. Return False on fail, True on success. ********************************************************************/ -int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, - min_share_mode_entry **old_shares) +BOOL set_share_mode(int token, int fnum, uint16 port, uint16 op_type) { - int fd = (int)token; - pstring fname; - int i; - int num_entries; - int num_entries_copied; - int newsize; - min_share_mode_entry *share_array; - char *buf = 0; - char *base = 0; - BOOL new_file; - - *old_shares = 0; - - /* Read the share file header - this is of the form: - 0 - locking version. - 4 - number of share mode entries. - 8 - 2 byte name length - [n bytes] file name (zero terminated). - - Followed by share mode entries of the form : - - 0 - tv_sec - 4 - tv_usec - 8 - share_mode - 12 - pid - 16 - oplock port (if oplocks in use) - 2 bytes. - */ - - share_name(cnum, dev, inode, fname); - - if(read_share_file( cnum, fd, fname, &buf, &new_file) != 0) - { - DEBUG(0,("ERROR: get_share_modes: Failed to read share file %s\n", - fname)); - return 0; - } - - if(new_file == True) - return 0; - - num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET); - - DEBUG(5,("get_share_modes: share file %s has %d share mode entries.\n", - fname, num_entries)); - - /* PARANOIA TEST */ - if(num_entries < 0) - { - DEBUG(0,("PANIC ERROR:get_share_mode: num_share_mode_entries < 0 (%d) \ -for share file %d\n", num_entries, fname)); - return 0; - } - - if(num_entries) - { - *old_shares = share_array = (min_share_mode_entry *) - malloc(num_entries * sizeof(min_share_mode_entry)); - if(*old_shares == 0) - { - DEBUG(0,("get_share_modes: malloc fail !\n")); - return 0; - } - } - else - { - /* No entries - just delete the file. */ - DEBUG(0,("get_share_modes: share file %s has no share mode entries - deleting.\n", - fname)); - if(buf) - free(buf); - delete_share_file(cnum, fname); - return 0; - } - - num_entries_copied = 0; - base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET); - - for( i = 0; i < num_entries; i++) - { - int pid; - char *p = base + (i*SMF_ENTRY_LENGTH); - - pid = IVAL(p,SME_PID_OFFSET); - - 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)); - 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].pid = pid; - 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); - - num_entries_copied++; - } - - if(num_entries_copied == 0) - { - /* Delete the whole file. */ - DEBUG(0,("get_share_modes: share file %s had no valid entries - deleting it !\n", - fname)); - if(*old_shares) - free((char *)*old_shares); - *old_shares = 0; - if(buf) - free(buf); - delete_share_file(cnum, fname); - return 0; - } - - /* If we deleted some entries we need to re-write the whole number of - share mode entries back into the file. */ - - if(num_entries_copied != num_entries) - { - if(lseek(fd, 0, SEEK_SET) != 0) - { - DEBUG(0,("ERROR: get_share_modes: lseek failed to reset to \ -position 0 for share mode file %s (%s)\n", fname, strerror(errno))); - if(*old_shares) - free((char *)*old_shares); - *old_shares = 0; - if(buf) - free(buf); - return 0; - } - - SIVAL(buf, SMF_NUM_ENTRIES_OFFSET, 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); - SSVAL(p,SME_PORT_OFFSET,share_array[i].op_port); - SSVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type); - } - - newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries_copied); - if(write(fd, buf, newsize) != newsize) - { - DEBUG(0,("ERROR: get_share_modes: failed to re-write share \ -mode file %s (%s)\n", fname, strerror(errno))); - if(*old_shares) - free((char *)*old_shares); - *old_shares = 0; - if(buf) - free(buf); - return 0; - } - /* Now truncate the file at this point. */ - if(ftruncate(fd, newsize)!= 0) - { - DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \ -mode file %s to size %d (%s)\n", fname, newsize, strerror(errno))); - if(*old_shares) - free((char *)*old_shares); - *old_shares = 0; - if(buf) - free(buf); - return 0; - } - } - - if(buf) - free(buf); - - DEBUG(5,("get_share_modes: Read share file %s returning %d entries\n",fname, - num_entries_copied)); - - return num_entries_copied; + return share_ops->set_entry(token, fnum, port, op_type); } /******************************************************************* -del a share mode from a share mode file. +Remove an oplock port and mode entry from a share mode. ********************************************************************/ -void del_share_mode(share_lock_token token, int fnum) +BOOL remove_share_oplock(int fnum, int token) { - pstring fname; - int fd = (int)token; - char *buf = 0; - char *base = 0; - int num_entries; - int newsize; - int i; - files_struct *fs_p = &Files[fnum]; - int pid; - BOOL deleted = 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: del_share_mode: Failed to read share file %s\n", - fname)); - return; - } - - if(new_file == True) - { - DEBUG(0,("ERROR:del_share_mode: share file %s is new (size zero), deleting it.\n", - fname)); - delete_share_file(fs_p->cnum, fname); - return; - } - - num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET); - - DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n", - fname, num_entries)); - - /* PARANOIA TEST */ - if(num_entries < 0) - { - DEBUG(0,("PANIC ERROR:del_share_mode: num_share_mode_entries < 0 (%d) \ -for share file %d\n", num_entries, fname)); - return; - } - - if(num_entries == 0) - { - /* No entries - just delete the file. */ - DEBUG(0,("del_share_mode: share file %s has no share mode entries - deleting.\n", - fname)); - if(buf) - free(buf); - delete_share_file(fs_p->cnum, fname); - return; - } - - pid = getpid(); - - /* Go through the entries looking for the particular one - we have set - delete 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,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n", - i, num_entries, fname)); - - /* Remove this entry. */ - if(i != num_entries - 1) - memcpy(p, p + SMF_ENTRY_LENGTH, (num_entries - i - 1)*SMF_ENTRY_LENGTH); - - deleted = True; - break; - } - - if(!deleted) - { - DEBUG(0,("del_share_mode: entry not found in share file %s\n", fname)); - if(buf) - free(buf); - return; - } - - num_entries--; - SIVAL(buf,SMF_NUM_ENTRIES_OFFSET, num_entries); - - if(num_entries == 0) - { - /* Deleted the last entry - remove the file. */ - DEBUG(5,("del_share_mode: removed last entry in share file - deleting share file %s\n", - fname)); - if(buf) - free(buf); - delete_share_file(fs_p->cnum,fname); - return; - } + return share_ops->remove_oplock(fnum, token); +} - /* 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 \ -position 0 for share mode file %s (%s)\n", fname, strerror(errno))); - if(buf) - free(buf); - return; - } - newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries); - if(write(fd, buf, newsize) != newsize) - { - DEBUG(0,("ERROR: del_share_mode: failed to re-write share \ -mode file %s (%s)\n", fname, strerror(errno))); - if(buf) - free(buf); - return; - } - /* Now truncate the file at this point. */ - if(ftruncate(fd, newsize) != 0) - { - DEBUG(0,("ERROR: del_share_mode: failed to ftruncate share \ -mode file %s to size %d (%s)\n", fname, newsize, strerror(errno))); - if(buf) - free(buf); - return; - } -} - /******************************************************************* -set the share mode of a file +call the specified function on each entry under management by the +share mode system ********************************************************************/ -BOOL set_share_mode(share_lock_token token,int fnum, uint16 port, uint16 op_type) +int share_mode_forall(void (*fn)(share_mode_entry *, char *)) { - files_struct *fs_p = &Files[fnum]; - pstring fname; - int fd = (int)token; - int pid = (int)getpid(); - struct stat sb; - char *buf; - int num_entries; - int header_size; - char *p; - - share_name(fs_p->cnum, fs_p->fd_ptr->dev, - fs_p->fd_ptr->inode, fname); - - if(fstat(fd, &sb) != 0) - { - DEBUG(0,("ERROR: set_share_mode: Failed to do stat on share file %s\n", - fname)); - return False; - } - - /* Sanity check for file contents (if it's not a new share file). */ - if(sb.st_size != 0) - { - 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) - { - DEBUG(0,("set_share_mode: malloc for file size %d fail !\n", - sb.st_size + SMF_ENTRY_LENGTH)); - return False; - } - - if(lseek(fd, 0, SEEK_SET) != 0) - { - DEBUG(0,("ERROR: set_share_mode: Failed to reset position \ -to 0 for share file %s (%s)\n", fname, strerror(errno))); - if(buf) - free(buf); - return False; - } - - if (read(fd,buf,sb.st_size) != sb.st_size) - { - DEBUG(0,("ERROR: set_share_mode: Failed to read share file %s (%s)\n", - fname, strerror(errno))); - if(buf) - free(buf); - return False; - } - - if (IVAL(buf,SMF_VERSION_OFFSET) != 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)); - 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 */ - - /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */ - if((size % SMF_ENTRY_LENGTH) != 0) - { - DEBUG(0,("ERROR: set_share_mode: share file %s is an incorrect length - \ -deleting it.\n", fname)); - if(buf) - free(buf); - delete_share_file(fs_p->cnum, fname); - return False; - } - - } - else - { - /* New file - just use a single_entry. */ - if((buf = (char *)malloc(SMF_HEADER_LENGTH + - strlen(fs_p->name) + 1 + SMF_ENTRY_LENGTH)) == 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); - } - - 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); - SSVAL(p,SME_PORT_OFFSET,port); - SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type); - - num_entries++; - - SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,num_entries); - - if(lseek(fd, 0, SEEK_SET) != 0) - { - DEBUG(0,("ERROR: set_share_mode: (1) Failed to reset position to \ -0 for share file %s (%s)\n", fname, strerror(errno))); - if(buf) - free(buf); - return False; - } - - if (write(fd,buf,header_size + (num_entries*SMF_ENTRY_LENGTH)) != - (header_size + (num_entries*SMF_ENTRY_LENGTH))) - { - DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \ -deleting it (%s).\n",fname, strerror(errno))); - delete_share_file(fs_p->cnum, fname); - if(buf) - free(buf); - return False; - } - - /* Now truncate the file at this point - just for safety. */ - if(ftruncate(fd, header_size + (SMF_ENTRY_LENGTH*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))); - if(buf) - free(buf); - return False; - } - - if(buf) - free(buf); - - DEBUG(3,("set_share_mode: Created share file %s with \ -mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid)); - - return True; + return share_ops->forall(fn); } /******************************************************************* -Remove an oplock port and mode entry from a share mode. +dump the state of the system ********************************************************************/ -BOOL remove_share_oplock(int fnum, share_lock_token token) +void share_status(FILE *f) { - 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; - + share_ops->status(f); } -#endif /* FAST_SHARE_MODES */ -- cgit From 71d648cdb431ecf984196a7e480208a94fcdf390 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Oct 1997 14:27:17 +0000 Subject: change the default file permissions on the SHARE_MEM_FILE* to 0644. smbstatus now gets only read permission on the share files and does no locking. also get rid of some unnecessary umask(0) calls. smbd always runs with umask(0) (This used to be commit c6ac10170dbba57dfebc54c50d79cb29d13bb442) --- source3/locking/locking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index c75497c6b9..ae977b0f69 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -111,17 +111,17 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 * /**************************************************************************** initialise the locking functions ****************************************************************************/ -BOOL locking_init(void) +BOOL locking_init(int read_only) { #ifdef FAST_SHARE_MODES - share_ops = locking_shm_init(); + share_ops = locking_shm_init(read_only); if (!share_ops) { DEBUG(0,("ERROR: Failed to initialise fast share modes - trying slow code\n")); } if (share_ops) return True; #endif - share_ops = locking_slow_init(); + share_ops = locking_slow_init(read_only); if (!share_ops) { DEBUG(0,("ERROR: Failed to initialise share modes!\n")); return False; -- cgit From cb6941a19390113cbe61f436e74c9d969afd00d0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 Oct 1997 02:18:08 +0000 Subject: - don't allow locking to initialise twice - check that it is initialised before de-initialising it! (This used to be commit 68ad7b91999216e5721207b5a79c3a66be7cf420) --- source3/locking/locking.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index ae977b0f69..d654d038c8 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -113,6 +113,8 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 * ****************************************************************************/ BOOL locking_init(int read_only) { + if (share_ops) return True; + #ifdef FAST_SHARE_MODES share_ops = locking_shm_init(read_only); if (!share_ops) { @@ -135,7 +137,9 @@ BOOL locking_init(int read_only) ******************************************************************/ BOOL locking_end(void) { - return share_ops->stop_mgmt(); + if (share_ops) + return share_ops->stop_mgmt(); + return True; } -- cgit From 55f400bd84f26027f5ec9b7fa06b22895de7557c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 1998 13:27:43 +0000 Subject: This is *not* a big change (although it looks like one). This is merely updating the Copyright statements from 1997 to 1998. It's a once a year thing :-). NO OTHER CHANGES WERE MADE. Jeremy. (This used to be commit b9c16977231efb274e08856f7f3f4408dad6d96c) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d654d038c8..189ac0bcfe 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. Locking functions - Copyright (C) Andrew Tridgell 1992-1997 + Copyright (C) Andrew Tridgell 1992-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From 06c0349c445958aebb8a4611bdb7082711585754 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Jul 1998 00:10:26 +0000 Subject: locking.c: Added lock type to is_locked() and do_lock() as the code in reply_lockingX wasn't taking account of the difference between read and write locks ! How did this ever work :-) ! reply.c: server.c: Add lock type to is_locked() and do_lock(). util.c: Also added code from klausr@ITAP.Physik.Uni-Stuttgart.De to fix problem with log files growing too large if an smbd writes less than 100 debug messages. Jeremy. (This used to be commit 80080abf772a470d5f0f4dcd4a75fb2a09a9fb2a) --- source3/locking/locking.c | 74 ++++++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 27 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 189ac0bcfe..d5d767d2cc 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -39,11 +39,13 @@ extern files_struct Files[]; static struct share_ops *share_ops; /**************************************************************************** - utility function called to see if a file region is locked + Utility function called to see if a file region is locked. ****************************************************************************/ -BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset) + +BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset, int lock_type) { int snum = SNUM(cnum); + files_struct *fsp = &Files[fnum]; if (count == 0) return(False); @@ -51,17 +53,22 @@ BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset) if (!lp_locking(snum) || !lp_strict_locking(snum)) return(False); - return(fcntl_lock(Files[fnum].fd_ptr->fd,F_GETLK,offset,count, - (Files[fnum].can_write?F_WRLCK:F_RDLCK))); + if((lock_type == F_WRLCK) && !fsp->can_write) + lock_type = F_RDLCK; + + return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count,lock_type)); } /**************************************************************************** - utility function called by locking requests + Utility function called by locking requests. ****************************************************************************/ -BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode) + +BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int lock_type, + int *eclass,uint32 *ecode) { BOOL ok = False; + files_struct *fsp = &Files[fnum]; if (!lp_locking(SNUM(cnum))) return(True); @@ -72,9 +79,12 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ec return False; } - 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)); + if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum)) { + if(lock_type == F_WRLCK && !fsp->can_write) + lock_type = F_RDLCK; + + ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,lock_type); + } if (!ok) { *eclass = ERRDOS; @@ -86,17 +96,19 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ec /**************************************************************************** - utility function called by unlocking requests + Utility function called by unlocking requests. ****************************************************************************/ + BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode) { BOOL ok = False; + files_struct *fsp = &Files[fnum]; if (!lp_locking(SNUM(cnum))) return(True); - if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum)) - ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count,F_UNLCK); + if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum)) + ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,F_UNLCK); if (!ok) { *eclass = ERRDOS; @@ -109,8 +121,9 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 * /**************************************************************************** - initialise the locking functions + Initialise the locking functions. ****************************************************************************/ + BOOL locking_init(int read_only) { if (share_ops) return True; @@ -133,8 +146,9 @@ BOOL locking_init(int read_only) } /******************************************************************* - deinitialize the share_mode management - ******************************************************************/ + Deinitialize the share_mode management. +******************************************************************/ + BOOL locking_end(void) { if (share_ops) @@ -144,24 +158,27 @@ BOOL locking_end(void) /******************************************************************* - lock a hash bucket entry - ******************************************************************/ + Lock a hash bucket entry. +******************************************************************/ + BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok) { return share_ops->lock_entry(cnum, dev, inode, ptok); } /******************************************************************* - unlock a hash bucket entry - ******************************************************************/ + Unlock a hash bucket entry. +******************************************************************/ + BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, int token) { return share_ops->unlock_entry(cnum, dev, inode, token); } /******************************************************************* -get all share mode entries for a dev/inode pair. + Get all share mode entries for a dev/inode pair. ********************************************************************/ + int get_share_modes(int cnum, int token, uint32 dev, uint32 inode, share_mode_entry **shares) { @@ -169,42 +186,45 @@ int get_share_modes(int cnum, int token, uint32 dev, uint32 inode, } /******************************************************************* -del the share mode of a file. + Del the share mode of a file. ********************************************************************/ + void del_share_mode(int token, int fnum) { share_ops->del_entry(token, fnum); } /******************************************************************* -set the share mode of a file. Return False on fail, True on success. + Set the share mode of a file. Return False on fail, True on success. ********************************************************************/ + BOOL set_share_mode(int token, int fnum, uint16 port, uint16 op_type) { return share_ops->set_entry(token, fnum, port, op_type); } /******************************************************************* -Remove an oplock port and mode entry from a share mode. + Remove an oplock port and mode entry from a share mode. ********************************************************************/ BOOL remove_share_oplock(int fnum, int token) { return share_ops->remove_oplock(fnum, token); } - /******************************************************************* -call the specified function on each entry under management by the -share mode system + Call the specified function on each entry under management by the + share mode system. ********************************************************************/ + int share_mode_forall(void (*fn)(share_mode_entry *, char *)) { return share_ops->forall(fn); } /******************************************************************* -dump the state of the system + Dump the state of the system. ********************************************************************/ + void share_status(FILE *f) { share_ops->status(f); -- cgit From 7abcd0521e36425bf7c3dc90929c00ed49e9ab07 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 28 Jul 1998 18:15:31 +0000 Subject: loadparm.c: Added strict sync parameter. locking.c: Added code to deal with real open mode of file. reply.c: Added strict sync parameter. server.c: Added strict sync parameter. Fixed open modes. Jeremy. (This used to be commit ed57b603b5c9333d588e62d774ad2be67e43ffd9) --- source3/locking/locking.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d5d767d2cc..6aecfed6a5 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -38,6 +38,35 @@ extern files_struct Files[]; static struct share_ops *share_ops; +/**************************************************************************** + Utility function to map a lock type correctly depending on the real open + mode of a file. +****************************************************************************/ + +static int map_lock_type( files_struct *fsp, int lock_type) +{ + if((lock_type == F_WRLCK) && (fsp->fd_ptr->real_open_flags == O_RDONLY)) { + /* + * Many UNIX's cannot get a write lock on a file opened read-only. + * Win32 locking semantics allow this. + * Do the best we can and attempt a read-only lock. + */ + return F_RDLCK; + } else if( (lock_type == F_RDLCK) && (fsp->fd_ptr->real_open_flags == O_WRONLY)) { + /* + * Ditto for read locks on write only files. + */ + return F_WRLCK; + } + + /* + * This return should be the most normal, as we attempt + * to always open files read/write. + */ + + return lock_type; +} + /**************************************************************************** Utility function called to see if a file region is locked. ****************************************************************************/ @@ -53,10 +82,8 @@ BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset, int lock_type) if (!lp_locking(snum) || !lp_strict_locking(snum)) return(False); - if((lock_type == F_WRLCK) && !fsp->can_write) - lock_type = F_RDLCK; - - return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count,lock_type)); + return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count, + map_lock_type(fsp,lock_type))); } @@ -79,12 +106,9 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int lock_type, return False; } - if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum)) { - if(lock_type == F_WRLCK && !fsp->can_write) - lock_type = F_RDLCK; - - ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,lock_type); - } + if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum)) + ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count, + map_lock_type(fsp,lock_type)); if (!ok) { *eclass = ERRDOS; -- cgit From 83951dd37685ac8c5e45f44270d932250f785be5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 28 Jul 1998 18:26:47 +0000 Subject: locking.c: Don't need to do map_lock_type on *testing* a lock, just on setting. Jeremy. (This used to be commit 17f68cc86cafbb04dbd9cc6ecc0aac7b911c9b70) --- source3/locking/locking.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 6aecfed6a5..f443482544 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -82,8 +82,13 @@ BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset, int lock_type) if (!lp_locking(snum) || !lp_strict_locking(snum)) return(False); - return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count, - map_lock_type(fsp,lock_type))); + /* + * Note that most UNIX's can *test* for a write lock on + * a read-only fd, just not *set* a write lock on a read-only + * fd. So we don't need to use map_lock_type here. + */ + + return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count,lock_type)); } -- cgit From c48b3fce6be6d5d952cbcda0ddae223dda5a576f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Jul 1998 00:27:23 +0000 Subject: locking.c: Print messages when we downgrade a lock. reply.c: Do the same mask expansion we do in trans2.c - needed for Win98. trans2.c: Make the mask expansion into a function call now we have to do it twice. Jeremy. (This used to be commit 7b3a9d6285cc0d1967155a68845e28c6296ecc67) --- source3/locking/locking.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index f443482544..e4ca6bbb04 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -51,11 +51,13 @@ static int map_lock_type( files_struct *fsp, int lock_type) * Win32 locking semantics allow this. * Do the best we can and attempt a read-only lock. */ + DEBUG(10,("map_lock_type: Downgrading write lock to read due to read-only file.\n")); return F_RDLCK; } else if( (lock_type == F_RDLCK) && (fsp->fd_ptr->real_open_flags == O_WRONLY)) { /* * Ditto for read locks on write only files. */ + DEBUG(10,("map_lock_type: Changing read lock to write due to write-only file.\n")); return F_WRLCK; } -- cgit From 64578c0589a3a741f81fb55c16eeb882128da00b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 Jul 1998 03:08:05 +0000 Subject: merge from the autoconf2 branch to the main branch (This used to be commit 3bda7ac417107a7b01d91805ca71c4330657ed21) --- source3/locking/locking.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e4ca6bbb04..e303fb5482 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -88,7 +88,7 @@ BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset, int lock_type) * Note that most UNIX's can *test* for a write lock on * a read-only fd, just not *set* a write lock on a read-only * fd. So we don't need to use map_lock_type here. - */ + */ return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count,lock_type)); } @@ -161,13 +161,10 @@ BOOL locking_init(int read_only) #ifdef FAST_SHARE_MODES share_ops = locking_shm_init(read_only); - if (!share_ops) { - DEBUG(0,("ERROR: Failed to initialise fast share modes - trying slow code\n")); - } - if (share_ops) return True; -#endif - +#else share_ops = locking_slow_init(read_only); +#endif + if (!share_ops) { DEBUG(0,("ERROR: Failed to initialise share modes!\n")); return False; -- cgit From 7284bb5ca049a682097bb25afcf25d40f1ac5479 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 30 Jul 1998 21:18:57 +0000 Subject: Makefile.in: Moved UBIQX stuff into UTILOBJ. loadparm.c: Added "ole locking compatibility" option (default "true"). locking.c: Changes to implement union in files_struct. locking_shm.c: Changes to implement union in files_struct. nttrans.c: Made opening a directory explicit (we have to). Added create directory code for nttrans. reply.c: Changes to implement union in files_struct. server.c: Changes to implement union in files_struct. Added create directory code. trans2.c: Changes to implement union in files_struct. smb.h: Changes to implement union in files_struct. util.c: Changed linked list code to UNIQX linked list. This will make the other lists I need to implement for ChangeNotify and blocking locks easier. Jeremy. (This used to be commit 3a5eea850bb256b39cff8ace1e4fb4e0c1f5472b) --- source3/locking/locking.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e303fb5482..1b01efd7ef 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -45,7 +45,7 @@ static struct share_ops *share_ops; static int map_lock_type( files_struct *fsp, int lock_type) { - if((lock_type == F_WRLCK) && (fsp->fd_ptr->real_open_flags == O_RDONLY)) { + if((lock_type == F_WRLCK) && (fsp->f_u.fd_ptr->real_open_flags == O_RDONLY)) { /* * Many UNIX's cannot get a write lock on a file opened read-only. * Win32 locking semantics allow this. @@ -53,7 +53,7 @@ static int map_lock_type( files_struct *fsp, int lock_type) */ DEBUG(10,("map_lock_type: Downgrading write lock to read due to read-only file.\n")); return F_RDLCK; - } else if( (lock_type == F_RDLCK) && (fsp->fd_ptr->real_open_flags == O_WRONLY)) { + } else if( (lock_type == F_RDLCK) && (fsp->f_u.fd_ptr->real_open_flags == O_WRONLY)) { /* * Ditto for read locks on write only files. */ @@ -90,7 +90,7 @@ BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset, int lock_type) * fd. So we don't need to use map_lock_type here. */ - return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count,lock_type)); + return(fcntl_lock(fsp->f_u.fd_ptr->fd,F_GETLK,offset,count,lock_type)); } @@ -114,7 +114,7 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int lock_type, } if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum)) - ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count, + ok = fcntl_lock(fsp->f_u.fd_ptr->fd,F_SETLK,offset,count, map_lock_type(fsp,lock_type)); if (!ok) { @@ -139,7 +139,7 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 * return(True); if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum)) - ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,F_UNLCK); + ok = fcntl_lock(fsp->f_u.fd_ptr->fd,F_SETLK,offset,count,F_UNLCK); if (!ok) { *eclass = ERRDOS; -- cgit From b1778b6b57401d78fb4352992fde54706af6b75f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Aug 1998 23:28:35 +0000 Subject: include/smb.h: Removed dir_ptr. Not needed. locking/locking.c: First cut a blocking lock code. #ifdef'ed out for now. locking/locking_shm.c: Removed dir_ptr. Not needed. smbd/nttrans.c: More work on ChangeNotify - return is not an error and needs to be handled as a nttrans with zero params. Removed dir_ptr. Not needed. smbd/reply.c: smbd/server.c: smbd/trans2.c: Removed dir_ptr. Not needed. Hmmm. At the moment smbclient is broken - doesn't issue prompt correctly. This needs looking at. Jeremy. (This used to be commit ddfbcc05815621d3c463f92faed047f126412342) --- source3/locking/locking.c | 144 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 139 insertions(+), 5 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 1b01efd7ef..b56d1cc7ed 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -38,6 +38,140 @@ extern files_struct Files[]; static struct share_ops *share_ops; +#if 0 /* JRATEST - blocking lock code - under development. */ + +/**************************************************************************** + This is the structure to queue to implement blocking locks. + notify. It consists of the requesting SMB and the expiry time. +*****************************************************************************/ + +typedef struct { + ubi_slNode msg_next; + time_t expire_time; + int lock_num; + char *inbuf; + int length; +} blocking_lock_record; + +static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_queue, 0}; + +/**************************************************************************** + Function to push a blocking lockingX request onto the lock queue. +****************************************************************************/ + +BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num) +{ + blocking_lock_record *blr; + int fnum = GETFNUM(inbuf,smb_vwv2); + + /* + * Now queue an entry on the blocking lock queue. We setup + * the expiration time here. + */ + + if((blr = (blocking_lock_record *)malloc(sizeof(blocking_lock_record))) == NULL) { + DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" )); + return False; + } + + if((blr->inbuf = (char *)malloc(length)) == NULL) { + DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" )); + free((char *)blr); + return False; + } + + memcpy(blr->inbuf, inbuf, length); + blr->length = length; + blr->lock_num = lock_num; + blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; + + ubi_slAddTail(&blocking_lock_queue, blr); + + DEBUG(3,("push_blocking_lock_request: lock request blocked with expiry time %d \ +for fnum = %d, name = %s\n", blr->expire_time, fnum, Files[fnum].name )); + + return True; +} + +/**************************************************************************** + Process the blocking lock queue. Note that this is only called as root. +*****************************************************************************/ + +void process_blocking_lock_queue(time_t t) +{ + blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); + blocking_lock_record *prev = NULL; + + if(blr == NULL) + return; + + /* + * Go through the queue and see if we can get any of the locks. + */ + + while(blr != NULL) { + int fnum = GETFNUM(blr->inbuf,smb_vwv2); + int cnum = SVAL(blr->inbuf,smb_tid); + files_struct *fsp = &Files[fnum]; + uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : + SVAL(blr->inbuf,smb_uid); + + if(blr->expire_time > t) { + /* + * Lock expired - throw away all previously + * obtained locks and return lock error. + */ + + blocking_lock_fail(blr); + blocking_lock_reply_error(blr); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); + continue; + } + + if(!become_user(&Connections[cnum],cnum,vuid)) { + DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", + vuid )); + /* + * Remove the entry and return an error to the client. + */ + blocking_lock_reply_error(blr); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); + continue; + } + + if(!become_service(cnum,True)) { + DEBUG(0,("process_blocking_lock_queue: Unable to become service cnum=%d. \ +Error was %s.\n", cnum, strerror(errno) )); + /* + * Remove the entry and return an error to the client. + */ + blocking_lock_reply_error(blr); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); + unbecome_user(); + continue; + } + + /* + * Go through the remaining locks and try and obtain them. + * If we get them all then return success and delete this + * record. + */ + + if(blocking_lock_record_process(blr)) { + /* + * Success - + unbecome_user(); + /* + * Move to the next in the list. + */ + prev = blr; + blr = (blocking_lock_record *)ubi_slNext(blr); + } +#endif /* JRATEST */ + /**************************************************************************** Utility function to map a lock type correctly depending on the real open mode of a file. @@ -45,7 +179,7 @@ static struct share_ops *share_ops; static int map_lock_type( files_struct *fsp, int lock_type) { - if((lock_type == F_WRLCK) && (fsp->f_u.fd_ptr->real_open_flags == O_RDONLY)) { + if((lock_type == F_WRLCK) && (fsp->fd_ptr->real_open_flags == O_RDONLY)) { /* * Many UNIX's cannot get a write lock on a file opened read-only. * Win32 locking semantics allow this. @@ -53,7 +187,7 @@ static int map_lock_type( files_struct *fsp, int lock_type) */ DEBUG(10,("map_lock_type: Downgrading write lock to read due to read-only file.\n")); return F_RDLCK; - } else if( (lock_type == F_RDLCK) && (fsp->f_u.fd_ptr->real_open_flags == O_WRONLY)) { + } else if( (lock_type == F_RDLCK) && (fsp->fd_ptr->real_open_flags == O_WRONLY)) { /* * Ditto for read locks on write only files. */ @@ -90,7 +224,7 @@ BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset, int lock_type) * fd. So we don't need to use map_lock_type here. */ - return(fcntl_lock(fsp->f_u.fd_ptr->fd,F_GETLK,offset,count,lock_type)); + return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count,lock_type)); } @@ -114,7 +248,7 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int lock_type, } if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum)) - ok = fcntl_lock(fsp->f_u.fd_ptr->fd,F_SETLK,offset,count, + ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count, map_lock_type(fsp,lock_type)); if (!ok) { @@ -139,7 +273,7 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 * return(True); if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum)) - ok = fcntl_lock(fsp->f_u.fd_ptr->fd,F_SETLK,offset,count,F_UNLCK); + ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,F_UNLCK); if (!ok) { *eclass = ERRDOS; -- cgit From fcb5437da6a32b641260502d371494df614949d0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 12 Aug 1998 10:09:41 +0000 Subject: fixed the nested comment - Jeremy, do you want that unbecome_user() or not? (This used to be commit 638ee7d265982ca95ae7f49e2a84431bdf147c21) --- source3/locking/locking.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index b56d1cc7ed..f15c76ba6d 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -163,8 +163,7 @@ Error was %s.\n", cnum, strerror(errno) )); if(blocking_lock_record_process(blr)) { /* * Success - - unbecome_user(); - /* + unbecome_user(); * Move to the next in the list. */ prev = blr; -- cgit From ce333b25dba43822b7f06b3afbd6c3cee04f357e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 13 Aug 1998 02:10:45 +0000 Subject: More blocking lock code - still #ifdef'ed out - under development. Jeremy. (This used to be commit c9695bdf2e22c3081841f116af37340308d447aa) --- source3/locking/locking.c | 180 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 170 insertions(+), 10 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index f15c76ba6d..da5cdf46dd 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -35,6 +35,7 @@ extern int DEBUGLEVEL; extern connection_struct Connections[]; extern files_struct Files[]; +extern int Client; static struct share_ops *share_ops; @@ -93,6 +94,154 @@ for fnum = %d, name = %s\n", blr->expire_time, fnum, Files[fnum].name )); return True; } +/**************************************************************************** + Return a blocking lock success SMB. +*****************************************************************************/ + +void blocking_lock_reply_success(blocking_lock_record *blr) +{ + extern int chain_size; + extern int chain_fnum; + extern char *OutBuffer; + char *outbuf = OutBuffer; + int bufsize = BUFFER_SIZE; + char *inbuf = blr->inbuf; + int fnum = GETFNUM(inbuf,smb_vwv2); + int outsize = 0; + + construct_reply_common(inbuf, outbuf); + set_message(outbuf,2,0,True); + + /* + * As this message is a lockingX call we must handle + * any following chained message correctly. + * This is normally handled in construct_reply(), + * but as that calls switch_message, we can't use + * that here and must set up the chain info manually. + */ + + chain_fnum = fnum; + chain_size = 0; + + outsize = chain_reply(inbuf,outbuf,blr->length,bufsize); + + outsize += chain_size; + + if(outsize > 4) + smb_setlen(outbuf,outsize - 4); + + send_smb(Client,outbuf); +} + +/**************************************************************************** + Return a lock fail error. Undo all the locks we have obtained first. +*****************************************************************************/ + +void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int32 ecode) +{ + extern char *OutBuffer; + char *outbuf = OutBuffer; + int bufsize = BUFFER_SIZE; + char *inbuf = blr->inbuf; + int fnum = GETFNUM(inbuf,smb_vwv2); + uint16 num_ulocks = SVAL(inbuf,smb_vwv6); + uint16 num_locks = SVAL(inbuf,smb_vwv7); + uint32 count, offset; + int cnum; + int lock_num = blr->lock_num; + char *data; + int i; + + cnum = SVAL(inbuf,smb_tid); + + data = smb_buf(inbuf) + 10*num_ulocks; + + /* + * Data now points at the beginning of the list + * of smb_lkrng structs. + */ + + for(i = blr->lock_num; i >= 0; i--) { + count = IVAL(data,SMB_LKLEN_OFFSET(i)); + offset = IVAL(data,SMB_LKOFF_OFFSET(i)); + do_unlock(fnum,cnum,count,offset,&dummy1,&dummy2); + } + + construct_reply_common(inbuf, outbuf); + ERROR(eclass,ecode); + send_smb(Client,outbuf); +} + +/**************************************************************************** + Attempt to finish off getting all pending blocking locks. + Returns True if we want to be removed from the list. +*****************************************************************************/ + +BOOL blocking_lock_record_process(blocking_lock_record *blr) +{ + char *inbuf = blr->inbuf; + unsigned char locktype = CVAL(inbuf,smb_vwv3); + int fnum = GETFNUM(inbuf,smb_vwv2); + uint16 num_ulocks = SVAL(inbuf,smb_vwv6); + uint16 num_locks = SVAL(inbuf,smb_vwv7); + uint32 count, offset; + int cnum; + int lock_num = blr->lock_num; + char *data; + int eclass=0; + uint32 ecode=0; + + cnum = SVAL(inbuf,smb_tid); + + data = smb_buf(inbuf) + 10*num_ulocks; + + /* + * Data now points at the beginning of the list + * of smb_lkrng structs. + */ + + for(; blr->lock_num < num_locks; blr->lock_num++) { + count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num)); + offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num)); + if(!do_lock(fnum,cnum,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), + &eclass, &ecode)) + break; + } + + if(blr->lock_num == num_locks) { + + /* + * Success - we got all the locks. + */ + + DEBUG(3,("blocking_lock_record_process fnum=%d cnum=%d type=%d num_locks=%d\n", + fnum, cnum, (unsigned int)locktype, num_locks) ); + + blocking_lock_reply_success(blr); + return True; + + } else if((errno != EACCES) && (errno != EAGAIN)) { + + /* + * We have other than a "can't get lock" POSIX + * error. Free any locks we had and return an error. + * Return True so we get dequeued. + */ + + blocking_lock_reply_error(blr, eclass, ecode); + return True; + } + + /* + * Still can't get all the locks - keep waiting. + */ + + DEBUG(10,("blocking_lock_record_process: only got %d locks of %d needed for fnum = %d. \ +Waiting..\n", blr->lock_num, num_locks, fnum )); + + return False; +} + /**************************************************************************** Process the blocking lock queue. Note that this is only called as root. *****************************************************************************/ @@ -116,14 +265,18 @@ void process_blocking_lock_queue(time_t t) uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(blr->inbuf,smb_uid); - if(blr->expire_time > t) { + DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", + fnum, fsp->name )); + + if((blr->expire_time != -1) && (blr->expire_time > t)) { /* * Lock expired - throw away all previously * obtained locks and return lock error. */ + DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", + fnum, fsp->name )); - blocking_lock_fail(blr); - blocking_lock_reply_error(blr); + blocking_lock_reply_error(blr,ERRSRV,ERRaccess); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); continue; @@ -135,7 +288,7 @@ void process_blocking_lock_queue(time_t t) /* * Remove the entry and return an error to the client. */ - blocking_lock_reply_error(blr); + blocking_lock_reply_error(blr,ERRSRV,ERRaccess); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); continue; @@ -147,7 +300,7 @@ Error was %s.\n", cnum, strerror(errno) )); /* * Remove the entry and return an error to the client. */ - blocking_lock_reply_error(blr); + blocking_lock_reply_error(blr,ERRSRV,ERRaccess); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); unbecome_user(); @@ -156,19 +309,26 @@ Error was %s.\n", cnum, strerror(errno) )); /* * Go through the remaining locks and try and obtain them. - * If we get them all then return success and delete this - * record. + * The call returns True if all locks were obtained successfully + * and False if we still need to wait. */ if(blocking_lock_record_process(blr)) { - /* - * Success - - unbecome_user(); + free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); + blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); + unbecome_user(); + continue; + } + + unbecome_user(); + + /* * Move to the next in the list. */ prev = blr; blr = (blocking_lock_record *)ubi_slNext(blr); } +} #endif /* JRATEST */ /**************************************************************************** -- cgit From 3cf6cc6134960c99adb702b21394a4a607cfe30a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Aug 1998 02:02:40 +0000 Subject: Makefile.in: Changed so that make proto will work with ldap & nisplus. locking/locking.c: Made #ifdef'ed out functions static for Make proto. lib/util.c: Re-instated old mask_match code for UNIX filesystem checks only. Client calls use the new mask_match code. Changed the name of the old function to unix_mask_match. Jeremy. (This used to be commit b68e756ff57622c6c74f28031d4be964d7b1c9bc) --- source3/locking/locking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index da5cdf46dd..c1c0659496 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -98,7 +98,7 @@ for fnum = %d, name = %s\n", blr->expire_time, fnum, Files[fnum].name )); Return a blocking lock success SMB. *****************************************************************************/ -void blocking_lock_reply_success(blocking_lock_record *blr) +static void blocking_lock_reply_success(blocking_lock_record *blr) { extern int chain_size; extern int chain_fnum; @@ -137,7 +137,7 @@ void blocking_lock_reply_success(blocking_lock_record *blr) Return a lock fail error. Undo all the locks we have obtained first. *****************************************************************************/ -void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int32 ecode) +static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int32 ecode) { extern char *OutBuffer; char *outbuf = OutBuffer; @@ -177,7 +177,7 @@ void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int32 ecod Returns True if we want to be removed from the list. *****************************************************************************/ -BOOL blocking_lock_record_process(blocking_lock_record *blr) +static BOOL blocking_lock_record_process(blocking_lock_record *blr) { char *inbuf = blr->inbuf; unsigned char locktype = CVAL(inbuf,smb_vwv3); -- cgit From b9623ab59e813131b1ed3f51616a46e719d59c21 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Aug 1998 17:38:29 +0000 Subject: this is the bug change to using connection_struct* instead of cnum. Connections[] is now a local array in server.c I might have broken something with this change. In particular the oplock code is suspect and some .dll files aren't being oplocked when I expected them to be. I'll look at it after I've got some sleep. (This used to be commit c7ee025ead4a85b6fa44a832047b878451845fb6) --- source3/locking/locking.c | 87 +++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 48 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index c1c0659496..bb852b07d6 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -33,7 +33,6 @@ #include "includes.h" extern int DEBUGLEVEL; -extern connection_struct Connections[]; extern files_struct Files[]; extern int Client; @@ -147,13 +146,10 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); uint32 count, offset; - int cnum; int lock_num = blr->lock_num; char *data; int i; - cnum = SVAL(inbuf,smb_tid); - data = smb_buf(inbuf) + 10*num_ulocks; /* @@ -164,7 +160,7 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int for(i = blr->lock_num; i >= 0; i--) { count = IVAL(data,SMB_LKLEN_OFFSET(i)); offset = IVAL(data,SMB_LKOFF_OFFSET(i)); - do_unlock(fnum,cnum,count,offset,&dummy1,&dummy2); + do_unlock(fnum,conn,count,offset,&dummy1,&dummy2); } construct_reply_common(inbuf, outbuf); @@ -185,14 +181,11 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); uint32 count, offset; - int cnum; int lock_num = blr->lock_num; char *data; int eclass=0; uint32 ecode=0; - cnum = SVAL(inbuf,smb_tid); - data = smb_buf(inbuf) + 10*num_ulocks; /* @@ -203,7 +196,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) for(; blr->lock_num < num_locks; blr->lock_num++) { count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num)); offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num)); - if(!do_lock(fnum,cnum,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), + if(!do_lock(fnum,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), &eclass, &ecode)) break; } @@ -214,8 +207,8 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) * Success - we got all the locks. */ - DEBUG(3,("blocking_lock_record_process fnum=%d cnum=%d type=%d num_locks=%d\n", - fnum, cnum, (unsigned int)locktype, num_locks) ); + DEBUG(3,("blocking_lock_record_process fnum=%d type=%d num_locks=%d\n", + fnum, (unsigned int)locktype, num_locks) ); blocking_lock_reply_success(blr); return True; @@ -260,7 +253,6 @@ void process_blocking_lock_queue(time_t t) while(blr != NULL) { int fnum = GETFNUM(blr->inbuf,smb_vwv2); - int cnum = SVAL(blr->inbuf,smb_tid); files_struct *fsp = &Files[fnum]; uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(blr->inbuf,smb_uid); @@ -282,7 +274,7 @@ void process_blocking_lock_queue(time_t t) continue; } - if(!become_user(&Connections[cnum],cnum,vuid)) { + if(!become_user(conn,vuid)) { DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", vuid )); /* @@ -294,9 +286,8 @@ void process_blocking_lock_queue(time_t t) continue; } - if(!become_service(cnum,True)) { - DEBUG(0,("process_blocking_lock_queue: Unable to become service cnum=%d. \ -Error was %s.\n", cnum, strerror(errno) )); + if(!become_service(conn,True)) { + DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); /* * Remove the entry and return an error to the client. */ @@ -365,39 +356,39 @@ static int map_lock_type( files_struct *fsp, int lock_type) /**************************************************************************** Utility function called to see if a file region is locked. ****************************************************************************/ - -BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset, int lock_type) +BOOL is_locked(int fnum,connection_struct *conn, + uint32 count,uint32 offset, int lock_type) { - int snum = SNUM(cnum); - files_struct *fsp = &Files[fnum]; + int snum = SNUM(conn); + files_struct *fsp = &Files[fnum]; - if (count == 0) - return(False); + if (count == 0) + return(False); - if (!lp_locking(snum) || !lp_strict_locking(snum)) - return(False); - - /* - * Note that most UNIX's can *test* for a write lock on - * a read-only fd, just not *set* a write lock on a read-only - * fd. So we don't need to use map_lock_type here. - */ + if (!lp_locking(snum) || !lp_strict_locking(snum)) + return(False); - return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count,lock_type)); + /* + * Note that most UNIX's can *test* for a write lock on + * a read-only fd, just not *set* a write lock on a read-only + * fd. So we don't need to use map_lock_type here. + */ + + return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count,lock_type)); } /**************************************************************************** Utility function called by locking requests. ****************************************************************************/ - -BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int lock_type, +BOOL do_lock(int fnum,connection_struct *conn, + uint32 count,uint32 offset,int lock_type, int *eclass,uint32 *ecode) { BOOL ok = False; files_struct *fsp = &Files[fnum]; - if (!lp_locking(SNUM(cnum))) + if (!lp_locking(SNUM(conn))) return(True); if (count == 0) { @@ -406,7 +397,7 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int lock_type, return False; } - if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum)) + if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->conn == conn)) ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count, map_lock_type(fsp,lock_type)); @@ -422,16 +413,16 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int lock_type, /**************************************************************************** Utility function called by unlocking requests. ****************************************************************************/ - -BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode) +BOOL do_unlock(int fnum,connection_struct *conn, + uint32 count,uint32 offset,int *eclass,uint32 *ecode) { BOOL ok = False; files_struct *fsp = &Files[fnum]; - if (!lp_locking(SNUM(cnum))) + if (!lp_locking(SNUM(conn))) return(True); - if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum)) + if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->conn == conn)) ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,F_UNLCK); if (!ok) { @@ -481,29 +472,29 @@ BOOL locking_end(void) /******************************************************************* Lock a hash bucket entry. ******************************************************************/ - -BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok) +BOOL lock_share_entry(connection_struct *conn, + uint32 dev, uint32 inode, int *ptok) { - return share_ops->lock_entry(cnum, dev, inode, ptok); + return share_ops->lock_entry(conn, dev, inode, ptok); } /******************************************************************* Unlock a hash bucket entry. ******************************************************************/ - -BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, int token) +BOOL unlock_share_entry(connection_struct *conn, + uint32 dev, uint32 inode, int token) { - return share_ops->unlock_entry(cnum, dev, inode, token); + return share_ops->unlock_entry(conn, dev, inode, token); } /******************************************************************* Get all share mode entries for a dev/inode pair. ********************************************************************/ - -int get_share_modes(int cnum, int token, uint32 dev, uint32 inode, +int get_share_modes(connection_struct *conn, + int token, uint32 dev, uint32 inode, share_mode_entry **shares) { - return share_ops->get_entries(cnum, token, dev, inode, shares); + return share_ops->get_entries(conn, token, dev, inode, shares); } /******************************************************************* -- cgit From 127655cc888ac40332d4e8e5b94aab03f5120aae Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 15 Aug 1998 07:27:34 +0000 Subject: this checkin gets rid of the global Files[] array and makes it local in files.c it should now be faily easy to expand the default MAX_OPEN_FILES to many thousands. (This used to be commit b088c804f98908eb02f05ab2f2e8a61691a0a582) --- source3/locking/locking.c | 56 +++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 31 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index bb852b07d6..50c4af2265 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -33,7 +33,6 @@ #include "includes.h" extern int DEBUGLEVEL; -extern files_struct Files[]; extern int Client; static struct share_ops *share_ops; @@ -62,7 +61,7 @@ static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_qu BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num) { blocking_lock_record *blr; - int fnum = GETFNUM(inbuf,smb_vwv2); + files_struct *fsp = GETFSP(inbuf,smb_vwv2); /* * Now queue an entry on the blocking lock queue. We setup @@ -88,7 +87,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int ubi_slAddTail(&blocking_lock_queue, blr); DEBUG(3,("push_blocking_lock_request: lock request blocked with expiry time %d \ -for fnum = %d, name = %s\n", blr->expire_time, fnum, Files[fnum].name )); +for fnum = %d, name = %s\n", blr->expire_time, fsp->fnum, fsp->name )); return True; } @@ -96,16 +95,15 @@ for fnum = %d, name = %s\n", blr->expire_time, fnum, Files[fnum].name )); /**************************************************************************** Return a blocking lock success SMB. *****************************************************************************/ - static void blocking_lock_reply_success(blocking_lock_record *blr) { extern int chain_size; - extern int chain_fnum; + extern files_struct *chain_fsp; extern char *OutBuffer; char *outbuf = OutBuffer; int bufsize = BUFFER_SIZE; char *inbuf = blr->inbuf; - int fnum = GETFNUM(inbuf,smb_vwv2); + files_struct *fsp = GETFSP(inbuf,smb_vwv2); int outsize = 0; construct_reply_common(inbuf, outbuf); @@ -119,7 +117,7 @@ static void blocking_lock_reply_success(blocking_lock_record *blr) * that here and must set up the chain info manually. */ - chain_fnum = fnum; + chain_fsp = fsp; chain_size = 0; outsize = chain_reply(inbuf,outbuf,blr->length,bufsize); @@ -142,7 +140,7 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int char *outbuf = OutBuffer; int bufsize = BUFFER_SIZE; char *inbuf = blr->inbuf; - int fnum = GETFNUM(inbuf,smb_vwv2); + files_struct *fsp = GETFSP(inbuf,smb_vwv2); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); uint32 count, offset; @@ -160,7 +158,7 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int for(i = blr->lock_num; i >= 0; i--) { count = IVAL(data,SMB_LKLEN_OFFSET(i)); offset = IVAL(data,SMB_LKOFF_OFFSET(i)); - do_unlock(fnum,conn,count,offset,&dummy1,&dummy2); + do_unlock(fsp,conn,count,offset,&dummy1,&dummy2); } construct_reply_common(inbuf, outbuf); @@ -177,7 +175,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) { char *inbuf = blr->inbuf; unsigned char locktype = CVAL(inbuf,smb_vwv3); - int fnum = GETFNUM(inbuf,smb_vwv2); + files_struct *fsp = GETFSP(inbuf,smb_vwv2); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); uint32 count, offset; @@ -196,7 +194,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) for(; blr->lock_num < num_locks; blr->lock_num++) { count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num)); offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num)); - if(!do_lock(fnum,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), + if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), &eclass, &ecode)) break; } @@ -208,7 +206,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) */ DEBUG(3,("blocking_lock_record_process fnum=%d type=%d num_locks=%d\n", - fnum, (unsigned int)locktype, num_locks) ); + fsp->fnum, (unsigned int)locktype, num_locks) ); blocking_lock_reply_success(blr); return True; @@ -230,7 +228,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) */ DEBUG(10,("blocking_lock_record_process: only got %d locks of %d needed for fnum = %d. \ -Waiting..\n", blr->lock_num, num_locks, fnum )); +Waiting..\n", blr->lock_num, num_locks, fsp->fnum)); return False; } @@ -252,13 +250,12 @@ void process_blocking_lock_queue(time_t t) */ while(blr != NULL) { - int fnum = GETFNUM(blr->inbuf,smb_vwv2); - files_struct *fsp = &Files[fnum]; + files_struct *fsp = GETFSP(blr->inbuf,smb_vwv2); uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(blr->inbuf,smb_uid); DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", - fnum, fsp->name )); + fsp->fnum, fsp->name )); if((blr->expire_time != -1) && (blr->expire_time > t)) { /* @@ -266,7 +263,7 @@ void process_blocking_lock_queue(time_t t) * obtained locks and return lock error. */ DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", - fnum, fsp->name )); + fsp->fnum, fsp->name )); blocking_lock_reply_error(blr,ERRSRV,ERRaccess); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); @@ -356,11 +353,10 @@ static int map_lock_type( files_struct *fsp, int lock_type) /**************************************************************************** Utility function called to see if a file region is locked. ****************************************************************************/ -BOOL is_locked(int fnum,connection_struct *conn, +BOOL is_locked(files_struct *fsp,connection_struct *conn, uint32 count,uint32 offset, int lock_type) { int snum = SNUM(conn); - files_struct *fsp = &Files[fnum]; if (count == 0) return(False); @@ -381,12 +377,11 @@ BOOL is_locked(int fnum,connection_struct *conn, /**************************************************************************** Utility function called by locking requests. ****************************************************************************/ -BOOL do_lock(int fnum,connection_struct *conn, +BOOL do_lock(files_struct *fsp,connection_struct *conn, uint32 count,uint32 offset,int lock_type, int *eclass,uint32 *ecode) { BOOL ok = False; - files_struct *fsp = &Files[fnum]; if (!lp_locking(SNUM(conn))) return(True); @@ -397,7 +392,7 @@ BOOL do_lock(int fnum,connection_struct *conn, return False; } - if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->conn == conn)) + if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count, map_lock_type(fsp,lock_type)); @@ -413,16 +408,15 @@ BOOL do_lock(int fnum,connection_struct *conn, /**************************************************************************** Utility function called by unlocking requests. ****************************************************************************/ -BOOL do_unlock(int fnum,connection_struct *conn, +BOOL do_unlock(files_struct *fsp,connection_struct *conn, uint32 count,uint32 offset,int *eclass,uint32 *ecode) { BOOL ok = False; - files_struct *fsp = &Files[fnum]; if (!lp_locking(SNUM(conn))) return(True); - if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->conn == conn)) + if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,F_UNLCK); if (!ok) { @@ -501,26 +495,26 @@ int get_share_modes(connection_struct *conn, Del the share mode of a file. ********************************************************************/ -void del_share_mode(int token, int fnum) +void del_share_mode(int token, files_struct *fsp) { - share_ops->del_entry(token, fnum); + share_ops->del_entry(token, fsp); } /******************************************************************* Set the share mode of a file. Return False on fail, True on success. ********************************************************************/ -BOOL set_share_mode(int token, int fnum, uint16 port, uint16 op_type) +BOOL set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type) { - return share_ops->set_entry(token, fnum, port, op_type); + return share_ops->set_entry(token, fsp, port, op_type); } /******************************************************************* Remove an oplock port and mode entry from a share mode. ********************************************************************/ -BOOL remove_share_oplock(int fnum, int token) +BOOL remove_share_oplock(files_struct *fsp, int token) { - return share_ops->remove_oplock(fnum, token); + return share_ops->remove_oplock(fsp, token); } /******************************************************************* -- cgit From a7acf10566af549eb71e7a421397c8073d55e0f6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Aug 1998 03:04:06 +0000 Subject: server.c: fixed a bug in close_file() with the new files.c handling code bitmap.c: added bitmap hanlding code in preparation for increasing the default max open files to several thousand (This used to be commit f573a65b67e7a57586fec57845598e49b157ee0a) --- source3/locking/locking.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 50c4af2265..cdaeea6d7e 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -494,7 +494,6 @@ int get_share_modes(connection_struct *conn, /******************************************************************* Del the share mode of a file. ********************************************************************/ - void del_share_mode(int token, files_struct *fsp) { share_ops->del_entry(token, fsp); @@ -503,7 +502,6 @@ void del_share_mode(int token, files_struct *fsp) /******************************************************************* Set the share mode of a file. Return False on fail, True on success. ********************************************************************/ - BOOL set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type) { return share_ops->set_entry(token, fsp, port, op_type); -- cgit From 8978aae69699ccab76fdf95037948b1cc7e7c286 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Aug 1998 03:52:05 +0000 Subject: much cleaner chain pointer handling for both files and pipes. the chain pointer is now stored as a static and is set whenever a handle is created or extracted. This also makes the code less error prone. (This used to be commit 068a862982bea726e8d7b1b4065d510b9840a272) --- source3/locking/locking.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index cdaeea6d7e..8737a12e17 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -61,7 +61,7 @@ static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_qu BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num) { blocking_lock_record *blr; - files_struct *fsp = GETFSP(inbuf,smb_vwv2); + files_struct *fsp = file_fsp(inbuf,smb_vwv2); /* * Now queue an entry on the blocking lock queue. We setup @@ -98,12 +98,11 @@ for fnum = %d, name = %s\n", blr->expire_time, fsp->fnum, fsp->name )); static void blocking_lock_reply_success(blocking_lock_record *blr) { extern int chain_size; - extern files_struct *chain_fsp; extern char *OutBuffer; char *outbuf = OutBuffer; int bufsize = BUFFER_SIZE; char *inbuf = blr->inbuf; - files_struct *fsp = GETFSP(inbuf,smb_vwv2); + files_struct *fsp = file_fsp(inbuf,smb_vwv2); int outsize = 0; construct_reply_common(inbuf, outbuf); @@ -117,7 +116,7 @@ static void blocking_lock_reply_success(blocking_lock_record *blr) * that here and must set up the chain info manually. */ - chain_fsp = fsp; + file_set_chain(fsp); chain_size = 0; outsize = chain_reply(inbuf,outbuf,blr->length,bufsize); @@ -140,7 +139,7 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int char *outbuf = OutBuffer; int bufsize = BUFFER_SIZE; char *inbuf = blr->inbuf; - files_struct *fsp = GETFSP(inbuf,smb_vwv2); + files_struct *fsp = file_fsp(inbuf,smb_vwv2); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); uint32 count, offset; @@ -175,7 +174,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) { char *inbuf = blr->inbuf; unsigned char locktype = CVAL(inbuf,smb_vwv3); - files_struct *fsp = GETFSP(inbuf,smb_vwv2); + files_struct *fsp = file_fsp(inbuf,smb_vwv2); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); uint32 count, offset; @@ -250,7 +249,7 @@ void process_blocking_lock_queue(time_t t) */ while(blr != NULL) { - files_struct *fsp = GETFSP(blr->inbuf,smb_vwv2); + files_struct *fsp = file_fsp(blr->inbuf,smb_vwv2); uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(blr->inbuf,smb_uid); -- cgit From 1e6837837ac402702ccadcbcfd853b8c673c783a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 17 Aug 1998 23:39:59 +0000 Subject: smbd/nttrans.c: Fixed bug in split off pipe code. locking/locking.c: More blocking lock changes. Jeremy. (This used to be commit 2ca4fc95a4227645f1009a057d46b58508846a92) --- source3/locking/locking.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 8737a12e17..873e382b46 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -116,7 +116,6 @@ static void blocking_lock_reply_success(blocking_lock_record *blr) * that here and must set up the chain info manually. */ - file_set_chain(fsp); chain_size = 0; outsize = chain_reply(inbuf,outbuf,blr->length,bufsize); @@ -227,7 +226,7 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr) */ DEBUG(10,("blocking_lock_record_process: only got %d locks of %d needed for fnum = %d. \ -Waiting..\n", blr->lock_num, num_locks, fsp->fnum)); +Waiting....\n", blr->lock_num, num_locks, fsp->fnum)); return False; } @@ -249,8 +248,17 @@ void process_blocking_lock_queue(time_t t) */ while(blr != NULL) { - files_struct *fsp = file_fsp(blr->inbuf,smb_vwv2); - uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : + files_struct *fsp = NULL; + uint16 vuid; + + /* + * Ensure we don't have any old chain_fnum values + * sitting around.... + */ + file_chain_reset(); + + fsp = file_fsp(blr->inbuf,smb_vwv2); + vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(blr->inbuf,smb_uid); DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", -- cgit From 12de4034c72ea5054d716bf848c2b16bef7a4d89 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 19 Aug 1998 01:49:34 +0000 Subject: Makefile.in: Moved blocking lock code into smbd/blocking.c for link purposes. include/includes.h: Added nterr.h. locking/locking.c: Moved blocking lock code into smbd/blocking.c for link purposes. smbd/close.c: Added blocking lock removal to file close. smbd/filename.c: Tidied up unix_convert() so I could read it (:-) in preparation for the stat_cache code. smbd/nttrans.c: Added WRITE_ATTRIBUTES check. smbd/reply.c: Fixed multibyte char problem in wildcard mask. Jeremy. (This used to be commit 148eaba3dadb1d0bd3ac3ef53da3d9811636e89a) --- source3/locking/locking.c | 290 ---------------------------------------------- 1 file changed, 290 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 873e382b46..f5e27317b5 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -33,299 +33,9 @@ #include "includes.h" extern int DEBUGLEVEL; -extern int Client; static struct share_ops *share_ops; -#if 0 /* JRATEST - blocking lock code - under development. */ - -/**************************************************************************** - This is the structure to queue to implement blocking locks. - notify. It consists of the requesting SMB and the expiry time. -*****************************************************************************/ - -typedef struct { - ubi_slNode msg_next; - time_t expire_time; - int lock_num; - char *inbuf; - int length; -} blocking_lock_record; - -static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_queue, 0}; - -/**************************************************************************** - Function to push a blocking lockingX request onto the lock queue. -****************************************************************************/ - -BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num) -{ - blocking_lock_record *blr; - files_struct *fsp = file_fsp(inbuf,smb_vwv2); - - /* - * Now queue an entry on the blocking lock queue. We setup - * the expiration time here. - */ - - if((blr = (blocking_lock_record *)malloc(sizeof(blocking_lock_record))) == NULL) { - DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" )); - return False; - } - - if((blr->inbuf = (char *)malloc(length)) == NULL) { - DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" )); - free((char *)blr); - return False; - } - - memcpy(blr->inbuf, inbuf, length); - blr->length = length; - blr->lock_num = lock_num; - blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; - - ubi_slAddTail(&blocking_lock_queue, blr); - - DEBUG(3,("push_blocking_lock_request: lock request blocked with expiry time %d \ -for fnum = %d, name = %s\n", blr->expire_time, fsp->fnum, fsp->name )); - - return True; -} - -/**************************************************************************** - Return a blocking lock success SMB. -*****************************************************************************/ -static void blocking_lock_reply_success(blocking_lock_record *blr) -{ - extern int chain_size; - extern char *OutBuffer; - char *outbuf = OutBuffer; - int bufsize = BUFFER_SIZE; - char *inbuf = blr->inbuf; - files_struct *fsp = file_fsp(inbuf,smb_vwv2); - int outsize = 0; - - construct_reply_common(inbuf, outbuf); - set_message(outbuf,2,0,True); - - /* - * As this message is a lockingX call we must handle - * any following chained message correctly. - * This is normally handled in construct_reply(), - * but as that calls switch_message, we can't use - * that here and must set up the chain info manually. - */ - - chain_size = 0; - - outsize = chain_reply(inbuf,outbuf,blr->length,bufsize); - - outsize += chain_size; - - if(outsize > 4) - smb_setlen(outbuf,outsize - 4); - - send_smb(Client,outbuf); -} - -/**************************************************************************** - Return a lock fail error. Undo all the locks we have obtained first. -*****************************************************************************/ - -static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int32 ecode) -{ - extern char *OutBuffer; - char *outbuf = OutBuffer; - int bufsize = BUFFER_SIZE; - char *inbuf = blr->inbuf; - files_struct *fsp = file_fsp(inbuf,smb_vwv2); - uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - uint16 num_locks = SVAL(inbuf,smb_vwv7); - uint32 count, offset; - int lock_num = blr->lock_num; - char *data; - int i; - - data = smb_buf(inbuf) + 10*num_ulocks; - - /* - * Data now points at the beginning of the list - * of smb_lkrng structs. - */ - - for(i = blr->lock_num; i >= 0; i--) { - count = IVAL(data,SMB_LKLEN_OFFSET(i)); - offset = IVAL(data,SMB_LKOFF_OFFSET(i)); - do_unlock(fsp,conn,count,offset,&dummy1,&dummy2); - } - - construct_reply_common(inbuf, outbuf); - ERROR(eclass,ecode); - send_smb(Client,outbuf); -} - -/**************************************************************************** - Attempt to finish off getting all pending blocking locks. - Returns True if we want to be removed from the list. -*****************************************************************************/ - -static BOOL blocking_lock_record_process(blocking_lock_record *blr) -{ - char *inbuf = blr->inbuf; - unsigned char locktype = CVAL(inbuf,smb_vwv3); - files_struct *fsp = file_fsp(inbuf,smb_vwv2); - uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - uint16 num_locks = SVAL(inbuf,smb_vwv7); - uint32 count, offset; - int lock_num = blr->lock_num; - char *data; - int eclass=0; - uint32 ecode=0; - - data = smb_buf(inbuf) + 10*num_ulocks; - - /* - * Data now points at the beginning of the list - * of smb_lkrng structs. - */ - - for(; blr->lock_num < num_locks; blr->lock_num++) { - count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num)); - offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num)); - if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), - &eclass, &ecode)) - break; - } - - if(blr->lock_num == num_locks) { - - /* - * Success - we got all the locks. - */ - - DEBUG(3,("blocking_lock_record_process fnum=%d type=%d num_locks=%d\n", - fsp->fnum, (unsigned int)locktype, num_locks) ); - - blocking_lock_reply_success(blr); - return True; - - } else if((errno != EACCES) && (errno != EAGAIN)) { - - /* - * We have other than a "can't get lock" POSIX - * error. Free any locks we had and return an error. - * Return True so we get dequeued. - */ - - blocking_lock_reply_error(blr, eclass, ecode); - return True; - } - - /* - * Still can't get all the locks - keep waiting. - */ - - DEBUG(10,("blocking_lock_record_process: only got %d locks of %d needed for fnum = %d. \ -Waiting....\n", blr->lock_num, num_locks, fsp->fnum)); - - return False; -} - -/**************************************************************************** - Process the blocking lock queue. Note that this is only called as root. -*****************************************************************************/ - -void process_blocking_lock_queue(time_t t) -{ - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - blocking_lock_record *prev = NULL; - - if(blr == NULL) - return; - - /* - * Go through the queue and see if we can get any of the locks. - */ - - while(blr != NULL) { - files_struct *fsp = NULL; - uint16 vuid; - - /* - * Ensure we don't have any old chain_fnum values - * sitting around.... - */ - file_chain_reset(); - - fsp = file_fsp(blr->inbuf,smb_vwv2); - vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : - SVAL(blr->inbuf,smb_uid); - - DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", - fsp->fnum, fsp->name )); - - if((blr->expire_time != -1) && (blr->expire_time > t)) { - /* - * Lock expired - throw away all previously - * obtained locks and return lock error. - */ - DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", - fsp->fnum, fsp->name )); - - blocking_lock_reply_error(blr,ERRSRV,ERRaccess); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); - continue; - } - - if(!become_user(conn,vuid)) { - DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", - vuid )); - /* - * Remove the entry and return an error to the client. - */ - blocking_lock_reply_error(blr,ERRSRV,ERRaccess); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); - continue; - } - - if(!become_service(conn,True)) { - DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); - /* - * Remove the entry and return an error to the client. - */ - blocking_lock_reply_error(blr,ERRSRV,ERRaccess); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); - unbecome_user(); - continue; - } - - /* - * Go through the remaining locks and try and obtain them. - * The call returns True if all locks were obtained successfully - * and False if we still need to wait. - */ - - if(blocking_lock_record_process(blr)) { - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); - unbecome_user(); - continue; - } - - unbecome_user(); - - /* - * Move to the next in the list. - */ - prev = blr; - blr = (blocking_lock_record *)ubi_slNext(blr); - } -} -#endif /* JRATEST */ - /**************************************************************************** Utility function to map a lock type correctly depending on the real open mode of a file. -- cgit From dc76502cd8a950f6aff84ce4eedfd9d2b30d3dcc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 20 Aug 1998 19:28:37 +0000 Subject: Turning on blocking locking code. NB. Blocking lock requests that are not the head of an SMB request (ie. are part of a chain) will not be queued - this will be fixed when we move to the new chain code. In practice, this doesn't seem to cause much of a problem (in my admittedly limited testing) bug a debug level zero message will be placed in the log when this happens to help determine how real the problem is. smbd/locking.c: New debug messages. smbd/blocking.c: New blocking code - handles SMBlock, SMBlockread and SMBlockingX smbd/chgpasswd.c: Fix for master fd leak. smbd/files.c: Tidyup comment. smbd/nttrans.c: Added fnum to debug message. smbd/process.c: Made chain_reply() use construct_reply_common(). Added blocking lock queue processing into idle loop. smbd/reply.c: Added queue pushes for SMBlock, SMBlockread and SMBlockingX. Jeremy. (This used to be commit e1dd03ecda0bc6d7eaa31070c83774bb5679fd1b) --- source3/locking/locking.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index f5e27317b5..4f2c9ab345 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -109,6 +109,9 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, return False; } + DEBUG(10,("do_lock: lock type %d start=%d len=%d requested for file %s\n", + lock_type, (int)offset, (int)count, fsp->fsp_name )); + if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count, map_lock_type(fsp,lock_type)); @@ -133,6 +136,9 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, if (!lp_locking(SNUM(conn))) return(True); + DEBUG(10,("do_unlock: unlock start=%d len=%d requested for file %s\n", + (int)offset, (int)count, fsp->fsp_name )); + if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,F_UNLCK); -- cgit From 693480af8bb2d3e83566af9463ca427f47a879da Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 31 Aug 1998 20:20:54 +0000 Subject: configure.in, configure: include/config.h.in: Added stropts and poll. include/smb.h: Moved old typedefs of uint8 etc. into include/includes.h where all the other defines live (changed them from typedefs to defines). Other changes : changed from using uint32 to SMB_DEV_T and SMB_INO_T in preparation for moving to size independed (ie. 64 bit clean) device and inode access. Stat call wrapper comes next :-). Jeremy. (This used to be commit 3d9ec96de5e04e83abafe9c5d980bd39eee856ea) --- source3/locking/locking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 4f2c9ab345..856b7cfcf6 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -190,7 +190,7 @@ BOOL locking_end(void) Lock a hash bucket entry. ******************************************************************/ BOOL lock_share_entry(connection_struct *conn, - uint32 dev, uint32 inode, int *ptok) + SMB_DEV_T dev, SMB_INO_T inode, int *ptok) { return share_ops->lock_entry(conn, dev, inode, ptok); } @@ -199,7 +199,7 @@ BOOL lock_share_entry(connection_struct *conn, Unlock a hash bucket entry. ******************************************************************/ BOOL unlock_share_entry(connection_struct *conn, - uint32 dev, uint32 inode, int token) + SMB_DEV_T dev, SMB_INO_T inode, int token) { return share_ops->unlock_entry(conn, dev, inode, token); } @@ -208,7 +208,7 @@ BOOL unlock_share_entry(connection_struct *conn, Get all share mode entries for a dev/inode pair. ********************************************************************/ int get_share_modes(connection_struct *conn, - int token, uint32 dev, uint32 inode, + int token, SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry **shares) { return share_ops->get_entries(conn, token, dev, inode, shares); -- cgit From 623a18db4b0f46c80c29e93a0ad0a2fcbfec71dc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Sep 1998 00:23:28 +0000 Subject: More 64 bit stuff - now the fcntl locks are 64 bit clean. Nearly at the stage where I can expose the 64-bit-ness to the NT clients.... Jeremy. (This used to be commit 422f1dd45074c0e28203aca5952e57bbe56676b6) --- source3/locking/locking.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 856b7cfcf6..bd484a18b6 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -71,7 +71,7 @@ static int map_lock_type( files_struct *fsp, int lock_type) Utility function called to see if a file region is locked. ****************************************************************************/ BOOL is_locked(files_struct *fsp,connection_struct *conn, - uint32 count,uint32 offset, int lock_type) + SMB_OFF_T count,SMB_OFF_T offset, int lock_type) { int snum = SNUM(conn); @@ -87,7 +87,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, * fd. So we don't need to use map_lock_type here. */ - return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count,lock_type)); + return(fcntl_lock(fsp->fd_ptr->fd,SMB_F_GETLK,offset,count,lock_type)); } @@ -95,7 +95,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, Utility function called by locking requests. ****************************************************************************/ BOOL do_lock(files_struct *fsp,connection_struct *conn, - uint32 count,uint32 offset,int lock_type, + SMB_OFF_T count,SMB_OFF_T offset,int lock_type, int *eclass,uint32 *ecode) { BOOL ok = False; @@ -109,11 +109,16 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, return False; } +#ifdef LARGE_SMB_OFF_T + 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 )); +#else /* LARGE_SMB_OFF_T */ DEBUG(10,("do_lock: lock type %d start=%d len=%d requested for file %s\n", lock_type, (int)offset, (int)count, fsp->fsp_name )); +#endif /* LARGE_SMB_OFF_T */ if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) - ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count, + ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count, map_lock_type(fsp,lock_type)); if (!ok) { @@ -129,18 +134,23 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, Utility function called by unlocking requests. ****************************************************************************/ BOOL do_unlock(files_struct *fsp,connection_struct *conn, - uint32 count,uint32 offset,int *eclass,uint32 *ecode) + SMB_OFF_T count,SMB_OFF_T offset,int *eclass,uint32 *ecode) { BOOL ok = False; if (!lp_locking(SNUM(conn))) return(True); +#ifdef LARGE_SMB_OFF_T + DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n", + (double)offset, (double)count, fsp->fsp_name )); +#else DEBUG(10,("do_unlock: unlock start=%d len=%d requested for file %s\n", (int)offset, (int)count, fsp->fsp_name )); +#endif if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) - ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,F_UNLCK); + ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK); if (!ok) { *eclass = ERRDOS; @@ -150,28 +160,27 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, return True; /* Did unlock */ } - - /**************************************************************************** Initialise the locking functions. ****************************************************************************/ 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); #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; } /******************************************************************* -- cgit From 012e575e1336fbba70174d32c26ecab9ce5523ce Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Sep 1998 05:23:29 +0000 Subject: ahh, the joy of deleting large chunks of code that someone else has painstakingly put in :) This gets rid of most of the #ifdef LARGE_SMB_INO_T ifdefs around DEBUG() statements. We just use %.0f in all cases. Makes the code a bit easier to read :) (This used to be commit 41f0069afc02169932e04ff0039bb6328eaaf04d) --- source3/locking/locking.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index bd484a18b6..f088720e0a 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -109,13 +109,8 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, return False; } -#ifdef LARGE_SMB_OFF_T 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 )); -#else /* LARGE_SMB_OFF_T */ - DEBUG(10,("do_lock: lock type %d start=%d len=%d requested for file %s\n", - lock_type, (int)offset, (int)count, fsp->fsp_name )); -#endif /* LARGE_SMB_OFF_T */ if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count, @@ -141,13 +136,8 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, if (!lp_locking(SNUM(conn))) return(True); -#ifdef LARGE_SMB_OFF_T DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n", (double)offset, (double)count, fsp->fsp_name )); -#else - DEBUG(10,("do_unlock: unlock start=%d len=%d requested for file %s\n", - (int)offset, (int)count, fsp->fsp_name )); -#endif if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK); -- cgit From 9bb7ac81b6e4d33e1be49447dbdbbb8d24259f53 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 23 Oct 1998 03:34:50 +0000 Subject: 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) --- source3/locking/locking.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') 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 @@ -229,12 +229,53 @@ BOOL set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type) return share_ops->set_entry(token, fsp, port, 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); } /******************************************************************* -- cgit From 233aae20814d1e0d90805279182b6acd09697871 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 31 Oct 1998 09:31:29 +0000 Subject: don't core dump in smbstatus if we can't open the shmem system (This used to be commit ef9749798ab72a5e26f9cb5d0904266d6df70f8c) --- source3/locking/locking.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index b71b775524..84c9c442b5 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -285,6 +285,7 @@ BOOL modify_share_mode(int token, files_struct *fsp, int new_mode) int share_mode_forall(void (*fn)(share_mode_entry *, char *)) { + if (!share_ops) return 0; return share_ops->forall(fn); } -- cgit From 9d4b57069cc5ce46c33079ed5ca3dfa3f58118e1 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 4 Apr 1999 05:32:42 +0000 Subject: Use VFS operations for file I/O. (This used to be commit 20bfa71c951a6e6018aafbd43946d1e0669feacb) --- source3/locking/locking.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 84c9c442b5..fdc39d0040 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -87,7 +87,8 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, * fd. So we don't need to use map_lock_type here. */ - return(fcntl_lock(fsp->fd_ptr->fd,SMB_F_GETLK,offset,count,lock_type)); + return(conn->vfs_ops.lock(fsp->fd_ptr->fd,SMB_F_GETLK,offset,count, + lock_type)); } @@ -113,8 +114,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 = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count, - map_lock_type(fsp,lock_type)); + ok = conn->vfs_ops.lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count, + map_lock_type(fsp,lock_type)); if (!ok) { *eclass = ERRDOS; @@ -140,7 +141,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 = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK); + ok = conn->vfs_ops.lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK); if (!ok) { *eclass = ERRDOS; -- cgit From 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:27:58 +0000 Subject: first pass at updating head branch to be to be the same as the SAMBA_2_0 branch (This used to be commit 453a822a76780063dff23526c35408866d0c0154) --- source3/locking/locking.c | 84 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 22 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index fdc39d0040..012d954e50 100644 --- a/source3/locking/locking.c +++ b/source3/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); } /******************************************************************* -- cgit From 4e1291a83f61a72989045879763d9ef05fd38f71 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Dec 1999 09:25:59 +0000 Subject: converted all our existing shared memory code to use a tdb database instead of either sysv or mmap shared memory or lock files. this means we can now completely remove locking_shm.c locking_slow.c shmem.c shmem_sysv.c and lots of other things also got simpler locking.c got a bit larger, but is much better compartmentalised now (This used to be commit e48c2d9937eea0667b8cd3332e49c06314ef31e7) --- source3/locking/locking.c | 423 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 295 insertions(+), 128 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 012d954e50..fc4ce725c5 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1,8 +1,8 @@ /* Unix SMB/Netbios implementation. - Version 1.9. + Version 3.0 Locking functions - Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Andrew Tridgell 1992-1999 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,42 +29,43 @@ September 1997. Jeremy Allison (jallison@whistle.com). Added oplock support. + rewrtten completely to use new tdb code. Tridge, Dec '99 */ #include "includes.h" extern int DEBUGLEVEL; -static struct share_ops *share_ops; +/* the locking database handle */ +static TDB_CONTEXT *tdb; /**************************************************************************** Utility function to map a lock type correctly depending on the real open mode of a file. ****************************************************************************/ - -static int map_lock_type( files_struct *fsp, int lock_type) +static int map_lock_type(files_struct *fsp, int lock_type) { - if((lock_type == F_WRLCK) && (fsp->fd_ptr->real_open_flags == O_RDONLY)) { - /* - * Many UNIX's cannot get a write lock on a file opened read-only. - * Win32 locking semantics allow this. - * Do the best we can and attempt a read-only lock. - */ - DEBUG(10,("map_lock_type: Downgrading write lock to read due to read-only file.\n")); - return F_RDLCK; - } else if( (lock_type == F_RDLCK) && (fsp->fd_ptr->real_open_flags == O_WRONLY)) { - /* - * Ditto for read locks on write only files. - */ - DEBUG(10,("map_lock_type: Changing read lock to write due to write-only file.\n")); - return F_WRLCK; - } - - /* - * This return should be the most normal, as we attempt - * to always open files read/write. - */ - - return lock_type; + if((lock_type == F_WRLCK) && (fsp->fd_ptr->real_open_flags == O_RDONLY)) { + /* + * Many UNIX's cannot get a write lock on a file opened read-only. + * Win32 locking semantics allow this. + * Do the best we can and attempt a read-only lock. + */ + DEBUG(10,("map_lock_type: Downgrading write lock to read due to read-only file.\n")); + return F_RDLCK; + } else if( (lock_type == F_RDLCK) && (fsp->fd_ptr->real_open_flags == O_WRONLY)) { + /* + * Ditto for read locks on write only files. + */ + DEBUG(10,("map_lock_type: Changing read lock to write due to write-only file.\n")); + return F_WRLCK; + } + + /* + * This return should be the most normal, as we attempt + * to always open files read/write. + */ + + return lock_type; } /**************************************************************************** @@ -74,7 +75,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, SMB_OFF_T count,SMB_OFF_T offset, int lock_type) { int snum = SNUM(conn); - + if (count == 0) return(False); @@ -98,30 +99,30 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, SMB_OFF_T count,SMB_OFF_T offset,int lock_type, int *eclass,uint32 *ecode) { - BOOL ok = False; - - if (!lp_locking(SNUM(conn))) - return(True); - - if (count == 0) { - *eclass = ERRDOS; - *ecode = ERRnoaccess; - 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 )); - - if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) - ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count, - map_lock_type(fsp,lock_type)); - - if (!ok) { - *eclass = ERRDOS; - *ecode = ERRlock; - return False; - } - return True; /* Got lock */ + BOOL ok = False; + + if (!lp_locking(SNUM(conn))) + return(True); + + if (count == 0) { + *eclass = ERRDOS; + *ecode = ERRnoaccess; + 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 )); + + if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) + ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count, + map_lock_type(fsp,lock_type)); + + if (!ok) { + *eclass = ERRDOS; + *ecode = ERRlock; + return False; + } + return True; /* Got lock */ } @@ -131,46 +132,38 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, BOOL do_unlock(files_struct *fsp,connection_struct *conn, SMB_OFF_T count,SMB_OFF_T offset,int *eclass,uint32 *ecode) { - BOOL ok = False; - - if (!lp_locking(SNUM(conn))) - return(True); - - DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n", - (double)offset, (double)count, fsp->fsp_name )); - - if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) - ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK); + BOOL ok = False; + + if (!lp_locking(SNUM(conn))) + return(True); + + DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n", + (double)offset, (double)count, fsp->fsp_name )); + + if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) + ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK); - if (!ok) { - *eclass = ERRDOS; - *ecode = ERRlock; - return False; - } - return True; /* Did unlock */ + if (!ok) { + *eclass = ERRDOS; + *ecode = ERRlock; + return False; + } + return True; /* Did unlock */ } /**************************************************************************** Initialise the locking functions. ****************************************************************************/ - BOOL locking_init(int read_only) { - if (share_ops) - return True; + if (tdb) return True; -#ifdef FAST_SHARE_MODES - 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); -#endif + tdb = tdb_open(lock_path("locking.tdb"), + 0, + read_only?O_RDONLY:O_RDWR|O_CREAT, + 0644); - if (!share_ops) { + if (!tdb) { DEBUG(0,("ERROR: Failed to initialise share modes\n")); return False; } @@ -181,110 +174,271 @@ BOOL locking_init(int read_only) /******************************************************************* Deinitialize the share_mode management. ******************************************************************/ - BOOL locking_end(void) { - if (share_ops) - return share_ops->stop_mgmt(); + if (tdb && tdb_close(tdb) != 0) return False; return True; } +/******************************************************************* + form a static locking key for a dev/inode pair +******************************************************************/ +static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode) +{ + static struct locking_key key; + TDB_DATA kbuf; + key.dev = dev; + key.inode = inode; + kbuf.dptr = (char *)&key; + kbuf.dsize = sizeof(key); + return kbuf; +} +static TDB_DATA locking_key_fsp(files_struct *fsp) +{ + return locking_key(fsp->fd_ptr->dev, fsp->fd_ptr->inode); +} /******************************************************************* Lock a hash bucket entry. ******************************************************************/ BOOL lock_share_entry(connection_struct *conn, - SMB_DEV_T dev, SMB_INO_T inode, int *ptok) + SMB_DEV_T dev, SMB_INO_T inode) { - return share_ops->lock_entry(conn, dev, inode, ptok); + return tdb_lockchain(tdb, locking_key(dev, inode)) == 0; } /******************************************************************* Unlock a hash bucket entry. ******************************************************************/ BOOL unlock_share_entry(connection_struct *conn, - SMB_DEV_T dev, SMB_INO_T inode, int token) + SMB_DEV_T dev, SMB_INO_T inode) { - return share_ops->unlock_entry(conn, dev, inode, token); + return tdb_unlockchain(tdb, locking_key(dev, inode)) == 0; } /******************************************************************* Get all share mode entries for a dev/inode pair. ********************************************************************/ int get_share_modes(connection_struct *conn, - int token, SMB_DEV_T dev, SMB_INO_T inode, + SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry **shares) { - return share_ops->get_entries(conn, token, dev, inode, shares); + TDB_DATA dbuf; + struct locking_data *data; + int ret; + + dbuf = tdb_fetch(tdb, locking_key(dev, inode)); + if (!dbuf.dptr) return 0; + + data = (struct locking_data *)dbuf.dptr; + ret = data->num_share_mode_entries; + *shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data), ret * sizeof(**shares)); + free(dbuf.dptr); + + if (! *shares) return 0; + + return ret; +} + +/******************************************************************* + Del the share mode of a file for this process +********************************************************************/ +void del_share_mode(files_struct *fsp) +{ + TDB_DATA dbuf; + struct locking_data *data; + int i, del_count=0; + share_mode_entry *shares; + pid_t pid = getpid(); + + /* read in the existing share modes */ + dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); + if (!dbuf.dptr) return; + + data = (struct locking_data *)dbuf.dptr; + shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); + + /* find any with our pid and delete it by overwriting with the rest of the data + from the record */ + for (i=0;inum_share_mode_entries;) { + if (shares[i].pid == pid && + memcmp(&shares[i].time, + &fsp->open_time,sizeof(struct timeval)) == 0) { + data->num_share_mode_entries--; + memmove(&shares[i], &shares[i+1], + dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); + del_count++; + } else { + i++; + } + } + + /* the record has shrunk a bit */ + dbuf.dsize -= del_count * sizeof(*shares); + + /* store it back in the database */ + tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); + + free(dbuf.dptr); } /******************************************************************* - Del the share mode of a file. +fill a share mode entry ********************************************************************/ -void del_share_mode(int token, files_struct *fsp) +static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_type) { - share_ops->del_entry(token, fsp); + share_mode_entry *e = (share_mode_entry *)p; + e->pid = getpid(); + e->share_mode = fsp->share_mode; + e->op_port = port; + e->op_type = op_type; + memcpy((char *)&e->time, (char *)&fsp->open_time, sizeof(struct timeval)); } /******************************************************************* Set the share mode of a file. Return False on fail, True on success. ********************************************************************/ -BOOL set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type) +BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) { - return share_ops->set_entry(token, fsp, port, op_type); + TDB_DATA dbuf; + struct locking_data *data; + share_mode_entry *shares; + char *p=NULL; + int size; + + /* read in the existing share modes if any */ + dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); + if (!dbuf.dptr) { + /* we'll need to create a new record */ + pstring fname; + + pstrcpy(fname, fsp->conn->connectpath); + pstrcat(fname, "/"); + pstrcat(fname, fsp->fsp_name); + + size = sizeof(*data) + sizeof(*shares) + strlen(fname) + 1; + p = (char *)malloc(size); + data = (struct locking_data *)p; + shares = (share_mode_entry *)(p + sizeof(*data)); + data->num_share_mode_entries = 1; + pstrcpy(p + sizeof(*data) + sizeof(*shares), fname); + fill_share_mode(p + sizeof(*data), fsp, port, op_type); + dbuf.dptr = p; + dbuf.dsize = size; + tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); + free(p); + return True; + } + + /* we're adding to an existing entry - this is a bit fiddly */ + data = (struct locking_data *)dbuf.dptr; + shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); + + data->num_share_mode_entries++; + size = dbuf.dsize + sizeof(*shares); + p = malloc(size); + memcpy(p, dbuf.dptr, sizeof(*data)); + fill_share_mode(p + sizeof(*data), fsp, port, op_type); + memcpy(p + sizeof(*data) + sizeof(*shares), dbuf.dptr + sizeof(*data), + dbuf.dsize - sizeof(*data)); + free(dbuf.dptr); + dbuf.dptr = p; + dbuf.dsize = size; + tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); + free(p); + return True; } + +/******************************************************************* +a generic in-place modification call for share mode entries +********************************************************************/ +static BOOL mod_share_mode(files_struct *fsp, + void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *), + void *param) +{ + TDB_DATA dbuf; + struct locking_data *data; + int i; + share_mode_entry *shares; + pid_t pid = getpid(); + int need_store=0; + + /* read in the existing share modes */ + dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); + if (!dbuf.dptr) return False; + + data = (struct locking_data *)dbuf.dptr; + shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); + + /* find any with our pid and call the supplied function */ + for (i=0;inum_share_mode_entries;i++) { + if (pid == shares[i].pid && + shares[i].share_mode == fsp->share_mode && + memcmp(&shares[i].time, + &fsp->open_time,sizeof(struct timeval)) == 0) { + mod_fn(&shares[i], fsp->fd_ptr->dev, fsp->fd_ptr->inode, param); + need_store=1; + } + } + + /* if the mod fn was called then store it back */ + if (need_store) { + tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); + } + + free(dbuf.dptr); + return need_store; +} + + /******************************************************************* 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 = NO_OPLOCK; + 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 = NO_OPLOCK; } /******************************************************************* Remove an oplock port and mode entry from a share mode. ********************************************************************/ - -BOOL remove_share_oplock(int token, files_struct *fsp) +BOOL remove_share_oplock(files_struct *fsp) { - return share_ops->mod_entry(token, fsp, remove_share_oplock_fn, NULL); + return mod_share_mode(fsp, remove_share_oplock_fn, NULL); } /******************************************************************* Static function that actually does the work for the generic function 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; + 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) +BOOL downgrade_share_oplock(files_struct *fsp) { - return share_ops->mod_entry(token, fsp, downgrade_share_oplock_fn, NULL); + return mod_share_mode(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; @@ -308,33 +462,46 @@ static void modify_share_mode_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO 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, uint16 new_oplock) +BOOL modify_share_mode(files_struct *fsp, int new_mode, uint16 new_oplock) { struct mod_val mv; mv.new_share_mode = new_mode; - mv.new_oplock = new_oplock; + mv.new_oplock = new_oplock; - return share_ops->mod_entry(token, fsp, modify_share_mode_fn, (void *)&mv); + return mod_share_mode(fsp, modify_share_mode_fn, (void *)&mv); } -/******************************************************************* - Call the specified function on each entry under management by the - share mode system. -********************************************************************/ +static void (*traverse_callback)(share_mode_entry *, char *); -int share_mode_forall(void (*fn)(share_mode_entry *, char *)) +/**************************************************************************** +traverse the whole database with this function, calling traverse_callback +on each share mode +****************************************************************************/ +int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf) { - if (!share_ops) return 0; - return share_ops->forall(fn); + struct locking_data *data; + share_mode_entry *shares; + char *name; + int i; + + data = (struct locking_data *)dbuf.dptr; + shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); + name = dbuf.dptr + sizeof(*data) + data->num_share_mode_entries*sizeof(*shares); + + for (i=0;inum_share_mode_entries;i++) { + traverse_callback(&shares[i], name); + } + return 0; } /******************************************************************* - Dump the state of the system. + Call the specified function on each entry under management by the + share mode system. ********************************************************************/ - -void share_status(FILE *f) +int share_mode_forall(void (*fn)(share_mode_entry *, char *)) { - share_ops->status(f); + if (!tdb) return 0; + traverse_callback = fn; + return tdb_traverse(tdb, traverse_fn); } -- cgit From 4b37a2c1ee8b7bedeb10950a4bae80b7545df2c1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 Dec 1999 00:08:25 +0000 Subject: when no shares are returned the *shares pointer must be set to null (This used to be commit 84fe2337c701a52c6dc5cd8c1f6e9050478703f1) --- source3/locking/locking.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index fc4ce725c5..156ff016ea 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -227,6 +227,8 @@ int get_share_modes(connection_struct *conn, struct locking_data *data; int ret; + *shares = NULL; + dbuf = tdb_fetch(tdb, locking_key(dev, inode)); if (!dbuf.dptr) return 0; -- cgit From 9a781a8c6de9513ba5f4cafef41379fae96807c1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 2 Jan 2000 23:00:27 +0000 Subject: - added tdb_flags option to tdb_open() - added TDB_CLEAR_IF_FIRST flag to clear the database if this is the first attached process. Useful for non-persistent databases like our locking area (this will also make upgrades to new database layouts easier) - use lock_path() in a couple of places - leave connections database open while smbd running - cleaned up some tdb code a little, using macros for constants (This used to be commit 00e9da3ca577527db392aced62f02c69cfee8f4f) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 156ff016ea..dafd324edc 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -159,7 +159,7 @@ BOOL locking_init(int read_only) if (tdb) return True; tdb = tdb_open(lock_path("locking.tdb"), - 0, + 0, TDB_CLEAR_IF_FIRST, read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); -- cgit From 574788039f53fada4769731ea3fafe9710417b71 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Jan 2000 03:17:16 +0000 Subject: added the unexpected packet database (unexpected.tdb) this means "nmblookup -S" now always works, even with broken servers the database stores all unexpected replies and these can be accessed by any client. while doing this I cleaned up a couple of functions, and put in place a better trn_id generator. in most places the code got quite a bit simpler due to the addition of simple helper functions. I haven't yet put the code in to take advantage of this for pdc replies - that will be next. Jeremys pdc finding code will then work :) (This used to be commit 280e6359d36c9bc8dcded302f15c3a1db8e3feeb) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index dafd324edc..78d5899322 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -480,7 +480,7 @@ static void (*traverse_callback)(share_mode_entry *, char *); traverse the whole database with this function, calling traverse_callback on each share mode ****************************************************************************/ -int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf) +static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf) { struct locking_data *data; share_mode_entry *shares; -- cgit From 6c2a1fdf360a8fcb100543fdb994860fe6268102 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 13 Jan 2000 12:09:36 +0000 Subject: the bulk of the new byte range locking coode it doesn't map to posix locks yet, that will come later. (This used to be commit 7f2a493095887cb0aae915ac36b9cded71d3a7a7) --- source3/locking/locking.c | 66 +++++++++++++++-------------------------------- 1 file changed, 21 insertions(+), 45 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 78d5899322..a0d140bffd 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -38,41 +38,12 @@ extern int DEBUGLEVEL; /* the locking database handle */ static TDB_CONTEXT *tdb; -/**************************************************************************** - Utility function to map a lock type correctly depending on the real open - mode of a file. -****************************************************************************/ -static int map_lock_type(files_struct *fsp, int lock_type) -{ - if((lock_type == F_WRLCK) && (fsp->fd_ptr->real_open_flags == O_RDONLY)) { - /* - * Many UNIX's cannot get a write lock on a file opened read-only. - * Win32 locking semantics allow this. - * Do the best we can and attempt a read-only lock. - */ - DEBUG(10,("map_lock_type: Downgrading write lock to read due to read-only file.\n")); - return F_RDLCK; - } else if( (lock_type == F_RDLCK) && (fsp->fd_ptr->real_open_flags == O_WRONLY)) { - /* - * Ditto for read locks on write only files. - */ - DEBUG(10,("map_lock_type: Changing read lock to write due to write-only file.\n")); - return F_WRLCK; - } - - /* - * This return should be the most normal, as we attempt - * to always open files read/write. - */ - - return lock_type; -} - /**************************************************************************** Utility function called to see if a file region is locked. ****************************************************************************/ BOOL is_locked(files_struct *fsp,connection_struct *conn, - SMB_OFF_T count,SMB_OFF_T offset, int lock_type) + SMB_OFF_T count,SMB_OFF_T offset, + enum lock_type lock_type) { int snum = SNUM(conn); @@ -82,13 +53,9 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, if (!lp_locking(snum) || !lp_strict_locking(snum)) return(False); - /* - * Note that most UNIX's can *test* for a write lock on - * a read-only fd, just not *set* a write lock on a read-only - * fd. So we don't need to use map_lock_type here. - */ - - return(fcntl_lock(fsp->fd_ptr->fd,SMB_F_GETLK,offset,count,lock_type)); + return !brl_locktest(fsp->fd_ptr->inode, fsp->fd_ptr->dev, + 1, getpid(), conn->cnum, + offset, count, lock_type); } @@ -96,7 +63,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, Utility function called by locking requests. ****************************************************************************/ BOOL do_lock(files_struct *fsp,connection_struct *conn, - SMB_OFF_T count,SMB_OFF_T offset,int lock_type, + SMB_OFF_T count,SMB_OFF_T offset,enum lock_type lock_type, int *eclass,uint32 *ecode) { BOOL ok = False; @@ -113,9 +80,12 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, 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 )); - if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) - ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count, - map_lock_type(fsp,lock_type)); + if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) { + ok = brl_lock(fsp->fd_ptr->inode, fsp->fd_ptr->dev, + 1, getpid(), conn->cnum, + offset, count, + lock_type); + } if (!ok) { *eclass = ERRDOS; @@ -130,7 +100,8 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, Utility function called by unlocking requests. ****************************************************************************/ BOOL do_unlock(files_struct *fsp,connection_struct *conn, - SMB_OFF_T count,SMB_OFF_T offset,int *eclass,uint32 *ecode) + SMB_OFF_T count,SMB_OFF_T offset, + int *eclass,uint32 *ecode) { BOOL ok = False; @@ -140,8 +111,11 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n", (double)offset, (double)count, fsp->fsp_name )); - if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) - ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK); + if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) { + ok = brl_unlock(fsp->fd_ptr->inode, fsp->fd_ptr->dev, + 1, getpid(), conn->cnum, + offset, count); + } if (!ok) { *eclass = ERRDOS; @@ -156,6 +130,8 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, ****************************************************************************/ BOOL locking_init(int read_only) { + brl_init(); + if (tdb) return True; tdb = tdb_open(lock_path("locking.tdb"), -- cgit From 2afd5d5eb5c176f09a9f4f00ea3b517e89ef0ddf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Jan 2000 00:50:48 +0000 Subject: some more work on the byte range locking note the ugly global_smbpid - I hope that won't bethere for long, I just didn't want to do two lots of major surgery at the one time. Using global_smbpid avoids the big change of getting rid of our inbuf/outbuf interface to reply routines. I'll do that once the locking stuff passes all tests. (This used to be commit f8bebf91abcaa5bda3ec8701f9242f220da8943a) --- source3/locking/locking.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index a0d140bffd..e95ec08c58 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -38,6 +38,8 @@ extern int DEBUGLEVEL; /* the locking database handle */ static TDB_CONTEXT *tdb; +int global_smbpid; + /**************************************************************************** Utility function called to see if a file region is locked. ****************************************************************************/ @@ -53,8 +55,8 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, if (!lp_locking(snum) || !lp_strict_locking(snum)) return(False); - return !brl_locktest(fsp->fd_ptr->inode, fsp->fd_ptr->dev, - 1, getpid(), conn->cnum, + return !brl_locktest(fsp->fd_ptr->dev, fsp->fd_ptr->inode, + global_smbpid, getpid(), conn->cnum, offset, count, lock_type); } @@ -81,8 +83,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 = brl_lock(fsp->fd_ptr->inode, fsp->fd_ptr->dev, - 1, getpid(), conn->cnum, + ok = brl_lock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, + global_smbpid, getpid(), conn->cnum, offset, count, lock_type); } @@ -112,8 +114,8 @@ 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 = brl_unlock(fsp->fd_ptr->inode, fsp->fd_ptr->dev, - 1, getpid(), conn->cnum, + ok = brl_unlock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, + global_smbpid, getpid(), conn->cnum, offset, count); } -- cgit From 82af221e4a7e456f580f16bc5d2fd904fc018c96 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Jan 2000 04:32:57 +0000 Subject: we now pass all byte range locking tests the last piece was to use a smb timeout slightly larger than the locking timeout in bloking locks to prevent a race (This used to be commit 1b54cb4a33a65e62c2e3189b78ef073869a60c75) --- source3/locking/locking.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e95ec08c58..350057d1a7 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -40,6 +40,19 @@ static TDB_CONTEXT *tdb; int global_smbpid; + +/**************************************************************************** +remove any locks on this fd +****************************************************************************/ +void locking_close_file(files_struct *fsp) +{ + if (!lp_locking(SNUM(fsp->conn))) return; + + brl_close(fsp->fd_ptr->dev, fsp->fd_ptr->inode, + getpid(), fsp->conn->cnum, fsp->fnum); +} + + /**************************************************************************** Utility function called to see if a file region is locked. ****************************************************************************/ @@ -83,7 +96,7 @@ 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 = brl_lock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, + ok = brl_lock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, fsp->fnum, global_smbpid, getpid(), conn->cnum, offset, count, lock_type); @@ -114,7 +127,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 = brl_unlock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, + ok = brl_unlock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, fsp->fnum, global_smbpid, getpid(), conn->cnum, offset, count); } -- cgit From 7bc1cc7e07991641d436b2c8a35b52663d4c5c05 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Jan 2000 08:01:44 +0000 Subject: damn, Solaris already has a "enum lock_type" changed it to "enum brl_type" (This used to be commit 6b9ee7662c7afa70f6b20889e6b0ae1dcd677f9f) --- source3/locking/locking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 350057d1a7..5348659917 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -58,7 +58,7 @@ void locking_close_file(files_struct *fsp) ****************************************************************************/ BOOL is_locked(files_struct *fsp,connection_struct *conn, SMB_OFF_T count,SMB_OFF_T offset, - enum lock_type lock_type) + enum brl_type lock_type) { int snum = SNUM(conn); @@ -78,7 +78,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, Utility function called by locking requests. ****************************************************************************/ BOOL do_lock(files_struct *fsp,connection_struct *conn, - SMB_OFF_T count,SMB_OFF_T offset,enum lock_type lock_type, + SMB_OFF_T count,SMB_OFF_T offset,enum brl_type lock_type, int *eclass,uint32 *ecode) { BOOL ok = False; -- cgit From 54e1176ba17eaaba82254e4b629fa135802cec10 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Jan 2000 11:14:44 +0000 Subject: added code to allow traversal of the byte range lock database this is used with "smbstatus -B" to dump the lock list (This used to be commit 5f022629146701e6d543f77007dc944e4277ab0c) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 5348659917..9753b5ea61 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -145,7 +145,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, ****************************************************************************/ BOOL locking_init(int read_only) { - brl_init(); + brl_init(read_only); if (tdb) return True; -- cgit From bbe275e95b86bc7af5a641455cbb379974823f84 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 4 Feb 2000 04:59:31 +0000 Subject: 1) added void* state argument to tdb_traverse. guess what! there were two places i found where it was appropriate to _use_ that third argument, in locking.c and brlock.c! there was a static traverse_function and i removed the static variable, typecast it to a void*, passed it to tdb_traverse and re-cast it back to the traverse_function inside the tdb_traverse function. this makes the use of tdb_traverse() reentrant, which is never going to happen, i know, i just don't like to see statics lying about when there's no need for them. as i had to do in samba-tng, all uses of tdb_traverse modified to take the new void* state argument. 2) disabled rpcclient: referring people to use SAMBA_TNG rpcclient. i don't know how the other samba team members would react if i deleted rpcclient from cvs main. damn, that code's so old, it's unreal. 20 rpcclient commands, instead of about 70 in SAMBA_TNG. (This used to be commit 49d7f0afbc1c5425d53019e234d54ddf205c8e9a) --- source3/locking/locking.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 9753b5ea61..890214f10e 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -465,19 +465,20 @@ BOOL modify_share_mode(files_struct *fsp, int new_mode, uint16 new_oplock) return mod_share_mode(fsp, modify_share_mode_fn, (void *)&mv); } -static void (*traverse_callback)(share_mode_entry *, char *); /**************************************************************************** traverse the whole database with this function, calling traverse_callback on each share mode ****************************************************************************/ -static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf) +static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* state) { struct locking_data *data; share_mode_entry *shares; char *name; int i; + SHAREMODE_FN(traverse_callback) = (SHAREMODE_FN_CAST())state; + data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); name = dbuf.dptr + sizeof(*data) + data->num_share_mode_entries*sizeof(*shares); @@ -492,9 +493,8 @@ static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf) Call the specified function on each entry under management by the share mode system. ********************************************************************/ -int share_mode_forall(void (*fn)(share_mode_entry *, char *)) +int share_mode_forall(SHAREMODE_FN(fn)) { if (!tdb) return 0; - traverse_callback = fn; - return tdb_traverse(tdb, traverse_fn); + return tdb_traverse(tdb, traverse_fn, (void*)fn); } -- cgit From ebbb007ed274c975ef5f36f6eb10e6e46df00dcb Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 7 Feb 2000 00:24:04 +0000 Subject: Fixed compile warning in locking.c:traverse_fn() (This used to be commit eefc8972217e5a700b90f13ab040a0919f184d23) --- source3/locking/locking.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 890214f10e..2f85e92932 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -470,7 +470,8 @@ BOOL modify_share_mode(files_struct *fsp, int new_mode, uint16 new_oplock) traverse the whole database with this function, calling traverse_callback on each share mode ****************************************************************************/ -static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* state) +static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, + void* state) { struct locking_data *data; share_mode_entry *shares; -- cgit From b36ea9a7e1fadc30a78c4eb2aabab9ff2011eacd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Apr 2000 12:58:14 +0000 Subject: the first of a bunch of changes to code with getting rid of the fd_ptr element in the fsp pretty mechanical stuff, but it affects lots of files. (This used to be commit 368b0bc1b122ece18d11854c1506517816a01a82) --- source3/locking/locking.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 2f85e92932..45d414daf1 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -48,7 +48,7 @@ void locking_close_file(files_struct *fsp) { if (!lp_locking(SNUM(fsp->conn))) return; - brl_close(fsp->fd_ptr->dev, fsp->fd_ptr->inode, + brl_close(fsp->dev, fsp->inode, getpid(), fsp->conn->cnum, fsp->fnum); } @@ -68,7 +68,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, if (!lp_locking(snum) || !lp_strict_locking(snum)) return(False); - return !brl_locktest(fsp->fd_ptr->dev, fsp->fd_ptr->inode, + return !brl_locktest(fsp->dev, fsp->inode, global_smbpid, getpid(), conn->cnum, offset, count, lock_type); } @@ -96,7 +96,7 @@ 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 = brl_lock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, fsp->fnum, + ok = brl_lock(fsp->dev, fsp->inode, fsp->fnum, global_smbpid, getpid(), conn->cnum, offset, count, lock_type); @@ -127,7 +127,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 = brl_unlock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, fsp->fnum, + ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, global_smbpid, getpid(), conn->cnum, offset, count); } @@ -186,7 +186,7 @@ static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode) } static TDB_DATA locking_key_fsp(files_struct *fsp) { - return locking_key(fsp->fd_ptr->dev, fsp->fd_ptr->inode); + return locking_key(fsp->dev, fsp->inode); } /******************************************************************* @@ -207,6 +207,23 @@ BOOL unlock_share_entry(connection_struct *conn, return tdb_unlockchain(tdb, locking_key(dev, inode)) == 0; } + +/******************************************************************* + Lock a hash bucket entry. use a fsp for convenience +******************************************************************/ +BOOL lock_share_entry_fsp(files_struct *fsp) +{ + return tdb_lockchain(tdb, locking_key(fsp->dev, fsp->inode)) == 0; +} + +/******************************************************************* + Unlock a hash bucket entry. +******************************************************************/ +BOOL unlock_share_entry_fsp(files_struct *fsp) +{ + return tdb_unlockchain(tdb, locking_key(fsp->dev, fsp->inode)) == 0; +} + /******************************************************************* Get all share mode entries for a dev/inode pair. ********************************************************************/ @@ -370,7 +387,7 @@ static BOOL mod_share_mode(files_struct *fsp, shares[i].share_mode == fsp->share_mode && memcmp(&shares[i].time, &fsp->open_time,sizeof(struct timeval)) == 0) { - mod_fn(&shares[i], fsp->fd_ptr->dev, fsp->fd_ptr->inode, param); + mod_fn(&shares[i], fsp->dev, fsp->inode, param); need_store=1; } } -- cgit From f6be38cae223f1ad3f4ecc5b81d14c44d92f58ba Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Apr 2000 19:44:54 +0000 Subject: include/byteorder.h: ALIGN4/ALIGN2 macros. include/includes.h: Added SMB_BIG_UINT_BITS. lib/util.c: Removed align2/align4 - use macros. libsmb/namequery.c: Use ALIGN2. locking/locking.c: Replace do_lock, do_unlock, args with SMB_BIG_UINT, not SMB_OFF_T. Needed to move to hiding POSIX locks at a lower layer. nmbd/nmbd_processlogon.c: Use ALIGN2/ALIGN4 macros. smbd/blocking.c: Replace do_lock, do_unlock, args with SMB_BIG_UINT, not SMB_OFF_T. smbd/reply.c: Replace do_lock, do_unlock, args with SMB_BIG_UINT, not SMB_OFF_T. Jeremy. (This used to be commit 491eea8a20bf80d426625479326211dc975857a6) --- source3/locking/locking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 45d414daf1..1bb0a3b59c 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -57,7 +57,7 @@ void locking_close_file(files_struct *fsp) Utility function called to see if a file region is locked. ****************************************************************************/ BOOL is_locked(files_struct *fsp,connection_struct *conn, - SMB_OFF_T count,SMB_OFF_T offset, + SMB_BIG_UINT count,SMB_BIG_UINT offset, enum brl_type lock_type) { int snum = SNUM(conn); @@ -78,7 +78,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, Utility function called by locking requests. ****************************************************************************/ BOOL do_lock(files_struct *fsp,connection_struct *conn, - SMB_OFF_T count,SMB_OFF_T offset,enum brl_type lock_type, + SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, int *eclass,uint32 *ecode) { BOOL ok = False; @@ -115,7 +115,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, Utility function called by unlocking requests. ****************************************************************************/ BOOL do_unlock(files_struct *fsp,connection_struct *conn, - SMB_OFF_T count,SMB_OFF_T offset, + SMB_BIG_UINT count,SMB_BIG_UINT offset, int *eclass,uint32 *ecode) { BOOL ok = False; -- cgit From 8316237e9ca83d1bd0cecdc63d7e47b44cf13181 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Apr 2000 17:59:09 +0000 Subject: 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 used to be commit db96f83e34a139f47776fcbb5c1624fbf9d9943b) --- source3/locking/locking.c | 166 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 157 insertions(+), 9 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 1bb0a3b59c..72ca91566a 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -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; + + 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. +****************************************************************************/ - brl_close(fsp->dev, fsp->inode, - getpid(), fsp->conn->cnum, fsp->fnum); +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) { -- cgit From 96b3bf3140a57c6adeaedd9f7ed427d207d47ee9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Apr 2000 21:46:22 +0000 Subject: Implmented mapping of lock offset/count from 64 bit MS ranges to either 63 or 31 bit POSIX ranges. Code to get these locks not yet added. Jeremy. (This used to be commit 9c3b9146a3baff4b2e403ae8fac6c48df1b7e642) --- source3/locking/locking.c | 170 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 157 insertions(+), 13 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 72ca91566a..d72d3908ce 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -90,9 +90,153 @@ static const char *lock_type_name(enum brl_type lock_type) False if not. ****************************************************************************/ -static BOOL posix_lock_in_range(SMB_OFF_T *p_offset, SMB_OFF_T *p_count) +static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out, + SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count) { - /* Placeholder. */ + SMB_OFF_T offset; + SMB_OFF_T count; + +#if defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS) + + /* + * In this case SMB_OFF_T is 64 bits, + * and the underlying system can handle 64 bit signed locks. + * Cast to signed type. + */ + + offset = (SMB_OFF_T)u_offset; + count = (SMB_OFF_T)u_count; + + /* + * POSIX lock ranges cannot be negative. + * Fail if any combination becomes negative. + */ + + if(offset < 0 || count < 0 || (offset + count < 0)) { + DEBUG(10,("posix_lock_in_range: negative range offset = %.0f, count = %.0f. Ignoring lock.\n", + (double)offset, (double)count )); + return False; + + /* + * In this case SMB_OFF_T is 64 bits, the offset and count + * fit within the positive range, and the underlying + * system can handle 64 bit locks. Just return as the + * cast values are ok. + */ + +#else /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */ + + /* + * In this case either SMB_OFF_T is 32 bits, + * or the underlying system cannot handle 64 bit signed locks. + * Either way we have to try and mangle to fit within 31 bits. + * This is difficult. + */ + +#if defined(HAVE_BROKEN_FCNTL64_LOCKS) + + /* + * SMB_OFF_T is 64 bits, but we need to use 31 bits due to + * broken large locking. + */ + + if(((u_offset >> 32) & 0xFFFFFFFF) || ((u_count >> 32) & 0xFFFFFFFF)) { + DEBUG(10,("posix_lock_in_range: top 32 bits not zero. offset = %.0f, count = %.0f. Ignoring lock.\n", + (double)u_offset, (double)u_count )); + /* Top 32 bits of offset or count were not zero. */ + return False; + } + + /* Cast from 64 bits unsigned to 64 bits signed. */ + offset = (SMB_OFF_T)u_offset; + count = (SMB_OFF_T)u_count; + + /* + * Check if we are within the 2^31 range. + */ + + { + int32 low_offset = (int32)offset; + int32 low_count = (int32)count; + + if(low_offset < 0 || low_count < 0 || (low_offset + low_count < 0)) { + DEBUG(10,("posix_lock_in_range: not within 2^31 range. low_offset = %d, low_count = %d. Ignoring lock.\n", + low_offset, low_count )); + return False; + } + } + + /* + * Ok - we can map from a 64 bit number to a 31 bit lock. + */ + +#else /* HAVE_BROKEN_FCNTL64_LOCKS */ + + /* + * SMB_OFF_T is 32 bits. + */ + +#if defined(HAVE_LONGLONG) + + /* + * SMB_BIG_UINT is 64 bits, we can do a 32 bit shift. + */ + + if(((u_offset >> 32) & 0xFFFFFFFF) || ((u_count >> 32) & 0xFFFFFFFF)) { + DEBUG(10,("posix_lock_in_range: top 32 bits not zero. u_offset = %.0f, u_count = %.0f. Ignoring lock.\n", + (double)u_offset, (double)u_count )); + return False; + } + + /* Cast from 64 bits unsigned to 32 bits signed. */ + offset = (SMB_OFF_T)u_offset; + count = (SMB_OFF_T)u_count; + + /* + * Check if we are within the 2^31 range. + */ + + if(offset < 0 || count < 0 || (offset + count < 0)) { + DEBUG(10,("posix_lock_in_range: not within 2^31 range. offset = %d, count = %d. Ignoring lock.\n", + (int)offset, (int)count )); + return False; + } + +#else /* HAVE_LONGLONG */ + + /* + * SMB_BIG_UINT and SMB_OFF_T are both 32 bits, + * just cast. + */ + + /* Cast from 32 bits unsigned to 32 bits signed. */ + offset = (SMB_OFF_T)u_offset; + count = (SMB_OFF_T)u_count; + + /* + * Check if we are within the 2^31 range. + */ + + if(offset < 0 || count < 0 || (offset + count < 0)) { + DEBUG(10,("posix_lock_in_range: not within 2^31 range. offset = %d, count = %d. Ignoring lock.\n", + (int)offset, (int)count )); + return False; + } + +#endif /* HAVE_LONGLONG */ +#endif /* LARGE_SMB_OFF_T */ +#endif /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */ + + /* + * The mapping was successful. + */ + + DEBUG(10,("posix_lock_in_range: offset_out = %.0f, count_out = %.0f\n", + (double)offset, (double)count )); + + *offset_out = offset; + *count_out = count; + return True; } @@ -103,13 +247,13 @@ static BOOL posix_lock_in_range(SMB_OFF_T *p_offset, SMB_OFF_T *p_count) 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; + SMB_OFF_T offset; + SMB_OFF_T 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)) + if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) return True; /* Placeholder - for now always return that the lock could be granted. */ @@ -123,13 +267,13 @@ static BOOL posix_locktest(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UIN 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; + SMB_OFF_T offset; + SMB_OFF_T count; - DEBUG(10,("get_posix_lock: File %s, offset = %.0f, count = %.0f, type = %s\n", + DEBUG(5,("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)) + if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) return True; /* Placeholder - for now always return that the lock could be granted. */ @@ -144,13 +288,13 @@ static BOOL get_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UIN 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; + SMB_OFF_T offset; + SMB_OFF_T count; - DEBUG(10,("release_posix_lock: File %s, offset = %.0f, count = %.0f\n", + DEBUG(5,("release_posix_lock: File %s, offset = %.0f, count = %.0f\n", fsp->fsp_name, (double)offset, (double)count )); - if(!posix_lock_in_range(&offset, &count)) + if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) return True; /* Placeholder - for now always return that the lock could be granted. */ -- cgit From a018d6b3262d0617242f8be10b4e2dfb96f813e1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Apr 2000 23:01:11 +0000 Subject: Removed "ole locking compat" parameter (no longer used). We now get/set/check POSIX locks, but I still need to code up the close fd braindamage... Jeremy. (This used to be commit 3de058bd43976853b0ed2b6b5529e2a3a08909eb) --- source3/locking/locking.c | 131 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 113 insertions(+), 18 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d72d3908ce..decc36fc03 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -84,6 +84,37 @@ static const char *lock_type_name(enum brl_type lock_type) return (lock_type == READ_LOCK) ? "READ" : "WRITE"; } +/**************************************************************************** + Utility function to map a lock type correctly depending on the open + mode of a file. +****************************************************************************/ + +static int map_posix_lock_type( files_struct *fsp, enum brl_type lock_type) +{ + if((lock_type == WRITE_LOCK) && !fsp->can_write) { + /* + * Many UNIX's cannot get a write lock on a file opened read-only. + * Win32 locking semantics allow this. + * Do the best we can and attempt a read-only lock. + */ + DEBUG(10,("map_posix_lock_type: Downgrading write lock to read due to read-only file.\n")); + return F_RDLCK; + } else if((lock_type == READ_LOCK) && !fsp->can_read) { + /* + * Ditto for read locks on write only files. + */ + DEBUG(10,("map_posix_lock_type: Changing read lock to write due to write-only file.\n")); + return F_WRLCK; + } + + /* + * This return should be the most normal, as we attempt + * to always open files read/write. + */ + + return (lock_type == READ_LOCK) ? F_RDLCK : F_WRLCK; +} + /**************************************************************************** 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 @@ -98,6 +129,10 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out, #if defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS) + SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4); + SMB_OFF_T mask = (mask2<<1); + SMB_OFF_T neg_mask = ~mask; + /* * In this case SMB_OFF_T is 64 bits, * and the underlying system can handle 64 bit signed locks. @@ -107,13 +142,21 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out, offset = (SMB_OFF_T)u_offset; count = (SMB_OFF_T)u_count; + /* + * Deal with a very common case of count of all ones. + * (lock entire file). + */ + + if(count == (SMB_OFF_T)-1) + count &= ~mask; + /* * POSIX lock ranges cannot be negative. * Fail if any combination becomes negative. */ if(offset < 0 || count < 0 || (offset + count < 0)) { - DEBUG(10,("posix_lock_in_range: negative range offset = %.0f, count = %.0f. Ignoring lock.\n", + DEBUG(10,("posix_lock_in_range: negative range: offset = %.0f, count = %.0f. Ignoring lock.\n", (double)offset, (double)count )); return False; @@ -140,6 +183,14 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out, * broken large locking. */ + /* + * Deal with a very common case of count of all ones. + * (lock entire file). + */ + + if(u_count == (SMB_BIG_UINT)-1) + count = 0x7FFFFFFF; + if(((u_offset >> 32) & 0xFFFFFFFF) || ((u_count >> 32) & 0xFFFFFFFF)) { DEBUG(10,("posix_lock_in_range: top 32 bits not zero. offset = %.0f, count = %.0f. Ignoring lock.\n", (double)u_offset, (double)u_count )); @@ -182,6 +233,14 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out, * SMB_BIG_UINT is 64 bits, we can do a 32 bit shift. */ + /* + * Deal with a very common case of count of all ones. + * (lock entire file). + */ + + if(u_count == (SMB_BIG_UINT)-1) + count = 0x7FFFFFFF; + if(((u_offset >> 32) & 0xFFFFFFFF) || ((u_count >> 32) & 0xFFFFFFFF)) { DEBUG(10,("posix_lock_in_range: top 32 bits not zero. u_offset = %.0f, u_count = %.0f. Ignoring lock.\n", (double)u_offset, (double)u_count )); @@ -209,6 +268,14 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out, * just cast. */ + /* + * Deal with a very common case of count of all ones. + * (lock entire file). + */ + + if(u_count == (SMB_BIG_UINT)-1) + count = 0x7FFFFFFF; + /* Cast from 32 bits unsigned to 32 bits signed. */ offset = (SMB_OFF_T)u_offset; count = (SMB_OFF_T)u_count; @@ -242,22 +309,32 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out, /**************************************************************************** POSIX function to see if a file region is locked. Returns True if the - lock could be granted, False if not. + region is locked, False otherwise. ****************************************************************************/ -static BOOL posix_locktest(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type) +static BOOL is_posix_locked(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 count; - DEBUG(10,("posix_locktest: File %s, offset = %.0f, count = %.0f, type = %s\n", + DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, type = %s\n", fsp->fsp_name, (double)offset, (double)count, lock_type_name(lock_type) )); + /* + * If the requested lock won't fit in the POSIX range, we will + * never set it, so presume it is not locked. + */ + if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) - return True; + return False; - /* Placeholder - for now always return that the lock could be granted. */ - return True; + /* + * Note that most UNIX's can *test* for a write lock on + * a read-only fd, just not *set* a write lock on a read-only + * fd. So we don't need to use map_lock_type here. + */ + + return fcntl_lock(fsp->fd,SMB_F_GETLK,offset,count,lock_type); } /**************************************************************************** @@ -265,40 +342,58 @@ static BOOL posix_locktest(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UIN 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) +static BOOL set_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 count; + BOOL ret = True; - DEBUG(5,("get_posix_lock: File %s, offset = %.0f, count = %.0f, type = %s\n", + DEBUG(5,("set_posix_lock: File %s, offset = %.0f, count = %.0f, type = %s\n", fsp->fsp_name, (double)offset, (double)count, lock_type_name(lock_type) )); + /* + * If the requested lock won't fit in the POSIX range, we will + * pretend it was successful. + */ + if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) return True; - /* Placeholder - for now always return that the lock could be granted. */ - fsp->num_posix_locks++; - return True; + ret = fcntl_lock(fsp->fd,SMB_F_SETLK,offset,count,map_posix_lock_type(fsp,lock_type)); + + if(ret) + fsp->num_posix_locks++; + + return ret; } /**************************************************************************** POSIX function to release a lock. Returns True if the - lock could be granted, False if not. + lock could be released, 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 count; + BOOL ret; DEBUG(5,("release_posix_lock: File %s, offset = %.0f, count = %.0f\n", fsp->fsp_name, (double)offset, (double)count )); + /* + * If the requested lock won't fit in the POSIX range, we will + * pretend it was successful. + */ + if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) return True; - /* Placeholder - for now always return that the lock could be granted. */ - fsp->num_posix_locks--; + ret = fcntl_lock(fsp->fd,SMB_F_SETLK,offset,count,F_UNLCK); + + if(ret) + fsp->num_posix_locks--; + return True; } @@ -332,7 +427,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, */ if(!ret && !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && lp_posix_locking(snum)) - ret = !posix_locktest(fsp, offset, count, lock_type); + ret = is_posix_locked(fsp, offset, count, lock_type); return ret; } @@ -371,7 +466,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, * Try and get a POSIX lock on this range. */ - ok = get_posix_lock(fsp, offset, count, lock_type); + ok = set_posix_lock(fsp, offset, count, lock_type); if(!ok) { /* @@ -393,10 +488,10 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, return True; /* Got lock */ } - /**************************************************************************** Utility function called by unlocking requests. ****************************************************************************/ + BOOL do_unlock(files_struct *fsp,connection_struct *conn, SMB_BIG_UINT count,SMB_BIG_UINT offset, int *eclass,uint32 *ecode) -- cgit From 019bab27c8ac811885a836eaf234a3ba6aa8a361 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 13 Apr 2000 16:46:32 +0000 Subject: Typo - missing '}'. Jeremy. (This used to be commit 0216d81f061ee599a798fdbf25625fbbbd88ef08) --- source3/locking/locking.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index decc36fc03..9ea9e08ded 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -159,6 +159,7 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out, DEBUG(10,("posix_lock_in_range: negative range: offset = %.0f, count = %.0f. Ignoring lock.\n", (double)offset, (double)count )); return False; + } /* * In this case SMB_OFF_T is 64 bits, the offset and count -- cgit From 4217c939ec6bdb80a3fe953e5b60f6f7b7a43635 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Apr 2000 20:41:04 +0000 Subject: locking/locking.c: Fixed placeholder code for POSIX locking. printing/printing.c: Cast tdb_delete to (tdb_traverse_func) to stop warning. tmpfile gives mirror warning. smbd/groupname.c: Remember to file_lines_free() on exit. tdb/tdb.h: Add tdb_traverse_func typedef. Jeremy (This used to be commit 204ca1195c86499bd9beb273ce573db7a56ccead) --- source3/locking/locking.c | 66 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 17 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 9ea9e08ded..bde1ffb567 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -60,6 +60,8 @@ void locking_close_file(files_struct *fsp) * Now release all the tdb locks. */ + /* Placeholder for code here.... */ +#if 0 brl_close(fsp->dev, fsp->inode, getpid(), fsp->conn->cnum, fsp->fnum); /* @@ -71,8 +73,7 @@ void locking_close_file(files_struct *fsp) * on *that* fd will get lost when we close this one. POSIX * braindamage... JRA. */ - - /* Placeholder for code here.... */ +#endif } /**************************************************************************** @@ -360,10 +361,15 @@ static BOOL set_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UIN if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) return True; - ret = fcntl_lock(fsp->fd,SMB_F_SETLK,offset,count,map_posix_lock_type(fsp,lock_type)); + /* + * Note that setting multiple overlapping read locks on different + * file descriptors will not be held separately by the kernel (POSIX + * braindamage), but will be merged into one continuous read lock + * range. We cope with this case in the release_posix_lock code + * below. JRA. + */ - if(ret) - fsp->num_posix_locks++; + ret = fcntl_lock(fsp->fd,SMB_F_SETLK,offset,count,map_posix_lock_type(fsp,lock_type)); return ret; } @@ -377,11 +383,23 @@ static BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG { SMB_OFF_T offset; SMB_OFF_T count; - BOOL ret; + BOOL ret = True; DEBUG(5,("release_posix_lock: File %s, offset = %.0f, count = %.0f\n", fsp->fsp_name, (double)offset, (double)count )); + if(u_count == 0) { + + /* + * This lock must overlap with an existing read-only lock + * help by another fd. Just decrement the count but don't + * do any POSIX call. + */ + + fsp->num_posix_locks--; + return True; + } + /* * If the requested lock won't fit in the POSIX range, we will * pretend it was successful. @@ -422,12 +440,9 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, /* * 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)) + if(!ret && lp_posix_locking(snum)) ret = is_posix_locked(fsp, offset, count, lock_type); return ret; @@ -465,11 +480,13 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, /* * Try and get a POSIX lock on this range. + * Note that this is ok if it is a read lock + * overlapping on a different fd. JRA. */ - ok = set_posix_lock(fsp, offset, count, lock_type); - - if(!ok) { + if((ok = set_posix_lock(fsp, offset, count, lock_type)) == True) + fsp->num_posix_locks++; + else { /* * We failed to map - we must now remove the brl * lock entry. @@ -506,18 +523,33 @@ 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 = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, getpid(), conn->cnum, - offset, count); - if(ok && lp_posix_locking(SNUM(conn))) { + if(lp_posix_locking(SNUM(conn))) { + +#if 0 + /* + * The following call calculates if there are any + * overlapping read locks held by this process on + * other fd's open on the same file and truncates + * any overlapping range and returns the value in + * the non_overlap_XXX variables. Thus the POSIX + * unlock may not be done on the same region as + * the brl_lock. JRA. + */ + + brl_unlock_list(fsp->dev, fsp->inode, fsp->fnum, +#endif /* * Release the POSIX lock on this range. */ (void)release_posix_lock(fsp, offset, count); + fsp->num_posix_locks--; } + + ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, + global_smbpid, getpid(), conn->cnum, offset, count); } if (!ok) { -- cgit From 6259f51dd9918eccc9697f3763d918f7c9b82b50 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 22 Apr 2000 00:33:16 +0000 Subject: This is a *big* checkin that may break some things, but implements the new open mechanism Andrew & I discussed. config.sub: configure: Included the QNX patch. include/vfs.h: smbd/vfs-wrap.c: smbd/vfs.c: Added ftruncate vfs call (needed). Note that we will also need locking calls in the vfs (to be added). lib/util_unistr.c: nmbd/nmbd_processlogon.c: Fix for NT domain logons causing nmbd to core dump. Also fix for sidsize DOS bug. locking/locking.c: Check value of ret before using it for memdup. printing/printing.c: Convert print_fsp_open to return an allocated fsp. rpc_server/srv_lsa.c: Fix for NT domain logons. I have removed all use of lp_share_modes() from the code (although I left the parameter in the table for backwards compatibility). It no longer makes sense for this to exist. smbd/close.c: Removed lp_share_modes(). smbd/fileio.c: Fixed parameters to unlock_share_entry call in panic code. smbd/files.c: Correctly set the unix_ERR_code to ERRnofids on fsp allocation fail. smbd/nttrans.c: smbd/reply.c: smbd/trans2.c: Changed all occurrences of open_file_shared/open_directory/ open_file_stat to return an fsp from the call. smbd/open.c: Changed all occurrences of open_file_shared/open_directory/ open_file_stat to return an fsp from the call. In addition I have fixed a long standing race condition in the deny mode processing w.r.t. two smbd's creating a file. Andrew, please note that your original idea of using open with O_EXCL in this case would not work (I went over the races very carefully) and so we must re-check deny modes *after* the open() call returns. This is because there is a race between the open with O_EXCL and the lock of the share mode entry. Imagine the case where the first smbd does the open with O_EXCL and a deny mode of DENY_ALL, but is pre-empted before it locks the share modes and creates the deny mode entry for DENY_ALL. A second smbd could then come in with O_RDONLY and a deny mode of DENY_NONE and the two opens would be allowed. The *only* way to fix this race is to lock the share modes after the open and then do the deny mode checks *after* this lock in the case where the file did not originally exist. This code will need extensive testing but seems to initially work. Jeremy. (This used to be commit ab0ecc39d688f16b9692fe90b991f0b89287070a) --- source3/locking/locking.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index bde1ffb567..affda89f08 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -662,7 +662,8 @@ int get_share_modes(connection_struct *conn, data = (struct locking_data *)dbuf.dptr; ret = data->num_share_mode_entries; - *shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data), ret * sizeof(**shares)); + if(ret) + *shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data), ret * sizeof(**shares)); free(dbuf.dptr); if (! *shares) return 0; -- cgit From a069d4d72fea8c283dd67a08ba30b49beefcd7de Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Apr 2000 14:25:04 +0000 Subject: fixed a locking database bug - it was actually harmless except that smbstatus could display the wrong filename when files change dev/inum after a rename (This used to be commit 990b16fcf7af74f376db157a3e5de7bb68c1a4a1) --- source3/locking/locking.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index affda89f08..9f33cba338 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -708,7 +708,11 @@ void del_share_mode(files_struct *fsp) dbuf.dsize -= del_count * sizeof(*shares); /* store it back in the database */ - tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); + if (data->num_share_mode_entries == 0) { + tdb_delete(tdb, locking_key_fsp(fsp)); + } else { + tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); + } free(dbuf.dptr); } @@ -815,7 +819,11 @@ static BOOL mod_share_mode(files_struct *fsp, /* if the mod fn was called then store it back */ if (need_store) { - tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); + if (data->num_share_mode_entries == 0) { + tdb_delete(tdb, locking_key_fsp(fsp)); + } else { + tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); + } } free(dbuf.dptr); -- cgit From 644f22ac6141f58f2badd3a9761ac156831c16a3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 24 Apr 2000 20:48:40 +0000 Subject: Added the code that keeps fd's open across a close if there are other fsp's open on the same dev/inode pair with existing POSIX locks. This is done at the smbd/open layer, so smbd just calls fd_close() and the transfer of any open fd's is done under the covers of fd_close(). When an fsp is closed and no other fsp's open on the same dev/inode pair have existing POSIX locks then all fd's associated with this fsp are closed. Now only the hard part of doing the POSIX range unlock code when read locks overlap remains for full POSIX/SMB lock integration.... Jeremy. (This used to be commit 1df48ed55ee303b6d84d7277fd79761cfe5f7052) --- source3/locking/locking.c | 59 ++++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 36 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 9f33cba338..a73af8fd07 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -40,42 +40,6 @@ static TDB_CONTEXT *tdb; int global_smbpid; -/**************************************************************************** - Remove any locks on this fd. -****************************************************************************/ - -void locking_close_file(files_struct *fsp) -{ - if (!lp_locking(SNUM(fsp->conn))) - return; - - 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. - */ - - /* Placeholder for code here.... */ -#if 0 - 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. - */ -#endif -} - /**************************************************************************** Debugging aid :-). ****************************************************************************/ @@ -416,6 +380,29 @@ static BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG return True; } +/**************************************************************************** + Remove any locks on this fd. Called from file_close(). +****************************************************************************/ + +void locking_close_file(files_struct *fsp) +{ + if (!lp_locking(SNUM(fsp->conn))) + return; + + 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); +} + /**************************************************************************** Utility function called to see if a file region is locked. ****************************************************************************/ -- cgit From e4d382750caa522b5e249d690fdb469d7b0c12a1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Apr 2000 20:30:58 +0000 Subject: Added the hard code :-). HEAD should now map brl locks correctly into POSIX locks, including the really nasty case of large range unlock. There is a lot of pretty ASCII art in locking/brlock.c explaining exactly how this code works. If it is unclear, please ask me. Jeremy. (This used to be commit 135855dbd3b8934a49229b81646cd4469acba926) --- source3/locking/locking.c | 171 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 121 insertions(+), 50 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index a73af8fd07..811dfbc101 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -380,29 +380,6 @@ static BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG return True; } -/**************************************************************************** - Remove any locks on this fd. Called from file_close(). -****************************************************************************/ - -void locking_close_file(files_struct *fsp) -{ - if (!lp_locking(SNUM(fsp->conn))) - return; - - 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); -} - /**************************************************************************** Utility function called to see if a file region is locked. ****************************************************************************/ @@ -502,51 +479,145 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, int *eclass,uint32 *ecode) { BOOL ok = False; + TALLOC_CTX *ul_ctx = NULL; + struct unlock_list *ulist = NULL; + struct unlock_list *ul = NULL; + pid_t pid; if (!lp_locking(SNUM(conn))) return(True); + if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) { + *eclass = ERRDOS; + *ecode = ERRlock; + return False; + } + DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n", (double)offset, (double)count, fsp->fsp_name )); - - if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) { - - if(lp_posix_locking(SNUM(conn))) { - -#if 0 - /* - * The following call calculates if there are any - * overlapping read locks held by this process on - * other fd's open on the same file and truncates - * any overlapping range and returns the value in - * the non_overlap_XXX variables. Thus the POSIX - * unlock may not be done on the same region as - * the brl_lock. JRA. - */ - brl_unlock_list(fsp->dev, fsp->inode, fsp->fnum, -#endif - - /* - * Release the POSIX lock on this range. - */ + /* + * Remove the existing lock record from the tdb lockdb + * before looking at POSIX locks. If this record doesn't + * match then don't bother looking to remove POSIX locks. + */ - (void)release_posix_lock(fsp, offset, count); - fsp->num_posix_locks--; - } + pid = getpid(); - ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, getpid(), conn->cnum, offset, count); - } + ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, + global_smbpid, pid, conn->cnum, offset, count); if (!ok) { *eclass = ERRDOS; *ecode = ERRlock; return False; } + + if (!lp_posix_locking(SNUM(conn))) + return True; + + if ((ul_ctx = talloc_init()) == NULL) { + DEBUG(0,("do_unlock: unable to init talloc context.\n")); + return True; /* Not a fatal error. */ + } + + if ((ul = (struct unlock_list *)talloc(ul_ctx, sizeof(struct unlock_list))) == NULL) { + DEBUG(0,("do_unlock: unable to talloc unlock list.\n")); + talloc_destroy(ul_ctx); + return True; /* Not a fatal error. */ + } + + /* + * Create the initial list entry containing the + * lock we want to remove. + */ + + ZERO_STRUCTP(ul); + ul->start = offset; + ul->size = count; + + DLIST_ADD(ulist, ul); + + /* + * The following call calculates if there are any + * overlapping read locks held by this process on + * other fd's open on the same file and creates a + * list of unlock ranges that will allow other + * POSIX lock ranges to remain on the file whilst the + * unlocks are performed. + */ + + ulist = brl_unlock_list(ul_ctx, ulist, pid, fsp->dev, fsp->inode); + + /* + * Release the POSIX locks on the list of ranges returned. + */ + + for(; ulist; ulist = ulist->next) + (void)release_posix_lock(fsp, ulist->start, ulist->size); + + talloc_destroy(ul_ctx); + + /* + * We treat this as one unlock request for POSIX accounting purposes even + * if it may have been split into multiple smaller POSIX unlock ranges. + */ + + fsp->num_posix_locks--; + return True; /* Did unlock */ } +/**************************************************************************** + Remove any locks on this fd. Called from file_close(). +****************************************************************************/ + +void locking_close_file(files_struct *fsp) +{ + pid_t pid = getpid(); + + if (!lp_locking(SNUM(fsp->conn))) + return; + + if(lp_posix_locking(SNUM(fsp->conn))) { + + TALLOC_CTX *ul_ctx = NULL; + struct unlock_list *ul = NULL; + int eclass; + uint32 ecode; + + if ((ul_ctx = talloc_init()) == NULL) { + DEBUG(0,("locking_close_file: unable to init talloc context.\n")); + return; + } + + /* + * We need to release all POSIX locks we have on this + * fd. Get all our existing locks from the tdb locking database. + */ + + ul = brl_getlocklist(ul_ctx, fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum); + + /* + * Now unlock all of them. This will remove the brl entry also + * for each lock. + */ + + for(; ul; ul = ul->next) + do_unlock(fsp,fsp->conn,ul->size,ul->start,&eclass,&ecode); + + talloc_destroy(ul_ctx); + + } else { + + /* + * Just release all the tdb locks, no need to release individually. + */ + + brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum); + } +} + /**************************************************************************** Initialise the locking functions. ****************************************************************************/ -- cgit From e3987ff7a638f9ea8b6794f1ed0df530d8488033 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Apr 2000 18:46:10 +0000 Subject: Fixed crash bugs Andrew pointed out with LOCK4 smbtorture test. Was miscounting posix locks, plus was not taking into account the case where other_fsp == fsp in the 'move locks' case. DOH ! This code will be re-written anyway :-). Jeremy. (This used to be commit 5278ec016cb24d8263fe6e7c1d389f466270ef24) --- source3/locking/locking.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 811dfbc101..b61e8acedc 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -284,7 +284,7 @@ static BOOL is_posix_locked(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UI SMB_OFF_T count; DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, type = %s\n", - fsp->fsp_name, (double)offset, (double)count, lock_type_name(lock_type) )); + fsp->fsp_name, (double)u_offset, (double)u_count, lock_type_name(lock_type) )); /* * If the requested lock won't fit in the POSIX range, we will @@ -315,7 +315,7 @@ static BOOL set_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UIN BOOL ret = True; DEBUG(5,("set_posix_lock: File %s, offset = %.0f, count = %.0f, type = %s\n", - fsp->fsp_name, (double)offset, (double)count, lock_type_name(lock_type) )); + fsp->fsp_name, (double)u_offset, (double)u_count, lock_type_name(lock_type) )); /* * If the requested lock won't fit in the POSIX range, we will @@ -350,17 +350,15 @@ static BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG BOOL ret = True; DEBUG(5,("release_posix_lock: File %s, offset = %.0f, count = %.0f\n", - fsp->fsp_name, (double)offset, (double)count )); + fsp->fsp_name, (double)u_offset, (double)u_count )); if(u_count == 0) { /* * This lock must overlap with an existing read-only lock - * help by another fd. Just decrement the count but don't - * do any POSIX call. + * help by another fd. Don't do any POSIX call. */ - fsp->num_posix_locks--; return True; } @@ -374,10 +372,7 @@ static BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG ret = fcntl_lock(fsp->fd,SMB_F_SETLK,offset,count,F_UNLCK); - if(ret) - fsp->num_posix_locks--; - - return True; + return ret; } /**************************************************************************** @@ -565,6 +560,8 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, fsp->num_posix_locks--; + SMB_ASSERT(fsp->num_posix_locks >= 0); + return True; /* Did unlock */ } -- cgit From 3d3c50326ba7f32ebb2fc683a3410dc0d1f18cdc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Apr 2000 21:12:33 +0000 Subject: Did the rewrite Andrew wanted where all knowledge of POSIX locking is removed from the smbd/open.c code. We now use a dlink list of structures indexed by dev/inode to store all pending fd's for close. This could be rewritten to use lib/hash.c if this is discovered to be too slow in use. Andrew, please take a look and let me know if this is what you had in mind. Jeremy. (This used to be commit 0487841120a7584da9a2b83b9574562c415d7024) --- source3/locking/locking.c | 184 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 179 insertions(+), 5 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index b61e8acedc..9d407bf16b 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -2,7 +2,8 @@ Unix SMB/Netbios implementation. Version 3.0 Locking functions - Copyright (C) Andrew Tridgell 1992-1999 + Copyright (C) Andrew Tridgell 1992-2000 + Copyright (C) Jeremy Allison 1992-2000 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,6 +31,8 @@ support. rewrtten completely to use new tdb code. Tridge, Dec '99 + + Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000. */ #include "includes.h" @@ -40,6 +43,179 @@ static TDB_CONTEXT *tdb; int global_smbpid; +/* + * Doubly linked list to hold pending closes needed for + * POSIX locks. This may be changed to use a hash table (as + * in lib/hash.c if this is too slow in use.... JRA. + */ + +struct pending_closes { + struct pending_closes *next; + struct pending_closes *prev; + SMB_DEV_T dev; + SMB_INO_T inode; + int num_posix_locks; + size_t fd_array_size; + int *fd_array; +}; + +static struct pending_closes *pending_close_list = NULL; + +/**************************************************************************** + Find a dev/inode pair in the pending close list. +****************************************************************************/ + +static struct pending_closes *find_pending_close_entry(SMB_DEV_T dev, SMB_INO_T inode) +{ + struct pending_closes *pc; + + for(pc = pending_close_list; pc; pc = pc->next) { + if (dev == pc->dev && inode == pc->inode) { + DLIST_PROMOTE(pending_close_list,pc); + return pc; + } + } + + return NULL; +} + +/**************************************************************************** + Add an fd into the pending close array. +****************************************************************************/ + +static BOOL add_fd_to_close_entry(struct pending_closes *pc, int fd) +{ + if ((pc->fd_array = (int *)Realloc(pc->fd_array, (pc->fd_array_size + 1)*sizeof(int))) == NULL) { + DEBUG(0,("add_fd_to_close_entry: Unable to increase fd_array !\n")); + return False; + } + + pc->fd_array[pc->fd_array_size] = fd; + pc->fd_array_size++; + + DEBUG(10,("add_fd_to_close_entry: added fd = %d, size = %u : dev = %.0f, ino = %.0f\n", + fd, (unsigned int)pc->fd_array_size, (double)pc->dev, (double)pc->inode )); + + return True; +} + +/**************************************************************************** + Deal with pending closes needed by POSIX locking support. +****************************************************************************/ + +BOOL fd_close_posix_locks(struct connection_struct *conn, files_struct *fsp) +{ + struct pending_closes *pc; + int saved_errno = 0; + size_t i; + + if (!lp_posix_locking(SNUM(conn))) + return True; + + pc = find_pending_close_entry(fsp->dev, fsp->inode); + + if (!pc) { + /* + * No other open with a POSIX lock on this dev/inode within this smbd. + * Just exit. + */ + return True; + } + + if (pc->num_posix_locks) { + /* + * There are outstanding locks on this dev/inode pair. + * Add our fd to the list and set fsp->fd to -1 to + * stop the close. + */ + + if (!add_fd_to_close_entry(pc, fsp->fd)) + return False; + + fsp->fd = -1; + return True; + } + + DEBUG(10,("fd_close_posix_locks: doing close on %u fd's.\n", (unsigned int)pc->fd_array_size )); + + /* + * This is the last close. If there are pending fd's close them + * now. Save the errno just in case. + */ + + for(i = 0; i < pc->fd_array_size; i++) { + if (pc->fd_array[i] != -1) { + if (conn->vfs_ops.close(pc->fd_array[i]) == -1) { + saved_errno = errno; + } + } + } + + if (pc->fd_array) + free((char *)pc->fd_array); + + DLIST_REMOVE(pending_close_list, pc); + + free((char *)pc); + + if (saved_errno != 0) { + errno = saved_errno; + } + + return True; +} + +/**************************************************************************** + A POSIX lock was granted. Increment the lock list count (create if needed). +****************************************************************************/ + +static void increment_posix_lock_list(files_struct *fsp) +{ + struct pending_closes *pc; + + if ((pc = find_pending_close_entry(fsp->dev, fsp->inode)) == NULL) { + if (!(pc = (struct pending_closes *)malloc(sizeof(struct pending_closes)))) { + DEBUG(0,("increment_lock_list: malloc fail.\n")); + return; + } + ZERO_STRUCTP(pc); + pc->dev = fsp->dev; + pc->inode = fsp->inode; + DLIST_ADD(pending_close_list, pc); + + DEBUG(10,("increment_posix_lock_list: creating entry for file %s: dev = %.0f, ino = %.0f\n", + fsp->fsp_name, (double)fsp->dev, (double)fsp->inode )); + } + + pc->num_posix_locks++; + + DEBUG(10,("increment_posix_lock_list: entry for file %s: dev = %.0f, ino = %.0f, num_locks = %d\n", + fsp->fsp_name, (double)pc->dev, (double)pc->inode, pc->num_posix_locks )); +} + + +/**************************************************************************** + A POSIX lock was granted. Decrement the lock list count. +****************************************************************************/ + +static void decrement_posix_lock_list(files_struct *fsp) +{ + struct pending_closes *pc; + + pc = find_pending_close_entry(fsp->dev, fsp->inode); + + if (pc == NULL) { + smb_panic("decrement_lock_list: Unlock not found !\n"); + } + + pc->num_posix_locks--; + + DEBUG(10,("decrement_posix_lock_list: entry for file %s: dev = %.0f, ino = %.0f, num_locks = %d\n", + fsp->fsp_name, (double)pc->dev, (double)pc->inode, pc->num_posix_locks )); + + SMB_ASSERT(pc->num_posix_locks >= 0); +} + /**************************************************************************** Debugging aid :-). ****************************************************************************/ @@ -444,7 +620,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, */ if((ok = set_posix_lock(fsp, offset, count, lock_type)) == True) - fsp->num_posix_locks++; + increment_posix_lock_list(fsp); else { /* * We failed to map - we must now remove the brl @@ -558,9 +734,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, * if it may have been split into multiple smaller POSIX unlock ranges. */ - fsp->num_posix_locks--; - - SMB_ASSERT(fsp->num_posix_locks >= 0); + decrement_posix_lock_list(fsp); return True; /* Did unlock */ } -- cgit From 36db78fedad935aaa689d52d7f58e075f1f71812 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Apr 2000 22:23:04 +0000 Subject: Fixed subtle unlocking bug when a file is closed. We need to store the smbpid used when a file was opened in the files_struct. Else we use the wrong global_smbpid when we are closing the file and trying to remove the brl locks - this causes the brl locks to be left when the file is closed as the samba_context check fails. Jeremy. (This used to be commit 2746e5602e493e5b022764b4b839eb4d2f14363b) --- source3/locking/locking.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 9d407bf16b..b6b34138e3 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -41,8 +41,6 @@ extern int DEBUGLEVEL; /* the locking database handle */ static TDB_CONTEXT *tdb; -int global_smbpid; - /* * Doubly linked list to hold pending closes needed for * POSIX locks. This may be changed to use a hash table (as @@ -569,7 +567,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, return(False); ret = !brl_locktest(fsp->dev, fsp->inode, - global_smbpid, getpid(), conn->cnum, + fsp->smbpid, getpid(), conn->cnum, offset, count, lock_type); /* @@ -607,7 +605,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) { ok = brl_lock(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, getpid(), conn->cnum, + fsp->smbpid, getpid(), conn->cnum, offset, count, lock_type); @@ -627,7 +625,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, * lock entry. */ (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, getpid(), conn->cnum, + fsp->smbpid, getpid(), conn->cnum, offset, count); } } @@ -676,9 +674,10 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, pid = getpid(); ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, pid, conn->cnum, offset, count); + fsp->smbpid, pid, conn->cnum, offset, count); if (!ok) { + DEBUG(10,("do_unlock: returning ERRlock.\n" )); *eclass = ERRDOS; *ecode = ERRlock; return False; -- cgit From 4b60a33c6fa733060068e192b87c2e858103d6eb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Apr 2000 23:28:56 +0000 Subject: Ok - this is more subtle than it looks :-). When a file is being closed, once it passes the fnum and tid tests then the locking context should be ignored when removing all locks. This is what is done in the brl close case, but when you have outstanding POSIX locks, then you cannot remove all the brl locks in one go, you have to get the lock list and call do_unlock individually. As this uses global_smbpid as the locking context, you need to make sure that this is set correctly for the specific lock being removed. I now do this by storing the smbpid in each entry in the unlock list returned from the query call. I removed the smbpid from fsp (not needed) and things seem ok (even with the stupid smbpid tricks that smbtorture plays :-). Jeremy. (This used to be commit 6baa96bb466915cc17e8cbad50254d6bd47b967b) --- source3/locking/locking.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index b6b34138e3..088693b6d4 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -37,6 +37,7 @@ #include "includes.h" extern int DEBUGLEVEL; +int global_smbpid; /* the locking database handle */ static TDB_CONTEXT *tdb; @@ -567,7 +568,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, return(False); ret = !brl_locktest(fsp->dev, fsp->inode, - fsp->smbpid, getpid(), conn->cnum, + global_smbpid, getpid(), conn->cnum, offset, count, lock_type); /* @@ -605,7 +606,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) { ok = brl_lock(fsp->dev, fsp->inode, fsp->fnum, - fsp->smbpid, getpid(), conn->cnum, + global_smbpid, getpid(), conn->cnum, offset, count, lock_type); @@ -625,7 +626,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, * lock entry. */ (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - fsp->smbpid, getpid(), conn->cnum, + global_smbpid, getpid(), conn->cnum, offset, count); } } @@ -674,7 +675,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, pid = getpid(); ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - fsp->smbpid, pid, conn->cnum, offset, count); + global_smbpid, pid, conn->cnum, offset, count); if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); @@ -705,6 +706,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, ZERO_STRUCTP(ul); ul->start = offset; ul->size = count; + ul->smbpid = global_smbpid; DLIST_ADD(ulist, ul); @@ -770,12 +772,16 @@ void locking_close_file(files_struct *fsp) /* * Now unlock all of them. This will remove the brl entry also - * for each lock. + * for each lock. Note we need to make sure the global_smbpid matches + * the one associated with each lock in case the client plays games + * with smbpids (like smbtorture does :-). */ - for(; ul; ul = ul->next) + for(; ul; ul = ul->next) { + global_smbpid = ul->smbpid; do_unlock(fsp,fsp->conn,ul->size,ul->start,&eclass,&ecode); - + } + talloc_destroy(ul_ctx); } else { -- cgit From be828fcec88a43306ddfb53473fda52df1d9965b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Apr 2000 00:39:23 +0000 Subject: Made changes suggested by Andrew review. fd_close now calls fd_close_posix() directly. set_posix_lock/release_posix_lock() now handle the reference counting. More changes due when this gets moved to the file locking/posix.c Jeremy. (This used to be commit 239abd48f049c6a8d2bbc0636eacf347ab77588c) --- source3/locking/locking.c | 89 +++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 37 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 088693b6d4..d69ab18006 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -102,10 +102,11 @@ static BOOL add_fd_to_close_entry(struct pending_closes *pc, int fd) Deal with pending closes needed by POSIX locking support. ****************************************************************************/ -BOOL fd_close_posix_locks(struct connection_struct *conn, files_struct *fsp) +int fd_close_posix(struct connection_struct *conn, files_struct *fsp) { struct pending_closes *pc; int saved_errno = 0; + int ret; size_t i; if (!lp_posix_locking(SNUM(conn))) @@ -116,9 +117,11 @@ BOOL fd_close_posix_locks(struct connection_struct *conn, files_struct *fsp) if (!pc) { /* * No other open with a POSIX lock on this dev/inode within this smbd. - * Just exit. + * Just close the fd. */ - return True; + ret = conn->vfs_ops.close(fsp->fd); + fsp->fd = -1; + return ret; } if (pc->num_posix_locks) { @@ -132,10 +135,10 @@ BOOL fd_close_posix_locks(struct connection_struct *conn, files_struct *fsp) return False; fsp->fd = -1; - return True; + return 0; } - DEBUG(10,("fd_close_posix_locks: doing close on %u fd's.\n", (unsigned int)pc->fd_array_size )); + DEBUG(10,("fd_close_posix: doing close on %u fd's.\n", (unsigned int)pc->fd_array_size )); /* * This is the last close. If there are pending fd's close them @@ -157,11 +160,16 @@ BOOL fd_close_posix_locks(struct connection_struct *conn, files_struct *fsp) free((char *)pc); + ret = conn->vfs_ops.close(fsp->fd); + if (saved_errno != 0) { errno = saved_errno; + ret = -1; } - return True; + fsp->fd = -1; + + return ret; } /**************************************************************************** @@ -497,8 +505,10 @@ static BOOL set_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UIN * pretend it was successful. */ - if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) + if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) { + increment_posix_lock_list(fsp); return True; + } /* * Note that setting multiple overlapping read locks on different @@ -510,42 +520,55 @@ static BOOL set_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UIN ret = fcntl_lock(fsp->fd,SMB_F_SETLK,offset,count,map_posix_lock_type(fsp,lock_type)); + if (ret) + increment_posix_lock_list(fsp); + return ret; } /**************************************************************************** - POSIX function to release a lock. Returns True if the + POSIX function to release a lock given a list. Returns True if the lock could be released, False if not. ****************************************************************************/ -static BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count) +static BOOL release_posix_lock(files_struct *fsp, struct unlock_list *ulist) { - SMB_OFF_T offset; - SMB_OFF_T count; BOOL ret = True; - DEBUG(5,("release_posix_lock: File %s, offset = %.0f, count = %.0f\n", - fsp->fsp_name, (double)u_offset, (double)u_count )); + for(; ulist; ulist = ulist->next) { + SMB_OFF_T offset = ulist->start; + SMB_OFF_T count = ulist->size; + + DEBUG(5,("release_posix_lock: File %s, offset = %.0f, count = %.0f\n", + fsp->fsp_name, (double)offset, (double)count )); + + if(count == 0) { - if(u_count == 0) { + /* + * This lock must overlap with an existing read-only lock + * held by another fd. Don't do any POSIX call. + */ + + continue; + } /* - * This lock must overlap with an existing read-only lock - * help by another fd. Don't do any POSIX call. + * If the requested lock won't fit in the POSIX range, we will + * pretend it was successful. */ - return True; + if(!posix_lock_in_range(&offset, &count, offset, count)) + continue; + + ret = fcntl_lock(fsp->fd,SMB_F_SETLK,offset,count,F_UNLCK); } /* - * If the requested lock won't fit in the POSIX range, we will - * pretend it was successful. - */ - - if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) - return True; + * We treat this as one unlock request for POSIX accounting purposes even + * if it may have been split into multiple smaller POSIX unlock ranges. + */ - ret = fcntl_lock(fsp->fd,SMB_F_SETLK,offset,count,F_UNLCK); + decrement_posix_lock_list(fsp); return ret; } @@ -610,7 +633,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, offset, count, lock_type); - if(ok && lp_posix_locking(SNUM(conn))) { + if (ok && lp_posix_locking(SNUM(conn))) { /* * Try and get a POSIX lock on this range. @@ -618,9 +641,9 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, * overlapping on a different fd. JRA. */ - if((ok = set_posix_lock(fsp, offset, count, lock_type)) == True) - increment_posix_lock_list(fsp); - else { + ok = set_posix_lock(fsp, offset, count, lock_type); + + if (!ok) { /* * We failed to map - we must now remove the brl * lock entry. @@ -725,18 +748,10 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, * Release the POSIX locks on the list of ranges returned. */ - for(; ulist; ulist = ulist->next) - (void)release_posix_lock(fsp, ulist->start, ulist->size); + (void)release_posix_lock(fsp, ulist); talloc_destroy(ul_ctx); - /* - * We treat this as one unlock request for POSIX accounting purposes even - * if it may have been split into multiple smaller POSIX unlock ranges. - */ - - decrement_posix_lock_list(fsp); - return True; /* Did unlock */ } -- cgit From f8e5696bd6d839dee9c98640519efe2f2512df99 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Apr 2000 01:01:07 +0000 Subject: Added optimization where we are single opener (don't free POSIX locks). Jeremy. (This used to be commit a2deb91128d59ad04f4ec858ffe4e30f2afb0edd) --- source3/locking/locking.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d69ab18006..62304076af 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -772,6 +772,26 @@ void locking_close_file(files_struct *fsp) struct unlock_list *ul = NULL; int eclass; uint32 ecode; + struct pending_closes *pc; + + /* + * Optimization for the common case where we are the only + * opener of a file. If all fd entries are our own, we don't + * need to explicitly release all the locks via the POSIX functions, + * we can just release all the brl locks, as in the no POSIX locking case. + */ + + if ((pc = find_pending_close_entry(fsp->dev, fsp->inode)) != NULL) { + + if (pc->fd_array_size == 1 && pc->fd_array[0] == fsp->fd ) { + /* + * Just release all the brl locks, no need to release individually. + */ + + brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum); + return; + } + } if ((ul_ctx = talloc_init()) == NULL) { DEBUG(0,("locking_close_file: unable to init talloc context.\n")); @@ -802,7 +822,7 @@ void locking_close_file(files_struct *fsp) } else { /* - * Just release all the tdb locks, no need to release individually. + * Just release all the brl locks, no need to release individually. */ brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum); -- cgit From 1f7d96ee0310f50af953621a81d335778b0c76dc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Apr 2000 01:08:32 +0000 Subject: Forgot to close when "posix locking" is set to False. Jeremy. (This used to be commit b812f09ba8ef074c9ff0747ea03a1e33f1ebbe71) --- source3/locking/locking.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 62304076af..fa56e0a628 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -109,8 +109,11 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp) int ret; size_t i; - if (!lp_posix_locking(SNUM(conn))) - return True; + if (!lp_posix_locking(SNUM(conn))) { + ret = conn->vfs_ops.close(fsp->fd); + fsp->fd = -1; + return ret; + } pc = find_pending_close_entry(fsp->dev, fsp->inode); -- cgit From 9a5eb068ab32418e793d482db1f078f147f9ee08 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Apr 2000 20:54:23 +0000 Subject: Ok - this is the *third* implementation of this (third time's the charm :-). This implementation keeps all POSIX lock records in a separate in memory tdb database only known about in locking/posix.c. In addition, the pending close fd's are also held in a tdb which has an array of fd's indexed by device and inode. The walk-split code uglyness has been moved to posix.c from brlock.c, which is the only place that needs to know about it, and the extra functions hacked into brlock to expose internal state have been removed. This implementation passes smbtorture locktest4, the only thing I need to check now for completeness is what to do about lock upgrade/downgrades which Win32 allows under some *very* strange circumstances. Jeremy. (This used to be commit 3f655de1c764b9ee1472a111621d4317f19f624d) --- source3/locking/locking.c | 641 +--------------------------------------------- 1 file changed, 13 insertions(+), 628 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index fa56e0a628..75198d6303 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -42,190 +42,6 @@ int global_smbpid; /* the locking database handle */ static TDB_CONTEXT *tdb; -/* - * Doubly linked list to hold pending closes needed for - * POSIX locks. This may be changed to use a hash table (as - * in lib/hash.c if this is too slow in use.... JRA. - */ - -struct pending_closes { - struct pending_closes *next; - struct pending_closes *prev; - SMB_DEV_T dev; - SMB_INO_T inode; - int num_posix_locks; - size_t fd_array_size; - int *fd_array; -}; - -static struct pending_closes *pending_close_list = NULL; - -/**************************************************************************** - Find a dev/inode pair in the pending close list. -****************************************************************************/ - -static struct pending_closes *find_pending_close_entry(SMB_DEV_T dev, SMB_INO_T inode) -{ - struct pending_closes *pc; - - for(pc = pending_close_list; pc; pc = pc->next) { - if (dev == pc->dev && inode == pc->inode) { - DLIST_PROMOTE(pending_close_list,pc); - return pc; - } - } - - return NULL; -} - -/**************************************************************************** - Add an fd into the pending close array. -****************************************************************************/ - -static BOOL add_fd_to_close_entry(struct pending_closes *pc, int fd) -{ - if ((pc->fd_array = (int *)Realloc(pc->fd_array, (pc->fd_array_size + 1)*sizeof(int))) == NULL) { - DEBUG(0,("add_fd_to_close_entry: Unable to increase fd_array !\n")); - return False; - } - - pc->fd_array[pc->fd_array_size] = fd; - pc->fd_array_size++; - - DEBUG(10,("add_fd_to_close_entry: added fd = %d, size = %u : dev = %.0f, ino = %.0f\n", - fd, (unsigned int)pc->fd_array_size, (double)pc->dev, (double)pc->inode )); - - return True; -} - -/**************************************************************************** - Deal with pending closes needed by POSIX locking support. -****************************************************************************/ - -int fd_close_posix(struct connection_struct *conn, files_struct *fsp) -{ - struct pending_closes *pc; - int saved_errno = 0; - int ret; - size_t i; - - if (!lp_posix_locking(SNUM(conn))) { - ret = conn->vfs_ops.close(fsp->fd); - fsp->fd = -1; - return ret; - } - - pc = find_pending_close_entry(fsp->dev, fsp->inode); - - if (!pc) { - /* - * No other open with a POSIX lock on this dev/inode within this smbd. - * Just close the fd. - */ - ret = conn->vfs_ops.close(fsp->fd); - fsp->fd = -1; - return ret; - } - - if (pc->num_posix_locks) { - /* - * There are outstanding locks on this dev/inode pair. - * Add our fd to the list and set fsp->fd to -1 to - * stop the close. - */ - - if (!add_fd_to_close_entry(pc, fsp->fd)) - return False; - - fsp->fd = -1; - return 0; - } - - DEBUG(10,("fd_close_posix: doing close on %u fd's.\n", (unsigned int)pc->fd_array_size )); - - /* - * This is the last close. If there are pending fd's close them - * now. Save the errno just in case. - */ - - for(i = 0; i < pc->fd_array_size; i++) { - if (pc->fd_array[i] != -1) { - if (conn->vfs_ops.close(pc->fd_array[i]) == -1) { - saved_errno = errno; - } - } - } - - if (pc->fd_array) - free((char *)pc->fd_array); - - DLIST_REMOVE(pending_close_list, pc); - - free((char *)pc); - - ret = conn->vfs_ops.close(fsp->fd); - - if (saved_errno != 0) { - errno = saved_errno; - ret = -1; - } - - fsp->fd = -1; - - return ret; -} - -/**************************************************************************** - A POSIX lock was granted. Increment the lock list count (create if needed). -****************************************************************************/ - -static void increment_posix_lock_list(files_struct *fsp) -{ - struct pending_closes *pc; - - if ((pc = find_pending_close_entry(fsp->dev, fsp->inode)) == NULL) { - if (!(pc = (struct pending_closes *)malloc(sizeof(struct pending_closes)))) { - DEBUG(0,("increment_lock_list: malloc fail.\n")); - return; - } - ZERO_STRUCTP(pc); - pc->dev = fsp->dev; - pc->inode = fsp->inode; - DLIST_ADD(pending_close_list, pc); - - DEBUG(10,("increment_posix_lock_list: creating entry for file %s: dev = %.0f, ino = %.0f\n", - fsp->fsp_name, (double)fsp->dev, (double)fsp->inode )); - } - - pc->num_posix_locks++; - - DEBUG(10,("increment_posix_lock_list: entry for file %s: dev = %.0f, ino = %.0f, num_locks = %d\n", - fsp->fsp_name, (double)pc->dev, (double)pc->inode, pc->num_posix_locks )); -} - - -/**************************************************************************** - A POSIX lock was granted. Decrement the lock list count. -****************************************************************************/ - -static void decrement_posix_lock_list(files_struct *fsp) -{ - struct pending_closes *pc; - - pc = find_pending_close_entry(fsp->dev, fsp->inode); - - if (pc == NULL) { - smb_panic("decrement_lock_list: Unlock not found !\n"); - } - - pc->num_posix_locks--; - - DEBUG(10,("decrement_posix_lock_list: entry for file %s: dev = %.0f, ino = %.0f, num_locks = %d\n", - fsp->fsp_name, (double)pc->dev, (double)pc->inode, pc->num_posix_locks )); - - SMB_ASSERT(pc->num_posix_locks >= 0); -} - /**************************************************************************** Debugging aid :-). ****************************************************************************/ @@ -235,347 +51,6 @@ static const char *lock_type_name(enum brl_type lock_type) return (lock_type == READ_LOCK) ? "READ" : "WRITE"; } -/**************************************************************************** - Utility function to map a lock type correctly depending on the open - mode of a file. -****************************************************************************/ - -static int map_posix_lock_type( files_struct *fsp, enum brl_type lock_type) -{ - if((lock_type == WRITE_LOCK) && !fsp->can_write) { - /* - * Many UNIX's cannot get a write lock on a file opened read-only. - * Win32 locking semantics allow this. - * Do the best we can and attempt a read-only lock. - */ - DEBUG(10,("map_posix_lock_type: Downgrading write lock to read due to read-only file.\n")); - return F_RDLCK; - } else if((lock_type == READ_LOCK) && !fsp->can_read) { - /* - * Ditto for read locks on write only files. - */ - DEBUG(10,("map_posix_lock_type: Changing read lock to write due to write-only file.\n")); - return F_WRLCK; - } - - /* - * This return should be the most normal, as we attempt - * to always open files read/write. - */ - - return (lock_type == READ_LOCK) ? F_RDLCK : F_WRLCK; -} - -/**************************************************************************** - 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 *offset_out, SMB_OFF_T *count_out, - SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count) -{ - SMB_OFF_T offset; - SMB_OFF_T count; - -#if defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS) - - SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4); - SMB_OFF_T mask = (mask2<<1); - SMB_OFF_T neg_mask = ~mask; - - /* - * In this case SMB_OFF_T is 64 bits, - * and the underlying system can handle 64 bit signed locks. - * Cast to signed type. - */ - - offset = (SMB_OFF_T)u_offset; - count = (SMB_OFF_T)u_count; - - /* - * Deal with a very common case of count of all ones. - * (lock entire file). - */ - - if(count == (SMB_OFF_T)-1) - count &= ~mask; - - /* - * POSIX lock ranges cannot be negative. - * Fail if any combination becomes negative. - */ - - if(offset < 0 || count < 0 || (offset + count < 0)) { - DEBUG(10,("posix_lock_in_range: negative range: offset = %.0f, count = %.0f. Ignoring lock.\n", - (double)offset, (double)count )); - return False; - } - - /* - * In this case SMB_OFF_T is 64 bits, the offset and count - * fit within the positive range, and the underlying - * system can handle 64 bit locks. Just return as the - * cast values are ok. - */ - -#else /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */ - - /* - * In this case either SMB_OFF_T is 32 bits, - * or the underlying system cannot handle 64 bit signed locks. - * Either way we have to try and mangle to fit within 31 bits. - * This is difficult. - */ - -#if defined(HAVE_BROKEN_FCNTL64_LOCKS) - - /* - * SMB_OFF_T is 64 bits, but we need to use 31 bits due to - * broken large locking. - */ - - /* - * Deal with a very common case of count of all ones. - * (lock entire file). - */ - - if(u_count == (SMB_BIG_UINT)-1) - count = 0x7FFFFFFF; - - if(((u_offset >> 32) & 0xFFFFFFFF) || ((u_count >> 32) & 0xFFFFFFFF)) { - DEBUG(10,("posix_lock_in_range: top 32 bits not zero. offset = %.0f, count = %.0f. Ignoring lock.\n", - (double)u_offset, (double)u_count )); - /* Top 32 bits of offset or count were not zero. */ - return False; - } - - /* Cast from 64 bits unsigned to 64 bits signed. */ - offset = (SMB_OFF_T)u_offset; - count = (SMB_OFF_T)u_count; - - /* - * Check if we are within the 2^31 range. - */ - - { - int32 low_offset = (int32)offset; - int32 low_count = (int32)count; - - if(low_offset < 0 || low_count < 0 || (low_offset + low_count < 0)) { - DEBUG(10,("posix_lock_in_range: not within 2^31 range. low_offset = %d, low_count = %d. Ignoring lock.\n", - low_offset, low_count )); - return False; - } - } - - /* - * Ok - we can map from a 64 bit number to a 31 bit lock. - */ - -#else /* HAVE_BROKEN_FCNTL64_LOCKS */ - - /* - * SMB_OFF_T is 32 bits. - */ - -#if defined(HAVE_LONGLONG) - - /* - * SMB_BIG_UINT is 64 bits, we can do a 32 bit shift. - */ - - /* - * Deal with a very common case of count of all ones. - * (lock entire file). - */ - - if(u_count == (SMB_BIG_UINT)-1) - count = 0x7FFFFFFF; - - if(((u_offset >> 32) & 0xFFFFFFFF) || ((u_count >> 32) & 0xFFFFFFFF)) { - DEBUG(10,("posix_lock_in_range: top 32 bits not zero. u_offset = %.0f, u_count = %.0f. Ignoring lock.\n", - (double)u_offset, (double)u_count )); - return False; - } - - /* Cast from 64 bits unsigned to 32 bits signed. */ - offset = (SMB_OFF_T)u_offset; - count = (SMB_OFF_T)u_count; - - /* - * Check if we are within the 2^31 range. - */ - - if(offset < 0 || count < 0 || (offset + count < 0)) { - DEBUG(10,("posix_lock_in_range: not within 2^31 range. offset = %d, count = %d. Ignoring lock.\n", - (int)offset, (int)count )); - return False; - } - -#else /* HAVE_LONGLONG */ - - /* - * SMB_BIG_UINT and SMB_OFF_T are both 32 bits, - * just cast. - */ - - /* - * Deal with a very common case of count of all ones. - * (lock entire file). - */ - - if(u_count == (SMB_BIG_UINT)-1) - count = 0x7FFFFFFF; - - /* Cast from 32 bits unsigned to 32 bits signed. */ - offset = (SMB_OFF_T)u_offset; - count = (SMB_OFF_T)u_count; - - /* - * Check if we are within the 2^31 range. - */ - - if(offset < 0 || count < 0 || (offset + count < 0)) { - DEBUG(10,("posix_lock_in_range: not within 2^31 range. offset = %d, count = %d. Ignoring lock.\n", - (int)offset, (int)count )); - return False; - } - -#endif /* HAVE_LONGLONG */ -#endif /* LARGE_SMB_OFF_T */ -#endif /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */ - - /* - * The mapping was successful. - */ - - DEBUG(10,("posix_lock_in_range: offset_out = %.0f, count_out = %.0f\n", - (double)offset, (double)count )); - - *offset_out = offset; - *count_out = count; - - return True; -} - -/**************************************************************************** - POSIX function to see if a file region is locked. Returns True if the - region is locked, False otherwise. -****************************************************************************/ - -static BOOL is_posix_locked(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 count; - - DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, type = %s\n", - fsp->fsp_name, (double)u_offset, (double)u_count, lock_type_name(lock_type) )); - - /* - * If the requested lock won't fit in the POSIX range, we will - * never set it, so presume it is not locked. - */ - - if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) - return False; - - /* - * Note that most UNIX's can *test* for a write lock on - * a read-only fd, just not *set* a write lock on a read-only - * fd. So we don't need to use map_lock_type here. - */ - - return fcntl_lock(fsp->fd,SMB_F_GETLK,offset,count,lock_type); -} - -/**************************************************************************** - POSIX function to acquire a lock. Returns True if the - lock could be granted, False if not. -****************************************************************************/ - -static BOOL set_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 count; - BOOL ret = True; - - DEBUG(5,("set_posix_lock: File %s, offset = %.0f, count = %.0f, type = %s\n", - fsp->fsp_name, (double)u_offset, (double)u_count, lock_type_name(lock_type) )); - - /* - * If the requested lock won't fit in the POSIX range, we will - * pretend it was successful. - */ - - if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) { - increment_posix_lock_list(fsp); - return True; - } - - /* - * Note that setting multiple overlapping read locks on different - * file descriptors will not be held separately by the kernel (POSIX - * braindamage), but will be merged into one continuous read lock - * range. We cope with this case in the release_posix_lock code - * below. JRA. - */ - - ret = fcntl_lock(fsp->fd,SMB_F_SETLK,offset,count,map_posix_lock_type(fsp,lock_type)); - - if (ret) - increment_posix_lock_list(fsp); - - return ret; -} - -/**************************************************************************** - POSIX function to release a lock given a list. Returns True if the - lock could be released, False if not. -****************************************************************************/ - -static BOOL release_posix_lock(files_struct *fsp, struct unlock_list *ulist) -{ - BOOL ret = True; - - for(; ulist; ulist = ulist->next) { - SMB_OFF_T offset = ulist->start; - SMB_OFF_T count = ulist->size; - - DEBUG(5,("release_posix_lock: File %s, offset = %.0f, count = %.0f\n", - fsp->fsp_name, (double)offset, (double)count )); - - if(count == 0) { - - /* - * This lock must overlap with an existing read-only lock - * held by another fd. Don't do any POSIX call. - */ - - continue; - } - - /* - * If the requested lock won't fit in the POSIX range, we will - * pretend it was successful. - */ - - if(!posix_lock_in_range(&offset, &count, offset, count)) - continue; - - ret = fcntl_lock(fsp->fd,SMB_F_SETLK,offset,count,F_UNLCK); - } - - /* - * We treat this as one unlock request for POSIX accounting purposes even - * if it may have been split into multiple smaller POSIX unlock ranges. - */ - - decrement_posix_lock_list(fsp); - - return ret; -} - /**************************************************************************** Utility function called to see if a file region is locked. ****************************************************************************/ @@ -675,10 +150,6 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, int *eclass,uint32 *ecode) { BOOL ok = False; - TALLOC_CTX *ul_ctx = NULL; - struct unlock_list *ulist = NULL; - struct unlock_list *ul = NULL; - pid_t pid; if (!lp_locking(SNUM(conn))) return(True); @@ -698,10 +169,8 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, * match then don't bother looking to remove POSIX locks. */ - pid = getpid(); - ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, pid, conn->cnum, offset, count); + global_smbpid, getpid(), conn->cnum, offset, count); if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); @@ -713,47 +182,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, if (!lp_posix_locking(SNUM(conn))) return True; - if ((ul_ctx = talloc_init()) == NULL) { - DEBUG(0,("do_unlock: unable to init talloc context.\n")); - return True; /* Not a fatal error. */ - } - - if ((ul = (struct unlock_list *)talloc(ul_ctx, sizeof(struct unlock_list))) == NULL) { - DEBUG(0,("do_unlock: unable to talloc unlock list.\n")); - talloc_destroy(ul_ctx); - return True; /* Not a fatal error. */ - } - - /* - * Create the initial list entry containing the - * lock we want to remove. - */ - - ZERO_STRUCTP(ul); - ul->start = offset; - ul->size = count; - ul->smbpid = global_smbpid; - - DLIST_ADD(ulist, ul); - - /* - * The following call calculates if there are any - * overlapping read locks held by this process on - * other fd's open on the same file and creates a - * list of unlock ranges that will allow other - * POSIX lock ranges to remain on the file whilst the - * unlocks are performed. - */ - - ulist = brl_unlock_list(ul_ctx, ulist, pid, fsp->dev, fsp->inode); - - /* - * Release the POSIX locks on the list of ranges returned. - */ - - (void)release_posix_lock(fsp, ulist); - - talloc_destroy(ul_ctx); + (void)release_posix_lock(fsp, offset, count); return True; /* Did unlock */ } @@ -769,66 +198,19 @@ void locking_close_file(files_struct *fsp) if (!lp_locking(SNUM(fsp->conn))) return; - if(lp_posix_locking(SNUM(fsp->conn))) { - - TALLOC_CTX *ul_ctx = NULL; - struct unlock_list *ul = NULL; - int eclass; - uint32 ecode; - struct pending_closes *pc; - - /* - * Optimization for the common case where we are the only - * opener of a file. If all fd entries are our own, we don't - * need to explicitly release all the locks via the POSIX functions, - * we can just release all the brl locks, as in the no POSIX locking case. - */ - - if ((pc = find_pending_close_entry(fsp->dev, fsp->inode)) != NULL) { - - if (pc->fd_array_size == 1 && pc->fd_array[0] == fsp->fd ) { - /* - * Just release all the brl locks, no need to release individually. - */ - - brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum); - return; - } - } - - if ((ul_ctx = talloc_init()) == NULL) { - DEBUG(0,("locking_close_file: unable to init talloc context.\n")); - return; - } - - /* - * We need to release all POSIX locks we have on this - * fd. Get all our existing locks from the tdb locking database. - */ - - ul = brl_getlocklist(ul_ctx, fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum); - - /* - * Now unlock all of them. This will remove the brl entry also - * for each lock. Note we need to make sure the global_smbpid matches - * the one associated with each lock in case the client plays games - * with smbpids (like smbtorture does :-). - */ + /* + * Just release all the brl locks, no need to release individually. + */ - for(; ul; ul = ul->next) { - global_smbpid = ul->smbpid; - do_unlock(fsp,fsp->conn,ul->size,ul->start,&eclass,&ecode); - } - - talloc_destroy(ul_ctx); + brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum); - } else { + if(lp_posix_locking(SNUM(fsp->conn))) { - /* - * Just release all the brl locks, no need to release individually. + /* + * Release all the POSIX locks. */ + posix_locking_close_file(fsp); - brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum); } } @@ -851,6 +233,9 @@ BOOL locking_init(int read_only) return False; } + if (!posix_locking_init()) + return False; + return True; } -- cgit From 693ffb8466ada58ecc59fde754ba79fc6f51528d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 2 May 2000 02:23:41 +0000 Subject: Added sys_fork() and sys_getpid() functions to stop the overhead of doing a system call every time we want to just get our pid. Jeremy. (This used to be commit 148628b616b5c29ba6340d65fc3ddbcabba6e67a) --- source3/locking/locking.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 75198d6303..47ae917f9a 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -69,7 +69,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, return(False); ret = !brl_locktest(fsp->dev, fsp->inode, - global_smbpid, getpid(), conn->cnum, + global_smbpid, sys_getpid(), conn->cnum, offset, count, lock_type); /* @@ -107,7 +107,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) { ok = brl_lock(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, getpid(), conn->cnum, + global_smbpid, sys_getpid(), conn->cnum, offset, count, lock_type); @@ -127,7 +127,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, * lock entry. */ (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, getpid(), conn->cnum, + global_smbpid, sys_getpid(), conn->cnum, offset, count); } } @@ -170,7 +170,7 @@ 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); + global_smbpid, sys_getpid(), conn->cnum, offset, count); if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); @@ -193,7 +193,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, void locking_close_file(files_struct *fsp) { - pid_t pid = getpid(); + pid_t pid = sys_getpid(); if (!lp_locking(SNUM(fsp->conn))) return; @@ -337,7 +337,7 @@ void del_share_mode(files_struct *fsp) struct locking_data *data; int i, del_count=0; share_mode_entry *shares; - pid_t pid = getpid(); + pid_t pid = sys_getpid(); /* read in the existing share modes */ dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); @@ -380,7 +380,7 @@ fill a share mode entry static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_type) { share_mode_entry *e = (share_mode_entry *)p; - e->pid = getpid(); + e->pid = sys_getpid(); e->share_mode = fsp->share_mode; e->op_port = port; e->op_type = op_type; @@ -453,7 +453,7 @@ static BOOL mod_share_mode(files_struct *fsp, struct locking_data *data; int i; share_mode_entry *shares; - pid_t pid = getpid(); + pid_t pid = sys_getpid(); int need_store=0; /* read in the existing share modes */ -- cgit From 6d9ce383061782b888f4b3403099a3c2c34b1a4c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 May 2000 20:50:22 +0000 Subject: Fix for uninitialized memory read in brlock code. brl_locktest now needs to correctly set the fnum, as the brl_conflict code looks at it. Jeremy. (This used to be commit df87259a356b91989604a10b3691480dcd16cf3f) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 47ae917f9a..07411e8919 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -68,7 +68,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, if (!lp_locking(snum) || !lp_strict_locking(snum)) return(False); - ret = !brl_locktest(fsp->dev, fsp->inode, + ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum, global_smbpid, sys_getpid(), conn->cnum, offset, count, lock_type); -- cgit From e522de480891b9d72ba4cd2d4c8decb6909809a9 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 10 May 2000 00:05:27 +0000 Subject: Using a structure for a tdb key can lead to insideous, hard to find bugs. On 64 bit IRIX, structure packing means that a struct { SMB_DEV_T dev /* 4 bytes */ SMB_INO_T ino /* 8 bytes */ } has 4 bytes of padding between the two members. If you don't null the memory before using it as a tdb key, you randomly can't find keys depending on what is in the padding. This caused me immense pain and was hard to track down.... :-) Jeremy. (This used to be commit f2a5ba3f0939f59097f0ef6a25f1cf9b5574f157) --- source3/locking/locking.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 07411e8919..302b5b56c9 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -255,6 +255,8 @@ static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode) { static struct locking_key key; TDB_DATA kbuf; + + memset(&key, '\0', sizeof(key)); key.dev = dev; key.inode = inode; kbuf.dptr = (char *)&key; -- cgit From b50ca095af232be3a88231965449a836e5321db5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Jun 2000 15:46:46 +0000 Subject: allow posix locking database to be opened read-only (for smbstatus) (This used to be commit b9d78738bb30da3d989dfacc95cfde529f2afca5) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 302b5b56c9..8fc1c4a4bc 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -233,7 +233,7 @@ BOOL locking_init(int read_only) return False; } - if (!posix_locking_init()) + if (!posix_locking_init(read_only)) return False; return True; -- cgit From 3689e4ffc10fceb4c39814ef58fe31697e7dd976 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 Sep 2000 07:02:43 +0000 Subject: the first cut of the internal messaging system. The motivation for this system is to replace the UDP message for oplocks, but this commit only does the "set debug level" message. (This used to be commit 2a34ee95f3929cff131db6c5a2b4820194c05b2d) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 8fc1c4a4bc..58e6b06e66 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -229,7 +229,7 @@ BOOL locking_init(int read_only) 0644); if (!tdb) { - DEBUG(0,("ERROR: Failed to initialise share modes\n")); + DEBUG(0,("ERROR: Failed to initialise locking database\n")); return False; } -- cgit From 7e4c4721b4fbfa71ce6712ec5b9f3e8e8a105147 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 6 Dec 2000 00:05:15 +0000 Subject: Changed to sourceforge tdb code. This includes spinlocks (so we now have a --with-spinlocks option to configure, this does mean the on-disk tdb format has changed, so 2.2alphaX sites will need to re-create their tdb's. The upside is no more tdb fragmentation and a +5% on netbench. Swings and roundabouts.... Jeremy. (This used to be commit 9dea7b7c257db487f8ced7dad3fce92fba03ea91) --- source3/locking/locking.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 58e6b06e66..2056e6dcf5 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -274,7 +274,7 @@ static TDB_DATA locking_key_fsp(files_struct *fsp) BOOL lock_share_entry(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode) { - return tdb_lockchain(tdb, locking_key(dev, inode)) == 0; + return tdb_chainlock(tdb, locking_key(dev, inode)) == 0; } /******************************************************************* @@ -283,7 +283,7 @@ BOOL lock_share_entry(connection_struct *conn, BOOL unlock_share_entry(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode) { - return tdb_unlockchain(tdb, locking_key(dev, inode)) == 0; + return tdb_chainunlock(tdb, locking_key(dev, inode)) == 0; } @@ -292,7 +292,7 @@ BOOL unlock_share_entry(connection_struct *conn, ******************************************************************/ BOOL lock_share_entry_fsp(files_struct *fsp) { - return tdb_lockchain(tdb, locking_key(fsp->dev, fsp->inode)) == 0; + return tdb_chainlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0; } /******************************************************************* @@ -300,7 +300,7 @@ BOOL lock_share_entry_fsp(files_struct *fsp) ******************************************************************/ BOOL unlock_share_entry_fsp(files_struct *fsp) { - return tdb_unlockchain(tdb, locking_key(fsp->dev, fsp->inode)) == 0; + return tdb_chainunlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0; } /******************************************************************* -- cgit From a58ca91245334515fbc0132ab72772bb067a8131 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 6 Dec 2000 02:51:13 +0000 Subject: tdb_unlockchain() no longer returns a value (This used to be commit aee52c7acf138f8fd651aeb3d9bef79f99d1a2a9) --- source3/locking/locking.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 2056e6dcf5..b3601e8752 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -280,10 +280,10 @@ BOOL lock_share_entry(connection_struct *conn, /******************************************************************* Unlock a hash bucket entry. ******************************************************************/ -BOOL unlock_share_entry(connection_struct *conn, +void unlock_share_entry(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode) { - return tdb_chainunlock(tdb, locking_key(dev, inode)) == 0; + tdb_chainunlock(tdb, locking_key(dev, inode)); } @@ -298,9 +298,9 @@ BOOL lock_share_entry_fsp(files_struct *fsp) /******************************************************************* Unlock a hash bucket entry. ******************************************************************/ -BOOL unlock_share_entry_fsp(files_struct *fsp) +void unlock_share_entry_fsp(files_struct *fsp) { - return tdb_chainunlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0; + tdb_chainunlock(tdb, locking_key(fsp->dev, fsp->inode)); } /******************************************************************* -- cgit From da3053048c3d224a20d6383ac6682d31059cd46c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 00:32:10 +0000 Subject: Merge of new 2.2 code into HEAD (Gerald I hate you :-) :-). Allows new SAMR RPC code to merge with new passdb code. Currently rpcclient doesn't compile. I'm working on it... Jeremy. (This used to be commit 0be41d5158ea4e645e93e8cd30617c038416e549) --- source3/locking/locking.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index b3601e8752..118d59cc10 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -396,7 +396,6 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) { TDB_DATA dbuf; struct locking_data *data; - share_mode_entry *shares; char *p=NULL; int size; @@ -410,12 +409,11 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) pstrcat(fname, "/"); pstrcat(fname, fsp->fsp_name); - size = sizeof(*data) + sizeof(*shares) + strlen(fname) + 1; + size = sizeof(*data) + sizeof(share_mode_entry) + strlen(fname) + 1; p = (char *)malloc(size); data = (struct locking_data *)p; - shares = (share_mode_entry *)(p + sizeof(*data)); data->num_share_mode_entries = 1; - pstrcpy(p + sizeof(*data) + sizeof(*shares), fname); + pstrcpy(p + sizeof(*data) + sizeof(share_mode_entry), fname); fill_share_mode(p + sizeof(*data), fsp, port, op_type); dbuf.dptr = p; dbuf.dsize = size; @@ -426,14 +424,13 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) /* we're adding to an existing entry - this is a bit fiddly */ data = (struct locking_data *)dbuf.dptr; - shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); data->num_share_mode_entries++; - size = dbuf.dsize + sizeof(*shares); + size = dbuf.dsize + sizeof(share_mode_entry); p = malloc(size); memcpy(p, dbuf.dptr, sizeof(*data)); fill_share_mode(p + sizeof(*data), fsp, port, op_type); - memcpy(p + sizeof(*data) + sizeof(*shares), dbuf.dptr + sizeof(*data), + memcpy(p + sizeof(*data) + sizeof(share_mode_entry), dbuf.dptr + sizeof(*data), dbuf.dsize - sizeof(*data)); free(dbuf.dptr); dbuf.dptr = p; -- cgit From 6e7f03f9b920d1b81056959cca8c0b27ada4ee2d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Mar 2001 08:57:24 +0000 Subject: This is a big, rather ugly patch. Whilst investigating the files not truncated when copying to a full disk problem, I discovered that we were not allowing the delete on close flag to be set properly, this led to other things, and after investigation of the proper delete on close semantics and their relationship to the file_share_delete flag I discovered there were some cases where we weren't doing the deny modes properly. And this after only 5 years working on them..... :-) :-). So here's the latest attempt. I realised the delete on close flag needs to be set across all smbds with a dev/ino pair open - in addition, the delete on close flag, allow share delete and delete access requested all need to be stored in the share mode tdb. The "delete_on_close" entry in the fsp struct is now redundant and should really be removed. This may also mean we can get rid of the "iterate_fsp" calls that I didn't like adding in the first place. Whilst doing this patch, I also discovered we needed to do the se_map_generic() call for file opens and POSIX ACL mapping, so I added that also. This code, although ugly, now passes the deny mode torture tests plus the delete on close tests I added. I do need to add one more multiple connection delete on close test to make sure I got the semantics exactly right, plus we should also (as Andrew suggested) move to random testing here. The good news is that NT should now correctly delete the file on disk full error when copying to a disk :-). Jeremy. (This used to be commit 51987684bd231c744da2e5f3705fd236d5616173) --- source3/locking/locking.c | 71 ++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 32 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 118d59cc10..5824287e91 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -331,19 +331,24 @@ int get_share_modes(connection_struct *conn, } /******************************************************************* - Del the share mode of a file for this process + Del the share mode of a file for this process. Return the number + of entries left, and a memdup'ed copy of the entry deleted. ********************************************************************/ -void del_share_mode(files_struct *fsp) + +size_t del_share_mode(files_struct *fsp, share_mode_entry **ppse) { TDB_DATA dbuf; struct locking_data *data; int i, del_count=0; share_mode_entry *shares; pid_t pid = sys_getpid(); + size_t count; + + *ppse = NULL; /* read in the existing share modes */ dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); - if (!dbuf.dptr) return; + if (!dbuf.dptr) return 0; data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); @@ -354,6 +359,7 @@ void del_share_mode(files_struct *fsp) if (shares[i].pid == pid && memcmp(&shares[i].time, &fsp->open_time,sizeof(struct timeval)) == 0) { + *ppse = memdup(&shares[i], sizeof(*shares)); data->num_share_mode_entries--; memmove(&shares[i], &shares[i+1], dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); @@ -366,6 +372,8 @@ void del_share_mode(files_struct *fsp) /* the record has shrunk a bit */ dbuf.dsize -= del_count * sizeof(*shares); + count = data->num_share_mode_entries; + /* store it back in the database */ if (data->num_share_mode_entries == 0) { tdb_delete(tdb, locking_key_fsp(fsp)); @@ -374,6 +382,7 @@ void del_share_mode(files_struct *fsp) } free(dbuf.dptr); + return count; } /******************************************************************* @@ -529,42 +538,40 @@ BOOL downgrade_share_oplock(files_struct *fsp) return mod_share_mode(fsp, downgrade_share_oplock_fn, NULL); } - /******************************************************************* - Static function that actually does the work for the generic function - below. + Get/Set the delete on close flag in a set of share modes. + Return False on fail, True on success. ********************************************************************/ -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) +BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) { - 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; -} + TDB_DATA dbuf; + struct locking_data *data; + int i; + share_mode_entry *shares; -/******************************************************************* - 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(files_struct *fsp, int new_mode, uint16 new_oplock) -{ - struct mod_val mv; + /* read in the existing share modes */ + dbuf = tdb_fetch(tdb, locking_key(dev, inode)); + if (!dbuf.dptr) return False; + + data = (struct locking_data *)dbuf.dptr; + shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); - mv.new_share_mode = new_mode; - mv.new_oplock = new_oplock; + /* Set/Unset the delete on close element. */ + for (i=0;inum_share_mode_entries;i++,shares++) { + shares->share_mode = (delete_on_close ? + (shares->share_mode | DELETE_ON_CLOSE_FLAG) : + (shares->share_mode & ~DELETE_ON_CLOSE_FLAG) ); + } - return mod_share_mode(fsp, modify_share_mode_fn, (void *)&mv); + /* store it back */ + if (data->num_share_mode_entries) { + if (tdb_store(tdb, locking_key(dev,inode), dbuf, TDB_REPLACE)==-1) + return False; + } + + free(dbuf.dptr); + return True; } -- cgit From faa0bef196b732b45c4614acd655af4881504808 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 22 May 2001 20:35:48 +0000 Subject: Defensive brlock and locking database cleaning code. Jeremy. (This used to be commit d7aa42e4593b02ee6e487f7a4633bd7e7620ef2f) --- source3/locking/locking.c | 83 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 5824287e91..c2d3106a67 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -214,14 +214,73 @@ void locking_close_file(files_struct *fsp) } } +/**************************************************************************** + Delete a record if it is for a dead process, if check_self is true, then + delete any records belonging to this pid also (there shouldn't be any). + This function is only called on locking startup and shutdown. +****************************************************************************/ + +static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) +{ + struct locking_data *data; + share_mode_entry *shares; + int i, del_count=0; + pid_t mypid = sys_getpid(); + BOOL check_self = *(BOOL *)state; + + tdb_chainlock(tdb, kbuf); + + data = (struct locking_data *)dbuf.dptr; + shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); + + for (i=0;inum_share_mode_entries;) { + + if (check_self && (shares[i].pid == mypid)) { + DEBUG(0,("locking : delete_fn. LOGIC ERROR ! Shutting down and a record for my pid (%u) exists !\n", + (unsigned int)shares[i].pid )); + } else if (!process_exists(shares[i].pid)) { + DEBUG(0,("locking : delete_fn. LOGIC ERROR ! Entry for pid %u and it no longer exists !\n", + (unsigned int)shares[i].pid )); + } else { + /* Process exists, leave this record alone. */ + i++; + continue; + } + + data->num_share_mode_entries--; + memmove(&shares[i], &shares[i+1], + dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); + del_count++; + + } + + /* the record has shrunk a bit */ + dbuf.dsize -= del_count * sizeof(*shares); + + /* store it back in the database */ + if (data->num_share_mode_entries == 0) + tdb_delete(ttdb, kbuf); + else + tdb_store(ttdb, kbuf, dbuf, TDB_REPLACE); + + tdb_chainunlock(tdb, kbuf); + return 0; +} + /**************************************************************************** Initialise the locking functions. ****************************************************************************/ + +static int open_read_only; + BOOL locking_init(int read_only) { + BOOL check_self = False; + brl_init(read_only); - if (tdb) return True; + if (tdb) + return True; tdb = tdb_open(lock_path("locking.tdb"), 0, TDB_CLEAR_IF_FIRST, @@ -236,15 +295,35 @@ BOOL locking_init(int read_only) if (!posix_locking_init(read_only)) return False; + /* delete any dead locks */ + if (!read_only) + tdb_traverse(tdb, delete_fn, &check_self); + + open_read_only = read_only; + return True; } /******************************************************************* Deinitialize the share_mode management. ******************************************************************/ + BOOL locking_end(void) { - if (tdb && tdb_close(tdb) != 0) return False; + BOOL check_self = True; + + brl_shutdown(open_read_only); + if (tdb) { + + /* delete any dead locks */ + + if (!open_read_only) + tdb_traverse(tdb, delete_fn, &check_self); + + if (tdb_close(tdb) != 0) + return False; + } + return True; } -- cgit From 05fc3e578c895f632b351969d09cd00feb7599c7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Jun 2001 05:13:59 +0000 Subject: use LDSHFLAGS not -shared in several places (This used to be commit 8ec9c87b5d1a7dae17d5b1a30f58effaf5e69e4b) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index c2d3106a67..c77a86cbf4 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -282,7 +282,7 @@ BOOL locking_init(int read_only) if (tdb) return True; - tdb = tdb_open(lock_path("locking.tdb"), + tdb = tdb_open_log(lock_path("locking.tdb"), 0, TDB_CLEAR_IF_FIRST, read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); -- cgit From d1f38ac53107d818b88cae9ee4d4442381dc4702 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 30 Jun 2001 01:59:48 +0000 Subject: Fixed the first locking error (test #8 found by locktest code from Clarion locktest. Jeremy. (This used to be commit 5c42845b5bb6fafd0ebf93fbdd23d9bf861da865) --- source3/locking/locking.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index c77a86cbf4..68c3c5b653 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -53,11 +53,14 @@ static const char *lock_type_name(enum brl_type lock_type) /**************************************************************************** Utility function called to see if a file region is locked. + If check_self is True, then checks on our own fd with the same locking context + are still made. If check_self is False, then checks are not made on our own fd + with the same locking context are not made. ****************************************************************************/ BOOL is_locked(files_struct *fsp,connection_struct *conn, SMB_BIG_UINT count,SMB_BIG_UINT offset, - enum brl_type lock_type) + enum brl_type lock_type, BOOL check_self) { int snum = SNUM(conn); BOOL ret; @@ -70,16 +73,25 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum, global_smbpid, sys_getpid(), conn->cnum, - offset, count, lock_type); + offset, count, lock_type, check_self); + + DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n", + (double)offset, (double)count, ret ? "locked" : "unlocked", + fsp->fsp_name )); /* * There is no lock held by an SMB daemon, check to * see if there is a POSIX lock from a UNIX or NFS process. */ - if(!ret && lp_posix_locking(snum)) + if(!ret && lp_posix_locking(snum)) { ret = is_posix_locked(fsp, offset, count, lock_type); + DEBUG(10,("is_locked: posix start=%.0f len=%.0f %s for file %s\n", + (double)offset, (double)count, ret ? "locked" : "unlocked", + fsp->fsp_name )); + } + return ret; } -- cgit From 064b4904f9695a766acc0d87a630e18a59e5c540 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 30 Jun 2001 03:11:44 +0000 Subject: Ensure we return correct error on trying to unlock a region not locked. Jeremy. (This used to be commit 015a077acc49e59179dc10256fd32166ee4623e2) --- source3/locking/locking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 68c3c5b653..a75388081e 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -168,7 +168,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) { *eclass = ERRDOS; - *ecode = ERRlock; + *ecode = ERRbadfid; return False; } @@ -187,7 +187,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); *eclass = ERRDOS; - *ecode = ERRlock; + *ecode = ERRnotlocked; return False; } -- cgit From 5b69009b25886bfa8b07e3ac885064ffa730f9bf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 2 Jul 2001 02:42:41 +0000 Subject: Fixed the nastiest locking bug to track down.... smb_pids are sent in the lockingX calls - use that instead of smb_pid in the packet. Jeremy. (This used to be commit a3925cb9c6303ce24e5fecad6c8f3a0ba78b9ee0) --- source3/locking/locking.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index a75388081e..067b1dc0dd 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -37,7 +37,7 @@ #include "includes.h" extern int DEBUGLEVEL; -int global_smbpid; +uint16 global_smbpid; /* the locking database handle */ static TDB_CONTEXT *tdb; @@ -99,7 +99,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, Utility function called by locking requests. ****************************************************************************/ -BOOL do_lock(files_struct *fsp,connection_struct *conn, +BOOL do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, int *eclass,uint32 *ecode) { @@ -119,7 +119,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) { ok = brl_lock(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, sys_getpid(), conn->cnum, + lock_pid, sys_getpid(), conn->cnum, offset, count, lock_type); @@ -139,7 +139,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, * lock entry. */ (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, sys_getpid(), conn->cnum, + lock_pid, sys_getpid(), conn->cnum, offset, count); } } @@ -157,7 +157,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, Utility function called by unlocking requests. ****************************************************************************/ -BOOL do_unlock(files_struct *fsp,connection_struct *conn, +BOOL do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, SMB_BIG_UINT count,SMB_BIG_UINT offset, int *eclass,uint32 *ecode) { @@ -182,7 +182,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, */ ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, sys_getpid(), conn->cnum, offset, count); + lock_pid, sys_getpid(), conn->cnum, offset, count); if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); -- cgit From 996719cce26700c68ff0e456e6a25d20085d091f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Jul 2001 22:21:31 +0000 Subject: Added "use mmap" for HPUX. Jeremy. (This used to be commit 840802f10677cb0009cb4df4c37c7d01aa5edacd) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 067b1dc0dd..9b393ed6ba 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -295,7 +295,7 @@ BOOL locking_init(int read_only) return True; tdb = tdb_open_log(lock_path("locking.tdb"), - 0, TDB_CLEAR_IF_FIRST, + 0, TDB_CLEAR_IF_FIRST|USE_TDB_MMAP_FLAG, read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); -- cgit From c786a4d89a3c4b7f2c6fdf0762e835ad7edbd664 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 20 Aug 2001 22:13:53 +0000 Subject: Ensure we are very explicit about what we're comparing when we're comparing structures (ie. don't just do a memcmp). I don't think this will fix the fcntl spin issue, but it's a "just in case" change. Jeremy. (This used to be commit 41066208ad8ca20d35a32bdf9ad934e11465c8f1) --- source3/locking/locking.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 9b393ed6ba..ee3ce7c7d4 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -448,8 +448,8 @@ size_t del_share_mode(files_struct *fsp, share_mode_entry **ppse) from the record */ for (i=0;inum_share_mode_entries;) { if (shares[i].pid == pid && - memcmp(&shares[i].time, - &fsp->open_time,sizeof(struct timeval)) == 0) { + shares[i].time.tv_sec == fsp->open_time.tv_sec && + shares[i].time.tv_usec == fsp->open_time.tv_usec ) { *ppse = memdup(&shares[i], sizeof(*shares)); data->num_share_mode_entries--; memmove(&shares[i], &shares[i+1], @@ -566,8 +566,8 @@ static BOOL mod_share_mode(files_struct *fsp, for (i=0;inum_share_mode_entries;i++) { if (pid == shares[i].pid && shares[i].share_mode == fsp->share_mode && - memcmp(&shares[i].time, - &fsp->open_time,sizeof(struct timeval)) == 0) { + shares[i].time.tv_sec == fsp->open_time.tv_sec && + shares[i].time.tv_usec == fsp->open_time.tv_usec ) { mod_fn(&shares[i], fsp->dev, fsp->inode, param); need_store=1; } -- cgit From e6a6dee0272a170848d3b9c177bf3839214d0a20 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 21 Aug 2001 01:25:45 +0000 Subject: This is Jeremy pretending to be Volker, 'cos the link from Seattle is having problems. I've added 3 things here to work on the fcntl spin problem. 1). Check *all* tdb return codes... :-). 2). If we're asking ourselves to break an oplock, and we can't find a fsp pointer that matches the entry, this is a *logic bug* and we should abort and panic so someone with gdb can pick up the pieces. 3). After we've broken an oplock, ensure that the entry itself has been removed, and if not remove it ourselves. This should not be neccessary in a correctly working environmen,t, but will provide an added layer of robustness in error situations. 4). I hate german keyboards :-) :-). Jeremy. (This used to be commit 1c94fa80646f9e31377fbb41332fe4780f550cab) --- source3/locking/locking.c | 200 +++++++++++++++++++++++++++++++--------------- 1 file changed, 136 insertions(+), 64 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index ee3ce7c7d4..4b037c0f3d 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -239,6 +239,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat int i, del_count=0; pid_t mypid = sys_getpid(); BOOL check_self = *(BOOL *)state; + int ret = 0; tdb_chainlock(tdb, kbuf); @@ -270,13 +271,16 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat dbuf.dsize -= del_count * sizeof(*shares); /* store it back in the database */ - if (data->num_share_mode_entries == 0) - tdb_delete(ttdb, kbuf); - else - tdb_store(ttdb, kbuf, dbuf, TDB_REPLACE); + if (data->num_share_mode_entries == 0) { + if (tdb_delete(ttdb, kbuf) == -1) + ret = -1; + } else { + if (tdb_store(ttdb, kbuf, dbuf, TDB_REPLACE) == -1) + ret = -1; + } tdb_chainunlock(tdb, kbuf); - return 0; + return ret; } /**************************************************************************** @@ -340,8 +344,9 @@ BOOL locking_end(void) } /******************************************************************* - form a static locking key for a dev/inode pair + Form a static locking key for a dev/inode pair. ******************************************************************/ + static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode) { static struct locking_key key; @@ -354,6 +359,7 @@ static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode) kbuf.dsize = sizeof(key); return kbuf; } + static TDB_DATA locking_key_fsp(files_struct *fsp) { return locking_key(fsp->dev, fsp->inode); @@ -377,10 +383,10 @@ void unlock_share_entry(connection_struct *conn, tdb_chainunlock(tdb, locking_key(dev, inode)); } - /******************************************************************* Lock a hash bucket entry. use a fsp for convenience ******************************************************************/ + BOOL lock_share_entry_fsp(files_struct *fsp) { return tdb_chainlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0; @@ -389,6 +395,7 @@ BOOL lock_share_entry_fsp(files_struct *fsp) /******************************************************************* Unlock a hash bucket entry. ******************************************************************/ + void unlock_share_entry_fsp(files_struct *fsp) { tdb_chainunlock(tdb, locking_key(fsp->dev, fsp->inode)); @@ -397,6 +404,7 @@ void unlock_share_entry_fsp(files_struct *fsp) /******************************************************************* Get all share mode entries for a dev/inode pair. ********************************************************************/ + int get_share_modes(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry **shares) @@ -408,7 +416,8 @@ int get_share_modes(connection_struct *conn, *shares = NULL; dbuf = tdb_fetch(tdb, locking_key(dev, inode)); - if (!dbuf.dptr) return 0; + if (!dbuf.dptr) + return 0; data = (struct locking_data *)dbuf.dptr; ret = data->num_share_mode_entries; @@ -416,41 +425,76 @@ int get_share_modes(connection_struct *conn, *shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data), ret * sizeof(**shares)); free(dbuf.dptr); - if (! *shares) return 0; + if (! *shares) + return 0; return ret; } /******************************************************************* - Del the share mode of a file for this process. Return the number - of entries left, and a memdup'ed copy of the entry deleted. + Fill a share mode entry. ********************************************************************/ -size_t del_share_mode(files_struct *fsp, share_mode_entry **ppse) +static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_type) +{ + share_mode_entry *e = (share_mode_entry *)p; + memset(e, '\0', sizeof(share_mode_entry)); + e->pid = sys_getpid(); + e->share_mode = fsp->share_mode; + e->op_port = port; + e->op_type = op_type; + memcpy((char *)&e->time, (char *)&fsp->open_time, sizeof(struct timeval)); +} + +/******************************************************************* + Check if two share mode entries are identical, ignoring oplock + and port info. +********************************************************************/ + +static BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2) +{ + return (e1->pid == e2->pid && + e1->share_mode == e2->share_mode && + e1->time.tv_sec == e2->time.tv_sec && + e1->time.tv_usec == e2->time.tv_usec ); +} + +/******************************************************************* + Delete a specific share mode. Return the number + of entries left, and a memdup'ed copy of the entry deleted (if required). + Ignore if no entry deleted. +********************************************************************/ + +ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, + share_mode_entry *entry, share_mode_entry **ppse) { TDB_DATA dbuf; struct locking_data *data; int i, del_count=0; share_mode_entry *shares; - pid_t pid = sys_getpid(); - size_t count; + ssize_t count; - *ppse = NULL; + if (ppse) + *ppse = NULL; /* read in the existing share modes */ - dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); - if (!dbuf.dptr) return 0; + dbuf = tdb_fetch(tdb, locking_key(dev, inode)); + if (!dbuf.dptr) + return -1; data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); - /* find any with our pid and delete it by overwriting with the rest of the data - from the record */ + /* + * Find any with this pid and delete it + * by overwriting with the rest of the data + * from the record. + */ + for (i=0;inum_share_mode_entries;) { - if (shares[i].pid == pid && - shares[i].time.tv_sec == fsp->open_time.tv_sec && - shares[i].time.tv_usec == fsp->open_time.tv_usec ) { - *ppse = memdup(&shares[i], sizeof(*shares)); + if (share_modes_identical(&shares[i], entry)) { + if (ppse) + *ppse = memdup(&shares[i], sizeof(*shares)); data->num_share_mode_entries--; memmove(&shares[i], &shares[i+1], dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); @@ -460,44 +504,53 @@ size_t del_share_mode(files_struct *fsp, share_mode_entry **ppse) } } - /* the record has shrunk a bit */ - dbuf.dsize -= del_count * sizeof(*shares); + if (del_count) { + /* the record may have shrunk a bit */ + dbuf.dsize -= del_count * sizeof(*shares); - count = data->num_share_mode_entries; + count = (ssize_t)data->num_share_mode_entries; - /* store it back in the database */ - if (data->num_share_mode_entries == 0) { - tdb_delete(tdb, locking_key_fsp(fsp)); - } else { - tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); + /* store it back in the database */ + if (data->num_share_mode_entries == 0) { + if (tdb_delete(tdb, locking_key(dev, inode)) == -1) + count = -1; + } else { + if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1) + count = -1; + } } - free(dbuf.dptr); return count; } /******************************************************************* -fill a share mode entry + Del the share mode of a file for this process. Return the number + of entries left, and a memdup'ed copy of the entry deleted. ********************************************************************/ -static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_type) + +ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse) { - share_mode_entry *e = (share_mode_entry *)p; - e->pid = sys_getpid(); - e->share_mode = fsp->share_mode; - e->op_port = port; - e->op_type = op_type; - memcpy((char *)&e->time, (char *)&fsp->open_time, sizeof(struct timeval)); + share_mode_entry entry; + + /* + * Fake up a share_mode_entry for comparisons. + */ + + fill_share_mode((char *)&entry, fsp, 0, 0); + return del_share_entry(fsp->dev, fsp->inode, &entry, ppse); } /******************************************************************* Set the share mode of a file. Return False on fail, True on success. ********************************************************************/ + BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) { TDB_DATA dbuf; struct locking_data *data; char *p=NULL; int size; + BOOL ret = True; /* read in the existing share modes if any */ dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); @@ -511,15 +564,18 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) size = sizeof(*data) + sizeof(share_mode_entry) + strlen(fname) + 1; p = (char *)malloc(size); + if (!p) + return False; data = (struct locking_data *)p; data->num_share_mode_entries = 1; pstrcpy(p + sizeof(*data) + sizeof(share_mode_entry), fname); fill_share_mode(p + sizeof(*data), fsp, port, op_type); dbuf.dptr = p; dbuf.dsize = size; - tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); + if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1) + ret = False; free(p); - return True; + return ret; } /* we're adding to an existing entry - this is a bit fiddly */ @@ -528,6 +584,8 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) data->num_share_mode_entries++; size = dbuf.dsize + sizeof(share_mode_entry); p = malloc(size); + if (!p) + return False; memcpy(p, dbuf.dptr, sizeof(*data)); fill_share_mode(p + sizeof(*data), fsp, port, op_type); memcpy(p + sizeof(*data) + sizeof(share_mode_entry), dbuf.dptr + sizeof(*data), @@ -535,15 +593,16 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) free(dbuf.dptr); dbuf.dptr = p; dbuf.dsize = size; - tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); + if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1) + ret = False; free(p); - return True; + return ret; } - /******************************************************************* -a generic in-place modification call for share mode entries + A generic in-place modification call for share mode entries. ********************************************************************/ + static BOOL mod_share_mode(files_struct *fsp, void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *), void *param) @@ -551,34 +610,39 @@ static BOOL mod_share_mode(files_struct *fsp, TDB_DATA dbuf; struct locking_data *data; int i; - share_mode_entry *shares; - pid_t pid = sys_getpid(); - int need_store=0; + share_mode_entry *shares, entry; + BOOL need_store=False; /* read in the existing share modes */ dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); - if (!dbuf.dptr) return False; + if (!dbuf.dptr) + return False; data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); + /* + * Fake up a share_mode_entry for comparisons. + */ + + fill_share_mode((char *)&entry, fsp, 0, 0); + /* find any with our pid and call the supplied function */ for (i=0;inum_share_mode_entries;i++) { - if (pid == shares[i].pid && - shares[i].share_mode == fsp->share_mode && - shares[i].time.tv_sec == fsp->open_time.tv_sec && - shares[i].time.tv_usec == fsp->open_time.tv_usec ) { + if (share_modes_identical(&entry, &shares[i])) { mod_fn(&shares[i], fsp->dev, fsp->inode, param); - need_store=1; + need_store=True; } } /* if the mod fn was called then store it back */ if (need_store) { if (data->num_share_mode_entries == 0) { - tdb_delete(tdb, locking_key_fsp(fsp)); + if (tdb_delete(tdb, locking_key_fsp(fsp)) == -1) + need_store = False; } else { - tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE); + if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1) + need_store = False; } } @@ -586,11 +650,11 @@ static BOOL mod_share_mode(files_struct *fsp, return need_store; } - /******************************************************************* 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) { @@ -604,6 +668,7 @@ static void remove_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_I /******************************************************************* Remove an oplock port and mode entry from a share mode. ********************************************************************/ + BOOL remove_share_oplock(files_struct *fsp) { return mod_share_mode(fsp, remove_share_oplock_fn, NULL); @@ -613,6 +678,7 @@ BOOL remove_share_oplock(files_struct *fsp) Static function that actually does the work for the generic function below. ********************************************************************/ + static void downgrade_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode, void *param) { @@ -624,6 +690,7 @@ static void downgrade_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SM /******************************************************************* Downgrade a oplock type from exclusive to level II. ********************************************************************/ + BOOL downgrade_share_oplock(files_struct *fsp) { return mod_share_mode(fsp, downgrade_share_oplock_fn, NULL); @@ -643,7 +710,8 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) /* read in the existing share modes */ dbuf = tdb_fetch(tdb, locking_key(dev, inode)); - if (!dbuf.dptr) return False; + if (!dbuf.dptr) + return False; data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); @@ -657,19 +725,21 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) /* store it back */ if (data->num_share_mode_entries) { - if (tdb_store(tdb, locking_key(dev,inode), dbuf, TDB_REPLACE)==-1) + if (tdb_store(tdb, locking_key(dev,inode), dbuf, TDB_REPLACE)==-1) { + free(dbuf.dptr); return False; + } } free(dbuf.dptr); return True; } - /**************************************************************************** -traverse the whole database with this function, calling traverse_callback -on each share mode + Traverse the whole database with this function, calling traverse_callback + on each share mode ****************************************************************************/ + static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* state) { @@ -694,8 +764,10 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, Call the specified function on each entry under management by the share mode system. ********************************************************************/ + int share_mode_forall(SHAREMODE_FN(fn)) { - if (!tdb) return 0; + if (!tdb) + return 0; return tdb_traverse(tdb, traverse_fn, (void*)fn); } -- cgit From dd5378522539b913e140dd58f72b5eca1d61360a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Aug 2001 18:33:58 +0000 Subject: Missed uninitialized variable return for del_share_mode(). Jeremy. (This used to be commit e4a57fb45660b82eaec751f1b41f657a64d963fd) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 4b037c0f3d..a9bcada026 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -472,7 +472,7 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, struct locking_data *data; int i, del_count=0; share_mode_entry *shares; - ssize_t count; + ssize_t count = 0; if (ppse) *ppse = NULL; -- cgit From e4275a35a64fde95a3b59307572d44c8d53909ad Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Aug 2001 00:29:40 +0000 Subject: Fixed the (incorrect) paranioa fix I put in for the fcntl lock spin. Don't delete a share mode that failed to remove the oplock (doh!), just set the oplock entry to zero.... Jeremy. (This used to be commit fe4aa720181a43f7a636ca029680fab0c836b968) --- source3/locking/locking.c | 52 +++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 17 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index a9bcada026..fea821baa1 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -451,7 +451,7 @@ static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_t and port info. ********************************************************************/ -static BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2) +BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2) { return (e1->pid == e2->pid && e1->share_mode == e2->share_mode && @@ -465,7 +465,7 @@ static BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2) Ignore if no entry deleted. ********************************************************************/ -ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, +static ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *entry, share_mode_entry **ppse) { TDB_DATA dbuf; @@ -491,6 +491,8 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, * from the record. */ + DEBUG(10,("del_share_mode: num_share_modes = %d\n", data->num_share_mode_entries )); + for (i=0;inum_share_mode_entries;) { if (share_modes_identical(&shares[i], entry)) { if (ppse) @@ -499,6 +501,9 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, memmove(&shares[i], &shares[i+1], dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); del_count++; + + DEBUG(10,("del_share_mode: deleting entry %d\n", i )); + } else { i++; } @@ -603,34 +608,28 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) A generic in-place modification call for share mode entries. ********************************************************************/ -static BOOL mod_share_mode(files_struct *fsp, +static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *entry, void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *), void *param) { TDB_DATA dbuf; struct locking_data *data; int i; - share_mode_entry *shares, entry; + share_mode_entry *shares; BOOL need_store=False; /* read in the existing share modes */ - dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); + dbuf = tdb_fetch(tdb, locking_key(dev, inode)); if (!dbuf.dptr) return False; data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); - /* - * Fake up a share_mode_entry for comparisons. - */ - - fill_share_mode((char *)&entry, fsp, 0, 0); - /* find any with our pid and call the supplied function */ for (i=0;inum_share_mode_entries;i++) { - if (share_modes_identical(&entry, &shares[i])) { - mod_fn(&shares[i], fsp->dev, fsp->inode, param); + if (share_modes_identical(entry, &shares[i])) { + mod_fn(&shares[i], dev, inode, param); need_store=True; } } @@ -638,10 +637,10 @@ static BOOL mod_share_mode(files_struct *fsp, /* if the mod fn was called then store it back */ if (need_store) { if (data->num_share_mode_entries == 0) { - if (tdb_delete(tdb, locking_key_fsp(fsp)) == -1) + if (tdb_delete(tdb, locking_key(dev, inode)) == -1) need_store = False; } else { - if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1) + if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1) need_store = False; } } @@ -671,7 +670,12 @@ static void remove_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_I BOOL remove_share_oplock(files_struct *fsp) { - return mod_share_mode(fsp, remove_share_oplock_fn, NULL); + share_mode_entry entry; + /* + * Fake up an entry for comparisons... + */ + fill_share_mode((char *)&entry, fsp, 0, 0); + return mod_share_mode(fsp->dev, fsp->inode, &entry, remove_share_oplock_fn, NULL); } /******************************************************************* @@ -693,7 +697,21 @@ static void downgrade_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SM BOOL downgrade_share_oplock(files_struct *fsp) { - return mod_share_mode(fsp, downgrade_share_oplock_fn, NULL); + share_mode_entry entry; + /* + * Fake up an entry for comparisons... + */ + fill_share_mode((char *)&entry, fsp, 0, 0); + return mod_share_mode(fsp->dev, fsp->inode, &entry, downgrade_share_oplock_fn, NULL); +} + +/******************************************************************* + Delete an exclusive share oplock owned by a defunct smbd.. +********************************************************************/ + +BOOL clear_share_entry(SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *entry) +{ + return mod_share_mode(dev, inode, entry, remove_share_oplock_fn, NULL); } /******************************************************************* -- cgit From 85e063f5b8b9ac872dc5e30da99b34230434df84 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Aug 2001 01:01:37 +0000 Subject: Tidyup fixes for fcntl spin problem. Jeremy. (This used to be commit 27d3dd0e7cb777ef6b21d6966c07045c2940fd37) --- source3/locking/locking.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index fea821baa1..80537c8bc1 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -299,7 +299,7 @@ BOOL locking_init(int read_only) return True; tdb = tdb_open_log(lock_path("locking.tdb"), - 0, TDB_CLEAR_IF_FIRST|USE_TDB_MMAP_FLAG, + 0, USE_TDB_MMAP_FLAG|(read_only?0x0:TDB_CLEAR_IF_FIRST), read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); @@ -365,18 +365,35 @@ static TDB_DATA locking_key_fsp(files_struct *fsp) 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. ******************************************************************/ + BOOL lock_share_entry(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode) { +#if 1 /* JRATEST */ + int count = 0; + for (count = 0; count < LOCK_SHARE_ENTRY_SPIN_COUNT; count++) + if (tdb_chainlock(tdb, locking_key(dev, inode)) == 0) + return True; + else + DEBUG(0,("lock_share_entry: locking (%d) for dev = %x, inode = %.0f failed with error %s\n", + count, (unsigned int)dev, (double)inode, strerror(errno) )); + return False; +#else return tdb_chainlock(tdb, locking_key(dev, inode)) == 0; +#endif } /******************************************************************* Unlock a hash bucket entry. ******************************************************************/ + void unlock_share_entry(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode) { @@ -389,7 +406,18 @@ void unlock_share_entry(connection_struct *conn, BOOL lock_share_entry_fsp(files_struct *fsp) { +#if 1 /* JRATEST */ + int count = 0; + for (count = 0; count < LOCK_SHARE_ENTRY_SPIN_COUNT; count++) + if (tdb_chainlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0) + return True; + else + DEBUG(0,("lock_share_entry_fsp: locking (%d) for dev = %x, inode = %.0f failed with error %s\n", + count, (unsigned int)fsp->dev, (double)fsp->inode, strerror(errno) )); + return False; +#else return tdb_chainlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0; +#endif } /******************************************************************* @@ -465,7 +493,7 @@ BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2) Ignore if no entry deleted. ********************************************************************/ -static ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, +ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *entry, share_mode_entry **ppse) { TDB_DATA dbuf; @@ -705,15 +733,6 @@ BOOL downgrade_share_oplock(files_struct *fsp) return mod_share_mode(fsp->dev, fsp->inode, &entry, downgrade_share_oplock_fn, NULL); } -/******************************************************************* - Delete an exclusive share oplock owned by a defunct smbd.. -********************************************************************/ - -BOOL clear_share_entry(SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *entry) -{ - return mod_share_mode(dev, inode, entry, remove_share_oplock_fn, NULL); -} - /******************************************************************* Get/Set the delete on close flag in a set of share modes. Return False on fail, True on success. -- cgit From 7874b0ac171449148a370f8c9da771efb591d0be Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Aug 2001 04:55:28 +0000 Subject: 0 byte lock ranges ARE valid (This used to be commit 5498da6664a457e4d64502d37fa887dabd9baaa0) --- source3/locking/locking.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 80537c8bc1..81b2e92f68 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -108,12 +108,9 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, if (!lp_locking(SNUM(conn))) return(True); - if (count == 0) { - *eclass = ERRDOS; - *ecode = ERRnoaccess; - return False; - } - + /* NOTE! 0 byte long ranges ARE allowed and should be stored */ + + 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 )); -- cgit From e8e98c9ea0690e3acf1126b50882e59e1056c7b3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Aug 2001 08:19:43 +0000 Subject: converted smbd to use NTSTATUS by default major changes include: - added NSTATUS type - added automatic mapping between dos and nt error codes - changed all ERROR() calls to ERROR_DOS() and many to ERROR_NT() these calls auto-translate to the client error code system - got rid of the cached error code and the writebmpx code We eventually will need to also: - get rid of BOOL, so we don't lose error info - replace all ERROR_DOS() calls with ERROR_NT() calls but that is too much for one night (This used to be commit 83d9896c1ea8be796192b51a4678c2a3b87f7518) --- source3/locking/locking.c | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 81b2e92f68..d6915140a5 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -99,14 +99,13 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, Utility function called by locking requests. ****************************************************************************/ -BOOL do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, - SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, - int *eclass,uint32 *ecode) +NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, + SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type) { BOOL ok = False; if (!lp_locking(SNUM(conn))) - return(True); + return NT_STATUS_NOPROBLEMO; /* NOTE! 0 byte long ranges ARE allowed and should be stored */ @@ -142,31 +141,25 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, } } - if (!ok) { - *eclass = ERRDOS; - *ecode = ERRlock; - return False; - } - return True; /* Got lock */ + if (!ok) return NT_STATUS_FILE_LOCK_CONFLICT; + + return NT_STATUS_NOPROBLEMO; /* Got lock */ } /**************************************************************************** Utility function called by unlocking requests. ****************************************************************************/ -BOOL do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, - SMB_BIG_UINT count,SMB_BIG_UINT offset, - int *eclass,uint32 *ecode) +NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, + SMB_BIG_UINT count,SMB_BIG_UINT offset) { BOOL ok = False; if (!lp_locking(SNUM(conn))) - return(True); + return NT_STATUS_NOPROBLEMO; if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) { - *eclass = ERRDOS; - *ecode = ERRbadfid; - return False; + return NT_STATUS_INVALID_HANDLE; } DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n", @@ -183,17 +176,15 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); - *eclass = ERRDOS; - *ecode = ERRnotlocked; - return False; + return NT_STATUS_LOCK_NOT_GRANTED; } if (!lp_posix_locking(SNUM(conn))) - return True; + return NT_STATUS_NOPROBLEMO; (void)release_posix_lock(fsp, offset, count); - return True; /* Did unlock */ + return NT_STATUS_NOPROBLEMO; /* Did unlock */ } /**************************************************************************** -- cgit From ee5f7237decfe446f4fdb08422beb2e6cb43af7f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Aug 2001 17:52:23 +0000 Subject: started converting NTSTATUS to be a structure on systems with gcc in order to make it type incompatible with BOOL so we catch errors sooner. This has already found a number of bugs (This used to be commit 1b778bc7d22efff3f90dc450eb12baa1241cf68f) --- source3/locking/locking.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d6915140a5..e905bd56e9 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -105,7 +105,7 @@ NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, BOOL ok = False; if (!lp_locking(SNUM(conn))) - return NT_STATUS_NOPROBLEMO; + return NT_STATUS(0); /* NOTE! 0 byte long ranges ARE allowed and should be stored */ @@ -156,10 +156,10 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, BOOL ok = False; if (!lp_locking(SNUM(conn))) - return NT_STATUS_NOPROBLEMO; + return NT_STATUS(0); if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) { - return NT_STATUS_INVALID_HANDLE; + return NT_STATUS(NT_STATUS_INVALID_HANDLE); } DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n", @@ -176,15 +176,15 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); - return NT_STATUS_LOCK_NOT_GRANTED; + return NT_STATUS(NT_STATUS_LOCK_NOT_GRANTED); } if (!lp_posix_locking(SNUM(conn))) - return NT_STATUS_NOPROBLEMO; + return NT_STATUS(0); (void)release_posix_lock(fsp, offset, count); - return NT_STATUS_NOPROBLEMO; /* Did unlock */ + return NT_STATUS(0); } /**************************************************************************** -- cgit From b031af348c7dcc8c74bf49945211c466b8eca079 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Aug 2001 19:46:22 +0000 Subject: converted another bunch of stuff to NTSTATUS (This used to be commit 1d36250e338ae0ff9fbbf86019809205dd97d05e) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e905bd56e9..4928d6d160 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -143,7 +143,7 @@ NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, if (!ok) return NT_STATUS_FILE_LOCK_CONFLICT; - return NT_STATUS_NOPROBLEMO; /* Got lock */ + return NT_STATUS_OK; /* Got lock */ } /**************************************************************************** -- cgit From 19fea3242cf6234786b6cbb60631e0071f31ff9f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Sep 2001 07:13:01 +0000 Subject: the next stage in the NTSTATUS/WERROR change. smbd and nmbd now compile, but the client code still needs some work (This used to be commit dcd6e735f709a9231860ceb9682db40ff26c9a66) --- source3/locking/locking.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 4928d6d160..1ed238f4d8 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -105,7 +105,7 @@ NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, BOOL ok = False; if (!lp_locking(SNUM(conn))) - return NT_STATUS(0); + return NT_STATUS_OK; /* NOTE! 0 byte long ranges ARE allowed and should be stored */ @@ -156,10 +156,10 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, BOOL ok = False; if (!lp_locking(SNUM(conn))) - return NT_STATUS(0); + return NT_STATUS_OK; if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) { - return NT_STATUS(NT_STATUS_INVALID_HANDLE); + return NT_STATUS_INVALID_HANDLE; } DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n", @@ -176,15 +176,15 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); - return NT_STATUS(NT_STATUS_LOCK_NOT_GRANTED); + return NT_STATUS_LOCK_NOT_GRANTED; } if (!lp_posix_locking(SNUM(conn))) - return NT_STATUS(0); + return NT_STATUS_OK; (void)release_posix_lock(fsp, offset, count); - return NT_STATUS(0); + return NT_STATUS_OK; } /**************************************************************************** -- cgit From 4f0509aeeb0e1a8ff6b962985e4468e94dab8273 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Sep 2001 21:39:43 +0000 Subject: 2nd DELETE_ON_CLOSE_FLAG fix ... we set the DELETE_ON_CLOSE_FLAG on all share modes on the file, which means the share mode in the fsp will not match the one in the tdb when we come to close for other file handles, which means we end up with share modes on files after all handles are closed fixed by making the comparison function that says if two shares modes are equal ignore the DELETE_ON_CLOSE_FLAG (This used to be commit 7b39c4c59897669106d7129bad8af3d592d25838) --- source3/locking/locking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 1ed238f4d8..d2bfc08dd3 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -470,9 +470,9 @@ 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) { return (e1->pid == e2->pid && - e1->share_mode == e2->share_mode && - e1->time.tv_sec == e2->time.tv_sec && - e1->time.tv_usec == e2->time.tv_usec ); + (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) && + e1->time.tv_sec == e2->time.tv_sec && + e1->time.tv_usec == e2->time.tv_usec ); } /******************************************************************* -- cgit From 9ef7a6c7865c14480139188c30744914c5b7af43 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Sep 2001 01:19:35 +0000 Subject: use NTSTATUS not BOOL in do_lock() (This used to be commit b1b2a5fa5d084dad8ae47777419ab75db1e51eff) --- source3/locking/locking.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d2bfc08dd3..a1e4ba6d6c 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -102,7 +102,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type) { - BOOL ok = False; + NTSTATUS status; if (!lp_locking(SNUM(conn))) return NT_STATUS_OK; @@ -114,12 +114,12 @@ NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, 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, - lock_pid, sys_getpid(), conn->cnum, - offset, count, - lock_type); + status = brl_lock(fsp->dev, fsp->inode, fsp->fnum, + lock_pid, sys_getpid(), conn->cnum, + offset, count, + lock_type); - if (ok && lp_posix_locking(SNUM(conn))) { + if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) { /* * Try and get a POSIX lock on this range. @@ -127,9 +127,8 @@ NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, * overlapping on a different fd. JRA. */ - ok = set_posix_lock(fsp, offset, count, lock_type); - - if (!ok) { + if (!set_posix_lock(fsp, offset, count, lock_type)) { + status = NT_STATUS_LOCK_NOT_GRANTED; /* * We failed to map - we must now remove the brl * lock entry. @@ -141,9 +140,7 @@ NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, } } - if (!ok) return NT_STATUS_FILE_LOCK_CONFLICT; - - return NT_STATUS_OK; /* Got lock */ + return status; } /**************************************************************************** -- cgit From 9a9ac2739bbdc993ecdfa78298bdd9c059328378 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Sep 2001 22:08:19 +0000 Subject: got rid of USE_TDB_MMAP_FLAG as its not needed any more (This used to be commit c26e0d3f27a05ecc8bd2390f9aab7f9451524e47) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index a1e4ba6d6c..4092c989d0 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -284,7 +284,7 @@ BOOL locking_init(int read_only) return True; tdb = tdb_open_log(lock_path("locking.tdb"), - 0, USE_TDB_MMAP_FLAG|(read_only?0x0:TDB_CLEAR_IF_FIRST), + 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); -- cgit From 81fdc3c3f76075babe3e1f4bf43ed2cfd5723472 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Sep 2001 04:16:35 +0000 Subject: move to SAFE_FREE() (This used to be commit e61aec84edaf55b9ee087b076d2f1311033dc839) --- source3/locking/locking.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 4092c989d0..750ebe6716 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -436,7 +436,7 @@ int get_share_modes(connection_struct *conn, ret = data->num_share_mode_entries; if(ret) *shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data), ret * sizeof(**shares)); - free(dbuf.dptr); + SAFE_FREE(dbuf.dptr); if (! *shares) return 0; @@ -537,7 +537,7 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, count = -1; } } - free(dbuf.dptr); + SAFE_FREE(dbuf.dptr); return count; } @@ -592,7 +592,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) dbuf.dsize = size; if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1) ret = False; - free(p); + SAFE_FREE(p); return ret; } @@ -608,12 +608,12 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) fill_share_mode(p + sizeof(*data), fsp, port, op_type); memcpy(p + sizeof(*data) + sizeof(share_mode_entry), dbuf.dptr + sizeof(*data), dbuf.dsize - sizeof(*data)); - free(dbuf.dptr); + SAFE_FREE(dbuf.dptr); dbuf.dptr = p; dbuf.dsize = size; if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1) ret = False; - free(p); + SAFE_FREE(p); return ret; } @@ -658,7 +658,7 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en } } - free(dbuf.dptr); + SAFE_FREE(dbuf.dptr); return need_store; } @@ -748,12 +748,12 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) /* store it back */ if (data->num_share_mode_entries) { if (tdb_store(tdb, locking_key(dev,inode), dbuf, TDB_REPLACE)==-1) { - free(dbuf.dptr); + SAFE_FREE(dbuf.dptr); return False; } } - free(dbuf.dptr); + SAFE_FREE(dbuf.dptr); return True; } -- cgit From 36a6611da2820da3635a8158dd26f41732b5b4fd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Sep 2001 06:20:28 +0000 Subject: Use structure copy to fix unaligned accesses on 64bit architectures on Linux. Jeremy. (This used to be commit b4b891279b6292237113456f1bb0d4393f1f9af1) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 750ebe6716..a942965684 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -456,7 +456,7 @@ static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_t e->share_mode = fsp->share_mode; e->op_port = port; e->op_type = op_type; - memcpy((char *)&e->time, (char *)&fsp->open_time, sizeof(struct timeval)); + e->time = fsp->open_time; } /******************************************************************* -- cgit From 5bc82e443b2da885aa0a504906789c006b3cf17a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Sep 2001 06:41:29 +0000 Subject: Correct fix for unaligned memcpy - malloc'ed memory incremented by sizeof(struct locking_data) was not forced to be 8 byte aligned. Use union to force it to be correctly aligned for memcpy and use void *, to tell compiler not to optimize aligned copy (this last fix suggested by Trond @ RedHat). The first fix should be sufficient, but this provides a "belt and braces" fix. Jeremy. (This used to be commit 22c5915bb466529ac1bcb5c2574888b360a9775b) --- source3/locking/locking.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index a942965684..23766f41dc 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -231,7 +231,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); - for (i=0;inum_share_mode_entries;) { + for (i=0;iu.num_share_mode_entries;) { if (check_self && (shares[i].pid == mypid)) { DEBUG(0,("locking : delete_fn. LOGIC ERROR ! Shutting down and a record for my pid (%u) exists !\n", @@ -245,7 +245,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat continue; } - data->num_share_mode_entries--; + data->u.num_share_mode_entries--; memmove(&shares[i], &shares[i+1], dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); del_count++; @@ -256,7 +256,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat dbuf.dsize -= del_count * sizeof(*shares); /* store it back in the database */ - if (data->num_share_mode_entries == 0) { + if (data->u.num_share_mode_entries == 0) { if (tdb_delete(ttdb, kbuf) == -1) ret = -1; } else { @@ -433,7 +433,7 @@ int get_share_modes(connection_struct *conn, return 0; data = (struct locking_data *)dbuf.dptr; - ret = data->num_share_mode_entries; + ret = data->u.num_share_mode_entries; if(ret) *shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data), ret * sizeof(**shares)); SAFE_FREE(dbuf.dptr); @@ -451,12 +451,14 @@ int get_share_modes(connection_struct *conn, static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_type) { share_mode_entry *e = (share_mode_entry *)p; + void *x = &e->time; /* Needed to force alignment. p may not be aligned.... */ + memset(e, '\0', sizeof(share_mode_entry)); e->pid = sys_getpid(); e->share_mode = fsp->share_mode; e->op_port = port; e->op_type = op_type; - e->time = fsp->open_time; + memcpy(x, &fsp->open_time, sizeof(struct timeval)); } /******************************************************************* @@ -504,13 +506,13 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, * from the record. */ - DEBUG(10,("del_share_mode: num_share_modes = %d\n", data->num_share_mode_entries )); + DEBUG(10,("del_share_mode: num_share_modes = %d\n", data->u.num_share_mode_entries )); - for (i=0;inum_share_mode_entries;) { + for (i=0;iu.num_share_mode_entries;) { if (share_modes_identical(&shares[i], entry)) { if (ppse) *ppse = memdup(&shares[i], sizeof(*shares)); - data->num_share_mode_entries--; + data->u.num_share_mode_entries--; memmove(&shares[i], &shares[i+1], dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); del_count++; @@ -526,10 +528,10 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, /* the record may have shrunk a bit */ dbuf.dsize -= del_count * sizeof(*shares); - count = (ssize_t)data->num_share_mode_entries; + count = (ssize_t)data->u.num_share_mode_entries; /* store it back in the database */ - if (data->num_share_mode_entries == 0) { + if (data->u.num_share_mode_entries == 0) { if (tdb_delete(tdb, locking_key(dev, inode)) == -1) count = -1; } else { @@ -585,7 +587,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) if (!p) return False; data = (struct locking_data *)p; - data->num_share_mode_entries = 1; + data->u.num_share_mode_entries = 1; pstrcpy(p + sizeof(*data) + sizeof(share_mode_entry), fname); fill_share_mode(p + sizeof(*data), fsp, port, op_type); dbuf.dptr = p; @@ -599,7 +601,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) /* we're adding to an existing entry - this is a bit fiddly */ data = (struct locking_data *)dbuf.dptr; - data->num_share_mode_entries++; + data->u.num_share_mode_entries++; size = dbuf.dsize + sizeof(share_mode_entry); p = malloc(size); if (!p) @@ -640,7 +642,7 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); /* find any with our pid and call the supplied function */ - for (i=0;inum_share_mode_entries;i++) { + for (i=0;iu.num_share_mode_entries;i++) { if (share_modes_identical(entry, &shares[i])) { mod_fn(&shares[i], dev, inode, param); need_store=True; @@ -649,7 +651,7 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en /* if the mod fn was called then store it back */ if (need_store) { - if (data->num_share_mode_entries == 0) { + if (data->u.num_share_mode_entries == 0) { if (tdb_delete(tdb, locking_key(dev, inode)) == -1) need_store = False; } else { @@ -739,14 +741,14 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); /* Set/Unset the delete on close element. */ - for (i=0;inum_share_mode_entries;i++,shares++) { + for (i=0;iu.num_share_mode_entries;i++,shares++) { shares->share_mode = (delete_on_close ? (shares->share_mode | DELETE_ON_CLOSE_FLAG) : (shares->share_mode & ~DELETE_ON_CLOSE_FLAG) ); } /* store it back */ - if (data->num_share_mode_entries) { + if (data->u.num_share_mode_entries) { if (tdb_store(tdb, locking_key(dev,inode), dbuf, TDB_REPLACE)==-1) { SAFE_FREE(dbuf.dptr); return False; @@ -774,9 +776,9 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); - name = dbuf.dptr + sizeof(*data) + data->num_share_mode_entries*sizeof(*shares); + name = dbuf.dptr + sizeof(*data) + data->u.num_share_mode_entries*sizeof(*shares); - for (i=0;inum_share_mode_entries;i++) { + for (i=0;iu.num_share_mode_entries;i++) { traverse_callback(&shares[i], name); } return 0; -- cgit From 8c8b9c69e5c92c6e18710af33c7851c2fb8913d3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 19 Sep 2001 06:49:02 +0000 Subject: Removed test code that got added by accident. Jeremy. (This used to be commit fc91ecc236e0d27f5836e9820332ababd762f1a7) --- source3/locking/locking.c | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 23766f41dc..db0de5bb3f 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -361,18 +361,7 @@ static TDB_DATA locking_key_fsp(files_struct *fsp) BOOL lock_share_entry(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode) { -#if 1 /* JRATEST */ - int count = 0; - for (count = 0; count < LOCK_SHARE_ENTRY_SPIN_COUNT; count++) - if (tdb_chainlock(tdb, locking_key(dev, inode)) == 0) - return True; - else - DEBUG(0,("lock_share_entry: locking (%d) for dev = %x, inode = %.0f failed with error %s\n", - count, (unsigned int)dev, (double)inode, strerror(errno) )); - return False; -#else return tdb_chainlock(tdb, locking_key(dev, inode)) == 0; -#endif } /******************************************************************* @@ -391,18 +380,7 @@ void unlock_share_entry(connection_struct *conn, BOOL lock_share_entry_fsp(files_struct *fsp) { -#if 1 /* JRATEST */ - int count = 0; - for (count = 0; count < LOCK_SHARE_ENTRY_SPIN_COUNT; count++) - if (tdb_chainlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0) - return True; - else - DEBUG(0,("lock_share_entry_fsp: locking (%d) for dev = %x, inode = %.0f failed with error %s\n", - count, (unsigned int)fsp->dev, (double)fsp->inode, strerror(errno) )); - return False; -#else return tdb_chainlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0; -#endif } /******************************************************************* -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/locking/locking.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index db0de5bb3f..70995da3e2 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -36,7 +36,6 @@ */ #include "includes.h" -extern int DEBUGLEVEL; uint16 global_smbpid; /* the locking database handle */ -- cgit From 07f54cb59270e2c3168ab2bb3e73e7a8d8563843 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 19 Oct 2001 23:56:21 +0000 Subject: Ensure we mask off deny modes correctly on being set (this shouldn't have caused problems but is tidier). Fix debug statement in locking.c Jeremy. (This used to be commit eac6bbd24ebf00b35e50953bc11186111dc39059) --- source3/locking/locking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 70995da3e2..ca57bd6b8f 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -483,7 +483,7 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, * from the record. */ - DEBUG(10,("del_share_mode: num_share_modes = %d\n", data->u.num_share_mode_entries )); + DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.num_share_mode_entries )); for (i=0;iu.num_share_mode_entries;) { if (share_modes_identical(&shares[i], entry)) { @@ -494,7 +494,7 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); del_count++; - DEBUG(10,("del_share_mode: deleting entry %d\n", i )); + DEBUG(10,("del_share_entry: deleting entry %d\n", i )); } else { i++; -- cgit From 88b55f47b4914f7d390939e4394ec3edd42be91f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 20 Oct 2001 21:59:34 +0000 Subject: Move from timestamp to gen count file id's for finding oplocked files in a tdb. Jeremy. (This used to be commit 058ae6b58f61ef46013dd076af3a84de5fbaaab1) --- source3/locking/locking.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index ca57bd6b8f..b551d8c6d6 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -349,10 +349,6 @@ static TDB_DATA locking_key_fsp(files_struct *fsp) 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. ******************************************************************/ @@ -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_type = op_type; 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) { +#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 && (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) && - e1->time.tv_sec == e2->time.tv_sec && - e1->time.tv_usec == e2->time.tv_usec ); + e1->dev == e2->dev && + e1->inode == e2->inode && + e1->share_file_id == e2->share_file_id ); } /******************************************************************* -- cgit From e5c5adb197b29b729598a74929558cc5fcd37ce9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Nov 2001 04:00:35 +0000 Subject: Don't scan locking db on closedown. Jeremy. (This used to be commit 59cfcd8a6c510204ac059a0d2fddc2fa17199f82) --- source3/locking/locking.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index b551d8c6d6..023ec59e89 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -310,15 +310,19 @@ BOOL locking_init(int read_only) BOOL locking_end(void) { +#if 0 BOOL check_self = True; +#endif brl_shutdown(open_read_only); if (tdb) { /* delete any dead locks */ +#if 0 /* Don't scan on close. */ if (!open_read_only) tdb_traverse(tdb, delete_fn, &check_self); +#endif if (tdb_close(tdb) != 0) return False; -- cgit From 9e88a7ebe9b37d642241f404fb4867ee0239cf6f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Nov 2001 01:59:03 +0000 Subject: After conversations with Andrew, improved the robustness of the sharemode db in the following way. Originally, on startup and shutdown, smbd would scan the share mode db to ensure it was correct. This lead to scalability issues as scans lock the db for quite a long time. Andrew had the brainstorm that we only care about the record we're about to read. This new code (small change really, but quite significant) causes get_share_modes() to do a process_exists() call against each pid in each record, and to delete any that don't and re-write the entry if any dead records were detected. This allowed me to remove the startup/shutdown scans of the db (they can be added into smbstatus if anyone really cares to have them back). This will please the vfs author who was worried about the time taken on open() calls, and will lead to much greater robustness and scalability in the share mode db. We need much testing of this, and also netbench tests to ensure the extra process_exists() calls don't hurt performance (they shouldn't it's a very simple system call). Jeremy. (This used to be commit 4098d442030e66601450baeb09ae06b39a1ab571) --- source3/locking/locking.c | 79 +++++++++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 26 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 023ec59e89..8a8a33b808 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -275,8 +275,6 @@ static int open_read_only; BOOL locking_init(int read_only) { - BOOL check_self = False; - brl_init(read_only); if (tdb) @@ -295,10 +293,6 @@ BOOL locking_init(int read_only) if (!posix_locking_init(read_only)) return False; - /* delete any dead locks */ - if (!read_only) - tdb_traverse(tdb, delete_fn, &check_self); - open_read_only = read_only; return True; @@ -310,20 +304,10 @@ BOOL locking_init(int read_only) BOOL locking_end(void) { -#if 0 - BOOL check_self = True; -#endif brl_shutdown(open_read_only); if (tdb) { - /* delete any dead locks */ - -#if 0 /* Don't scan on close. */ - if (!open_read_only) - tdb_traverse(tdb, delete_fn, &check_self); -#endif - if (tdb_close(tdb) != 0) return False; } @@ -397,28 +381,71 @@ void unlock_share_entry_fsp(files_struct *fsp) int get_share_modes(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode, - share_mode_entry **shares) + share_mode_entry **pp_shares) { TDB_DATA dbuf; struct locking_data *data; - int ret; + int num_share_modes; + share_mode_entry *shares = NULL; - *shares = NULL; + *pp_shares = NULL; dbuf = tdb_fetch(tdb, locking_key(dev, inode)); if (!dbuf.dptr) return 0; data = (struct locking_data *)dbuf.dptr; - ret = data->u.num_share_mode_entries; - if(ret) - *shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data), ret * sizeof(**shares)); - SAFE_FREE(dbuf.dptr); + num_share_modes = data->u.num_share_mode_entries; + if(num_share_modes) { + int i; + int del_count = 0; - if (! *shares) - return 0; + shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data), + num_share_modes * sizeof(share_mode_entry)); - return ret; + if (!shares) { + SAFE_FREE(dbuf.dptr); + return 0; + } + + /* + * Ensure that each entry has a real process attached. + */ + + for (i = 0; i < num_share_modes; ) { + share_mode_entry *entry_p = &shares[i]; + if (process_exists(entry_p->pid)) + i++; + else { + memcpy( &shares[i], &shares[i+1], + sizeof(share_mode_entry) * (num_share_modes - i - 1)); + num_share_modes--; + del_count++; + } + } + + /* Did we delete any ? If so, re-store in tdb. */ + if (del_count) { + data->u.num_share_mode_entries = num_share_modes; + + if (num_share_modes) + memcpy(dbuf.dptr + sizeof(*data), shares, + num_share_modes * sizeof(share_mode_entry)); + + /* The record has shrunk a bit */ + dbuf.dsize -= del_count * sizeof(share_mode_entry); + + if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1) { + SAFE_FREE(shares); + SAFE_FREE(dbuf.dptr); + return 0; + } + } + } + + SAFE_FREE(dbuf.dptr); + *pp_shares = shares; + return num_share_modes; } /******************************************************************* -- cgit From 95a4903b20b892c461198dd1dff77ccca159d2ca Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 18 Dec 2001 05:04:09 +0000 Subject: Removed unused function, delete_fn() (This used to be commit f26e8205cff63967b9c1659b8e6ad71cbe36dace) --- source3/locking/locking.c | 57 ----------------------------------------------- 1 file changed, 57 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 8a8a33b808..cb523532d8 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -210,63 +210,6 @@ void locking_close_file(files_struct *fsp) } } -/**************************************************************************** - Delete a record if it is for a dead process, if check_self is true, then - delete any records belonging to this pid also (there shouldn't be any). - This function is only called on locking startup and shutdown. -****************************************************************************/ - -static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) -{ - struct locking_data *data; - share_mode_entry *shares; - int i, del_count=0; - pid_t mypid = sys_getpid(); - BOOL check_self = *(BOOL *)state; - int ret = 0; - - tdb_chainlock(tdb, kbuf); - - data = (struct locking_data *)dbuf.dptr; - shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); - - for (i=0;iu.num_share_mode_entries;) { - - if (check_self && (shares[i].pid == mypid)) { - DEBUG(0,("locking : delete_fn. LOGIC ERROR ! Shutting down and a record for my pid (%u) exists !\n", - (unsigned int)shares[i].pid )); - } else if (!process_exists(shares[i].pid)) { - DEBUG(0,("locking : delete_fn. LOGIC ERROR ! Entry for pid %u and it no longer exists !\n", - (unsigned int)shares[i].pid )); - } else { - /* Process exists, leave this record alone. */ - i++; - continue; - } - - data->u.num_share_mode_entries--; - memmove(&shares[i], &shares[i+1], - dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); - del_count++; - - } - - /* the record has shrunk a bit */ - dbuf.dsize -= del_count * sizeof(*shares); - - /* store it back in the database */ - if (data->u.num_share_mode_entries == 0) { - if (tdb_delete(ttdb, kbuf) == -1) - ret = -1; - } else { - if (tdb_store(ttdb, kbuf, dbuf, TDB_REPLACE) == -1) - ret = -1; - } - - tdb_chainunlock(tdb, kbuf); - return ret; -} - /**************************************************************************** Initialise the locking functions. ****************************************************************************/ -- cgit From 86b3aeb42a32a767e6411a730526d67472273c6f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 5 Jan 2002 02:37:23 +0000 Subject: Added DEBUG in set_share_mode to track down logic insanity. Jeremy. (This used to be commit 32f4f3a45d473b3be1ae07f6c60897c12323d60c) --- source3/locking/locking.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index cb523532d8..0eca0b61bc 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -552,6 +552,10 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) return False; data = (struct locking_data *)p; data->u.num_share_mode_entries = 1; + + DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n", + fsp->fsp_name )); + pstrcpy(p + sizeof(*data) + sizeof(share_mode_entry), fname); fill_share_mode(p + sizeof(*data), fsp, port, op_type); dbuf.dptr = p; @@ -566,6 +570,10 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) data = (struct locking_data *)dbuf.dptr; data->u.num_share_mode_entries++; + + DEBUG(10,("set_share_mode: adding entry for file %s. new num_share_modes = %d\n", + fsp->fsp_name, data->u.num_share_mode_entries )); + size = dbuf.dsize + sizeof(share_mode_entry); p = malloc(size); if (!p) -- cgit From c1efcac59c001f70dcb4468d927cadcd49fdcf7a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 8 Jan 2002 00:52:36 +0000 Subject: Debugs that print out a share mode table in debug level 10. This code enabled me to track down a *nasty* bug. Jeremy. (This used to be commit ed5a9a0ee32aec460b9247ab4e4f5e38e8149e08) --- source3/locking/locking.c | 50 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 0eca0b61bc..8aace93503 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -318,6 +318,38 @@ void unlock_share_entry_fsp(files_struct *fsp) tdb_chainunlock(tdb, locking_key(fsp->dev, fsp->inode)); } +/******************************************************************* + Print out a share mode. +********************************************************************/ + +static char *share_mode_str(int num, share_mode_entry *e) +{ + static pstring share_str; + + slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \ +pid = %u, share_mode = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f", + num, e->pid, e->share_mode, e->op_port, e->op_type, e->share_file_id, + (unsigned int)e->dev, (double)e->inode ); + + return share_str; +} + +/******************************************************************* + Print out a share mode table. +********************************************************************/ + +static void print_share_mode_table(struct locking_data *data) +{ + int num_share_modes = data->u.num_share_mode_entries; + share_mode_entry *shares = (share_mode_entry *)(data + 1); + int i; + + for (i = 0; i < num_share_modes; i++) { + share_mode_entry *entry_p = &shares[i]; + DEBUG(10,("print_share_mode_table: %s\n", share_mode_str(i, entry_p) )); + } +} + /******************************************************************* Get all share mode entries for a dev/inode pair. ********************************************************************/ @@ -344,7 +376,7 @@ int get_share_modes(connection_struct *conn, int del_count = 0; shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data), - num_share_modes * sizeof(share_mode_entry)); + num_share_modes * sizeof(share_mode_entry)); if (!shares) { SAFE_FREE(dbuf.dptr); @@ -357,11 +389,13 @@ int get_share_modes(connection_struct *conn, for (i = 0; i < num_share_modes; ) { share_mode_entry *entry_p = &shares[i]; - if (process_exists(entry_p->pid)) + if (process_exists(entry_p->pid)) { + DEBUG(10,("get_share_modes: %s\n", share_mode_str(i, entry_p) )); i++; - else { + } else { + DEBUG(10,("get_share_modes: deleted %s\n", share_mode_str(i, entry_p) )); memcpy( &shares[i], &shares[i+1], - sizeof(share_mode_entry) * (num_share_modes - i - 1)); + sizeof(share_mode_entry) * (num_share_modes - i - 1)); num_share_modes--; del_count++; } @@ -474,6 +508,8 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, for (i=0;iu.num_share_mode_entries;) { if (share_modes_identical(&shares[i], entry)) { + DEBUG(10,("del_share_entry: deleted %s\n", + share_mode_str(i, &shares[i]) )); if (ppse) *ppse = memdup(&shares[i], sizeof(*shares)); data->u.num_share_mode_entries--; @@ -503,6 +539,8 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, count = -1; } } + DEBUG(10,("del_share_entry: Remaining table.\n")); + print_share_mode_table((struct locking_data *)dbuf.dptr); SAFE_FREE(dbuf.dptr); return count; } @@ -562,6 +600,9 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) dbuf.dsize = size; if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1) ret = False; + + print_share_mode_table((struct locking_data *)p); + SAFE_FREE(p); return ret; } @@ -587,6 +628,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) dbuf.dsize = size; if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1) ret = False; + print_share_mode_table((struct locking_data *)p); SAFE_FREE(p); return ret; } -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/locking/locking.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 8aace93503..97366a1f9b 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. Locking functions Copyright (C) Andrew Tridgell 1992-2000 Copyright (C) Jeremy Allison 1992-2000 -- cgit From be389e25ddff982a490c2b88c4649ce437a0d4d7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Mar 2002 23:17:07 +0000 Subject: this attempts to handle the rather bizarre lock cache semantics in w2k. It isn't entirely accurate, but its close (This used to be commit e02d7364707c4939efa4ff0ddf9b6d4f48e5d411) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 97366a1f9b..dd6ca62e70 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -171,7 +171,7 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); - return NT_STATUS_LOCK_NOT_GRANTED; + return NT_STATUS_RANGE_NOT_LOCKED; } if (!lp_posix_locking(SNUM(conn))) -- cgit From 5e3b923124e82b1d19875746676df13cfdb0f918 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 13 Mar 2002 20:28:19 +0000 Subject: include/smb_macros.h: Don't round up an allocation if the size is zero. "One of these locks is not like the others... One of these locks is not quite the same" :-). When is a zero timeout lock not zero ? When it's being processed by Windows 2000 of course.. This code change, ugly though it is - completely fixes the foxpro/access multi-user file system database problems that people have been having. I used a *wonderful* test program donated by "Gerald Drouillard" which allowed me to completely reproduce this problem, and to finally determine the correct fix. This also explains why Windows 2000 is *so slow* when responding to the smbtorture lock tests. I *love* it when all these things come together and finally make sense :-). Jeremy. (This used to be commit 8aa9860ea2ea7f5aed4b6aa12794fffdfa81b0d0) --- source3/locking/locking.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index dd6ca62e70..8f3e4a278e 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -97,7 +97,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, Utility function called by locking requests. ****************************************************************************/ -NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, +static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type) { NTSTATUS status; @@ -141,6 +141,30 @@ NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, return status; } +/**************************************************************************** + Utility function called by locking requests. This is *DISGISTING*. It also + appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000 + is so slow on the locking tests...... ? This is the reason. Much though I hate + it, we need this. JRA. +****************************************************************************/ + +NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid, + SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type) +{ + int j, maxj = lp_lock_spin_count(); + int sleeptime = lp_lock_sleep_time(); + NTSTATUS status; + + for (j = 0; j < maxj; j++) { + status = do_lock(fsp, conn, lock_pid, count, offset, lock_type); + if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) && + !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) + break; + usleep(sleeptime); + } + return status; +} + /**************************************************************************** Utility function called by unlocking requests. ****************************************************************************/ -- cgit From f9af25c4ecaf30ccd9bb01762f65fe93ef566687 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 13 Mar 2002 20:49:57 +0000 Subject: Ensure we attempt to lock at least once. Only sleep if time param set. Jeremy. (This used to be commit 62b80d5c65ae8cf35347ee5c3d21ce1702c6449e) --- source3/locking/locking.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 8f3e4a278e..1090b0fcbf 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -155,12 +155,16 @@ NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid int sleeptime = lp_lock_sleep_time(); NTSTATUS status; + if (maxj <= 0) + maxj = 1; + for (j = 0; j < maxj; j++) { status = do_lock(fsp, conn, lock_pid, count, offset, lock_type); if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) && !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) break; - usleep(sleeptime); + if (sleeptime) + usleep(sleeptime); } return status; } -- cgit From d6d9e385cc6ce61de9fec572209134be728cf1b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 14 Mar 2002 01:05:34 +0000 Subject: Use sys_usleep not usleep. Jeremy. (This used to be commit 8587dd95f850b4c6d2f015fe97ef98759ee8c236) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 1090b0fcbf..7a2e8cf1d7 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -164,7 +164,7 @@ NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) break; if (sleeptime) - usleep(sleeptime); + sys_usleep(sleeptime); } return status; } -- cgit From 7d4378cc892550465b75aae563cd6f7ea1608c21 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 15 Mar 2002 09:51:37 +0000 Subject: if our lock spin code fails then return the first error code, not the last one. This is what caused the lock1 and lock2 tests to fail. (This used to be commit e7ae8003cb4fdc93db5f842754884a6d2ec93dc0) --- source3/locking/locking.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 7a2e8cf1d7..6efe4a73d7 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -153,20 +153,27 @@ NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid { int j, maxj = lp_lock_spin_count(); int sleeptime = lp_lock_sleep_time(); - NTSTATUS status; + NTSTATUS status, ret; if (maxj <= 0) maxj = 1; + ret = NT_STATUS_OK; /* to keep dumb compilers happy */ + for (j = 0; j < maxj; j++) { status = do_lock(fsp, conn, lock_pid, count, offset, lock_type); if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) && - !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) - break; + !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { + return status; + } + /* if we do fail then return the first error code we got */ + if (j == 0) { + ret = status; + } if (sleeptime) sys_usleep(sleeptime); } - return status; + return ret; } /**************************************************************************** -- cgit From c90cd26e9430b2fc065f620bdb6aaf4be0372fcc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 23 Mar 2002 02:57:44 +0000 Subject: Fix the mp3 rename bug - also tidy up our open code and remove the special cases for rename and unlink. Had to add desired_access into the share mode record. Jeremy. (This used to be commit 3b1b8ac43535fb0839c5474fa55bf7150f6cde31) --- source3/locking/locking.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 6efe4a73d7..87df805250 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -361,8 +361,8 @@ static char *share_mode_str(int num, share_mode_entry *e) static pstring share_str; slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \ -pid = %u, share_mode = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f", - num, e->pid, e->share_mode, e->op_port, e->op_type, e->share_file_id, +pid = %u, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f", + num, e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id, (unsigned int)e->dev, (double)e->inode ); return share_str; @@ -471,6 +471,7 @@ static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_t memset(e, '\0', sizeof(share_mode_entry)); e->pid = sys_getpid(); e->share_mode = fsp->share_mode; + e->desired_access = fsp->desired_access; e->op_port = port; e->op_type = op_type; memcpy(x, &fsp->open_time, sizeof(struct timeval)); @@ -481,7 +482,7 @@ static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_t /******************************************************************* Check if two share mode entries are identical, ignoring oplock - and port info. + and port info and desired_access. ********************************************************************/ BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2) -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/locking/locking.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 87df805250..d42d041b79 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -681,6 +681,7 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en int i; share_mode_entry *shares; BOOL need_store=False; + BOOL ret = True; /* read in the existing share modes */ dbuf = tdb_fetch(tdb, locking_key(dev, inode)); @@ -702,15 +703,15 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en if (need_store) { if (data->u.num_share_mode_entries == 0) { if (tdb_delete(tdb, locking_key(dev, inode)) == -1) - need_store = False; + ret = False; } else { if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1) - need_store = False; + ret = False; } } SAFE_FREE(dbuf.dptr); - return need_store; + return ret; } /******************************************************************* -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d42d041b79..3eb7ca4783 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -142,7 +142,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p } /**************************************************************************** - Utility function called by locking requests. This is *DISGISTING*. It also + Utility function called by locking requests. This is *DISGUSTING*. It also appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000 is so slow on the locking tests...... ? This is the reason. Much though I hate it, we need this. JRA. -- cgit From de474974ea25df7738dd175126e3f1de0df47ea6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 23 Nov 2002 02:52:36 +0000 Subject: Lots of fixes for error paths where tdb_fetch() data need freeing. Found via a post from Arcady Chernyak . Jeremy. (This used to be commit 5d5762d1787db4392d2dff16024097c638b2d494) --- source3/locking/locking.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 3eb7ca4783..e8b6f3428f 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -652,8 +652,10 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) size = dbuf.dsize + sizeof(share_mode_entry); p = malloc(size); - if (!p) + if (!p) { + SAFE_FREE(dbuf.dptr); return False; + } memcpy(p, dbuf.dptr, sizeof(*data)); fill_share_mode(p + sizeof(*data), fsp, port, op_type); memcpy(p + sizeof(*data) + sizeof(share_mode_entry), dbuf.dptr + sizeof(*data), -- cgit From 20f1cf6cdcf9fc74d18fb9401e627a3455183ef3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 3 Jan 2003 18:50:13 +0000 Subject: Fix problem with "hide unreadable". stat file opens are baaack :-). Jeremy. (This used to be commit 62038a0abf193d4dc4f37c31ac77216a10f6f326) --- source3/locking/locking.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e8b6f3428f..e5a72d2208 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -100,14 +100,13 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type) { - NTSTATUS status; + NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED; if (!lp_locking(SNUM(conn))) return NT_STATUS_OK; /* NOTE! 0 byte long ranges ARE allowed and should be stored */ - 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 )); -- cgit From 8a20407442efa0f9fe43e1b1c61140a0771c6ff8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 10 Feb 2003 11:47:21 +0000 Subject: Cleanups: (merge from HEAD) - use safe_strcpy() instead of pstrcpy() for malloc()ed strings - CUPS: a failure in an attempt to automaticly add a printer is not level 0 stuff. - Fix up a possible Realloc() failure segfault Andrew Bartlett (This used to be commit c1cfc296c2efdb2b5972202146e80f0e3b6a3da4) --- source3/locking/locking.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e5a72d2208..d4794560f6 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -611,6 +611,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) /* read in the existing share modes if any */ dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); if (!dbuf.dptr) { + size_t offset; /* we'll need to create a new record */ pstring fname; @@ -628,7 +629,8 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n", fsp->fsp_name )); - pstrcpy(p + sizeof(*data) + sizeof(share_mode_entry), fname); + offset = sizeof(*data) + sizeof(share_mode_entry); + safe_strcpy(p + offset, fname, size - offset); fill_share_mode(p + sizeof(*data), fsp, port, op_type); dbuf.dptr = p; dbuf.dsize = size; -- cgit From 98410be6074362acdd3c1799a59602f590c9decb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 03:03:15 +0000 Subject: Merge off-by-one fix from HEAD (caused crash with --enable-developer) (This used to be commit d71425413075af25f91f715950c06ab698cf5fb7) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d4794560f6..fdfd4d661c 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -630,7 +630,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) fsp->fsp_name )); offset = sizeof(*data) + sizeof(share_mode_entry); - safe_strcpy(p + offset, fname, size - offset); + safe_strcpy(p + offset, fname, size - offset - 1); fill_share_mode(p + sizeof(*data), fsp, port, op_type); dbuf.dptr = p; dbuf.dsize = size; -- cgit From fb3e4b87973e9ad0c818e8d9dd60329c47f22afe Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Feb 2003 01:04:34 +0000 Subject: Fix to allow blocking lock notification to be done rapidly (no wait for smb -> smb lock release). Adds new PENDING_LOCK type to lockdb (does not interfere with existing locks). Jeremy. (This used to be commit 766928bbba1e597c9c2b12458dd8d37e6080593e) --- source3/locking/locking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index fdfd4d661c..651f905e15 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -132,7 +132,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p */ (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum, lock_pid, sys_getpid(), conn->cnum, - offset, count); + offset, count, False); } } } @@ -201,7 +201,7 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, */ ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - lock_pid, sys_getpid(), conn->cnum, offset, count); + lock_pid, sys_getpid(), conn->cnum, offset, count, False); if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); -- cgit From 34226f1bd4d90ffe0f324277b11bbc4f2b575740 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Apr 2003 20:38:12 +0000 Subject: Fix for very subtle POSIX lock interaction race condition found by Herb. We need to unlock POSIX locks before notifying pending lock processes. Jeremy. (This used to be commit 6999eef51c3e597b3b2cd9cc26138acdfbb6a23a) --- source3/locking/locking.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 651f905e15..1b40187ac4 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -132,7 +132,8 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p */ (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum, lock_pid, sys_getpid(), conn->cnum, - offset, count, False); + offset, count, False, + NULL, NULL); } } } @@ -175,6 +176,25 @@ NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid return ret; } +/* Struct passed to brl_unlock. */ +struct posix_unlock_data_struct { + files_struct *fsp; + SMB_BIG_UINT offset; + SMB_BIG_UINT count; +}; + +/**************************************************************************** + Function passed to brl_unlock to allow POSIX unlock to be done first. +****************************************************************************/ + +static void posix_unlock(void *pre_data) +{ + struct posix_unlock_data_struct *pdata = (struct posix_unlock_data_struct *)pre_data; + + if (lp_posix_locking(SNUM(pdata->fsp->conn))) + release_posix_lock(pdata->fsp, pdata->offset, pdata->count); +} + /**************************************************************************** Utility function called by unlocking requests. ****************************************************************************/ @@ -183,6 +203,7 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, SMB_BIG_UINT count,SMB_BIG_UINT offset) { BOOL ok = False; + struct posix_unlock_data_struct posix_data; if (!lp_locking(SNUM(conn))) return NT_STATUS_OK; @@ -200,19 +221,18 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, * match then don't bother looking to remove POSIX locks. */ + posix_data.fsp = fsp; + posix_data.offset = offset; + posix_data.count = count; + ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - lock_pid, sys_getpid(), conn->cnum, offset, count, False); + lock_pid, sys_getpid(), conn->cnum, offset, count, + False, posix_unlock, (void *)&posix_data); if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); return NT_STATUS_RANGE_NOT_LOCKED; } - - if (!lp_posix_locking(SNUM(conn))) - return NT_STATUS_OK; - - (void)release_posix_lock(fsp, offset, count); - return NT_STATUS_OK; } -- cgit From 78a4f6fc4b8938fcab5bb3b7ae9c3a151f7070f8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 May 2003 18:56:51 +0000 Subject: More fixes for debug log to catch logic error. Jeremy. (This used to be commit 84a7714eba801fefa7ad56493f20813de3943bc5) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 1b40187ac4..1a5757f817 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -375,7 +375,7 @@ void unlock_share_entry_fsp(files_struct *fsp) Print out a share mode. ********************************************************************/ -static char *share_mode_str(int num, share_mode_entry *e) +char *share_mode_str(int num, share_mode_entry *e) { static pstring share_str; -- cgit From 80c1f1d865b13a63c7a60876b63458119566e044 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 22 Jul 2003 04:31:20 +0000 Subject: Fixup a bunch of printf-style functions and debugs to use unsigned long when displaying pid_t, uid_t and gid_t values. This removes a whole lot of warnings on some of the 64-bit build farm machines as well as help us out when 64-bit uid/gid/pid values come along. (This used to be commit f93528ba007c8800a850678f35f499fb7360fb9a) --- source3/locking/locking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 1a5757f817..f4de83c346 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -380,8 +380,8 @@ char *share_mode_str(int num, share_mode_entry *e) static pstring share_str; slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \ -pid = %u, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f", - num, e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id, +pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f", + num, (unsigned long)e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id, (unsigned int)e->dev, (double)e->inode ); return share_str; -- cgit From ef915c8eaf1d8335aa331d3b2376c40e3a63de22 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 1 Aug 2003 06:10:30 +0000 Subject: Final fix for the bug tridge found. Only push locks onto a blocking lock queue if the posix lock failed with EACCES or EAGAIN (this means another lock conflicts). Else return an error and don't queue the request. Jeremy. (This used to be commit 43fbc18fdc184bf29c15186c16bc99fb208de963) --- source3/locking/locking.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index f4de83c346..4475f1446f 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -125,7 +125,11 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p */ if (!set_posix_lock(fsp, offset, count, lock_type)) { - status = NT_STATUS_LOCK_NOT_GRANTED; + if (errno == EACCES || errno == EAGAIN) + status = NT_STATUS_FILE_LOCK_CONFLICT; + else + status = map_nt_error_from_unix(errno); + /* * We failed to map - we must now remove the brl * lock entry. -- cgit From 07c90e499e5e02db94d4ca3f3d303b2b1952ace9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 8 Sep 2003 20:42:33 +0000 Subject: Tidy up some formatting. Get ready for allowing bad password lockout. (based on a patch posted from Richard Renard . Jeremy. (This used to be commit abf54b58e95a949cb883d4485853dc560489c03f) --- source3/locking/locking.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 4475f1446f..91bc20af90 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -419,10 +419,10 @@ int get_share_modes(connection_struct *conn, struct locking_data *data; int num_share_modes; share_mode_entry *shares = NULL; - + TDB_DATA key = locking_key(dev, inode); *pp_shares = NULL; - dbuf = tdb_fetch(tdb, locking_key(dev, inode)); + dbuf = tdb_fetch(tdb, key); if (!dbuf.dptr) return 0; @@ -469,7 +469,7 @@ int get_share_modes(connection_struct *conn, /* The record has shrunk a bit */ dbuf.dsize -= del_count * sizeof(share_mode_entry); - if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1) { + if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) { SAFE_FREE(shares); SAFE_FREE(dbuf.dptr); return 0; @@ -544,12 +544,13 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, int i, del_count=0; share_mode_entry *shares; ssize_t count = 0; + TDB_DATA key = locking_key(dev, inode); if (ppse) *ppse = NULL; /* read in the existing share modes */ - dbuf = tdb_fetch(tdb, locking_key(dev, inode)); + dbuf = tdb_fetch(tdb, key); if (!dbuf.dptr) return -1; @@ -590,10 +591,10 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, /* store it back in the database */ if (data->u.num_share_mode_entries == 0) { - if (tdb_delete(tdb, locking_key(dev, inode)) == -1) + if (tdb_delete(tdb, key) == -1) count = -1; } else { - if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1) + if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) count = -1; } } @@ -630,10 +631,11 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) struct locking_data *data; char *p=NULL; int size; + TDB_DATA key = locking_key_fsp(fsp); BOOL ret = True; /* read in the existing share modes if any */ - dbuf = tdb_fetch(tdb, locking_key_fsp(fsp)); + dbuf = tdb_fetch(tdb, key); if (!dbuf.dptr) { size_t offset; /* we'll need to create a new record */ @@ -658,7 +660,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) fill_share_mode(p + sizeof(*data), fsp, port, op_type); dbuf.dptr = p; dbuf.dsize = size; - if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1) + if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) ret = False; print_share_mode_table((struct locking_data *)p); @@ -688,7 +690,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) SAFE_FREE(dbuf.dptr); dbuf.dptr = p; dbuf.dsize = size; - if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1) + if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) ret = False; print_share_mode_table((struct locking_data *)p); SAFE_FREE(p); @@ -709,9 +711,10 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en share_mode_entry *shares; BOOL need_store=False; BOOL ret = True; + TDB_DATA key = locking_key(dev, inode); /* read in the existing share modes */ - dbuf = tdb_fetch(tdb, locking_key(dev, inode)); + dbuf = tdb_fetch(tdb, key); if (!dbuf.dptr) return False; @@ -729,10 +732,10 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en /* if the mod fn was called then store it back */ if (need_store) { if (data->u.num_share_mode_entries == 0) { - if (tdb_delete(tdb, locking_key(dev, inode)) == -1) + if (tdb_delete(tdb, key) == -1) ret = False; } else { - if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1) + if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) ret = False; } } @@ -808,9 +811,10 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) struct locking_data *data; int i; share_mode_entry *shares; + TDB_DATA key = locking_key(dev, inode); /* read in the existing share modes */ - dbuf = tdb_fetch(tdb, locking_key(dev, inode)); + dbuf = tdb_fetch(tdb, key); if (!dbuf.dptr) return False; @@ -826,7 +830,7 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) /* store it back */ if (data->u.num_share_mode_entries) { - if (tdb_store(tdb, locking_key(dev,inode), dbuf, TDB_REPLACE)==-1) { + if (tdb_store(tdb, key, dbuf, TDB_REPLACE)==-1) { SAFE_FREE(dbuf.dptr); return False; } -- cgit From 22c024157129e287a6e4bb4bc7232144c36d9604 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Oct 2003 01:46:01 +0000 Subject: Changes to allow Samba3 to pass the Samba4 RAW-READ tests. Jeremy. (This used to be commit e7565dbba696adbb0fd8cca6b86a1a7e5a655f2e) --- source3/locking/locking.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 91bc20af90..c3abd63818 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -98,7 +98,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, ****************************************************************************/ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, - SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type) + SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx) { NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED; @@ -114,7 +114,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p status = brl_lock(fsp->dev, fsp->inode, fsp->fnum, lock_pid, sys_getpid(), conn->cnum, offset, count, - lock_type); + lock_type, my_lock_ctx); if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) { @@ -153,7 +153,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p ****************************************************************************/ NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid, - SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type) + SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx) { int j, maxj = lp_lock_spin_count(); int sleeptime = lp_lock_sleep_time(); @@ -165,7 +165,7 @@ NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid ret = NT_STATUS_OK; /* to keep dumb compilers happy */ for (j = 0; j < maxj; j++) { - status = do_lock(fsp, conn, lock_pid, count, offset, lock_type); + status = do_lock(fsp, conn, lock_pid, count, offset, lock_type, my_lock_ctx); if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) && !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { return status; @@ -173,6 +173,9 @@ NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid /* if we do fail then return the first error code we got */ if (j == 0) { ret = status; + /* Don't spin if we blocked ourselves. */ + if (*my_lock_ctx) + return ret; } if (sleeptime) sys_usleep(sleeptime); -- cgit From df6d2db4ced5586320804950da58a62248db4d56 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 12 Feb 2004 05:24:02 +0000 Subject: merge from old APP_HEAD * remove corrupt tdb and shutdown (only for printing tdbs, connections, sessionid & locking) * decrement smbd counter in connections.tdb in smb_panic() * various Makefile hack to get things to link 'max smbd processes' looks like it might be broken. The counter KEY is not being set. Will look into that tomorrow. (This used to be commit 6e22c5da929b6d9a4e32dc704c83112b2ad8fcfd) --- source3/locking/locking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index c3abd63818..42036cc70c 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -283,10 +283,10 @@ BOOL locking_init(int read_only) if (tdb) return True; - tdb = tdb_open_log(lock_path("locking.tdb"), + tdb = tdb_open_ex(lock_path("locking.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), read_only?O_RDONLY:O_RDWR|O_CREAT, - 0644); + 0644, smbd_tdb_log); if (!tdb) { DEBUG(0,("ERROR: Failed to initialise locking database\n")); -- cgit From ac5f0785c83d971a043cc99369dd491bee2be302 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 2 Jun 2004 23:19:36 +0000 Subject: r984: Ensure memmove & memcpy aren't called with len == 0. Jeremy. (This used to be commit 40c77dddc65e18b879d922379d562ffb8be80ab5) --- source3/locking/locking.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 42036cc70c..2a27d7d4cd 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -454,8 +454,10 @@ int get_share_modes(connection_struct *conn, i++; } else { DEBUG(10,("get_share_modes: deleted %s\n", share_mode_str(i, entry_p) )); - memcpy( &shares[i], &shares[i+1], - sizeof(share_mode_entry) * (num_share_modes - i - 1)); + if (num_share_modes - i - 1 > 0) { + memcpy( &shares[i], &shares[i+1], + sizeof(share_mode_entry) * (num_share_modes - i - 1)); + } num_share_modes--; del_count++; } @@ -575,8 +577,10 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, if (ppse) *ppse = memdup(&shares[i], sizeof(*shares)); data->u.num_share_mode_entries--; - memmove(&shares[i], &shares[i+1], - dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); + if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))) > 0) { + memmove(&shares[i], &shares[i+1], + dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); + } del_count++; DEBUG(10,("del_share_entry: deleting entry %d\n", i )); -- cgit From 386a11f49eff2ec60d75b9966ecdc5627b259f0d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 4 Jun 2004 17:26:09 +0000 Subject: r1011: fix bad merge (from a few months ago) and ensure that we always use tdb_open_log() instead of tdb_open_ex() (This used to be commit e65564ab4aa1240e84b8d272510aa770cad0ed0e) --- source3/locking/locking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 2a27d7d4cd..fd03a25940 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -283,10 +283,10 @@ BOOL locking_init(int read_only) if (tdb) return True; - tdb = tdb_open_ex(lock_path("locking.tdb"), + tdb = tdb_open_log(lock_path("locking.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), read_only?O_RDONLY:O_RDWR|O_CREAT, - 0644, smbd_tdb_log); + 0644); if (!tdb) { DEBUG(0,("ERROR: Failed to initialise locking database\n")); -- cgit From 2fc57c9a2ce3a266534dd20e6fed4883e052c557 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 8 Jun 2004 16:14:31 +0000 Subject: r1085: Now it's had some proper user testing, merge in the deferred open fix. I'm still doing more testing, but it fixes a behaviour that we've been wrong on ever since the start of Samba. Jeremy. (This used to be commit 894cc6d16296b934c112786eec896846156aee5d) --- source3/locking/locking.c | 392 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 387 insertions(+), 5 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index fd03a25940..8f53b55fc5 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -40,6 +40,17 @@ uint16 global_smbpid; /* the locking database handle */ static TDB_CONTEXT *tdb; +struct locking_data { + union { + int num_share_mode_entries; + share_mode_entry dummy; /* Needed for alignment. */ + } u; + /* the following two entries are implicit + share_mode_entry modes[num_share_mode_entries]; + char file_name[]; + */ +}; + /**************************************************************************** Debugging aid :-). ****************************************************************************/ @@ -432,6 +443,7 @@ int get_share_modes(connection_struct *conn, data = (struct locking_data *)dbuf.dptr; num_share_modes = data->u.num_share_mode_entries; if(num_share_modes) { + pstring fname; int i; int del_count = 0; @@ -443,6 +455,9 @@ int get_share_modes(connection_struct *conn, return 0; } + /* Save off the associated filename. */ + pstrcpy(fname, dbuf.dptr + sizeof(*data) + num_share_modes * sizeof(share_mode_entry)); + /* * Ensure that each entry has a real process attached. */ @@ -467,17 +482,28 @@ int get_share_modes(connection_struct *conn, if (del_count) { data->u.num_share_mode_entries = num_share_modes; - if (num_share_modes) + if (num_share_modes) { memcpy(dbuf.dptr + sizeof(*data), shares, num_share_modes * sizeof(share_mode_entry)); + /* Append the filename. */ + pstrcpy(dbuf.dptr + sizeof(*data) + num_share_modes * sizeof(share_mode_entry), fname); + } /* The record has shrunk a bit */ dbuf.dsize -= del_count * sizeof(share_mode_entry); - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) { - SAFE_FREE(shares); - SAFE_FREE(dbuf.dptr); - return 0; + if (data->u.num_share_mode_entries == 0) { + if (tdb_delete(tdb, key) == -1) { + SAFE_FREE(shares); + SAFE_FREE(dbuf.dptr); + return 0; + } + } else { + if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) { + SAFE_FREE(shares); + SAFE_FREE(dbuf.dptr); + return 0; + } } } } @@ -847,6 +873,358 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) return True; } +/******************************************************************* + Print out a deferred open entry. +********************************************************************/ + +char *deferred_open_str(int num, deferred_open_entry *e) +{ + static pstring de_str; + + slprintf(de_str, sizeof(de_str)-1, "deferred_open_entry[%d]: \ +pid = %lu, mid = %u, dev = 0x%x, inode = %.0f, port = %u, time = [%u.%06u]", + num, (unsigned long)e->pid, (unsigned int)e->mid, (unsigned int)e->dev, (double)e->inode, + (unsigned int)e->port, + (unsigned int)e->time.tv_sec, (unsigned int)e->time.tv_usec ); + + return de_str; +} + +/* Internal data structures for deferred opens... */ + +struct de_locking_key { + char name[4]; + SMB_DEV_T dev; + SMB_INO_T inode; +}; + +struct deferred_open_data { + union { + int num_deferred_open_entries; + deferred_open_entry dummy; /* Needed for alignment. */ + } u; + /* the following two entries are implicit + deferred_open_entry de_entries[num_deferred_open_entries]; + char file_name[]; + */ +}; + +/******************************************************************* + Print out a deferred open table. +********************************************************************/ + +static void print_deferred_open_table(struct deferred_open_data *data) +{ + int num_de_entries = data->u.num_deferred_open_entries; + deferred_open_entry *de_entries = (deferred_open_entry *)(data + 1); + int i; + + for (i = 0; i < num_de_entries; i++) { + deferred_open_entry *entry_p = &de_entries[i]; + DEBUG(10,("print_deferred_open_table: %s\n", deferred_open_str(i, entry_p) )); + } +} + + +/******************************************************************* + Form a static deferred open locking key for a dev/inode pair. +******************************************************************/ + +static TDB_DATA deferred_open_locking_key(SMB_DEV_T dev, SMB_INO_T inode) +{ + static struct de_locking_key key; + TDB_DATA kbuf; + + memset(&key, '\0', sizeof(key)); + memcpy(&key.name[0], "DOE", 4); + key.dev = dev; + key.inode = inode; + kbuf.dptr = (char *)&key; + kbuf.dsize = sizeof(key); + return kbuf; +} + +/******************************************************************* + Get all deferred open entries for a dev/inode pair. +********************************************************************/ + +int get_deferred_opens(connection_struct *conn, + SMB_DEV_T dev, SMB_INO_T inode, + deferred_open_entry **pp_de_entries) +{ + TDB_DATA dbuf; + struct deferred_open_data *data; + int num_de_entries; + deferred_open_entry *de_entries = NULL; + TDB_DATA key = deferred_open_locking_key(dev, inode); + + *pp_de_entries = NULL; + + dbuf = tdb_fetch(tdb, key); + if (!dbuf.dptr) + return 0; + + data = (struct deferred_open_data *)dbuf.dptr; + num_de_entries = data->u.num_deferred_open_entries; + if(num_de_entries) { + pstring fname; + int i; + int del_count = 0; + + de_entries = (deferred_open_entry *)memdup(dbuf.dptr + sizeof(*data), + num_de_entries * sizeof(deferred_open_entry)); + + if (!de_entries) { + SAFE_FREE(dbuf.dptr); + return 0; + } + + /* Save off the associated filename. */ + pstrcpy(fname, dbuf.dptr + sizeof(*data) + num_de_entries * sizeof(deferred_open_entry)); + + /* + * Ensure that each entry has a real process attached. + */ + + for (i = 0; i < num_de_entries; ) { + deferred_open_entry *entry_p = &de_entries[i]; + if (process_exists(entry_p->pid)) { + DEBUG(10,("get_deferred_opens: %s\n", deferred_open_str(i, entry_p) )); + i++; + } else { + DEBUG(10,("get_deferred_opens: deleted %s\n", deferred_open_str(i, entry_p) )); + if (num_de_entries - i - 1 > 0) { + memcpy( &de_entries[i], &de_entries[i+1], + sizeof(deferred_open_entry) * (num_de_entries - i - 1)); + } + num_de_entries--; + del_count++; + } + } + + /* Did we delete any ? If so, re-store in tdb. */ + if (del_count) { + data->u.num_deferred_open_entries = num_de_entries; + + if (num_de_entries) { + memcpy(dbuf.dptr + sizeof(*data), de_entries, + num_de_entries * sizeof(deferred_open_entry)); + /* Append the filename. */ + pstrcpy(dbuf.dptr + sizeof(*data) + num_de_entries * sizeof(deferred_open_entry), fname); + } + + /* The record has shrunk a bit */ + dbuf.dsize -= del_count * sizeof(deferred_open_entry); + + if (data->u.num_deferred_open_entries == 0) { + if (tdb_delete(tdb, key) == -1) { + SAFE_FREE(de_entries); + SAFE_FREE(dbuf.dptr); + return 0; + } + } else { + if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) { + SAFE_FREE(de_entries); + SAFE_FREE(dbuf.dptr); + return 0; + } + } + } + } + + SAFE_FREE(dbuf.dptr); + *pp_de_entries = de_entries; + return num_de_entries; +} + +/******************************************************************* + Check if two deferred open entries are identical. +********************************************************************/ + +static BOOL deferred_open_entries_identical( deferred_open_entry *e1, deferred_open_entry *e2) +{ +#if 1 /* JRA PARANOIA TEST - REMOVE LATER */ + if (e1->pid == e2->pid && + e1->port == e2->port && + e1->dev == e2->dev && + e1->inode == e2->inode && + ((e1->time.tv_sec != e2->time.tv_sec) || + (e1->time.tv_usec != e2->time.tv_usec) || + (e1->mid != e2->mid))) { + smb_panic("PANIC: deferred_open_entries_identical: logic error.\n"); + } +#endif + + return (e1->pid == e2->pid && + e1->mid == e2->mid && + e1->port == e2->port && + e1->dev == e2->dev && + e1->inode == e2->inode && + e1->time.tv_sec == e2->time.tv_sec && + e1->time.tv_usec == e2->time.tv_usec); +} + + +/******************************************************************* + Delete a specific deferred open entry. + Ignore if no entry deleted. +********************************************************************/ + +BOOL delete_deferred_open_entry(deferred_open_entry *entry) +{ + TDB_DATA dbuf; + struct deferred_open_data *data; + int i, del_count=0; + deferred_open_entry *de_entries; + BOOL ret = True; + TDB_DATA key = deferred_open_locking_key(entry->dev, entry->inode); + + /* read in the existing share modes */ + dbuf = tdb_fetch(tdb, key); + if (!dbuf.dptr) + return -1; + + data = (struct deferred_open_data *)dbuf.dptr; + de_entries = (deferred_open_entry *)(dbuf.dptr + sizeof(*data)); + + /* + * Find any with this pid and delete it + * by overwriting with the rest of the data + * from the record. + */ + + DEBUG(10,("delete_deferred_open_entry: num_deferred_open_entries = %d\n", + data->u.num_deferred_open_entries )); + + for (i=0;iu.num_deferred_open_entries;) { + if (deferred_open_entries_identical(&de_entries[i], entry)) { + DEBUG(10,("delete_deferred_open_entry: deleted %s\n", + deferred_open_str(i, &de_entries[i]) )); + + data->u.num_deferred_open_entries--; + if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*de_entries))) > 0) { + memmove(&de_entries[i], &de_entries[i+1], + dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*de_entries))); + } + del_count++; + + DEBUG(10,("delete_deferred_open_entry: deleting entry %d\n", i )); + + } else { + i++; + } + } + + SMB_ASSERT(del_count == 0 || del_count == 1); + + if (del_count) { + /* the record may have shrunk a bit */ + dbuf.dsize -= del_count * sizeof(*de_entries); + + /* store it back in the database */ + if (data->u.num_deferred_open_entries == 0) { + if (tdb_delete(tdb, key) == -1) + ret = False; + } else { + if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) + ret = False; + } + } + DEBUG(10,("delete_deferred_open_entry: Remaining table.\n")); + print_deferred_open_table((struct deferred_open_data*)dbuf.dptr); + SAFE_FREE(dbuf.dptr); + return ret; +} + +/******************************************************************* + Fill a deferred open entry. +********************************************************************/ + +static void fill_deferred_open(char *p, uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T inode, uint16 port) +{ + deferred_open_entry *e = (deferred_open_entry *)p; + void *x = &e->time; /* Needed to force alignment. p may not be aligned.... */ + + memset(e, '\0', sizeof(deferred_open_entry)); + e->mid = mid; + e->pid = sys_getpid(); + memcpy(x, ptv, sizeof(struct timeval)); + e->dev = dev; + e->inode = inode; + e->port = port; +} + +/******************************************************************* + Add a deferred open record. Return False on fail, True on success. +********************************************************************/ + +BOOL add_deferred_open(uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T inode, uint16 port, const char *fname) +{ + TDB_DATA dbuf; + struct deferred_open_data *data; + char *p=NULL; + int size; + TDB_DATA key = deferred_open_locking_key(dev, inode); + BOOL ret = True; + + /* read in the existing deferred open records if any */ + dbuf = tdb_fetch(tdb, key); + if (!dbuf.dptr) { + size_t offset; + /* we'll need to create a new record */ + + size = sizeof(*data) + sizeof(deferred_open_entry) + strlen(fname) + 1; + p = (char *)malloc(size); + if (!p) + return False; + data = (struct deferred_open_data *)p; + data->u.num_deferred_open_entries = 1; + + DEBUG(10,("add_deferred_open: creating entry for file %s. num_deferred_open_entries = 1\n", + fname )); + + offset = sizeof(*data) + sizeof(deferred_open_entry); + safe_strcpy(p + offset, fname, size - offset - 1); + fill_deferred_open(p + sizeof(*data), mid, ptv, dev, inode, port); + dbuf.dptr = p; + dbuf.dsize = size; + if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) + ret = False; + + print_deferred_open_table((struct deferred_open_data *)p); + + SAFE_FREE(p); + return ret; + } + + /* we're adding to an existing entry - this is a bit fiddly */ + data = (struct deferred_open_data *)dbuf.dptr; + + data->u.num_deferred_open_entries++; + + DEBUG(10,("add_deferred_open: adding entry for file %s. new num_deferred_open_entries = %d\n", + fname, data->u.num_deferred_open_entries )); + + size = dbuf.dsize + sizeof(deferred_open_entry); + p = malloc(size); + if (!p) { + SAFE_FREE(dbuf.dptr); + return False; + } + memcpy(p, dbuf.dptr, sizeof(*data)); + fill_deferred_open(p + sizeof(*data), mid, ptv, dev, inode, port); + memcpy(p + sizeof(*data) + sizeof(deferred_open_entry), dbuf.dptr + sizeof(*data), + dbuf.dsize - sizeof(*data)); + SAFE_FREE(dbuf.dptr); + dbuf.dptr = p; + dbuf.dsize = size; + if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) + ret = False; + print_deferred_open_table((struct deferred_open_data *)p); + SAFE_FREE(p); + return ret; +} + /**************************************************************************** Traverse the whole database with this function, calling traverse_callback on each share mode @@ -862,6 +1240,10 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, SHAREMODE_FN(traverse_callback) = (SHAREMODE_FN_CAST())state; + /* Ensure this is a locking_key record. */ + if (kbuf.dsize != sizeof(struct locking_key)) + return 0; + data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); name = dbuf.dptr + sizeof(*data) + data->u.num_share_mode_entries*sizeof(*shares); -- cgit From f820b921cdeba93f21237e32f9872340d3afc347 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 19 Sep 2004 01:16:45 +0000 Subject: r2413: Arggg. Stupid, stupid, stupid me ! I added a paranoia test case when I was developing the deferred open case and made it too tight. It will fire (incorrectly) and panic when a client does a second open for a file with a different mid (multiplex-id) request. Doh ! This is a perfectly valid thing for a client to do (have two pending opens with different mids outstanding on the same file) and currently when the first pending open expires with a share violation the paranoia code will panic smbd. It's a rare condition, but obvious now I've looked at the code. Fix for bug #1743. Jeremy. (This used to be commit e1bf108ae965ae730c67524164fa36497ea905b5) --- source3/locking/locking.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 8f53b55fc5..d4e8c493d5 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1043,18 +1043,6 @@ int get_deferred_opens(connection_struct *conn, static BOOL deferred_open_entries_identical( deferred_open_entry *e1, deferred_open_entry *e2) { -#if 1 /* JRA PARANOIA TEST - REMOVE LATER */ - if (e1->pid == e2->pid && - e1->port == e2->port && - e1->dev == e2->dev && - e1->inode == e2->inode && - ((e1->time.tv_sec != e2->time.tv_sec) || - (e1->time.tv_usec != e2->time.tv_usec) || - (e1->mid != e2->mid))) { - smb_panic("PANIC: deferred_open_entries_identical: logic error.\n"); - } -#endif - return (e1->pid == e2->pid && e1->mid == e2->mid && e1->port == e2->port && @@ -1064,7 +1052,6 @@ static BOOL deferred_open_entries_identical( deferred_open_entry *e1, deferred_o e1->time.tv_usec == e2->time.tv_usec); } - /******************************************************************* Delete a specific deferred open entry. Ignore if no entry deleted. -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/locking/locking.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d4e8c493d5..b2f30a5684 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -679,7 +679,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) pstrcat(fname, fsp->fsp_name); size = sizeof(*data) + sizeof(share_mode_entry) + strlen(fname) + 1; - p = (char *)malloc(size); + p = (char *)SMB_MALLOC(size); if (!p) return False; data = (struct locking_data *)p; @@ -711,7 +711,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) fsp->fsp_name, data->u.num_share_mode_entries )); size = dbuf.dsize + sizeof(share_mode_entry); - p = malloc(size); + p = SMB_MALLOC(size); if (!p) { SAFE_FREE(dbuf.dptr); return False; @@ -1161,7 +1161,7 @@ BOOL add_deferred_open(uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T /* we'll need to create a new record */ size = sizeof(*data) + sizeof(deferred_open_entry) + strlen(fname) + 1; - p = (char *)malloc(size); + p = (char *)SMB_MALLOC(size); if (!p) return False; data = (struct deferred_open_data *)p; @@ -1193,7 +1193,7 @@ BOOL add_deferred_open(uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T fname, data->u.num_deferred_open_entries )); size = dbuf.dsize + sizeof(deferred_open_entry); - p = malloc(size); + p = SMB_MALLOC(size); if (!p) { SAFE_FREE(dbuf.dptr); return False; -- cgit From 695188cc262c08807760670c2b6d8c70deda2cdc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Dec 2004 01:07:06 +0000 Subject: r4108: As check_self is *always* False in every invokation, remove the logic for it. We still pass Samba4 RAW-LOCK test. Jeremy. (This used to be commit 596f23051363f8cc8896119b3eca0663a61a38c3) --- source3/locking/locking.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index b2f30a5684..b6e2ced336 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -62,14 +62,11 @@ static const char *lock_type_name(enum brl_type lock_type) /**************************************************************************** Utility function called to see if a file region is locked. - If check_self is True, then checks on our own fd with the same locking context - are still made. If check_self is False, then checks are not made on our own fd - with the same locking context are not made. ****************************************************************************/ BOOL is_locked(files_struct *fsp,connection_struct *conn, SMB_BIG_UINT count,SMB_BIG_UINT offset, - enum brl_type lock_type, BOOL check_self) + enum brl_type lock_type) { int snum = SNUM(conn); BOOL ret; @@ -82,7 +79,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum, global_smbpid, sys_getpid(), conn->cnum, - offset, count, lock_type, check_self); + offset, count, lock_type); DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n", (double)offset, (double)count, ret ? "locked" : "unlocked", -- cgit From 822fcec39d6597524a94b0e8b9c244d5eb62b972 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Dec 2004 22:10:40 +0000 Subject: r4121: Optimisation from Nadav Danieli . If we're oplocked, short circuit some is_locked() tests. Jeremy. (This used to be commit f4feed8f90be98eaea59bebcc142fd398ffe2a59) --- source3/locking/locking.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index b6e2ced336..4c6d89571e 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -77,9 +77,17 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, if (!lp_locking(snum) || !lp_strict_locking(snum)) return(False); - ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum, + if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) { + DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name )); + ret = 0; + } else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK)) { + DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name )); + ret = 0; + } else { + ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum, global_smbpid, sys_getpid(), conn->cnum, offset, count, lock_type); + } DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n", (double)offset, (double)count, ret ? "locked" : "unlocked", -- cgit From 934566332835eed5a3b768e07642c569eca37001 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 11 Dec 2004 00:30:28 +0000 Subject: r4143: Make strict locking an enum. Auto means use oplock optimization. Jeremy. (This used to be commit 0dd4adeae2042d0ea64398a78b3f48eb0150c133) --- source3/locking/locking.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 4c6d89571e..e10e8a1fa0 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -69,24 +69,31 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, enum brl_type lock_type) { int snum = SNUM(conn); + int strict_locking = lp_strict_locking(snum); BOOL ret; if (count == 0) return(False); - if (!lp_locking(snum) || !lp_strict_locking(snum)) + if (!lp_locking(snum) || !strict_locking) return(False); - if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) { - DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name )); - ret = 0; - } else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK)) { - DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name )); - ret = 0; + if (strict_locking == Auto) { + if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) { + DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name )); + ret = 0; + } else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK)) { + DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name )); + ret = 0; + } else { + ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum, + global_smbpid, sys_getpid(), conn->cnum, + offset, count, lock_type); + } } else { ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, sys_getpid(), conn->cnum, - offset, count, lock_type); + global_smbpid, sys_getpid(), conn->cnum, + offset, count, lock_type); } DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n", -- cgit From ed1f7121a39d863066ef47e985b77fe3dbedbc9b Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 27 Apr 2005 18:32:37 +0000 Subject: r6502: add LOCKING debug class - pull PRINTINGDB class definition from trunk so our numbers don't get out of sync (This used to be commit 58e307664e02ebf0415f19ed625d2f166d9cb1cc) --- source3/locking/locking.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e10e8a1fa0..75b40d74a4 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -37,6 +37,9 @@ #include "includes.h" uint16 global_smbpid; +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_LOCKING + /* the locking database handle */ static TDB_CONTEXT *tdb; -- cgit From fc396cb2202dadc9acf741957d2dc3420bd0a7ac Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 1 May 2005 07:01:18 +0000 Subject: r6543: Fix EDEADLCK problem with deferred open calls. Problem found by "Hu, David J" Jeremy. (This used to be commit ec86ac4b28e99df41d3dd77586ea259500e5dfcd) --- source3/locking/locking.c | 46 +++++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 75b40d74a4..f0a45c2bcb 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -42,6 +42,7 @@ uint16 global_smbpid; /* the locking database handle */ static TDB_CONTEXT *tdb; +static TDB_CONTEXT *deferred_open_tdb; struct locking_data { union { @@ -318,7 +319,21 @@ BOOL locking_init(int read_only) DEBUG(0,("ERROR: Failed to initialise locking database\n")); return False; } - + + if (!read_only && !deferred_open_tdb) { + deferred_open_tdb = tdb_open_log(lock_path("deferred_open.tdb"), + 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST, + O_RDWR|O_CREAT, + 0644); + + if (!deferred_open_tdb) { + DEBUG(0,("ERROR: Failed to initialise deferred open database\n")); + tdb_close(tdb); + tdb = NULL; + return False; + } + } + if (!posix_locking_init(read_only)) return False; @@ -333,15 +348,20 @@ BOOL locking_init(int read_only) BOOL locking_end(void) { + BOOL ret = True; brl_shutdown(open_read_only); if (tdb) { - if (tdb_close(tdb) != 0) - return False; + ret = False; } - return True; + if (deferred_open_tdb) { + if (tdb_close(tdb) != 0) + ret = False; + } + + return ret; } /******************************************************************* @@ -975,7 +995,7 @@ int get_deferred_opens(connection_struct *conn, *pp_de_entries = NULL; - dbuf = tdb_fetch(tdb, key); + dbuf = tdb_fetch(deferred_open_tdb, key); if (!dbuf.dptr) return 0; @@ -1032,13 +1052,13 @@ int get_deferred_opens(connection_struct *conn, dbuf.dsize -= del_count * sizeof(deferred_open_entry); if (data->u.num_deferred_open_entries == 0) { - if (tdb_delete(tdb, key) == -1) { + if (tdb_delete(deferred_open_tdb, key) == -1) { SAFE_FREE(de_entries); SAFE_FREE(dbuf.dptr); return 0; } } else { - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) { + if (tdb_store(deferred_open_tdb, key, dbuf, TDB_REPLACE) == -1) { SAFE_FREE(de_entries); SAFE_FREE(dbuf.dptr); return 0; @@ -1082,7 +1102,7 @@ BOOL delete_deferred_open_entry(deferred_open_entry *entry) TDB_DATA key = deferred_open_locking_key(entry->dev, entry->inode); /* read in the existing share modes */ - dbuf = tdb_fetch(tdb, key); + dbuf = tdb_fetch(deferred_open_tdb, key); if (!dbuf.dptr) return -1; @@ -1125,10 +1145,10 @@ BOOL delete_deferred_open_entry(deferred_open_entry *entry) /* store it back in the database */ if (data->u.num_deferred_open_entries == 0) { - if (tdb_delete(tdb, key) == -1) + if (tdb_delete(deferred_open_tdb, key) == -1) ret = False; } else { - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) + if (tdb_store(deferred_open_tdb, key, dbuf, TDB_REPLACE) == -1) ret = False; } } @@ -1170,7 +1190,7 @@ BOOL add_deferred_open(uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T BOOL ret = True; /* read in the existing deferred open records if any */ - dbuf = tdb_fetch(tdb, key); + dbuf = tdb_fetch(deferred_open_tdb, key); if (!dbuf.dptr) { size_t offset; /* we'll need to create a new record */ @@ -1190,7 +1210,7 @@ BOOL add_deferred_open(uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T fill_deferred_open(p + sizeof(*data), mid, ptv, dev, inode, port); dbuf.dptr = p; dbuf.dsize = size; - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) + if (tdb_store(deferred_open_tdb, key, dbuf, TDB_REPLACE) == -1) ret = False; print_deferred_open_table((struct deferred_open_data *)p); @@ -1220,7 +1240,7 @@ BOOL add_deferred_open(uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T SAFE_FREE(dbuf.dptr); dbuf.dptr = p; dbuf.dsize = size; - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) + if (tdb_store(deferred_open_tdb, key, dbuf, TDB_REPLACE) == -1) ret = False; print_deferred_open_table((struct deferred_open_data *)p); SAFE_FREE(p); -- cgit From 114067ced1d301a3c8b67aee0af0eab771d44dd4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 May 2005 07:27:44 +0000 Subject: r6594: Fix silly typo causing tdb to be freed twice. Jeremy. (This used to be commit 4f431dfc6b57e1609672c4daa53ab5d62613f6d1) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index f0a45c2bcb..3c5ab63b4a 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -357,7 +357,7 @@ BOOL locking_end(void) } if (deferred_open_tdb) { - if (tdb_close(tdb) != 0) + if (tdb_close(deferred_open_tdb) != 0) ret = False; } -- cgit From af8a691db11a5072865f8b03fd1cbd3aab5cb6d7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Jul 2005 04:51:27 +0000 Subject: r8219: Merge the new open code from HEAD to 3.0. Haven't yet run the torture tests on this as it's very late NY time (just wanted to get this work into the tree). I'll test this over the weekend.... Jerry - in looking at the difference between the two trees there seem to be some printing/ntprinting.c and registry changes we might want to examine to try keep in sync. Jeremy. (This used to be commit c7fe18761e2c753afbffd3a78abff46472a9b8eb) --- source3/locking/locking.c | 120 ++++++++++++++++++++++++++-------------------- 1 file changed, 69 insertions(+), 51 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 3c5ab63b4a..5bcf7f2eda 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -3,6 +3,7 @@ Locking functions Copyright (C) Andrew Tridgell 1992-2000 Copyright (C) Jeremy Allison 1992-2000 + Copyright (C) Volker Lendecke 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -46,7 +47,10 @@ static TDB_CONTEXT *deferred_open_tdb; struct locking_data { union { - int num_share_mode_entries; + struct { + int num_share_mode_entries; + BOOL delete_on_close; + } s; share_mode_entry dummy; /* Needed for alignment. */ } u; /* the following two entries are implicit @@ -432,10 +436,14 @@ char *share_mode_str(int num, share_mode_entry *e) { static pstring share_str; - slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \ -pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f", - num, (unsigned long)e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id, - (unsigned int)e->dev, (double)e->inode ); + slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: " + "pid = %lu, share_access = 0x%x, private_options = 0x%x, " + "access_mask = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, " + "dev = 0x%x, inode = %.0f", + num, (unsigned long)e->pid, + e->share_access, e->private_options, + e->access_mask, e->op_port, e->op_type, e->share_file_id, + (unsigned int)e->dev, (double)e->inode ); return share_str; } @@ -446,7 +454,7 @@ pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, fi static void print_share_mode_table(struct locking_data *data) { - int num_share_modes = data->u.num_share_mode_entries; + int num_share_modes = data->u.s.num_share_mode_entries; share_mode_entry *shares = (share_mode_entry *)(data + 1); int i; @@ -460,9 +468,9 @@ static void print_share_mode_table(struct locking_data *data) Get all share mode entries for a dev/inode pair. ********************************************************************/ -int get_share_modes(connection_struct *conn, - SMB_DEV_T dev, SMB_INO_T inode, - share_mode_entry **pp_shares) +int get_share_modes(SMB_DEV_T dev, SMB_INO_T inode, + share_mode_entry **pp_shares, + BOOL *delete_on_close) { TDB_DATA dbuf; struct locking_data *data; @@ -470,13 +478,18 @@ int get_share_modes(connection_struct *conn, share_mode_entry *shares = NULL; TDB_DATA key = locking_key(dev, inode); *pp_shares = NULL; + *delete_on_close = False; dbuf = tdb_fetch(tdb, key); if (!dbuf.dptr) return 0; data = (struct locking_data *)dbuf.dptr; - num_share_modes = data->u.num_share_mode_entries; + + *delete_on_close = data->u.s.delete_on_close; + DEBUG(10, ("get_share_modes: delete_on_close: %d\n", + *delete_on_close)); + num_share_modes = data->u.s.num_share_mode_entries; if(num_share_modes) { pstring fname; int i; @@ -515,7 +528,7 @@ int get_share_modes(connection_struct *conn, /* Did we delete any ? If so, re-store in tdb. */ if (del_count) { - data->u.num_share_mode_entries = num_share_modes; + data->u.s.num_share_mode_entries = num_share_modes; if (num_share_modes) { memcpy(dbuf.dptr + sizeof(*data), shares, @@ -527,7 +540,7 @@ int get_share_modes(connection_struct *conn, /* The record has shrunk a bit */ dbuf.dsize -= del_count * sizeof(share_mode_entry); - if (data->u.num_share_mode_entries == 0) { + if (data->u.s.num_share_mode_entries == 0) { if (tdb_delete(tdb, key) == -1) { SAFE_FREE(shares); SAFE_FREE(dbuf.dptr); @@ -548,6 +561,15 @@ int get_share_modes(connection_struct *conn, return num_share_modes; } +BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode) +{ + share_mode_entry *shares; + BOOL result; + get_share_modes(dev, inode, &shares, &result); + SAFE_FREE(shares); + return result; +} + /******************************************************************* Fill a share mode entry. ********************************************************************/ @@ -559,8 +581,9 @@ static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_t memset(e, '\0', sizeof(share_mode_entry)); e->pid = sys_getpid(); - e->share_mode = fsp->share_mode; - e->desired_access = fsp->desired_access; + e->share_access = fsp->share_access; + e->private_options = fsp->fh->private_options; + e->access_mask = fsp->access_mask; e->op_port = port; e->op_type = op_type; memcpy(x, &fsp->open_time, sizeof(struct timeval)); @@ -581,16 +604,17 @@ BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2) 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) )); + (e1->share_access) != (e2->share_access)) { + DEBUG(0,("PANIC: share_modes_identical: share_mode " + "mismatch (e1 = 0x%x, e2 = 0x%x). Logic error.\n", + (unsigned int)e1->share_access, + (unsigned int)e2->share_access )); smb_panic("PANIC: share_modes_identical logic error.\n"); } #endif return (e1->pid == e2->pid && - (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) && + (e1->share_access) == (e2->share_access) && e1->dev == e2->dev && e1->inode == e2->inode && e1->share_file_id == e2->share_file_id ); @@ -602,8 +626,9 @@ BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2) Ignore if no entry deleted. ********************************************************************/ -ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, - share_mode_entry *entry, share_mode_entry **ppse) +ssize_t del_share_entry(SMB_DEV_T dev, SMB_INO_T inode, + share_mode_entry *entry, share_mode_entry **ppse, + BOOL *delete_on_close) { TDB_DATA dbuf; struct locking_data *data; @@ -621,6 +646,7 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, return -1; data = (struct locking_data *)dbuf.dptr; + *delete_on_close = data->u.s.delete_on_close; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); /* @@ -629,15 +655,15 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, * from the record. */ - DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.num_share_mode_entries )); + DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.s.num_share_mode_entries )); - for (i=0;iu.num_share_mode_entries;) { + for (i=0;iu.s.num_share_mode_entries;) { if (share_modes_identical(&shares[i], entry)) { DEBUG(10,("del_share_entry: deleted %s\n", share_mode_str(i, &shares[i]) )); if (ppse) *ppse = memdup(&shares[i], sizeof(*shares)); - data->u.num_share_mode_entries--; + data->u.s.num_share_mode_entries--; if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))) > 0) { memmove(&shares[i], &shares[i+1], dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); @@ -655,10 +681,10 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, /* the record may have shrunk a bit */ dbuf.dsize -= del_count * sizeof(*shares); - count = (ssize_t)data->u.num_share_mode_entries; + count = (ssize_t)data->u.s.num_share_mode_entries; /* store it back in the database */ - if (data->u.num_share_mode_entries == 0) { + if (data->u.s.num_share_mode_entries == 0) { if (tdb_delete(tdb, key) == -1) count = -1; } else { @@ -677,7 +703,8 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, of entries left, and a memdup'ed copy of the entry deleted. ********************************************************************/ -ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse) +ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse, + BOOL *delete_on_close) { share_mode_entry entry; @@ -686,7 +713,8 @@ ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse) */ fill_share_mode((char *)&entry, fsp, 0, 0); - return del_share_entry(fsp->dev, fsp->inode, &entry, ppse); + return del_share_entry(fsp->dev, fsp->inode, &entry, ppse, + delete_on_close); } /******************************************************************* @@ -718,7 +746,8 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) if (!p) return False; data = (struct locking_data *)p; - data->u.num_share_mode_entries = 1; + ZERO_STRUCT(data->u); /* Keep valgrind happy */ + data->u.s.num_share_mode_entries = 1; DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n", fsp->fsp_name )); @@ -740,10 +769,10 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) /* we're adding to an existing entry - this is a bit fiddly */ data = (struct locking_data *)dbuf.dptr; - data->u.num_share_mode_entries++; + data->u.s.num_share_mode_entries++; DEBUG(10,("set_share_mode: adding entry for file %s. new num_share_modes = %d\n", - fsp->fsp_name, data->u.num_share_mode_entries )); + fsp->fsp_name, data->u.s.num_share_mode_entries )); size = dbuf.dsize + sizeof(share_mode_entry); p = SMB_MALLOC(size); @@ -790,7 +819,7 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); /* find any with our pid and call the supplied function */ - for (i=0;iu.num_share_mode_entries;i++) { + for (i=0;iu.s.num_share_mode_entries;i++) { if (share_modes_identical(entry, &shares[i])) { mod_fn(&shares[i], dev, inode, param); need_store=True; @@ -799,7 +828,7 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en /* if the mod fn was called then store it back */ if (need_store) { - if (data->u.num_share_mode_entries == 0) { + if (data->u.s.num_share_mode_entries == 0) { if (tdb_delete(tdb, key) == -1) ret = False; } else { @@ -877,8 +906,7 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) { TDB_DATA dbuf; struct locking_data *data; - int i; - share_mode_entry *shares; + BOOL res; TDB_DATA key = locking_key(dev, inode); /* read in the existing share modes */ @@ -887,25 +915,14 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) return False; data = (struct locking_data *)dbuf.dptr; - shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); /* Set/Unset the delete on close element. */ - for (i=0;iu.num_share_mode_entries;i++,shares++) { - shares->share_mode = (delete_on_close ? - (shares->share_mode | DELETE_ON_CLOSE_FLAG) : - (shares->share_mode & ~DELETE_ON_CLOSE_FLAG) ); - } + data->u.s.delete_on_close = delete_on_close; - /* store it back */ - if (data->u.num_share_mode_entries) { - if (tdb_store(tdb, key, dbuf, TDB_REPLACE)==-1) { - SAFE_FREE(dbuf.dptr); - return False; - } - } + res = (tdb_store(tdb, key, dbuf, TDB_REPLACE)!=-1); SAFE_FREE(dbuf.dptr); - return True; + return res; } /******************************************************************* @@ -1200,6 +1217,7 @@ BOOL add_deferred_open(uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T if (!p) return False; data = (struct deferred_open_data *)p; + ZERO_STRUCT(data->u.dummy); /* Keep valgrind happy */ data->u.num_deferred_open_entries = 1; DEBUG(10,("add_deferred_open: creating entry for file %s. num_deferred_open_entries = 1\n", @@ -1268,9 +1286,9 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); - name = dbuf.dptr + sizeof(*data) + data->u.num_share_mode_entries*sizeof(*shares); + name = dbuf.dptr + sizeof(*data) + data->u.s.num_share_mode_entries*sizeof(*shares); - for (i=0;iu.num_share_mode_entries;i++) { + for (i=0;iu.s.num_share_mode_entries;i++) { traverse_callback(&shares[i], name); } return 0; -- cgit From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: r10656: BIG merge from trunk. Features not copied over * \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3) --- source3/locking/locking.c | 1204 +++++++++++++++++---------------------------- 1 file changed, 455 insertions(+), 749 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 5bcf7f2eda..e3131e26a2 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -43,7 +43,6 @@ uint16 global_smbpid; /* the locking database handle */ static TDB_CONTEXT *tdb; -static TDB_CONTEXT *deferred_open_tdb; struct locking_data { union { @@ -51,10 +50,10 @@ struct locking_data { int num_share_mode_entries; BOOL delete_on_close; } s; - share_mode_entry dummy; /* Needed for alignment. */ + struct share_mode_entry dummy; /* Needed for alignment. */ } u; /* the following two entries are implicit - share_mode_entry modes[num_share_mode_entries]; + struct share_mode_entry modes[num_share_mode_entries]; char file_name[]; */ }; @@ -90,17 +89,18 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) { DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name )); ret = 0; - } else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK)) { + } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) && + (lock_type == READ_LOCK)) { DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name )); ret = 0; } else { ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, sys_getpid(), conn->cnum, + global_smbpid, procid_self(), conn->cnum, offset, count, lock_type); } } else { ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, sys_getpid(), conn->cnum, + global_smbpid, procid_self(), conn->cnum, offset, count, lock_type); } @@ -143,7 +143,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) { status = brl_lock(fsp->dev, fsp->inode, fsp->fnum, - lock_pid, sys_getpid(), conn->cnum, + lock_pid, procid_self(), conn->cnum, offset, count, lock_type, my_lock_ctx); @@ -166,7 +166,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p * lock entry. */ (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - lock_pid, sys_getpid(), conn->cnum, + lock_pid, procid_self(), conn->cnum, offset, count, False, NULL, NULL); } @@ -264,7 +264,7 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, posix_data.count = count; ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - lock_pid, sys_getpid(), conn->cnum, offset, count, + lock_pid, procid_self(), conn->cnum, offset, count, False, posix_unlock, (void *)&posix_data); if (!ok) { @@ -280,7 +280,7 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, void locking_close_file(files_struct *fsp) { - pid_t pid = sys_getpid(); + struct process_id pid = procid_self(); if (!lp_locking(SNUM(fsp->conn))) return; @@ -324,20 +324,6 @@ BOOL locking_init(int read_only) return False; } - if (!read_only && !deferred_open_tdb) { - deferred_open_tdb = tdb_open_log(lock_path("deferred_open.tdb"), - 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST, - O_RDWR|O_CREAT, - 0644); - - if (!deferred_open_tdb) { - DEBUG(0,("ERROR: Failed to initialise deferred open database\n")); - tdb_close(tdb); - tdb = NULL; - return False; - } - } - if (!posix_locking_init(read_only)) return False; @@ -360,11 +346,6 @@ BOOL locking_end(void) ret = False; } - if (deferred_open_tdb) { - if (tdb_close(deferred_open_tdb) != 0) - ret = False; - } - return ret; } @@ -372,6 +353,16 @@ BOOL locking_end(void) Form a static locking key for a dev/inode pair. ******************************************************************/ +/* key and data records in the tdb locking database */ +struct locking_key { + SMB_DEV_T dev; + SMB_INO_T ino; +}; + +/******************************************************************* + Form a static locking key for a dev/inode pair. +******************************************************************/ + static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode) { static struct locking_key key; @@ -379,70 +370,27 @@ static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode) memset(&key, '\0', sizeof(key)); key.dev = dev; - key.inode = inode; + key.ino = inode; kbuf.dptr = (char *)&key; kbuf.dsize = sizeof(key); return kbuf; } -static TDB_DATA locking_key_fsp(files_struct *fsp) -{ - return locking_key(fsp->dev, fsp->inode); -} - -/******************************************************************* - Lock a hash bucket entry. -******************************************************************/ - -BOOL lock_share_entry(connection_struct *conn, - SMB_DEV_T dev, SMB_INO_T inode) -{ - return tdb_chainlock(tdb, locking_key(dev, inode)) == 0; -} - -/******************************************************************* - Unlock a hash bucket entry. -******************************************************************/ - -void unlock_share_entry(connection_struct *conn, - SMB_DEV_T dev, SMB_INO_T inode) -{ - tdb_chainunlock(tdb, locking_key(dev, inode)); -} - -/******************************************************************* - Lock a hash bucket entry. use a fsp for convenience -******************************************************************/ - -BOOL lock_share_entry_fsp(files_struct *fsp) -{ - return tdb_chainlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0; -} - -/******************************************************************* - Unlock a hash bucket entry. -******************************************************************/ - -void unlock_share_entry_fsp(files_struct *fsp) -{ - tdb_chainunlock(tdb, locking_key(fsp->dev, fsp->inode)); -} - /******************************************************************* Print out a share mode. ********************************************************************/ -char *share_mode_str(int num, share_mode_entry *e) +char *share_mode_str(int num, struct share_mode_entry *e) { static pstring share_str; slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: " - "pid = %lu, share_access = 0x%x, private_options = 0x%x, " - "access_mask = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, " + "pid = %s, share_access = 0x%x, private_options = 0x%x, " + "access_mask = 0x%x, mid = 0x%x, type= 0x%x, file_id = %lu, " "dev = 0x%x, inode = %.0f", - num, (unsigned long)e->pid, + num, procid_str_static(&e->pid), e->share_access, e->private_options, - e->access_mask, e->op_port, e->op_type, e->share_file_id, + e->access_mask, e->op_mid, e->op_type, e->share_file_id, (unsigned int)e->dev, (double)e->inode ); return share_str; @@ -455,12 +403,14 @@ char *share_mode_str(int num, share_mode_entry *e) static void print_share_mode_table(struct locking_data *data) { int num_share_modes = data->u.s.num_share_mode_entries; - share_mode_entry *shares = (share_mode_entry *)(data + 1); + struct share_mode_entry *shares = + (struct share_mode_entry *)(data + 1); int i; for (i = 0; i < num_share_modes; i++) { - share_mode_entry *entry_p = &shares[i]; - DEBUG(10,("print_share_mode_table: %s\n", share_mode_str(i, entry_p) )); + struct share_mode_entry *entry_p = &shares[i]; + DEBUG(10,("print_share_mode_table: %s\n", + share_mode_str(i, entry_p))); } } @@ -468,825 +418,581 @@ static void print_share_mode_table(struct locking_data *data) Get all share mode entries for a dev/inode pair. ********************************************************************/ -int get_share_modes(SMB_DEV_T dev, SMB_INO_T inode, - share_mode_entry **pp_shares, - BOOL *delete_on_close) +static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) { - TDB_DATA dbuf; struct locking_data *data; - int num_share_modes; - share_mode_entry *shares = NULL; - TDB_DATA key = locking_key(dev, inode); - *pp_shares = NULL; - *delete_on_close = False; - - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) - return 0; - - data = (struct locking_data *)dbuf.dptr; + int i; - *delete_on_close = data->u.s.delete_on_close; - DEBUG(10, ("get_share_modes: delete_on_close: %d\n", - *delete_on_close)); - num_share_modes = data->u.s.num_share_mode_entries; - if(num_share_modes) { - pstring fname; - int i; - int del_count = 0; - - shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data), - num_share_modes * sizeof(share_mode_entry)); - - if (!shares) { - SAFE_FREE(dbuf.dptr); - return 0; - } + if (dbuf.dsize < sizeof(struct locking_data)) { + DEBUG(0, ("parse_share_modes: buffer too short\n")); + return False; + } - /* Save off the associated filename. */ - pstrcpy(fname, dbuf.dptr + sizeof(*data) + num_share_modes * sizeof(share_mode_entry)); + data = (struct locking_data *)dbuf.dptr; - /* - * Ensure that each entry has a real process attached. - */ + lck->delete_on_close = data->u.s.delete_on_close; + lck->num_share_modes = data->u.s.num_share_mode_entries; - for (i = 0; i < num_share_modes; ) { - share_mode_entry *entry_p = &shares[i]; - if (process_exists(entry_p->pid)) { - DEBUG(10,("get_share_modes: %s\n", share_mode_str(i, entry_p) )); - i++; - } else { - DEBUG(10,("get_share_modes: deleted %s\n", share_mode_str(i, entry_p) )); - if (num_share_modes - i - 1 > 0) { - memcpy( &shares[i], &shares[i+1], - sizeof(share_mode_entry) * (num_share_modes - i - 1)); - } - num_share_modes--; - del_count++; - } - } + DEBUG(10, ("parse_share_modes: delete_on_close: %d, " + "num_share_modes: %d\n", lck->delete_on_close, + lck->num_share_modes)); - /* Did we delete any ? If so, re-store in tdb. */ - if (del_count) { - data->u.s.num_share_mode_entries = num_share_modes; - - if (num_share_modes) { - memcpy(dbuf.dptr + sizeof(*data), shares, - num_share_modes * sizeof(share_mode_entry)); - /* Append the filename. */ - pstrcpy(dbuf.dptr + sizeof(*data) + num_share_modes * sizeof(share_mode_entry), fname); - } - - /* The record has shrunk a bit */ - dbuf.dsize -= del_count * sizeof(share_mode_entry); - - if (data->u.s.num_share_mode_entries == 0) { - if (tdb_delete(tdb, key) == -1) { - SAFE_FREE(shares); - SAFE_FREE(dbuf.dptr); - return 0; - } - } else { - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) { - SAFE_FREE(shares); - SAFE_FREE(dbuf.dptr); - return 0; - } - } - } + if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) { + DEBUG(0, ("invalid number of share modes: %d\n", + lck->num_share_modes)); + return False; } - SAFE_FREE(dbuf.dptr); - *pp_shares = shares; - return num_share_modes; -} + lck->share_modes = NULL; -BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode) -{ - share_mode_entry *shares; - BOOL result; - get_share_modes(dev, inode, &shares, &result); - SAFE_FREE(shares); - return result; -} + if (lck->num_share_modes != 0) { -/******************************************************************* - Fill a share mode entry. -********************************************************************/ + if (dbuf.dsize < (sizeof(struct locking_data) + + (lck->num_share_modes * + sizeof(struct share_mode_entry)))) { + DEBUG(0, ("parse_share_modes: buffer too short\n")); + return False; + } + + lck->share_modes = talloc_memdup(lck, dbuf.dptr+sizeof(*data), + lck->num_share_modes * + sizeof(struct share_mode_entry)); -static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_type) -{ - share_mode_entry *e = (share_mode_entry *)p; - void *x = &e->time; /* Needed to force alignment. p may not be aligned.... */ + if (lck->share_modes == NULL) { + DEBUG(0, ("talloc failed\n")); + return False; + } + } - memset(e, '\0', sizeof(share_mode_entry)); - e->pid = sys_getpid(); - e->share_access = fsp->share_access; - e->private_options = fsp->fh->private_options; - e->access_mask = fsp->access_mask; - e->op_port = port; - e->op_type = op_type; - memcpy(x, &fsp->open_time, sizeof(struct timeval)); - e->share_file_id = fsp->file_id; - e->dev = fsp->dev; - e->inode = fsp->inode; -} + /* Save off the associated filename. */ + lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) + + lck->num_share_modes * + sizeof(struct share_mode_entry)); -/******************************************************************* - Check if two share mode entries are identical, ignoring oplock - and port info and desired_access. -********************************************************************/ + /* + * Ensure that each entry has a real process attached. + */ -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_access) != (e2->share_access)) { - DEBUG(0,("PANIC: share_modes_identical: share_mode " - "mismatch (e1 = 0x%x, e2 = 0x%x). Logic error.\n", - (unsigned int)e1->share_access, - (unsigned int)e2->share_access )); - smb_panic("PANIC: share_modes_identical logic error.\n"); + for (i = 0; i < lck->num_share_modes; i++) { + struct share_mode_entry *entry_p = &lck->share_modes[i]; + DEBUG(10,("parse_share_modes: %s\n", + share_mode_str(i, entry_p) )); + if (!process_exists(entry_p->pid)) { + DEBUG(10,("parse_share_modes: deleted %s\n", + share_mode_str(i, entry_p) )); + entry_p->op_type = UNUSED_SHARE_MODE_ENTRY; + lck->modified = True; + } } -#endif - return (e1->pid == e2->pid && - (e1->share_access) == (e2->share_access) && - e1->dev == e2->dev && - e1->inode == e2->inode && - e1->share_file_id == e2->share_file_id ); + return True; } -/******************************************************************* - Delete a specific share mode. Return the number - of entries left, and a memdup'ed copy of the entry deleted (if required). - Ignore if no entry deleted. -********************************************************************/ - -ssize_t del_share_entry(SMB_DEV_T dev, SMB_INO_T inode, - share_mode_entry *entry, share_mode_entry **ppse, - BOOL *delete_on_close) +static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) { - TDB_DATA dbuf; + TDB_DATA result; + int num_valid = 0; + int i; struct locking_data *data; - int i, del_count=0; - share_mode_entry *shares; - ssize_t count = 0; - TDB_DATA key = locking_key(dev, inode); - - if (ppse) - *ppse = NULL; - - /* read in the existing share modes */ - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) - return -1; - - data = (struct locking_data *)dbuf.dptr; - *delete_on_close = data->u.s.delete_on_close; - shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); - - /* - * Find any with this pid and delete it - * by overwriting with the rest of the data - * from the record. - */ - - DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.s.num_share_mode_entries )); - - for (i=0;iu.s.num_share_mode_entries;) { - if (share_modes_identical(&shares[i], entry)) { - DEBUG(10,("del_share_entry: deleted %s\n", - share_mode_str(i, &shares[i]) )); - if (ppse) - *ppse = memdup(&shares[i], sizeof(*shares)); - data->u.s.num_share_mode_entries--; - if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))) > 0) { - memmove(&shares[i], &shares[i+1], - dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); - } - del_count++; + ssize_t offset; - DEBUG(10,("del_share_entry: deleting entry %d\n", i )); + result.dptr = NULL; + result.dsize = 0; - } else { - i++; + for (i=0; inum_share_modes; i++) { + if (!is_unused_share_mode_entry(&lck->share_modes[i])) { + num_valid += 1; } } - if (del_count) { - /* the record may have shrunk a bit */ - dbuf.dsize -= del_count * sizeof(*shares); - - count = (ssize_t)data->u.s.num_share_mode_entries; - - /* store it back in the database */ - if (data->u.s.num_share_mode_entries == 0) { - if (tdb_delete(tdb, key) == -1) - count = -1; - } else { - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) - count = -1; - } + if (num_valid == 0) { + return result; } - DEBUG(10,("del_share_entry: Remaining table.\n")); - print_share_mode_table((struct locking_data *)dbuf.dptr); - SAFE_FREE(dbuf.dptr); - return count; -} -/******************************************************************* - Del the share mode of a file for this process. Return the number - of entries left, and a memdup'ed copy of the entry deleted. -********************************************************************/ - -ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse, - BOOL *delete_on_close) -{ - share_mode_entry entry; + result.dsize = sizeof(*data) + + lck->num_share_modes * sizeof(struct share_mode_entry) + + strlen(lck->filename) + 1; + result.dptr = talloc_size(lck, result.dsize); - /* - * Fake up a share_mode_entry for comparisons. - */ + if (result.dptr == NULL) { + smb_panic("talloc failed\n"); + } - fill_share_mode((char *)&entry, fsp, 0, 0); - return del_share_entry(fsp->dev, fsp->inode, &entry, ppse, - delete_on_close); + data = (struct locking_data *)result.dptr; + ZERO_STRUCTP(data); + data->u.s.num_share_mode_entries = lck->num_share_modes; + data->u.s.delete_on_close = lck->delete_on_close; + DEBUG(10, ("unparse_share_modes: del: %d, num: %d\n", + data->u.s.delete_on_close, + data->u.s.num_share_mode_entries)); + memcpy(result.dptr + sizeof(*data), lck->share_modes, + sizeof(struct share_mode_entry)*lck->num_share_modes); + offset = sizeof(*data) + + sizeof(struct share_mode_entry)*lck->num_share_modes; + safe_strcpy(result.dptr + offset, lck->filename, + result.dsize - offset - 1); + print_share_mode_table(data); + return result; } -/******************************************************************* - Set the share mode of a file. Return False on fail, True on success. -********************************************************************/ - -BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type) +static int share_mode_lock_destructor(void *p) { - TDB_DATA dbuf; - struct locking_data *data; - char *p=NULL; - int size; - TDB_DATA key = locking_key_fsp(fsp); - BOOL ret = True; - - /* read in the existing share modes if any */ - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) { - size_t offset; - /* we'll need to create a new record */ - pstring fname; - - pstrcpy(fname, fsp->conn->connectpath); - pstrcat(fname, "/"); - pstrcat(fname, fsp->fsp_name); - - size = sizeof(*data) + sizeof(share_mode_entry) + strlen(fname) + 1; - p = (char *)SMB_MALLOC(size); - if (!p) - return False; - data = (struct locking_data *)p; - ZERO_STRUCT(data->u); /* Keep valgrind happy */ - data->u.s.num_share_mode_entries = 1; - - DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n", - fsp->fsp_name )); + struct share_mode_lock *lck = + talloc_get_type_abort(p, struct share_mode_lock); + TDB_DATA key = locking_key(lck->dev, lck->ino); + TDB_DATA data; - offset = sizeof(*data) + sizeof(share_mode_entry); - safe_strcpy(p + offset, fname, size - offset - 1); - fill_share_mode(p + sizeof(*data), fsp, port, op_type); - dbuf.dptr = p; - dbuf.dsize = size; - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) - ret = False; + if (!lck->modified) { + goto done; + } - print_share_mode_table((struct locking_data *)p); + data = unparse_share_modes(lck); - SAFE_FREE(p); - return ret; + if (data.dptr == NULL) { + if (!lck->fresh) { + /* There has been an entry before, delete it */ + if (tdb_delete(tdb, key) == -1) { + smb_panic("Could not delete share entry\n"); + } + } + goto done; } - /* we're adding to an existing entry - this is a bit fiddly */ - data = (struct locking_data *)dbuf.dptr; + if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) { + smb_panic("Could not store share mode entry\n"); + } - data->u.s.num_share_mode_entries++; - - DEBUG(10,("set_share_mode: adding entry for file %s. new num_share_modes = %d\n", - fsp->fsp_name, data->u.s.num_share_mode_entries )); + done: + tdb_chainunlock(tdb, key); - size = dbuf.dsize + sizeof(share_mode_entry); - p = SMB_MALLOC(size); - if (!p) { - SAFE_FREE(dbuf.dptr); - return False; - } - memcpy(p, dbuf.dptr, sizeof(*data)); - fill_share_mode(p + sizeof(*data), fsp, port, op_type); - memcpy(p + sizeof(*data) + sizeof(share_mode_entry), dbuf.dptr + sizeof(*data), - dbuf.dsize - sizeof(*data)); - SAFE_FREE(dbuf.dptr); - dbuf.dptr = p; - dbuf.dsize = size; - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) - ret = False; - print_share_mode_table((struct locking_data *)p); - SAFE_FREE(p); - return ret; + return 0; } -/******************************************************************* - A generic in-place modification call for share mode entries. -********************************************************************/ - -static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *entry, - void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *), - void *param) +struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, + SMB_DEV_T dev, SMB_INO_T ino, + const char *fname) { - TDB_DATA dbuf; - struct locking_data *data; - int i; - share_mode_entry *shares; - BOOL need_store=False; - BOOL ret = True; - TDB_DATA key = locking_key(dev, inode); - - /* read in the existing share modes */ - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) - return False; + struct share_mode_lock *lck; + TDB_DATA key = locking_key(dev, ino); + TDB_DATA data; - data = (struct locking_data *)dbuf.dptr; - shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); + lck = TALLOC_P(mem_ctx, struct share_mode_lock); + if (lck == NULL) { + DEBUG(0, ("talloc failed\n")); + return NULL; + } - /* find any with our pid and call the supplied function */ - for (i=0;iu.s.num_share_mode_entries;i++) { - if (share_modes_identical(entry, &shares[i])) { - mod_fn(&shares[i], dev, inode, param); - need_store=True; - } + lck->dev = dev; + lck->ino = ino; + lck->delete_on_close = False; + lck->num_share_modes = 0; + lck->share_modes = NULL; + lck->modified = False; + + if (tdb_chainlock(tdb, key) != 0) { + DEBUG(3, ("Could not lock share entry\n")); + talloc_free(lck); + return NULL; } - /* if the mod fn was called then store it back */ - if (need_store) { - if (data->u.s.num_share_mode_entries == 0) { - if (tdb_delete(tdb, key) == -1) - ret = False; - } else { - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) - ret = False; + data = tdb_fetch(tdb, key); + lck->fresh = (data.dptr == NULL); + + if (lck->fresh) { + if (fname == NULL) { + DEBUG(0, ("New file, but no filename supplied\n")); + talloc_free(lck); + return NULL; + } + lck->filename = talloc_strdup(lck, fname); + if (lck->filename == NULL) { + DEBUG(0, ("talloc failed\n")); + talloc_free(lck); + return NULL; + } + } else { + if (!parse_share_modes(data, lck)) { + DEBUG(0, ("Could not parse share modes\n")); + talloc_free(lck); + SAFE_FREE(data.dptr); + return NULL; } } - SAFE_FREE(dbuf.dptr); - return ret; -} + talloc_set_destructor(lck, share_mode_lock_destructor); + SAFE_FREE(data.dptr); -/******************************************************************* - Static function that actually does the work for the generic function - below. -********************************************************************/ + return lck; +} -static void remove_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode, - void *param) +BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode, + const char *fname) { - 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 = NO_OPLOCK; + BOOL result; + struct share_mode_lock *lck = get_share_mode_lock(NULL, dev, inode, + fname); + result = lck->delete_on_close; + talloc_free(lck); + return result; } -/******************************************************************* - Remove an oplock port and mode entry from a share mode. -********************************************************************/ - -BOOL remove_share_oplock(files_struct *fsp) +BOOL is_valid_share_mode_entry(const struct share_mode_entry *e) { - share_mode_entry entry; - /* - * Fake up an entry for comparisons... - */ - fill_share_mode((char *)&entry, fsp, 0, 0); - return mod_share_mode(fsp->dev, fsp->inode, &entry, remove_share_oplock_fn, NULL); + int num_props = 0; + + num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0); + num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0); + num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0); + + SMB_ASSERT(num_props <= 1); + return (num_props != 0); } -/******************************************************************* - Static function that actually does the work for the generic function - below. -********************************************************************/ +BOOL is_deferred_open_entry(const struct share_mode_entry *e) +{ + return (e->op_type == DEFERRED_OPEN_ENTRY); +} -static void downgrade_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode, - void *param) +BOOL is_unused_share_mode_entry(const struct share_mode_entry *e) { - 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; + return (e->op_type == UNUSED_SHARE_MODE_ENTRY); } /******************************************************************* - Downgrade a oplock type from exclusive to level II. + Fill a share mode entry. ********************************************************************/ -BOOL downgrade_share_oplock(files_struct *fsp) +static void fill_share_mode_entry(struct share_mode_entry *e, + files_struct *fsp, + uint16 mid, uint16 op_type) { - share_mode_entry entry; - /* - * Fake up an entry for comparisons... - */ - fill_share_mode((char *)&entry, fsp, 0, 0); - return mod_share_mode(fsp->dev, fsp->inode, &entry, downgrade_share_oplock_fn, NULL); + ZERO_STRUCTP(e); + e->pid = procid_self(); + e->share_access = fsp->share_access; + e->private_options = fsp->fh->private_options; + e->access_mask = fsp->access_mask; + e->op_mid = mid; + e->op_type = op_type; + e->time.tv_sec = fsp->open_time.tv_sec; + e->time.tv_usec = fsp->open_time.tv_usec; + e->share_file_id = fsp->file_id; + e->dev = fsp->dev; + e->inode = fsp->inode; } -/******************************************************************* - Get/Set the delete on close flag in a set of share modes. - Return False on fail, True on success. -********************************************************************/ - -BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close) +static void fill_deferred_open_entry(struct share_mode_entry *e, + const struct timeval request_time, + SMB_DEV_T dev, SMB_INO_T ino, uint16 mid) { - TDB_DATA dbuf; - struct locking_data *data; - BOOL res; - TDB_DATA key = locking_key(dev, inode); + ZERO_STRUCTP(e); + e->pid = procid_self(); + e->op_mid = mid; + e->op_type = DEFERRED_OPEN_ENTRY; + e->time.tv_sec = request_time.tv_sec; + e->time.tv_usec = request_time.tv_usec; + e->dev = dev; + e->inode = ino; +} - /* read in the existing share modes */ - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) - return False; +static void add_share_mode_entry(struct share_mode_lock *lck, + const struct share_mode_entry *entry) +{ + int i; - data = (struct locking_data *)dbuf.dptr; + for (i=0; inum_share_modes; i++) { + struct share_mode_entry *e = &lck->share_modes[i]; + if (is_unused_share_mode_entry(e)) { + *e = *entry; + break; + } + } - /* Set/Unset the delete on close element. */ - data->u.s.delete_on_close = delete_on_close; + if (i == lck->num_share_modes) { + /* No unused entry found */ + ADD_TO_ARRAY(lck, struct share_mode_entry, *entry, + &lck->share_modes, &lck->num_share_modes); + } + lck->modified = True; +} - res = (tdb_store(tdb, key, dbuf, TDB_REPLACE)!=-1); +void set_share_mode(struct share_mode_lock *lck, files_struct *fsp, + uint16 mid, uint16 op_type) +{ + struct share_mode_entry entry; + fill_share_mode_entry(&entry, fsp, mid, op_type); + add_share_mode_entry(lck, &entry); +} - SAFE_FREE(dbuf.dptr); - return res; +void add_deferred_open(struct share_mode_lock *lck, uint16 mid, + struct timeval request_time, + SMB_DEV_T dev, SMB_INO_T ino) +{ + struct share_mode_entry entry; + fill_deferred_open_entry(&entry, request_time, dev, ino, mid); + add_share_mode_entry(lck, &entry); } /******************************************************************* - Print out a deferred open entry. + Check if two share mode entries are identical, ignoring oplock + and mid info and desired_access. ********************************************************************/ -char *deferred_open_str(int num, deferred_open_entry *e) +static BOOL share_modes_identical(struct share_mode_entry *e1, + struct share_mode_entry *e2) { - static pstring de_str; - - slprintf(de_str, sizeof(de_str)-1, "deferred_open_entry[%d]: \ -pid = %lu, mid = %u, dev = 0x%x, inode = %.0f, port = %u, time = [%u.%06u]", - num, (unsigned long)e->pid, (unsigned int)e->mid, (unsigned int)e->dev, (double)e->inode, - (unsigned int)e->port, - (unsigned int)e->time.tv_sec, (unsigned int)e->time.tv_usec ); +#if 1 /* JRA PARANOIA TEST - REMOVE LATER */ + if (procid_equal(&e1->pid, &e2->pid) && + e1->share_file_id == e2->share_file_id && + e1->dev == e2->dev && + e1->inode == e2->inode && + (e1->share_access) != (e2->share_access)) { + DEBUG(0,("PANIC: share_modes_identical: share_mode " + "mismatch (e1 = 0x%x, e2 = 0x%x). Logic error.\n", + (unsigned int)e1->share_access, + (unsigned int)e2->share_access )); + smb_panic("PANIC: share_modes_identical logic error.\n"); + } +#endif - return de_str; + return (procid_equal(&e1->pid, &e2->pid) && + (e1->share_access) == (e2->share_access) && + e1->dev == e2->dev && + e1->inode == e2->inode && + e1->share_file_id == e2->share_file_id ); } -/* Internal data structures for deferred opens... */ +static BOOL deferred_open_identical(struct share_mode_entry *e1, + struct share_mode_entry *e2) +{ + return (procid_equal(&e1->pid, &e2->pid) && + (e1->op_mid == e2->op_mid) && + (e1->dev == e2->dev) && + (e1->inode == e2->inode)); +} -struct de_locking_key { - char name[4]; - SMB_DEV_T dev; - SMB_INO_T inode; -}; +static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck, + struct share_mode_entry *entry) +{ + int i; -struct deferred_open_data { - union { - int num_deferred_open_entries; - deferred_open_entry dummy; /* Needed for alignment. */ - } u; - /* the following two entries are implicit - deferred_open_entry de_entries[num_deferred_open_entries]; - char file_name[]; - */ -}; + for (i=0; inum_share_modes; i++) { + struct share_mode_entry *e = &lck->share_modes[i]; + if (is_valid_share_mode_entry(entry) && + is_valid_share_mode_entry(e) && + share_modes_identical(e, entry)) { + return e; + } + if (is_deferred_open_entry(entry) && + is_deferred_open_entry(e) && + deferred_open_identical(e, entry)) { + return e; + } + } + return NULL; +} /******************************************************************* - Print out a deferred open table. + Del the share mode of a file for this process. Return the number of + entries left. ********************************************************************/ -static void print_deferred_open_table(struct deferred_open_data *data) +BOOL del_share_mode(struct share_mode_lock *lck, files_struct *fsp) { - int num_de_entries = data->u.num_deferred_open_entries; - deferred_open_entry *de_entries = (deferred_open_entry *)(data + 1); - int i; + struct share_mode_entry entry, *e; + + fill_share_mode_entry(&entry, fsp, 0, 0); - for (i = 0; i < num_de_entries; i++) { - deferred_open_entry *entry_p = &de_entries[i]; - DEBUG(10,("print_deferred_open_table: %s\n", deferred_open_str(i, entry_p) )); + e = find_share_mode_entry(lck, &entry); + if (e == NULL) { + return False; } + + e->op_type = UNUSED_SHARE_MODE_ENTRY; + lck->modified = True; + return True; } +void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid) +{ + struct share_mode_entry entry, *e; -/******************************************************************* - Form a static deferred open locking key for a dev/inode pair. -******************************************************************/ + fill_deferred_open_entry(&entry, timeval_zero(), + lck->dev, lck->ino, mid); -static TDB_DATA deferred_open_locking_key(SMB_DEV_T dev, SMB_INO_T inode) -{ - static struct de_locking_key key; - TDB_DATA kbuf; + e = find_share_mode_entry(lck, &entry); + if (e == NULL) { + return; + } - memset(&key, '\0', sizeof(key)); - memcpy(&key.name[0], "DOE", 4); - key.dev = dev; - key.inode = inode; - kbuf.dptr = (char *)&key; - kbuf.dsize = sizeof(key); - return kbuf; + e->op_type = UNUSED_SHARE_MODE_ENTRY; + lck->modified = True; } /******************************************************************* - Get all deferred open entries for a dev/inode pair. + Remove an oplock mid and mode entry from a share mode. ********************************************************************/ -int get_deferred_opens(connection_struct *conn, - SMB_DEV_T dev, SMB_INO_T inode, - deferred_open_entry **pp_de_entries) +BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp) { - TDB_DATA dbuf; - struct deferred_open_data *data; - int num_de_entries; - deferred_open_entry *de_entries = NULL; - TDB_DATA key = deferred_open_locking_key(dev, inode); + struct share_mode_entry entry, *e; - *pp_de_entries = NULL; + fill_share_mode_entry(&entry, fsp, 0, 0); - dbuf = tdb_fetch(deferred_open_tdb, key); - if (!dbuf.dptr) - return 0; - - data = (struct deferred_open_data *)dbuf.dptr; - num_de_entries = data->u.num_deferred_open_entries; - if(num_de_entries) { - pstring fname; - int i; - int del_count = 0; - - de_entries = (deferred_open_entry *)memdup(dbuf.dptr + sizeof(*data), - num_de_entries * sizeof(deferred_open_entry)); - - if (!de_entries) { - SAFE_FREE(dbuf.dptr); - return 0; - } + e = find_share_mode_entry(lck, &entry); + if (e == NULL) { + return False; + } - /* Save off the associated filename. */ - pstrcpy(fname, dbuf.dptr + sizeof(*data) + num_de_entries * sizeof(deferred_open_entry)); + e->op_mid = 0; + e->op_type = NO_OPLOCK; + lck->modified = True; + return True; +} - /* - * Ensure that each entry has a real process attached. - */ +/******************************************************************* + Downgrade a oplock type from exclusive to level II. +********************************************************************/ - for (i = 0; i < num_de_entries; ) { - deferred_open_entry *entry_p = &de_entries[i]; - if (process_exists(entry_p->pid)) { - DEBUG(10,("get_deferred_opens: %s\n", deferred_open_str(i, entry_p) )); - i++; - } else { - DEBUG(10,("get_deferred_opens: deleted %s\n", deferred_open_str(i, entry_p) )); - if (num_de_entries - i - 1 > 0) { - memcpy( &de_entries[i], &de_entries[i+1], - sizeof(deferred_open_entry) * (num_de_entries - i - 1)); - } - num_de_entries--; - del_count++; - } - } +BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp) +{ + struct share_mode_entry entry, *e; - /* Did we delete any ? If so, re-store in tdb. */ - if (del_count) { - data->u.num_deferred_open_entries = num_de_entries; - - if (num_de_entries) { - memcpy(dbuf.dptr + sizeof(*data), de_entries, - num_de_entries * sizeof(deferred_open_entry)); - /* Append the filename. */ - pstrcpy(dbuf.dptr + sizeof(*data) + num_de_entries * sizeof(deferred_open_entry), fname); - } + fill_share_mode_entry(&entry, fsp, 0, 0); - /* The record has shrunk a bit */ - dbuf.dsize -= del_count * sizeof(deferred_open_entry); - - if (data->u.num_deferred_open_entries == 0) { - if (tdb_delete(deferred_open_tdb, key) == -1) { - SAFE_FREE(de_entries); - SAFE_FREE(dbuf.dptr); - return 0; - } - } else { - if (tdb_store(deferred_open_tdb, key, dbuf, TDB_REPLACE) == -1) { - SAFE_FREE(de_entries); - SAFE_FREE(dbuf.dptr); - return 0; - } - } - } + e = find_share_mode_entry(lck, &entry); + if (e == NULL) { + return False; } - SAFE_FREE(dbuf.dptr); - *pp_de_entries = de_entries; - return num_de_entries; + e->op_type = LEVEL_II_OPLOCK; + lck->modified = True; + return True; } + /******************************************************************* - Check if two deferred open entries are identical. + We've just told all the smbd's that our level2 or fake level2 has been + written to. ********************************************************************/ - -static BOOL deferred_open_entries_identical( deferred_open_entry *e1, deferred_open_entry *e2) +BOOL remove_all_share_oplocks(struct share_mode_lock *lck, files_struct *fsp) { - return (e1->pid == e2->pid && - e1->mid == e2->mid && - e1->port == e2->port && - e1->dev == e2->dev && - e1->inode == e2->inode && - e1->time.tv_sec == e2->time.tv_sec && - e1->time.tv_usec == e2->time.tv_usec); + int i; + for (i=0; inum_share_modes; i++) { + struct share_mode_entry *e = &lck->share_modes[i]; + if (!is_valid_share_mode_entry(e)) { + continue; + } + if (e->op_type == NO_OPLOCK) { + continue; + } + e->op_type = NO_OPLOCK; + lck->modified = True; + } + return True; } -/******************************************************************* - Delete a specific deferred open entry. - Ignore if no entry deleted. -********************************************************************/ +/**************************************************************************** + Deal with the internal needs of setting the delete on close flag. Note that + as the tdb locking is recursive, it is safe to call this from within + open_file_shared. JRA. +****************************************************************************/ -BOOL delete_deferred_open_entry(deferred_open_entry *entry) +NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close, + uint32 dosmode) { - TDB_DATA dbuf; - struct deferred_open_data *data; - int i, del_count=0; - deferred_open_entry *de_entries; - BOOL ret = True; - TDB_DATA key = deferred_open_locking_key(entry->dev, entry->inode); - - /* read in the existing share modes */ - dbuf = tdb_fetch(deferred_open_tdb, key); - if (!dbuf.dptr) - return -1; - - data = (struct deferred_open_data *)dbuf.dptr; - de_entries = (deferred_open_entry *)(dbuf.dptr + sizeof(*data)); + if (!delete_on_close) { + return NT_STATUS_OK; + } /* - * Find any with this pid and delete it - * by overwriting with the rest of the data - * from the record. + * Only allow delete on close for writable files. */ - DEBUG(10,("delete_deferred_open_entry: num_deferred_open_entries = %d\n", - data->u.num_deferred_open_entries )); - - for (i=0;iu.num_deferred_open_entries;) { - if (deferred_open_entries_identical(&de_entries[i], entry)) { - DEBUG(10,("delete_deferred_open_entry: deleted %s\n", - deferred_open_str(i, &de_entries[i]) )); - - data->u.num_deferred_open_entries--; - if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*de_entries))) > 0) { - memmove(&de_entries[i], &de_entries[i+1], - dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*de_entries))); - } - del_count++; - - DEBUG(10,("delete_deferred_open_entry: deleting entry %d\n", i )); - - } else { - i++; - } + if ((dosmode & aRONLY) && + !lp_delete_readonly(SNUM(fsp->conn))) { + DEBUG(10,("can_set_delete_on_close: file %s delete on close " + "flag set but file attribute is readonly.\n", + fsp->fsp_name )); + return NT_STATUS_CANNOT_DELETE; } - SMB_ASSERT(del_count == 0 || del_count == 1); - - if (del_count) { - /* the record may have shrunk a bit */ - dbuf.dsize -= del_count * sizeof(*de_entries); + /* + * Only allow delete on close for writable shares. + */ - /* store it back in the database */ - if (data->u.num_deferred_open_entries == 0) { - if (tdb_delete(deferred_open_tdb, key) == -1) - ret = False; - } else { - if (tdb_store(deferred_open_tdb, key, dbuf, TDB_REPLACE) == -1) - ret = False; - } + if (!CAN_WRITE(fsp->conn)) { + DEBUG(10,("can_set_delete_on_close: file %s delete on " + "close flag set but write access denied on share.\n", + fsp->fsp_name )); + return NT_STATUS_ACCESS_DENIED; } - DEBUG(10,("delete_deferred_open_entry: Remaining table.\n")); - print_deferred_open_table((struct deferred_open_data*)dbuf.dptr); - SAFE_FREE(dbuf.dptr); - return ret; -} -/******************************************************************* - Fill a deferred open entry. -********************************************************************/ + /* + * Only allow delete on close for files/directories opened with delete + * intent. + */ -static void fill_deferred_open(char *p, uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T inode, uint16 port) -{ - deferred_open_entry *e = (deferred_open_entry *)p; - void *x = &e->time; /* Needed to force alignment. p may not be aligned.... */ + if (!(fsp->access_mask & DELETE_ACCESS)) { + DEBUG(10,("can_set_delete_on_close: file %s delete on " + "close flag set but delete access denied.\n", + fsp->fsp_name )); + return NT_STATUS_ACCESS_DENIED; + } - memset(e, '\0', sizeof(deferred_open_entry)); - e->mid = mid; - e->pid = sys_getpid(); - memcpy(x, ptv, sizeof(struct timeval)); - e->dev = dev; - e->inode = inode; - e->port = port; + return NT_STATUS_OK; } -/******************************************************************* - Add a deferred open record. Return False on fail, True on success. -********************************************************************/ +/**************************************************************************** + Sets the delete on close flag over all share modes on this file. + Modify the share mode entry for all files open + on this device and inode to tell other smbds we have + changed the delete on close flag. This will be noticed + in the close code, the last closer will delete the file + if flag is set. +****************************************************************************/ -BOOL add_deferred_open(uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T inode, uint16 port, const char *fname) +BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close) { - TDB_DATA dbuf; - struct deferred_open_data *data; - char *p=NULL; - int size; - TDB_DATA key = deferred_open_locking_key(dev, inode); - BOOL ret = True; - - /* read in the existing deferred open records if any */ - dbuf = tdb_fetch(deferred_open_tdb, key); - if (!dbuf.dptr) { - size_t offset; - /* we'll need to create a new record */ - - size = sizeof(*data) + sizeof(deferred_open_entry) + strlen(fname) + 1; - p = (char *)SMB_MALLOC(size); - if (!p) - return False; - data = (struct deferred_open_data *)p; - ZERO_STRUCT(data->u.dummy); /* Keep valgrind happy */ - data->u.num_deferred_open_entries = 1; + struct share_mode_lock *lck; - DEBUG(10,("add_deferred_open: creating entry for file %s. num_deferred_open_entries = 1\n", - fname )); - - offset = sizeof(*data) + sizeof(deferred_open_entry); - safe_strcpy(p + offset, fname, size - offset - 1); - fill_deferred_open(p + sizeof(*data), mid, ptv, dev, inode, port); - dbuf.dptr = p; - dbuf.dsize = size; - if (tdb_store(deferred_open_tdb, key, dbuf, TDB_REPLACE) == -1) - ret = False; - - print_deferred_open_table((struct deferred_open_data *)p); - - SAFE_FREE(p); - return ret; - } - - /* we're adding to an existing entry - this is a bit fiddly */ - data = (struct deferred_open_data *)dbuf.dptr; + DEBUG(10,("set_delete_on_close: %s delete on close flag for " + "fnum = %d, file %s\n", + delete_on_close ? "Adding" : "Removing", fsp->fnum, + fsp->fsp_name )); - data->u.num_deferred_open_entries++; - - DEBUG(10,("add_deferred_open: adding entry for file %s. new num_deferred_open_entries = %d\n", - fname, data->u.num_deferred_open_entries )); + if (fsp->is_directory || fsp->is_stat) + return True; - size = dbuf.dsize + sizeof(deferred_open_entry); - p = SMB_MALLOC(size); - if (!p) { - SAFE_FREE(dbuf.dptr); + lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL); + if (lck == NULL) { return False; } - memcpy(p, dbuf.dptr, sizeof(*data)); - fill_deferred_open(p + sizeof(*data), mid, ptv, dev, inode, port); - memcpy(p + sizeof(*data) + sizeof(deferred_open_entry), dbuf.dptr + sizeof(*data), - dbuf.dsize - sizeof(*data)); - SAFE_FREE(dbuf.dptr); - dbuf.dptr = p; - dbuf.dsize = size; - if (tdb_store(deferred_open_tdb, key, dbuf, TDB_REPLACE) == -1) - ret = False; - print_deferred_open_table((struct deferred_open_data *)p); - SAFE_FREE(p); - return ret; -} + if (lck->delete_on_close != delete_on_close) { + lck->delete_on_close = delete_on_close; + lck->modified = True; + } -/**************************************************************************** - Traverse the whole database with this function, calling traverse_callback - on each share mode -****************************************************************************/ + talloc_free(lck); + return True; +} static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, - void* state) + void *state) { struct locking_data *data; - share_mode_entry *shares; + struct share_mode_entry *shares; char *name; int i; - - SHAREMODE_FN(traverse_callback) = (SHAREMODE_FN_CAST())state; + void (*traverse_callback)(struct share_mode_entry *, char *) = state; /* Ensure this is a locking_key record. */ if (kbuf.dsize != sizeof(struct locking_key)) return 0; data = (struct locking_data *)dbuf.dptr; - shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); - name = dbuf.dptr + sizeof(*data) + data->u.s.num_share_mode_entries*sizeof(*shares); + shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data)); + name = dbuf.dptr + sizeof(*data) + + data->u.s.num_share_mode_entries*sizeof(*shares); for (i=0;iu.s.num_share_mode_entries;i++) { traverse_callback(&shares[i], name); @@ -1299,9 +1005,9 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, share mode system. ********************************************************************/ -int share_mode_forall(SHAREMODE_FN(fn)) +int share_mode_forall(void (*fn)(const struct share_mode_entry *, char *)) { - if (!tdb) + if (tdb == NULL) return 0; - return tdb_traverse(tdb, traverse_fn, (void*)fn); + return tdb_traverse(tdb, traverse_fn, fn); } -- cgit From 533da83852b13c2e008938a026f99937ef320f3c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Oct 2005 22:35:08 +0000 Subject: r11341: Put directory opens into the share mode db so we can treat them similarly to file opens (delete on close, share mode violations etc.). This fixes bug #3216 I will up the default hash size on the locking db in a later commit as this means more entries. Jeremy. (This used to be commit 1134abbbb3fd8e8b88e1a5817aae106476a4c126) --- source3/locking/locking.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e3131e26a2..aad254f276 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -960,8 +960,9 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close) delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name )); - if (fsp->is_directory || fsp->is_stat) + if (fsp->is_stat) { return True; + } lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL); if (lck == NULL) { -- cgit From a00c76d9fb11241f968336834ba4e4ced926e727 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Nov 2005 02:07:26 +0000 Subject: r11435: Allow the hash size of the tdb open (locking) database to be set in local.h. Change from the default (131) to another prime (1049). Should this be an smb.conf tunable parameter based on the number of open file descriptors available ? If so what scaling factor ? More tests to follow. Jeremy. (This used to be commit 6a902ec49ffea5d0ca0308d5ff51584cece41043) --- source3/locking/locking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index aad254f276..322824ea2f 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -315,9 +315,9 @@ BOOL locking_init(int read_only) return True; tdb = tdb_open_log(lock_path("locking.tdb"), - 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), - read_only?O_RDONLY:O_RDWR|O_CREAT, - 0644); + SMB_OPEN_DATABASE_TDB_HASH_SIZE, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), + read_only?O_RDONLY:O_RDWR|O_CREAT, + 0644); if (!tdb) { DEBUG(0,("ERROR: Failed to initialise locking database\n")); -- cgit From 7d2771e758d4e8ef0adb45e55775b524de4dba9a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 12 Dec 2005 22:07:36 +0000 Subject: r12203: Add the share path into the sharemode db. This involves revving the minor version number for libsmbsharemodes (we now have a new _ex interface that takes the share path as well as the filename). Needed for #3303. Some code written by SATOH Fumiyasu included in the changes to locking/locking.c. The smbstatus output is a bit of a mess and needs overhauling... Jeremy. (This used to be commit 9d93af713f8520ca506730dd32aa2b994937eaba) --- source3/locking/locking.c | 84 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 66 insertions(+), 18 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 322824ea2f..2debc2c23e 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -464,10 +464,15 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) } } - /* Save off the associated filename. */ + /* Save off the associated service path and filename. */ + lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) + + (lck->num_share_modes * + sizeof(struct share_mode_entry))); + lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) + - lck->num_share_modes * - sizeof(struct share_mode_entry)); + (lck->num_share_modes * + sizeof(struct share_mode_entry)) + + strlen(lck->servicepath) + 1 ); /* * Ensure that each entry has a real process attached. @@ -495,6 +500,7 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) int i; struct locking_data *data; ssize_t offset; + ssize_t sp_len; result.dptr = NULL; result.dsize = 0; @@ -509,8 +515,11 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) return result; } + sp_len = strlen(lck->servicepath); + result.dsize = sizeof(*data) + lck->num_share_modes * sizeof(struct share_mode_entry) + + sp_len + 1 + strlen(lck->filename) + 1; result.dptr = talloc_size(lck, result.dsize); @@ -529,6 +538,9 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) sizeof(struct share_mode_entry)*lck->num_share_modes); offset = sizeof(*data) + sizeof(struct share_mode_entry)*lck->num_share_modes; + safe_strcpy(result.dptr + offset, lck->servicepath, + result.dsize - offset - 1); + offset += sp_len + 1; safe_strcpy(result.dptr + offset, lck->filename, result.dsize - offset - 1); print_share_mode_table(data); @@ -569,8 +581,9 @@ static int share_mode_lock_destructor(void *p) } struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, - SMB_DEV_T dev, SMB_INO_T ino, - const char *fname) + SMB_DEV_T dev, SMB_INO_T ino, + const char *servicepath, + const char *fname) { struct share_mode_lock *lck; TDB_DATA key = locking_key(dev, ino); @@ -599,13 +612,15 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, lck->fresh = (data.dptr == NULL); if (lck->fresh) { - if (fname == NULL) { - DEBUG(0, ("New file, but no filename supplied\n")); + + if (fname == NULL || servicepath == NULL) { + DEBUG(0, ("New file, but no filename or servicepath supplied\n")); talloc_free(lck); return NULL; } lck->filename = talloc_strdup(lck, fname); - if (lck->filename == NULL) { + lck->servicepath = talloc_strdup(lck, servicepath); + if (lck->filename == NULL || lck->servicepath == NULL) { DEBUG(0, ("talloc failed\n")); talloc_free(lck); return NULL; @@ -625,12 +640,41 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, return lck; } -BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode, - const char *fname) +/******************************************************************* + Sets the service name and filename for rename. + At this point we should emit "rename" smbd messages to all + interested process id's. +********************************************************************/ + +BOOL rename_share_filename(struct share_mode_lock *lck, + const char *servicepath, + const char *newname) +{ + /* + * rename_internal_fsp() and rename_internals() add './' to + * head of newname if newname does not contain a '/'. + */ + while (newname[0] && newname[1] && newname[0] == '.' && newname[1] == '/') { + newname += 2; + } + + lck->filename = talloc_strdup(lck, newname); + lck->servicepath = talloc_strdup(lck, servicepath); + if (lck->filename == NULL || lck->servicepath == NULL) { + DEBUG(0, ("rename_share_filename: talloc failed\n")); + return False; + } + lck->modified = True; + return True; +} + +BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode) { BOOL result; - struct share_mode_lock *lck = get_share_mode_lock(NULL, dev, inode, - fname); + struct share_mode_lock *lck = get_share_mode_lock(NULL, dev, inode, NULL, NULL); + if (!lck) { + return False; + } result = lck->delete_on_close; talloc_free(lck); return result; @@ -964,7 +1008,7 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close) return True; } - lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL); + lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL); if (lck == NULL) { return False; } @@ -982,9 +1026,10 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, { struct locking_data *data; struct share_mode_entry *shares; - char *name; + const char *sharepath; + const char *fname; int i; - void (*traverse_callback)(struct share_mode_entry *, char *) = state; + void (*traverse_callback)(struct share_mode_entry *, const char *, const char *) = state; /* Ensure this is a locking_key record. */ if (kbuf.dsize != sizeof(struct locking_key)) @@ -992,11 +1037,14 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, data = (struct locking_data *)dbuf.dptr; shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data)); - name = dbuf.dptr + sizeof(*data) + + sharepath = dbuf.dptr + sizeof(*data) + data->u.s.num_share_mode_entries*sizeof(*shares); + fname = dbuf.dptr + sizeof(*data) + + data->u.s.num_share_mode_entries*sizeof(*shares) + + strlen(sharepath) + 1; for (i=0;iu.s.num_share_mode_entries;i++) { - traverse_callback(&shares[i], name); + traverse_callback(&shares[i], sharepath, fname); } return 0; } @@ -1006,7 +1054,7 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, share mode system. ********************************************************************/ -int share_mode_forall(void (*fn)(const struct share_mode_entry *, char *)) +int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, const char *)) { if (tdb == NULL) return 0; -- cgit From ab7a4f7e8e4b946a8acd0a205c16dbf6a3afecad Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 13 Dec 2005 18:11:50 +0000 Subject: r12213: Final fix for #3303 - send rename messages to smbd's that have open file handles to allow them to correctly implement delete on close. There is a further correctness fix I'm intending to add to this to cope with different share paths, but not right now... Jeremy. (This used to be commit 932e337db8788e75344e1c7cf1ef009d090cb039) --- source3/locking/locking.c | 56 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 2debc2c23e..d89fe931ef 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -642,14 +642,24 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, /******************************************************************* Sets the service name and filename for rename. - At this point we should emit "rename" smbd messages to all - interested process id's. + At this point we emit "file renamed" messages to all + process id's that have this file open. + Based on an initial code idea from SATOH Fumiyasu ********************************************************************/ BOOL rename_share_filename(struct share_mode_lock *lck, const char *servicepath, const char *newname) { + struct file_renamed_message *frm = NULL; + size_t sp_len; + size_t fn_len; + size_t msg_len; + int i; + + DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n", + servicepath, newname)); + /* * rename_internal_fsp() and rename_internals() add './' to * head of newname if newname does not contain a '/'. @@ -658,13 +668,53 @@ BOOL rename_share_filename(struct share_mode_lock *lck, newname += 2; } - lck->filename = talloc_strdup(lck, newname); lck->servicepath = talloc_strdup(lck, servicepath); + lck->filename = talloc_strdup(lck, newname); if (lck->filename == NULL || lck->servicepath == NULL) { DEBUG(0, ("rename_share_filename: talloc failed\n")); return False; } lck->modified = True; + + sp_len = strlen(lck->servicepath); + fn_len = strlen(lck->filename); + + msg_len = sizeof(*frm) + sp_len + 1 + fn_len + 1; + + /* Set up the name changed message. */ + frm = TALLOC(lck, msg_len); + if (!frm) { + return False; + } + frm->dev = lck->dev; + frm->inode = lck->ino; + + DEBUG(10,("rename_share_filename: msg_len = %d\n", msg_len )); + + safe_strcpy(&frm->names[0], lck->servicepath, sp_len); + safe_strcpy(&frm->names[sp_len + 1], lck->filename, fn_len); + + /* Send the messages. */ + for (i=0; inum_share_modes; i++) { + struct share_mode_entry *se = &lck->share_modes[i]; + if (!is_valid_share_mode_entry(se)) { + continue; + } + /* But not to ourselves... */ + if (procid_is_me(&se->pid)) { + continue; + } + + DEBUG(10,("rename_share_filename: sending rename message to pid %u " + "dev %x, inode %.0f sharepath %s newname %s\n", + (unsigned int)procid_to_pid(&se->pid), + (unsigned int)frm->dev, (double)frm->inode, + lck->servicepath, lck->filename )); + + message_send_pid(se->pid, MSG_SMB_FILE_RENAME, + frm, msg_len, True); + } + return True; } -- cgit From 762901cfb9aabb717b8312d546ab20f8bacb1e29 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 14 Dec 2005 00:42:40 +0000 Subject: r12221: Fix error code paths that can potentially leave a dangling lock. Jeremy. (This used to be commit 123135ed1ddd84cc0a5e8e5ca06a0703d1944e37) --- source3/locking/locking.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d89fe931ef..b823b4712e 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -595,12 +595,18 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, return NULL; } + /* Ensure we set every field here as the destructor must be + valid even if parse_share_modes fails. */ + + lck->servicepath = NULL; + lck->filename = NULL; lck->dev = dev; lck->ino = ino; - lck->delete_on_close = False; lck->num_share_modes = 0; lck->share_modes = NULL; + lck->delete_on_close = False; lck->modified = False; + lck->fresh = False; if (tdb_chainlock(tdb, key) != 0) { DEBUG(3, ("Could not lock share entry\n")); @@ -608,6 +614,12 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, return NULL; } + /* We must set the destructor immediately after the chainlock + ensure the lock is cleaned up on any of the error return + paths below. */ + + talloc_set_destructor(lck, share_mode_lock_destructor); + data = tdb_fetch(tdb, key); lck->fresh = (data.dptr == NULL); @@ -634,7 +646,6 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, } } - talloc_set_destructor(lck, share_mode_lock_destructor); SAFE_FREE(data.dptr); return lck; -- cgit From e7d2e311a293709c74a97d0e30665dadae510712 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 14 Dec 2005 17:46:29 +0000 Subject: r12234: Reduce the race condition for renames by holding the lock longer. Instigated by complaints on the fix for #3303 from SATOH Fumiyasu . Jeremy. (This used to be commit 855f5f8c32aa530dbad244805a40200824724618) --- source3/locking/locking.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index b823b4712e..07377831b4 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -605,8 +605,8 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, lck->num_share_modes = 0; lck->share_modes = NULL; lck->delete_on_close = False; - lck->modified = False; lck->fresh = False; + lck->modified = False; if (tdb_chainlock(tdb, key) != 0) { DEBUG(3, ("Could not lock share entry\n")); @@ -668,6 +668,10 @@ BOOL rename_share_filename(struct share_mode_lock *lck, size_t msg_len; int i; + if (!lck) { + return False; + } + DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n", servicepath, newname)); -- cgit From 33174847994128387a36a8103f147fe5a96c15fd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 12 Jan 2006 22:17:54 +0000 Subject: r12877: Stop passing structs around in smb messages, instead always linearize into little-endian. Should fix all Solaris issues with this, plus provide a cleaner base moving forward for cluster-aware Samba where smbd's can communicate across different compilers/architectures (eventually these message will have to go cross-machine). Jeremy. (This used to be commit d01824b78576a034428e1cef73868d1169057991) --- source3/locking/locking.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 07377831b4..d9737895ba 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -662,10 +662,10 @@ BOOL rename_share_filename(struct share_mode_lock *lck, const char *servicepath, const char *newname) { - struct file_renamed_message *frm = NULL; size_t sp_len; size_t fn_len; size_t msg_len; + char *frm = NULL; int i; if (!lck) { @@ -694,20 +694,21 @@ BOOL rename_share_filename(struct share_mode_lock *lck, sp_len = strlen(lck->servicepath); fn_len = strlen(lck->filename); - msg_len = sizeof(*frm) + sp_len + 1 + fn_len + 1; + msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + fn_len + 1; /* Set up the name changed message. */ frm = TALLOC(lck, msg_len); if (!frm) { return False; } - frm->dev = lck->dev; - frm->inode = lck->ino; + + SDEV_T_VAL(frm,0,lck->dev); + SINO_T_VAL(frm,8,lck->ino); DEBUG(10,("rename_share_filename: msg_len = %d\n", msg_len )); - safe_strcpy(&frm->names[0], lck->servicepath, sp_len); - safe_strcpy(&frm->names[sp_len + 1], lck->filename, fn_len); + safe_strcpy(&frm[16], lck->servicepath, sp_len); + safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len); /* Send the messages. */ for (i=0; inum_share_modes; i++) { @@ -723,11 +724,13 @@ BOOL rename_share_filename(struct share_mode_lock *lck, DEBUG(10,("rename_share_filename: sending rename message to pid %u " "dev %x, inode %.0f sharepath %s newname %s\n", (unsigned int)procid_to_pid(&se->pid), - (unsigned int)frm->dev, (double)frm->inode, + (unsigned int)lck->dev, (double)lck->ino, lck->servicepath, lck->filename )); + become_root(); message_send_pid(se->pid, MSG_SMB_FILE_RENAME, frm, msg_len, True); + unbecome_root(); } return True; -- cgit From 6afd823e42aef3cc64a64d085438cc4d14ef3498 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 24 Jan 2006 17:27:30 +0000 Subject: r13110: remove an invalid debug message about call get_share_mode_lock() with a NULL service path and fname (we do it all the time internally) (This used to be commit e1f75ea63780f4a1661f19554d18bbd73b069c1b) --- source3/locking/locking.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d9737895ba..9a13e099db 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -626,7 +626,6 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, if (lck->fresh) { if (fname == NULL || servicepath == NULL) { - DEBUG(0, ("New file, but no filename or servicepath supplied\n")); talloc_free(lck); return NULL; } -- cgit From 6a097ab20ea54a7b090ad6e62c1538d5e5997f31 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 Jan 2006 19:54:39 +0000 Subject: r13192: Fix up alignment issues when printing share mode entries. Add paranioa to debug so we know when an entry is unused. Jeremy. (This used to be commit fa5fab313e3728ff49c00ca1097242039506f83e) --- source3/locking/locking.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 9a13e099db..770ef918b8 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -384,11 +384,13 @@ char *share_mode_str(int num, struct share_mode_entry *e) { static pstring share_str; - slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: " + slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: %s " "pid = %s, share_access = 0x%x, private_options = 0x%x, " "access_mask = 0x%x, mid = 0x%x, type= 0x%x, file_id = %lu, " "dev = 0x%x, inode = %.0f", - num, procid_str_static(&e->pid), + num, + e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "", + procid_str_static(&e->pid), e->share_access, e->private_options, e->access_mask, e->op_mid, e->op_type, e->share_file_id, (unsigned int)e->dev, (double)e->inode ); @@ -408,9 +410,11 @@ static void print_share_mode_table(struct locking_data *data) int i; for (i = 0; i < num_share_modes; i++) { - struct share_mode_entry *entry_p = &shares[i]; + struct share_mode_entry entry; + + memcpy(&entry, &shares[i], sizeof(struct share_mode_entry)); DEBUG(10,("print_share_mode_table: %s\n", - share_mode_str(i, entry_p))); + share_mode_str(i, &entry))); } } -- cgit From 6f08a557bae46eb9a2f992dfcdc6c1954f55c703 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 Jan 2006 19:59:48 +0000 Subject: r13194: Don't do extra memcpy's unless we're asked to. Jeremy. (This used to be commit f93e1e75563679dc07958168b283dfc0eb2de5b0) --- source3/locking/locking.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 770ef918b8..be1e83121b 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -547,7 +547,11 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) offset += sp_len + 1; safe_strcpy(result.dptr + offset, lck->filename, result.dsize - offset - 1); - print_share_mode_table(data); + + if (DEBUGLEVEL >= 10) { + print_share_mode_table(data); + } + return result; } -- cgit From bd34c2ac25af690a00cbbded5b57a834a4e35875 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 Jan 2006 23:30:30 +0000 Subject: r13198: Fix issues exposed by Jerry's testing on 64-bit Solaris (I hope). Separate 3.0.21b patch sent to Jerry. Jeremy. (This used to be commit 837e7ea7e40cedc6b01e023445feb4a90c4bf8b9) --- source3/locking/locking.c | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index be1e83121b..e31ead30e4 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -988,28 +988,6 @@ BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp) return True; } - -/******************************************************************* - We've just told all the smbd's that our level2 or fake level2 has been - written to. -********************************************************************/ -BOOL remove_all_share_oplocks(struct share_mode_lock *lck, files_struct *fsp) -{ - int i; - for (i=0; inum_share_modes; i++) { - struct share_mode_entry *e = &lck->share_modes[i]; - if (!is_valid_share_mode_entry(e)) { - continue; - } - if (e->op_type == NO_OPLOCK) { - continue; - } - e->op_type = NO_OPLOCK; - lck->modified = True; - } - return True; -} - /**************************************************************************** Deal with the internal needs of setting the delete on close flag. Note that as the tdb locking is recursive, it is safe to call this from within -- cgit From 86c9bac4c31df1606e3758ec42672506dde26cc6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 1 Feb 2006 04:14:07 +0000 Subject: r13274: Fix for bug #3467. Not a show stopper. jason qian was a *fantastic* help in tracking this down. Jeremy. (This used to be commit 9f4a9c70fa232047868e5d8a3f132a2dd6bfee82) --- source3/locking/locking.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e31ead30e4..e8309582fd 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -49,6 +49,7 @@ struct locking_data { struct { int num_share_mode_entries; BOOL delete_on_close; + BOOL initial_delete_on_close; /* Only set at NTCreateX if file was created. */ } s; struct share_mode_entry dummy; /* Needed for alignment. */ } u; @@ -435,11 +436,15 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) data = (struct locking_data *)dbuf.dptr; lck->delete_on_close = data->u.s.delete_on_close; + lck->initial_delete_on_close = data->u.s.initial_delete_on_close; lck->num_share_modes = data->u.s.num_share_mode_entries; DEBUG(10, ("parse_share_modes: delete_on_close: %d, " - "num_share_modes: %d\n", lck->delete_on_close, - lck->num_share_modes)); + "initial_delete_on_close: %d, " + "num_share_modes: %d\n", + lck->delete_on_close, + lck->initial_delete_on_close, + lck->num_share_modes)); if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) { DEBUG(0, ("invalid number of share modes: %d\n", @@ -535,8 +540,10 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) ZERO_STRUCTP(data); data->u.s.num_share_mode_entries = lck->num_share_modes; data->u.s.delete_on_close = lck->delete_on_close; - DEBUG(10, ("unparse_share_modes: del: %d, num: %d\n", + data->u.s.initial_delete_on_close = lck->initial_delete_on_close; + DEBUG(10, ("unparse_share_modes: del: %d, initial del %d, num: %d\n", data->u.s.delete_on_close, + data->u.s.initial_delete_on_close, data->u.s.num_share_mode_entries)); memcpy(result.dptr + sizeof(*data), lck->share_modes, sizeof(struct share_mode_entry)*lck->num_share_modes); @@ -613,6 +620,7 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, lck->num_share_modes = 0; lck->share_modes = NULL; lck->delete_on_close = False; + lck->initial_delete_on_close = False; lck->fresh = False; lck->modified = False; @@ -1046,6 +1054,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close, changed the delete on close flag. This will be noticed in the close code, the last closer will delete the file if flag is set. + Note that setting this to any value clears the initial_delete_on_close flag. ****************************************************************************/ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close) @@ -1070,6 +1079,11 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close) lck->modified = True; } + if (lck->initial_delete_on_close) { + lck->initial_delete_on_close = False; + lck->modified = True; + } + talloc_free(lck); return True; } -- cgit From d14af63e6ab600eb3ac705f2f425c860e927553a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 2 Feb 2006 20:44:50 +0000 Subject: r13293: Rather a big patch I'm afraid, but this should fix bug #3347 by saving the UNIX token used to set a delete on close flag, and using it when doing the delete. libsmbsharemodes.so still needs updating to cope with this change. Samba4 torture tests to follow. Jeremy. (This used to be commit 23f16cbc2e8cde97c486831e26bcafd4ab4a9654) --- source3/locking/locking.c | 157 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 142 insertions(+), 15 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e8309582fd..e558c6d74f 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -50,6 +50,9 @@ struct locking_data { int num_share_mode_entries; BOOL delete_on_close; BOOL initial_delete_on_close; /* Only set at NTCreateX if file was created. */ + uint32 delete_token_size; /* Only valid if either of + the two previous fields + are True. */ } s; struct share_mode_entry dummy; /* Needed for alignment. */ } u; @@ -429,8 +432,7 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) int i; if (dbuf.dsize < sizeof(struct locking_data)) { - DEBUG(0, ("parse_share_modes: buffer too short\n")); - return False; + smb_panic("PANIC: parse_share_modes: buffer too short.\n"); } data = (struct locking_data *)dbuf.dptr; @@ -449,18 +451,17 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) { DEBUG(0, ("invalid number of share modes: %d\n", lck->num_share_modes)); - return False; + smb_panic("PANIC: invalid number of share modes"); } lck->share_modes = NULL; - + if (lck->num_share_modes != 0) { if (dbuf.dsize < (sizeof(struct locking_data) + (lck->num_share_modes * sizeof(struct share_mode_entry)))) { - DEBUG(0, ("parse_share_modes: buffer too short\n")); - return False; + smb_panic("PANIC: parse_share_modes: buffer too short.\n"); } lck->share_modes = talloc_memdup(lck, dbuf.dptr+sizeof(*data), @@ -468,20 +469,67 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) sizeof(struct share_mode_entry)); if (lck->share_modes == NULL) { - DEBUG(0, ("talloc failed\n")); - return False; + smb_panic("talloc failed\n"); } } + /* Get any delete token. */ + if (data->u.s.delete_token_size) { + /* Each uid/gid is stored as a 4 byte value. */ + uint32 val; + uint32 *p = (uint32 *)(dbuf.dptr + sizeof(*data) + + (lck->num_share_modes * + sizeof(struct share_mode_entry))); + + if ((data->u.s.delete_token_size < 8) || (data->u.s.delete_token_size % 4) != 0) { + DEBUG(0, ("parse_share_modes: invalid token size %d\n", + data->u.s.delete_token_size)); + smb_panic("parse_share_modes: invalid token size\n"); + } + + lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN); + if (!lck->delete_token) { + smb_panic("talloc failed\n"); + } + + /* Copy out the uid and gid. */ + memcpy(&val, p++, 4); + lck->delete_token->uid = (uid_t)val; + memcpy(&val, p++, 4); + lck->delete_token->gid = (gid_t)val; + + /* Any supplementary groups ? */ + lck->delete_token->ngroups = (data->u.s.delete_token_size > 8) ? + ((data->u.s.delete_token_size - 8)/4) : 0; + if (lck->delete_token->ngroups) { + /* Make this a talloc child of lck->delete_token. */ + lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t, + lck->delete_token->ngroups); + if (!lck->delete_token) { + smb_panic("talloc failed\n"); + } + + for (i = 0; i < lck->delete_token->ngroups; i++) { + memcpy(&val, p++, 4); + lck->delete_token->groups[i] = (gid_t)val; + } + } + + } else { + lck->delete_token = NULL; + } + /* Save off the associated service path and filename. */ lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) + - (lck->num_share_modes * - sizeof(struct share_mode_entry))); + (lck->num_share_modes * + sizeof(struct share_mode_entry)) + + data->u.s.delete_token_size ); lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) + - (lck->num_share_modes * - sizeof(struct share_mode_entry)) + - strlen(lck->servicepath) + 1 ); + (lck->num_share_modes * + sizeof(struct share_mode_entry)) + + data->u.s.delete_token_size + + strlen(lck->servicepath) + 1 ); /* * Ensure that each entry has a real process attached. @@ -528,6 +576,7 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) result.dsize = sizeof(*data) + lck->num_share_modes * sizeof(struct share_mode_entry) + + (lck->delete_token ? (8 + (lck->delete_token->ngroups*4)) : 0) + sp_len + 1 + strlen(lck->filename) + 1; result.dptr = talloc_size(lck, result.dsize); @@ -549,6 +598,25 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) sizeof(struct share_mode_entry)*lck->num_share_modes); offset = sizeof(*data) + sizeof(struct share_mode_entry)*lck->num_share_modes; + + /* Store any delete on close token. */ + if (lck->delete_token) { + uint32 val; + uint32 *p = (uint32 *)(result.dptr + offset); + + val = (uint32)lck->delete_token->uid; + memcpy(p++, &val, 4); + + val = (uint32)lck->delete_token->uid; + memcpy(p++, &val, 4); + + for (i = 0; i < lck->delete_token->ngroups; i++) { + val = (uint32)lck->delete_token->groups[i]; + memcpy(p++, &val, 4); + } + offset = ((char *)p - result.dptr); + } + safe_strcpy(result.dptr + offset, lck->servicepath, result.dsize - offset - 1); offset += sp_len + 1; @@ -619,6 +687,7 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, lck->ino = ino; lck->num_share_modes = 0; lck->share_modes = NULL; + lck->delete_token = NULL; lck->delete_on_close = False; lck->initial_delete_on_close = False; lck->fresh = False; @@ -1047,6 +1116,55 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close, return NT_STATUS_OK; } +/************************************************************************* + Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail. + (Should this be in locking.c.... ?). +*************************************************************************/ + +static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok) +{ + UNIX_USER_TOKEN *cpy; + + if (tok == NULL) { + return NULL; + } + + cpy = TALLOC_P(ctx, UNIX_USER_TOKEN); + if (!cpy) { + return NULL; + } + + cpy->uid = tok->uid; + cpy->gid = tok->gid; + cpy->ngroups = tok->ngroups; + if (tok->ngroups) { + /* Make this a talloc child of cpy. */ + cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups); + if (!cpy->groups) { + return NULL; + } + memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t)); + } + return cpy; +} + +/**************************************************************************** + Replace the delete on close token. +****************************************************************************/ + +void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok) +{ + /* Ensure there's no token. */ + if (lck->delete_token) { + talloc_free(lck->delete_token); /* Also deletes groups... */ + lck->delete_token = NULL; + } + + /* Copy the new token (can be NULL). */ + lck->delete_token = copy_unix_token(lck, tok); + lck->modified = True; +} + /**************************************************************************** Sets the delete on close flag over all share modes on this file. Modify the share mode entry for all files open @@ -1055,9 +1173,11 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close, in the close code, the last closer will delete the file if flag is set. Note that setting this to any value clears the initial_delete_on_close flag. + If delete_on_close is True this makes a copy of any UNIX_USER_TOKEN into the + lck entry. ****************************************************************************/ -BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close) +BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKEN *tok) { struct share_mode_lock *lck; @@ -1074,8 +1194,13 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close) if (lck == NULL) { return False; } + if (lck->delete_on_close != delete_on_close) { + set_delete_on_close_token(lck, tok); lck->delete_on_close = delete_on_close; + if (delete_on_close) { + SMB_ASSERT(lck->delete_token != NULL); + } lck->modified = True; } @@ -1105,9 +1230,11 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, data = (struct locking_data *)dbuf.dptr; shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data)); sharepath = dbuf.dptr + sizeof(*data) + - data->u.s.num_share_mode_entries*sizeof(*shares); + data->u.s.num_share_mode_entries*sizeof(*shares) + + data->u.s.delete_token_size; fname = dbuf.dptr + sizeof(*data) + data->u.s.num_share_mode_entries*sizeof(*shares) + + data->u.s.delete_token_size + strlen(sharepath) + 1; for (i=0;iu.s.num_share_mode_entries;i++) { -- cgit From 466230e5a10c2175535f7224df644fa6d09607e6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 2 Feb 2006 21:29:49 +0000 Subject: r13294: Fix basic delete on close tests - don't forget to tell the data struct how big the token is... :-). Jeremy. (This used to be commit f259de8b69f94ae8b5f4553180f245234bffd397) --- source3/locking/locking.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e558c6d74f..666988b541 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -558,6 +558,7 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) struct locking_data *data; ssize_t offset; ssize_t sp_len; + uint32 delete_token_size; result.dptr = NULL; result.dsize = 0; @@ -573,10 +574,12 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) } sp_len = strlen(lck->servicepath); + delete_token_size = (lck->delete_token ? + (8 + (lck->delete_token->ngroups*4)) : 0); result.dsize = sizeof(*data) + lck->num_share_modes * sizeof(struct share_mode_entry) + - (lck->delete_token ? (8 + (lck->delete_token->ngroups*4)) : 0) + + delete_token_size + sp_len + 1 + strlen(lck->filename) + 1; result.dptr = talloc_size(lck, result.dsize); @@ -590,10 +593,12 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) data->u.s.num_share_mode_entries = lck->num_share_modes; data->u.s.delete_on_close = lck->delete_on_close; data->u.s.initial_delete_on_close = lck->initial_delete_on_close; - DEBUG(10, ("unparse_share_modes: del: %d, initial del %d, num: %d\n", - data->u.s.delete_on_close, - data->u.s.initial_delete_on_close, - data->u.s.num_share_mode_entries)); + data->u.s.delete_token_size = delete_token_size; + DEBUG(10, ("unparse_share_modes: del: %d, initial del %d, tok = %u, num: %d\n", + data->u.s.delete_on_close, + data->u.s.initial_delete_on_close, + (unsigned int)data->u.s.delete_token_size, + data->u.s.num_share_mode_entries)); memcpy(result.dptr + sizeof(*data), lck->share_modes, sizeof(struct share_mode_entry)*lck->num_share_modes); offset = sizeof(*data) + -- cgit From 40d3c7ebb22bae6f486e8c60c3bb0494d2d397d9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 4 Feb 2006 06:31:04 +0000 Subject: r13329: Fix libsmbsharemodes.so to work with the stored delete token. Less trouble than I thought plus it didn't need an interface change (thank goodness !). Jeremy. (This used to be commit dbe2572d1c713f46b0d1d0c405f88456c9336297) --- source3/locking/locking.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 666988b541..9a707f80a4 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -44,24 +44,6 @@ uint16 global_smbpid; /* the locking database handle */ static TDB_CONTEXT *tdb; -struct locking_data { - union { - struct { - int num_share_mode_entries; - BOOL delete_on_close; - BOOL initial_delete_on_close; /* Only set at NTCreateX if file was created. */ - uint32 delete_token_size; /* Only valid if either of - the two previous fields - are True. */ - } s; - struct share_mode_entry dummy; /* Needed for alignment. */ - } u; - /* the following two entries are implicit - struct share_mode_entry modes[num_share_mode_entries]; - char file_name[]; - */ -}; - /**************************************************************************** Debugging aid :-). ****************************************************************************/ -- cgit From 30e47fdfe2fa7e5fee18718a09a094a7474b3a1b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Feb 2006 18:18:51 +0000 Subject: r13412: Don't use arbitrary uint32 size for uid and gid storage. Use correct system size. Fixed a bug that was accidentally introduced by use of uint32 - uid was stored twice, not uid and gid. Jeremy. (This used to be commit 89db006997588c6523ce8f2470d67f3136042256) --- source3/locking/locking.c | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 9a707f80a4..d157c30c82 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -457,13 +457,12 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) /* Get any delete token. */ if (data->u.s.delete_token_size) { - /* Each uid/gid is stored as a 4 byte value. */ - uint32 val; - uint32 *p = (uint32 *)(dbuf.dptr + sizeof(*data) + + char *p = dbuf.dptr + sizeof(*data) + (lck->num_share_modes * - sizeof(struct share_mode_entry))); + sizeof(struct share_mode_entry)); - if ((data->u.s.delete_token_size < 8) || (data->u.s.delete_token_size % 4) != 0) { + if ((data->u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) || + ((data->u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) { DEBUG(0, ("parse_share_modes: invalid token size %d\n", data->u.s.delete_token_size)); smb_panic("parse_share_modes: invalid token size\n"); @@ -475,14 +474,16 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) } /* Copy out the uid and gid. */ - memcpy(&val, p++, 4); - lck->delete_token->uid = (uid_t)val; - memcpy(&val, p++, 4); - lck->delete_token->gid = (gid_t)val; + memcpy(&lck->delete_token->uid, p, sizeof(uid_t)); + p += sizeof(uid_t); + memcpy(&lck->delete_token->gid, p, sizeof(gid_t)); + p += sizeof(gid_t); /* Any supplementary groups ? */ - lck->delete_token->ngroups = (data->u.s.delete_token_size > 8) ? - ((data->u.s.delete_token_size - 8)/4) : 0; + lck->delete_token->ngroups = (data->u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ? + ((data->u.s.delete_token_size - + (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0; + if (lck->delete_token->ngroups) { /* Make this a talloc child of lck->delete_token. */ lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t, @@ -492,8 +493,8 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) } for (i = 0; i < lck->delete_token->ngroups; i++) { - memcpy(&val, p++, 4); - lck->delete_token->groups[i] = (gid_t)val; + memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t)); + p += sizeof(gid_t); } } @@ -557,7 +558,7 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) sp_len = strlen(lck->servicepath); delete_token_size = (lck->delete_token ? - (8 + (lck->delete_token->ngroups*4)) : 0); + (sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0); result.dsize = sizeof(*data) + lck->num_share_modes * sizeof(struct share_mode_entry) + @@ -588,20 +589,18 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) /* Store any delete on close token. */ if (lck->delete_token) { - uint32 val; - uint32 *p = (uint32 *)(result.dptr + offset); + char *p = result.dptr + offset; - val = (uint32)lck->delete_token->uid; - memcpy(p++, &val, 4); + memcpy(p, &lck->delete_token->uid, sizeof(uid_t)); + p += sizeof(uid_t); - val = (uint32)lck->delete_token->uid; - memcpy(p++, &val, 4); + memcpy(p, &lck->delete_token->gid, sizeof(gid_t)); for (i = 0; i < lck->delete_token->ngroups; i++) { - val = (uint32)lck->delete_token->groups[i]; - memcpy(p++, &val, 4); + memcpy(p, &lck->delete_token->groups[i], sizeof(gid_t)); + p += sizeof(gid_t); } - offset = ((char *)p - result.dptr); + offset = p - result.dptr; } safe_strcpy(result.dptr + offset, lck->servicepath, -- cgit From fb5362c069b5b6548478b2217a0519c56d856705 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 20 Feb 2006 17:59:58 +0000 Subject: r13571: Replace all calls to talloc_free() with thye TALLOC_FREE() macro which sets the freed pointer to NULL. (This used to be commit b65be8874a2efe5a4b167448960a4fcf6bd995e2) --- source3/locking/locking.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d157c30c82..076f8a4969 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -681,7 +681,7 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, if (tdb_chainlock(tdb, key) != 0) { DEBUG(3, ("Could not lock share entry\n")); - talloc_free(lck); + TALLOC_FREE(lck); return NULL; } @@ -697,20 +697,20 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, if (lck->fresh) { if (fname == NULL || servicepath == NULL) { - talloc_free(lck); + TALLOC_FREE(lck); return NULL; } lck->filename = talloc_strdup(lck, fname); lck->servicepath = talloc_strdup(lck, servicepath); if (lck->filename == NULL || lck->servicepath == NULL) { DEBUG(0, ("talloc failed\n")); - talloc_free(lck); + TALLOC_FREE(lck); return NULL; } } else { if (!parse_share_modes(data, lck)) { DEBUG(0, ("Could not parse share modes\n")); - talloc_free(lck); + TALLOC_FREE(lck); SAFE_FREE(data.dptr); return NULL; } @@ -814,7 +814,7 @@ BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode) return False; } result = lck->delete_on_close; - talloc_free(lck); + TALLOC_FREE(lck); return result; } @@ -1142,7 +1142,7 @@ void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok { /* Ensure there's no token. */ if (lck->delete_token) { - talloc_free(lck->delete_token); /* Also deletes groups... */ + TALLOC_FREE(lck->delete_token); /* Also deletes groups... */ lck->delete_token = NULL; } @@ -1195,7 +1195,7 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKE lck->modified = True; } - talloc_free(lck); + TALLOC_FREE(lck); return True; } -- cgit From d6eebce490cfa7b17f9ca2779744db2924f1d165 Mon Sep 17 00:00:00 2001 From: James Peach Date: Wed, 15 Mar 2006 05:49:32 +0000 Subject: r14428: Call fill_share_mode_entry with NO_OPLOCK instead of 0. (This used to be commit a39cbaa699d111264c2c9dda49a6e4f42acd3fb8) --- source3/locking/locking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 076f8a4969..5cb1f71555 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -982,7 +982,7 @@ BOOL del_share_mode(struct share_mode_lock *lck, files_struct *fsp) { struct share_mode_entry entry, *e; - fill_share_mode_entry(&entry, fsp, 0, 0); + fill_share_mode_entry(&entry, fsp, 0, NO_OPLOCK); e = find_share_mode_entry(lck, &entry); if (e == NULL) { @@ -1018,7 +1018,7 @@ BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp) { struct share_mode_entry entry, *e; - fill_share_mode_entry(&entry, fsp, 0, 0); + fill_share_mode_entry(&entry, fsp, 0, NO_OPLOCK); e = find_share_mode_entry(lck, &entry); if (e == NULL) { @@ -1039,7 +1039,7 @@ BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp) { struct share_mode_entry entry, *e; - fill_share_mode_entry(&entry, fsp, 0, 0); + fill_share_mode_entry(&entry, fsp, 0, NO_OPLOCK); e = find_share_mode_entry(lck, &entry); if (e == NULL) { -- cgit From 81d4f40bbe202e5dae3d4d1070b02edf16a9f62e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Mar 2006 22:19:01 +0000 Subject: r14763: Add a new tuning parameter, open files database hash size, this allows us to experiment with ensuring the tdb hash size for our open files and locking db are appropriately sized. Make the hash size larger by default (10007 instead of 1049) and make the locking db hash size the same as the open file db hash size. Jeremy. (This used to be commit e7225f7e813423c3e2a94af6a9d7ce8a1b50a166) --- source3/locking/locking.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 5cb1f71555..0ecc90c794 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -301,7 +301,8 @@ BOOL locking_init(int read_only) return True; tdb = tdb_open_log(lock_path("locking.tdb"), - SMB_OPEN_DATABASE_TDB_HASH_SIZE, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), + lp_open_files_db_hash_size(), + TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); -- cgit From 22dbd67708f1651a2341d70ce576fac360affccf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Apr 2006 15:33:04 +0000 Subject: r15018: Merge Volker's ipc/trans2/nttrans changes over into 3.0. Also merge the new POSIX lock code - this is not enabled unless -DDEVELOPER is defined. This doesn't yet map onto underlying system POSIX locks. Updates vfs to allow lock queries. Jeremy. (This used to be commit 08e52ead03304ff04229e1bfe544ff40e2564fc7) --- source3/locking/locking.c | 305 ++++++++++++++++++++++++++++------------------ 1 file changed, 187 insertions(+), 118 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 0ecc90c794..0b3f625d03 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. Locking functions Copyright (C) Andrew Tridgell 1992-2000 - Copyright (C) Jeremy Allison 1992-2000 + Copyright (C) Jeremy Allison 1992-2006 Copyright (C) Volker Lendecke 2005 This program is free software; you can redistribute it and/or modify @@ -33,6 +33,7 @@ rewrtten completely to use new tdb code. Tridge, Dec '99 Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000. + Added Unix Extensions POSIX locking support. Jeremy Allison Mar 2006. */ #include "includes.h" @@ -45,120 +46,179 @@ uint16 global_smbpid; static TDB_CONTEXT *tdb; /**************************************************************************** - Debugging aid :-). + Debugging aids :-). ****************************************************************************/ -static const char *lock_type_name(enum brl_type lock_type) +const char *lock_type_name(enum brl_type lock_type) { - return (lock_type == READ_LOCK) ? "READ" : "WRITE"; + switch (lock_type) { + case READ_LOCK: + return "READ"; + case WRITE_LOCK: + return "WRITE"; + case PENDING_LOCK: + return "PENDING"; + default: + return "other"; + } +} + +const char *lock_flav_name(enum brl_flavour lock_flav) +{ + return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK"; } /**************************************************************************** Utility function called to see if a file region is locked. + Called in the read/write codepath. ****************************************************************************/ -BOOL is_locked(files_struct *fsp,connection_struct *conn, - SMB_BIG_UINT count,SMB_BIG_UINT offset, - enum brl_type lock_type) +BOOL is_locked(files_struct *fsp, + SMB_BIG_UINT count, + SMB_BIG_UINT offset, + enum brl_type lock_type) { - int snum = SNUM(conn); + int snum = SNUM(fsp->conn); int strict_locking = lp_strict_locking(snum); - BOOL ret; + enum brl_flavour lock_flav = lp_posix_cifsu_locktype(); + BOOL ret = True; - if (count == 0) - return(False); + if (count == 0) { + return False; + } - if (!lp_locking(snum) || !strict_locking) - return(False); + if (!lp_locking(snum) || !strict_locking) { + return False; + } if (strict_locking == Auto) { if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) { DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name )); - ret = 0; + ret = False; } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) && (lock_type == READ_LOCK)) { DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name )); - ret = 0; + ret = False; } else { - ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, procid_self(), conn->cnum, - offset, count, lock_type); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + if (!br_lck) { + return False; + } + ret = !brl_locktest(br_lck, + global_smbpid, + procid_self(), + offset, + count, + lock_type, + lock_flav); + TALLOC_FREE(br_lck); } } else { - ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum, - global_smbpid, procid_self(), conn->cnum, - offset, count, lock_type); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + if (!br_lck) { + return False; + } + ret = !brl_locktest(br_lck, + global_smbpid, + procid_self(), + offset, + count, + lock_type, + lock_flav); + TALLOC_FREE(br_lck); } - DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n", + DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n", + lock_flav_name(lock_flav), (double)offset, (double)count, ret ? "locked" : "unlocked", - fsp->fsp_name )); + fsp->fnum, fsp->fsp_name )); - /* - * There is no lock held by an SMB daemon, check to - * see if there is a POSIX lock from a UNIX or NFS process. - */ + return ret; +} - if(!ret && lp_posix_locking(snum)) { - ret = is_posix_locked(fsp, offset, count, lock_type); +/**************************************************************************** + Find out if a lock could be granted - return who is blocking us if we can't. +****************************************************************************/ + +NTSTATUS query_lock(files_struct *fsp, + uint16 *psmbpid, + SMB_BIG_UINT *pcount, + SMB_BIG_UINT *poffset, + enum brl_type *plock_type, + enum brl_flavour lock_flav) +{ + struct byte_range_lock *br_lck = NULL; + NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED; - DEBUG(10,("is_locked: posix start=%.0f len=%.0f %s for file %s\n", - (double)offset, (double)count, ret ? "locked" : "unlocked", - fsp->fsp_name )); + if (!OPEN_FSP(fsp) || !fsp->can_lock) { + return NT_STATUS_INVALID_HANDLE; } - return ret; + if (!lp_locking(SNUM(fsp->conn))) { + return NT_STATUS_OK; + } + + br_lck = brl_get_locks(NULL, fsp); + if (!br_lck) { + return NT_STATUS_NO_MEMORY; + } + + status = brl_lockquery(br_lck, + psmbpid, + procid_self(), + poffset, + pcount, + plock_type, + lock_flav); + + TALLOC_FREE(br_lck); + return status; } /**************************************************************************** Utility function called by locking requests. ****************************************************************************/ -static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, - SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx) +NTSTATUS do_lock(files_struct *fsp, + uint16 lock_pid, + SMB_BIG_UINT count, + SMB_BIG_UINT offset, + enum brl_type lock_type, + enum brl_flavour lock_flav, + BOOL *my_lock_ctx) { + struct byte_range_lock *br_lck = NULL; NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED; - if (!lp_locking(SNUM(conn))) + if (!OPEN_FSP(fsp) || !fsp->can_lock) { + return NT_STATUS_INVALID_HANDLE; + } + + if (!lp_locking(SNUM(fsp->conn))) { return NT_STATUS_OK; + } /* NOTE! 0 byte long ranges ARE allowed and should be stored */ - 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)) { - status = brl_lock(fsp->dev, fsp->inode, fsp->fnum, - lock_pid, procid_self(), conn->cnum, - offset, count, - lock_type, my_lock_ctx); - - if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) { - - /* - * Try and get a POSIX lock on this range. - * Note that this is ok if it is a read lock - * overlapping on a different fd. JRA. - */ - - if (!set_posix_lock(fsp, offset, count, lock_type)) { - if (errno == EACCES || errno == EAGAIN) - status = NT_STATUS_FILE_LOCK_CONFLICT; - else - status = map_nt_error_from_unix(errno); - - /* - * We failed to map - we must now remove the brl - * lock entry. - */ - (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - lock_pid, procid_self(), conn->cnum, - offset, count, False, - NULL, NULL); - } - } + DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f requested for fnum %d file %s\n", + lock_flav_name(lock_flav), lock_type_name(lock_type), + (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); + + br_lck = brl_get_locks(NULL, fsp); + if (!br_lck) { + return NT_STATUS_NO_MEMORY; } + status = brl_lock(br_lck, + lock_pid, + procid_self(), + offset, + count, + lock_type, + lock_flav, + my_lock_ctx); + + TALLOC_FREE(br_lck); return status; } @@ -169,20 +229,33 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p it, we need this. JRA. ****************************************************************************/ -NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid, - SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx) +NTSTATUS do_lock_spin(files_struct *fsp, + uint16 lock_pid, + SMB_BIG_UINT count, + SMB_BIG_UINT offset, + enum brl_type lock_type, + enum brl_flavour lock_flav, + BOOL *my_lock_ctx) { int j, maxj = lp_lock_spin_count(); int sleeptime = lp_lock_sleep_time(); NTSTATUS status, ret; - if (maxj <= 0) + if (maxj <= 0) { maxj = 1; + } ret = NT_STATUS_OK; /* to keep dumb compilers happy */ for (j = 0; j < maxj; j++) { - status = do_lock(fsp, conn, lock_pid, count, offset, lock_type, my_lock_ctx); + status = do_lock(fsp, + lock_pid, + count, + offset, + lock_type, + lock_flav, + my_lock_ctx); + if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) && !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { return status; @@ -191,72 +264,66 @@ NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid if (j == 0) { ret = status; /* Don't spin if we blocked ourselves. */ - if (*my_lock_ctx) + if (*my_lock_ctx) { return ret; + } + + /* Only spin for Windows locks. */ + if (lock_flav == POSIX_LOCK) { + return ret; + } } - if (sleeptime) + + if (sleeptime) { sys_usleep(sleeptime); + } } return ret; } -/* Struct passed to brl_unlock. */ -struct posix_unlock_data_struct { - files_struct *fsp; - SMB_BIG_UINT offset; - SMB_BIG_UINT count; -}; - -/**************************************************************************** - Function passed to brl_unlock to allow POSIX unlock to be done first. -****************************************************************************/ - -static void posix_unlock(void *pre_data) -{ - struct posix_unlock_data_struct *pdata = (struct posix_unlock_data_struct *)pre_data; - - if (lp_posix_locking(SNUM(pdata->fsp->conn))) - release_posix_lock(pdata->fsp, pdata->offset, pdata->count); -} - /**************************************************************************** Utility function called by unlocking requests. ****************************************************************************/ -NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, - SMB_BIG_UINT count,SMB_BIG_UINT offset) +NTSTATUS do_unlock(files_struct *fsp, + uint16 lock_pid, + SMB_BIG_UINT count, + SMB_BIG_UINT offset, + enum brl_flavour lock_flav) { BOOL ok = False; - struct posix_unlock_data_struct posix_data; + struct byte_range_lock *br_lck = NULL; - if (!lp_locking(SNUM(conn))) + if (!lp_locking(SNUM(fsp->conn))) { return NT_STATUS_OK; + } - if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) { + if (!OPEN_FSP(fsp) || !fsp->can_lock) { return NT_STATUS_INVALID_HANDLE; } - DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n", - (double)offset, (double)count, fsp->fsp_name )); + DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n", + (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); - /* - * Remove the existing lock record from the tdb lockdb - * before looking at POSIX locks. If this record doesn't - * match then don't bother looking to remove POSIX locks. - */ - - posix_data.fsp = fsp; - posix_data.offset = offset; - posix_data.count = count; + br_lck = brl_get_locks(NULL, fsp); + if (!br_lck) { + return NT_STATUS_NO_MEMORY; + } - ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - lock_pid, procid_self(), conn->cnum, offset, count, - False, posix_unlock, (void *)&posix_data); + ok = brl_unlock(br_lck, + lock_pid, + procid_self(), + offset, + count, + lock_flav); + TALLOC_FREE(br_lck); + if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); return NT_STATUS_RANGE_NOT_LOCKED; } + return NT_STATUS_OK; } @@ -266,6 +333,7 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid, void locking_close_file(files_struct *fsp) { + struct byte_range_lock *br_lck; struct process_id pid = procid_self(); if (!lp_locking(SNUM(fsp->conn))) @@ -275,13 +343,14 @@ void locking_close_file(files_struct *fsp) * Just release all the brl locks, no need to release individually. */ - brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum); + br_lck = brl_get_locks(NULL,fsp); + if (br_lck) { + brl_close_fnum(br_lck, pid); + TALLOC_FREE(br_lck); + } if(lp_posix_locking(SNUM(fsp->conn))) { - - /* - * Release all the POSIX locks. - */ + /* Release all the POSIX locks.*/ posix_locking_close_file(fsp); } -- cgit From 713eaf1d67d9ef967fb4526113e2a3ba3dd5e229 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 13 Apr 2006 22:22:54 +0000 Subject: r15083: Using talloc with destructors is nice and all, but in this case it's in a performace critical path and it *hurts* us. Go back to plain malloc/free with an explicit destructor call. Jeremy. (This used to be commit 1c99aed563c29e1b3d70939878af747a0660bfec) --- source3/locking/locking.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 0b3f625d03..2b6023c0c4 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -100,7 +100,7 @@ BOOL is_locked(files_struct *fsp, DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name )); ret = False; } else { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks(fsp); if (!br_lck) { return False; } @@ -111,10 +111,10 @@ BOOL is_locked(files_struct *fsp, count, lock_type, lock_flav); - TALLOC_FREE(br_lck); + byte_range_lock_destructor(br_lck); } } else { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks(fsp); if (!br_lck) { return False; } @@ -125,7 +125,7 @@ BOOL is_locked(files_struct *fsp, count, lock_type, lock_flav); - TALLOC_FREE(br_lck); + byte_range_lock_destructor(br_lck); } DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n", @@ -158,7 +158,7 @@ NTSTATUS query_lock(files_struct *fsp, return NT_STATUS_OK; } - br_lck = brl_get_locks(NULL, fsp); + br_lck = brl_get_locks(fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } @@ -171,7 +171,7 @@ NTSTATUS query_lock(files_struct *fsp, plock_type, lock_flav); - TALLOC_FREE(br_lck); + byte_range_lock_destructor(br_lck); return status; } @@ -204,7 +204,7 @@ NTSTATUS do_lock(files_struct *fsp, lock_flav_name(lock_flav), lock_type_name(lock_type), (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); - br_lck = brl_get_locks(NULL, fsp); + br_lck = brl_get_locks(fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } @@ -218,7 +218,7 @@ NTSTATUS do_lock(files_struct *fsp, lock_flav, my_lock_ctx); - TALLOC_FREE(br_lck); + byte_range_lock_destructor(br_lck); return status; } @@ -305,7 +305,7 @@ NTSTATUS do_unlock(files_struct *fsp, DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n", (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); - br_lck = brl_get_locks(NULL, fsp); + br_lck = brl_get_locks(fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } @@ -317,7 +317,7 @@ NTSTATUS do_unlock(files_struct *fsp, count, lock_flav); - TALLOC_FREE(br_lck); + byte_range_lock_destructor(br_lck); if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); @@ -343,10 +343,10 @@ void locking_close_file(files_struct *fsp) * Just release all the brl locks, no need to release individually. */ - br_lck = brl_get_locks(NULL,fsp); + br_lck = brl_get_locks(fsp); if (br_lck) { brl_close_fnum(br_lck, pid); - TALLOC_FREE(br_lck); + byte_range_lock_destructor(br_lck); } if(lp_posix_locking(SNUM(fsp->conn))) { -- cgit From cc9ea93456e594432e203e6d2d2f4dbcaac9a3dd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 May 2006 23:15:53 +0000 Subject: r15668: DOS or FCB opens share one share mode entry from different fsp pointers. Ensure we cope with this to pass Samba4 DENY tests (we used to pass these, there must have been a regression with newer code). We now pass them. Jeremy (This used to be commit fd6fa1d4eaf61783df74ee2da50d331477f06998) --- source3/locking/locking.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 2b6023c0c4..2766b257be 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -927,7 +927,7 @@ static void fill_share_mode_entry(struct share_mode_entry *e, e->op_type = op_type; e->time.tv_sec = fsp->open_time.tv_sec; e->time.tv_usec = fsp->open_time.tv_usec; - e->share_file_id = fsp->file_id; + e->share_file_id = fsp->fh->file_id; e->dev = fsp->dev; e->inode = fsp->inode; } @@ -986,28 +986,19 @@ void add_deferred_open(struct share_mode_lock *lck, uint16 mid, /******************************************************************* Check if two share mode entries are identical, ignoring oplock - and mid info and desired_access. + and mid info and desired_access. (Removed paranoia test - it's + not automatically a logic error if they are identical. JRA.) ********************************************************************/ static BOOL share_modes_identical(struct share_mode_entry *e1, struct share_mode_entry *e2) { -#if 1 /* JRA PARANOIA TEST - REMOVE LATER */ - if (procid_equal(&e1->pid, &e2->pid) && - e1->share_file_id == e2->share_file_id && - e1->dev == e2->dev && - e1->inode == e2->inode && - (e1->share_access) != (e2->share_access)) { - DEBUG(0,("PANIC: share_modes_identical: share_mode " - "mismatch (e1 = 0x%x, e2 = 0x%x). Logic error.\n", - (unsigned int)e1->share_access, - (unsigned int)e2->share_access )); - smb_panic("PANIC: share_modes_identical logic error.\n"); - } -#endif + /* We used to check for e1->share_access == e2->share_access here + as well as the other fields but 2 different DOS or FCB opens + sharing the same share mode entry may validly differ in + fsp->share_access field. */ return (procid_equal(&e1->pid, &e2->pid) && - (e1->share_access) == (e2->share_access) && e1->dev == e2->dev && e1->inode == e2->inode && e1->share_file_id == e2->share_file_id ); -- cgit From 6a026d56185f56dc9bf5ae8e5c1d33a0ce32562b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 May 2006 00:22:07 +0000 Subject: r15670: Fix valgrind-spotted issue in BASE-DELETE test. We were forgetting to increment after copying the primary group gid. Jeremy (This used to be commit 31d16c434e1ee94691f013ed0b31d9f26baeb2cb) --- source3/locking/locking.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 2766b257be..a532a90d0d 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -665,6 +665,7 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) p += sizeof(uid_t); memcpy(p, &lck->delete_token->gid, sizeof(gid_t)); + p += sizeof(gid_t); for (i = 0; i < lck->delete_token->ngroups; i++) { memcpy(p, &lck->delete_token->groups[i], sizeof(gid_t)); -- cgit From 0a1ca7fa3d19f46c4bcb0c80c78a619c90fe5f2a Mon Sep 17 00:00:00 2001 From: James Peach Date: Mon, 29 May 2006 23:54:53 +0000 Subject: r15943: Update misleading DEBUG statements and comments that refer to open_file_shared. (This used to be commit 784126edff942d1c2f79f7c9feb59980426f331e) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index a532a90d0d..b536844319 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1116,7 +1116,7 @@ BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp) /**************************************************************************** Deal with the internal needs of setting the delete on close flag. Note that as the tdb locking is recursive, it is safe to call this from within - open_file_shared. JRA. + open_file_ntcreate. JRA. ****************************************************************************/ NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close, -- cgit From c115570b857cff15c929cf80ad3c8f32272818d5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Jun 2006 01:35:08 +0000 Subject: r16281: Start fixing up gcc4 -O6 warnings on an x86_64 box. size_t != unsigned int in a format string. Jeremy. (This used to be commit c49ad9200bf3fdd8b9404d93182c2e04e662190a) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index b536844319..0ffb937432 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -846,7 +846,7 @@ BOOL rename_share_filename(struct share_mode_lock *lck, SDEV_T_VAL(frm,0,lck->dev); SINO_T_VAL(frm,8,lck->ino); - DEBUG(10,("rename_share_filename: msg_len = %d\n", msg_len )); + DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len )); safe_strcpy(&frm[16], lck->servicepath, sp_len); safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len); -- cgit From 54ea3c23e3bfd25008198e85fdcc1f48b0325eab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Jun 2006 02:31:12 +0000 Subject: r16435: Add in the uid info that Jerry needs into the share_mode struct. Allows us to know the unix uid of the opener of the file/directory. Needed for info level queries on open files. Jeremy. (This used to be commit d929323d6f513902381369d77bcd7b714346d713) --- source3/locking/locking.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 0ffb937432..01f12bbb58 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -443,13 +443,13 @@ char *share_mode_str(int num, struct share_mode_entry *e) slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: %s " "pid = %s, share_access = 0x%x, private_options = 0x%x, " "access_mask = 0x%x, mid = 0x%x, type= 0x%x, file_id = %lu, " - "dev = 0x%x, inode = %.0f", + "uid = %u, dev = 0x%x, inode = %.0f", num, e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "", procid_str_static(&e->pid), e->share_access, e->private_options, e->access_mask, e->op_mid, e->op_type, e->share_file_id, - (unsigned int)e->dev, (double)e->inode ); + (unsigned int)e->uid, (unsigned int)e->dev, (double)e->inode ); return share_str; } @@ -917,7 +917,7 @@ BOOL is_unused_share_mode_entry(const struct share_mode_entry *e) static void fill_share_mode_entry(struct share_mode_entry *e, files_struct *fsp, - uint16 mid, uint16 op_type) + uid_t uid, uint16 mid, uint16 op_type) { ZERO_STRUCTP(e); e->pid = procid_self(); @@ -928,9 +928,10 @@ static void fill_share_mode_entry(struct share_mode_entry *e, e->op_type = op_type; e->time.tv_sec = fsp->open_time.tv_sec; e->time.tv_usec = fsp->open_time.tv_usec; - e->share_file_id = fsp->fh->file_id; e->dev = fsp->dev; e->inode = fsp->inode; + e->share_file_id = fsp->fh->file_id; + e->uid = (uint32)uid; } static void fill_deferred_open_entry(struct share_mode_entry *e, @@ -945,6 +946,7 @@ static void fill_deferred_open_entry(struct share_mode_entry *e, e->time.tv_usec = request_time.tv_usec; e->dev = dev; e->inode = ino; + e->uid = (uint32)-1; } static void add_share_mode_entry(struct share_mode_lock *lck, @@ -969,10 +971,10 @@ static void add_share_mode_entry(struct share_mode_lock *lck, } void set_share_mode(struct share_mode_lock *lck, files_struct *fsp, - uint16 mid, uint16 op_type) + uid_t uid, uint16 mid, uint16 op_type) { struct share_mode_entry entry; - fill_share_mode_entry(&entry, fsp, mid, op_type); + fill_share_mode_entry(&entry, fsp, uid, mid, op_type); add_share_mode_entry(lck, &entry); } @@ -1044,7 +1046,8 @@ BOOL del_share_mode(struct share_mode_lock *lck, files_struct *fsp) { struct share_mode_entry entry, *e; - fill_share_mode_entry(&entry, fsp, 0, NO_OPLOCK); + /* Don't care about the pid owner being correct here - just a search. */ + fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK); e = find_share_mode_entry(lck, &entry); if (e == NULL) { @@ -1080,7 +1083,8 @@ BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp) { struct share_mode_entry entry, *e; - fill_share_mode_entry(&entry, fsp, 0, NO_OPLOCK); + /* Don't care about the pid owner being correct here - just a search. */ + fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK); e = find_share_mode_entry(lck, &entry); if (e == NULL) { @@ -1101,7 +1105,8 @@ BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp) { struct share_mode_entry entry, *e; - fill_share_mode_entry(&entry, fsp, 0, NO_OPLOCK); + /* Don't care about the pid owner being correct here - just a search. */ + fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK); e = find_share_mode_entry(lck, &entry); if (e == NULL) { -- cgit From cc1457beb00faa6869e2472e305b4e97c0995ea3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Jun 2006 22:33:10 +0000 Subject: r16661: Fix from jason@ncac.gwu.edu for bug #3875, bad cast warning. Jeremy. (This used to be commit d60e6e0abc17361fe180d6723b970552dc377741) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 01f12bbb58..9d3ca95601 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1274,7 +1274,7 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, const char *sharepath; const char *fname; int i; - void (*traverse_callback)(struct share_mode_entry *, const char *, const char *) = state; + LOCKING_FN(traverse_callback) = (LOCKING_FN_CAST())state; /* Ensure this is a locking_key record. */ if (kbuf.dsize != sizeof(struct locking_key)) -- cgit From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/locking/locking.c | 87 +++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 48 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 9d3ca95601..ac50c9b648 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -37,7 +37,6 @@ */ #include "includes.h" -uint16 global_smbpid; #undef DBGC_CLASS #define DBGC_CLASS DBGC_LOCKING @@ -74,6 +73,7 @@ const char *lock_flav_name(enum brl_flavour lock_flav) ****************************************************************************/ BOOL is_locked(files_struct *fsp, + uint32 smbpid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type) @@ -100,32 +100,32 @@ BOOL is_locked(files_struct *fsp, DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name )); ret = False; } else { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); if (!br_lck) { return False; } ret = !brl_locktest(br_lck, - global_smbpid, + smbpid, procid_self(), offset, count, lock_type, lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } } else { - struct byte_range_lock *br_lck = brl_get_locks(fsp); + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); if (!br_lck) { return False; } ret = !brl_locktest(br_lck, - global_smbpid, + smbpid, procid_self(), offset, count, lock_type, lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); } DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n", @@ -141,7 +141,7 @@ BOOL is_locked(files_struct *fsp, ****************************************************************************/ NTSTATUS query_lock(files_struct *fsp, - uint16 *psmbpid, + uint32 *psmbpid, SMB_BIG_UINT *pcount, SMB_BIG_UINT *poffset, enum brl_type *plock_type, @@ -150,15 +150,15 @@ NTSTATUS query_lock(files_struct *fsp, struct byte_range_lock *br_lck = NULL; NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED; - if (!OPEN_FSP(fsp) || !fsp->can_lock) { - return NT_STATUS_INVALID_HANDLE; + if (!fsp->can_lock) { + return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } if (!lp_locking(SNUM(fsp->conn))) { return NT_STATUS_OK; } - br_lck = brl_get_locks(fsp); + br_lck = brl_get_locks(NULL, fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } @@ -171,7 +171,7 @@ NTSTATUS query_lock(files_struct *fsp, plock_type, lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); return status; } @@ -180,7 +180,7 @@ NTSTATUS query_lock(files_struct *fsp, ****************************************************************************/ NTSTATUS do_lock(files_struct *fsp, - uint16 lock_pid, + uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type, @@ -190,8 +190,8 @@ NTSTATUS do_lock(files_struct *fsp, struct byte_range_lock *br_lck = NULL; NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED; - if (!OPEN_FSP(fsp) || !fsp->can_lock) { - return NT_STATUS_INVALID_HANDLE; + if (!fsp->can_lock) { + return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } if (!lp_locking(SNUM(fsp->conn))) { @@ -204,7 +204,7 @@ NTSTATUS do_lock(files_struct *fsp, lock_flav_name(lock_flav), lock_type_name(lock_type), (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); - br_lck = brl_get_locks(fsp); + br_lck = brl_get_locks(NULL, fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } @@ -218,7 +218,7 @@ NTSTATUS do_lock(files_struct *fsp, lock_flav, my_lock_ctx); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); return status; } @@ -230,7 +230,7 @@ NTSTATUS do_lock(files_struct *fsp, ****************************************************************************/ NTSTATUS do_lock_spin(files_struct *fsp, - uint16 lock_pid, + uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type, @@ -286,7 +286,7 @@ NTSTATUS do_lock_spin(files_struct *fsp, ****************************************************************************/ NTSTATUS do_unlock(files_struct *fsp, - uint16 lock_pid, + uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_flavour lock_flav) @@ -294,18 +294,18 @@ NTSTATUS do_unlock(files_struct *fsp, BOOL ok = False; struct byte_range_lock *br_lck = NULL; - if (!lp_locking(SNUM(fsp->conn))) { - return NT_STATUS_OK; + if (!fsp->can_lock) { + return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } - if (!OPEN_FSP(fsp) || !fsp->can_lock) { - return NT_STATUS_INVALID_HANDLE; + if (!lp_locking(SNUM(fsp->conn))) { + return NT_STATUS_OK; } DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n", (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); - br_lck = brl_get_locks(fsp); + br_lck = brl_get_locks(NULL, fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } @@ -317,7 +317,7 @@ NTSTATUS do_unlock(files_struct *fsp, count, lock_flav); - byte_range_lock_destructor(br_lck); + TALLOC_FREE(br_lck); if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); @@ -334,25 +334,15 @@ NTSTATUS do_unlock(files_struct *fsp, void locking_close_file(files_struct *fsp) { struct byte_range_lock *br_lck; - struct process_id pid = procid_self(); - if (!lp_locking(SNUM(fsp->conn))) + if (!lp_locking(SNUM(fsp->conn))) { return; - - /* - * Just release all the brl locks, no need to release individually. - */ - - br_lck = brl_get_locks(fsp); - if (br_lck) { - brl_close_fnum(br_lck, pid); - byte_range_lock_destructor(br_lck); } - if(lp_posix_locking(SNUM(fsp->conn))) { - /* Release all the POSIX locks.*/ - posix_locking_close_file(fsp); - + br_lck = brl_get_locks(NULL,fsp); + if (br_lck) { + brl_close_fnum(br_lck); + TALLOC_FREE(br_lck); } } @@ -516,9 +506,10 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) smb_panic("PANIC: parse_share_modes: buffer too short.\n"); } - lck->share_modes = talloc_memdup(lck, dbuf.dptr+sizeof(*data), - lck->num_share_modes * - sizeof(struct share_mode_entry)); + lck->share_modes = (struct share_mode_entry *) + talloc_memdup(lck, dbuf.dptr+sizeof(*data), + lck->num_share_modes * + sizeof(struct share_mode_entry)); if (lck->share_modes == NULL) { smb_panic("talloc failed\n"); @@ -635,7 +626,7 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) delete_token_size + sp_len + 1 + strlen(lck->filename) + 1; - result.dptr = talloc_size(lck, result.dsize); + result.dptr = TALLOC_ARRAY(lck, char, result.dsize); if (result.dptr == NULL) { smb_panic("talloc failed\n"); @@ -838,7 +829,7 @@ BOOL rename_share_filename(struct share_mode_lock *lck, msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + fn_len + 1; /* Set up the name changed message. */ - frm = TALLOC(lck, msg_len); + frm = TALLOC_ARRAY(lck, char, msg_len); if (!frm) { return False; } @@ -862,9 +853,9 @@ BOOL rename_share_filename(struct share_mode_lock *lck, continue; } - DEBUG(10,("rename_share_filename: sending rename message to pid %u " + DEBUG(10,("rename_share_filename: sending rename message to pid %s " "dev %x, inode %.0f sharepath %s newname %s\n", - (unsigned int)procid_to_pid(&se->pid), + procid_str_static(&se->pid), (unsigned int)lck->dev, (double)lck->ino, lck->servicepath, lck->filename )); @@ -1305,5 +1296,5 @@ int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, { if (tdb == NULL) return 0; - return tdb_traverse(tdb, traverse_fn, fn); + return tdb_traverse(tdb, traverse_fn, (void *)fn); } -- cgit From e1da1fcf12164f50f3462c90f0bb785d18c59b0b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 17 Jul 2006 21:09:02 +0000 Subject: r17098: Samba3 now cleanly passes Samba4 RAW-LOCK torture test. Phew - that was painful :-). But what it means is that we now implement lock cancels and I can add lock cancels into POSIX lock handling which will fix the fast/slow system call issue with cifsfs ! Jeremy. (This used to be commit f1a9cf075b87c76c032d19da0168424c90f6cb3c) --- source3/locking/locking.c | 102 +++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 56 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index ac50c9b648..cd1d9547f3 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -185,7 +185,7 @@ NTSTATUS do_lock(files_struct *fsp, SMB_BIG_UINT offset, enum brl_type lock_type, enum brl_flavour lock_flav, - BOOL *my_lock_ctx) + int32 lock_timeout) { struct byte_range_lock *br_lck = NULL; NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED; @@ -216,76 +216,63 @@ NTSTATUS do_lock(files_struct *fsp, count, lock_type, lock_flav, - my_lock_ctx); + lock_timeout); TALLOC_FREE(br_lck); return status; } /**************************************************************************** - Utility function called by locking requests. This is *DISGUSTING*. It also - appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000 - is so slow on the locking tests...... ? This is the reason. Much though I hate - it, we need this. JRA. + Utility function called by unlocking requests. ****************************************************************************/ -NTSTATUS do_lock_spin(files_struct *fsp, +NTSTATUS do_unlock(files_struct *fsp, uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, - enum brl_type lock_type, - enum brl_flavour lock_flav, - BOOL *my_lock_ctx) + enum brl_flavour lock_flav) { - int j, maxj = lp_lock_spin_count(); - int sleeptime = lp_lock_sleep_time(); - NTSTATUS status, ret; - - if (maxj <= 0) { - maxj = 1; + BOOL ok = False; + struct byte_range_lock *br_lck = NULL; + + if (!fsp->can_lock) { + return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } + + if (!lp_locking(SNUM(fsp->conn))) { + return NT_STATUS_OK; + } + + DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n", + (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); - ret = NT_STATUS_OK; /* to keep dumb compilers happy */ - - for (j = 0; j < maxj; j++) { - status = do_lock(fsp, - lock_pid, - count, - offset, - lock_type, - lock_flav, - my_lock_ctx); - - if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) && - !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { - return status; - } - /* if we do fail then return the first error code we got */ - if (j == 0) { - ret = status; - /* Don't spin if we blocked ourselves. */ - if (*my_lock_ctx) { - return ret; - } + br_lck = brl_get_locks(NULL, fsp); + if (!br_lck) { + return NT_STATUS_NO_MEMORY; + } - /* Only spin for Windows locks. */ - if (lock_flav == POSIX_LOCK) { - return ret; - } - } + ok = brl_unlock(br_lck, + lock_pid, + procid_self(), + offset, + count, + lock_flav); + + TALLOC_FREE(br_lck); - if (sleeptime) { - sys_usleep(sleeptime); - } + if (!ok) { + DEBUG(10,("do_unlock: returning ERRlock.\n" )); + return NT_STATUS_RANGE_NOT_LOCKED; } - return ret; + + return NT_STATUS_OK; } /**************************************************************************** - Utility function called by unlocking requests. + Cancel any pending blocked locks. ****************************************************************************/ -NTSTATUS do_unlock(files_struct *fsp, +NTSTATUS do_lock_cancel(files_struct *fsp, uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, @@ -295,14 +282,15 @@ NTSTATUS do_unlock(files_struct *fsp, struct byte_range_lock *br_lck = NULL; if (!fsp->can_lock) { - return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; + return fsp->is_directory ? + NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } if (!lp_locking(SNUM(fsp->conn))) { - return NT_STATUS_OK; + return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } - - DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n", + + DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n", (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); br_lck = brl_get_locks(NULL, fsp); @@ -310,7 +298,7 @@ NTSTATUS do_unlock(files_struct *fsp, return NT_STATUS_NO_MEMORY; } - ok = brl_unlock(br_lck, + ok = brl_lock_cancel(br_lck, lock_pid, procid_self(), offset, @@ -320,8 +308,8 @@ NTSTATUS do_unlock(files_struct *fsp, TALLOC_FREE(br_lck); if (!ok) { - DEBUG(10,("do_unlock: returning ERRlock.\n" )); - return NT_STATUS_RANGE_NOT_LOCKED; + DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" )); + return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } return NT_STATUS_OK; @@ -340,7 +328,9 @@ void locking_close_file(files_struct *fsp) } br_lck = brl_get_locks(NULL,fsp); + if (br_lck) { + cancel_pending_lock_requests_by_fid(fsp, br_lck); brl_close_fnum(br_lck); TALLOC_FREE(br_lck); } -- cgit From b737f26764cce935d9482335ece11c71a96720f4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Jul 2006 01:05:51 +0000 Subject: r17105: Fix the race Volker found - we had a non-locked region between detecting a pending lock was needed and when we added the blocking lock record. Make sure that we hold the lock over all this period. Removed the old code for doing blocking locks on SMB requests that never block (the old SMBlock and friends). Discovered something interesting about the strange NT_STATUS_FILE_LOCK_CONFLICT return. If we asked for a lock with zero timeout, and we got an error of NT_STATUS_FILE_LOCK_CONFLICT, treat it as though it was a blocking lock with a timeout of 150 - 300ms. This only happens when timeout is sent as zero and can be seen quite clearly in ethereal. This is the real replacement for old do_lock_spin() code. Re-worked the blocking lock select timeout to correctly use milliseconds instead of the old second level resolution (far too coarse for this work). Jeremy. (This used to be commit b81d6d1ae95a3d3e449dde629884b565eac289d9) --- source3/locking/locking.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index cd1d9547f3..a7cadd3a40 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -179,23 +179,25 @@ NTSTATUS query_lock(files_struct *fsp, Utility function called by locking requests. ****************************************************************************/ -NTSTATUS do_lock(files_struct *fsp, +struct byte_range_lock *do_lock(files_struct *fsp, uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, enum brl_type lock_type, enum brl_flavour lock_flav, - int32 lock_timeout) + BOOL blocking_lock, + NTSTATUS *perr) { struct byte_range_lock *br_lck = NULL; - NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED; if (!fsp->can_lock) { - return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; + *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; + return NULL; } if (!lp_locking(SNUM(fsp->conn))) { - return NT_STATUS_OK; + *perr = NT_STATUS_OK; + return NULL; } /* NOTE! 0 byte long ranges ARE allowed and should be stored */ @@ -206,20 +208,20 @@ NTSTATUS do_lock(files_struct *fsp, br_lck = brl_get_locks(NULL, fsp); if (!br_lck) { - return NT_STATUS_NO_MEMORY; + *perr = NT_STATUS_NO_MEMORY; + return NULL; } - status = brl_lock(br_lck, + *perr = brl_lock(br_lck, lock_pid, procid_self(), offset, count, lock_type, lock_flav, - lock_timeout); + blocking_lock); - TALLOC_FREE(br_lck); - return status; + return br_lck; } /**************************************************************************** -- cgit From e0c68d0a1d591e4285746a8af70040448752a735 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 21 Jul 2006 14:13:30 +0000 Subject: r17177: Get rid of a global variable by adding a private data pointer to share_mode_forall(). Volker (This used to be commit f97f6cedffdc4d10afcac90a163b93a801acf514) --- source3/locking/locking.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index a7cadd3a40..3cbf318007 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1249,15 +1249,23 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKE return True; } +struct forall_state { + void (*fn)(const struct share_mode_entry *entry, + const char *sharepath, + const char *fname, + void *private_data); + void *private_data; +}; + static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, - void *state) + void *_state) { + struct forall_state *state = (struct forall_state *)_state; struct locking_data *data; struct share_mode_entry *shares; const char *sharepath; const char *fname; int i; - LOCKING_FN(traverse_callback) = (LOCKING_FN_CAST())state; /* Ensure this is a locking_key record. */ if (kbuf.dsize != sizeof(struct locking_key)) @@ -1274,7 +1282,8 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, strlen(sharepath) + 1; for (i=0;iu.s.num_share_mode_entries;i++) { - traverse_callback(&shares[i], sharepath, fname); + state->fn(&shares[i], sharepath, fname, + state->private_data); } return 0; } @@ -1284,9 +1293,17 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, share mode system. ********************************************************************/ -int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, const char *)) +int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, + const char *, void *), + void *private_data) { + struct forall_state state; + if (tdb == NULL) return 0; - return tdb_traverse(tdb, traverse_fn, (void *)fn); + + state.fn = fn; + state.private_data = private_data; + + return tdb_traverse(tdb, traverse_fn, (void *)&state); } -- cgit From a093a76dc14303fd1c42fb2c0b87faf3748815e4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Jul 2006 22:42:39 +0000 Subject: r17293: After the results from the cluster tests in Germany, fix the messaging code to call the efficient calls : save_re_uid() set_effective_uid(0); messaging_op restore_re_uid(); instead of using heavyweight become_root()/unbecome_root() pairs around all messaging code. Fixup the messaging code to ensure sec_init() is called (only once) so that non-root processes still work when sending messages. This is a lighter weight solution to become_root()/unbecome_root() (which swaps all the supplemental groups) and should be more efficient. I will migrate all server code over to using this (a similar technique should be used in the passdb backend where needed). Jeremy. (This used to be commit 4ace291278d9a44f5c577bdd3b282c1231e543df) --- source3/locking/locking.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 3cbf318007..3879d40cba 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -851,10 +851,8 @@ BOOL rename_share_filename(struct share_mode_lock *lck, (unsigned int)lck->dev, (double)lck->ino, lck->servicepath, lck->filename )); - become_root(); message_send_pid(se->pid, MSG_SMB_FILE_RENAME, frm, msg_len, True); - unbecome_root(); } return True; -- cgit From 2c6030415e0b1f421ea6e85fe6ffe7389ee7a941 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 29 Jul 2006 19:14:24 +0000 Subject: r17314: Optimisation for POSIX locking. If we're downgrading a POSIX lock (applying a read-lock) and we overlap pending read locks then send them an unlock message, we may have allowed them to proceed. Jeremy. (This used to be commit a7a0b6ba50f4cf7c5a0a29809fdff9e1266a29e7) --- source3/locking/locking.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 3879d40cba..4cd6b436c3 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -55,8 +55,10 @@ const char *lock_type_name(enum brl_type lock_type) return "READ"; case WRITE_LOCK: return "WRITE"; - case PENDING_LOCK: - return "PENDING"; + case PENDING_READ_LOCK: + return "PENDING_READ"; + case PENDING_WRITE_LOCK: + return "PENDING_WRITE"; default: return "other"; } -- cgit From 49001a5b1b07e9a24e5f7efa0dfd880772bdb435 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 31 Jul 2006 20:58:02 +0000 Subject: r17346: Add optimisation vl needs for the cluster code where we don't get the chainlock when getting the byte range lock record read-only. Jeremy. (This used to be commit fcd798ca0c1b76adb2bcda4a99c40c7aacb0addb) --- source3/locking/locking.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 4cd6b436c3..8dd7fafd3b 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -102,7 +102,7 @@ BOOL is_locked(files_struct *fsp, DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name )); ret = False; } else { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks_readonly(NULL, fsp); if (!br_lck) { return False; } @@ -116,7 +116,7 @@ BOOL is_locked(files_struct *fsp, TALLOC_FREE(br_lck); } } else { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks_readonly(NULL, fsp); if (!br_lck) { return False; } @@ -160,7 +160,7 @@ NTSTATUS query_lock(files_struct *fsp, return NT_STATUS_OK; } - br_lck = brl_get_locks(NULL, fsp); + br_lck = brl_get_locks_readonly(NULL, fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } -- cgit From 3bc4fd1bb9bfbd0e0efd89d47c50bf798e5a1481 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 Aug 2006 19:14:25 +0000 Subject: r17924: Get rid of warnings now that talloc is merged. Destructors now take a pointer to the "real" destroyed object as an argument. Volker (This used to be commit 70edd716ef0ccb218fe18d1233bd30abe46b62bf) --- source3/locking/locking.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 8dd7fafd3b..371f1b474c 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -672,10 +672,8 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) return result; } -static int share_mode_lock_destructor(void *p) +static int share_mode_lock_destructor(struct share_mode_lock *lck) { - struct share_mode_lock *lck = - talloc_get_type_abort(p, struct share_mode_lock); TDB_DATA key = locking_key(lck->dev, lck->ino); TDB_DATA data; -- cgit From 8f553d8d3cbdf372ddbcbdaab48ef16296d3872c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 4 Oct 2006 20:51:17 +0000 Subject: r19078: talloc_strdup can fail (This used to be commit 2b3b9ce2a122ec5fd945728c117c321087d85203) --- source3/locking/locking.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 371f1b474c..fbe22f4e1d 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -562,12 +562,18 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) (lck->num_share_modes * sizeof(struct share_mode_entry)) + data->u.s.delete_token_size ); + if (lck->servicepath == NULL) { + smb_panic("talloc_strdup failed\n"); + } lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) + (lck->num_share_modes * sizeof(struct share_mode_entry)) + data->u.s.delete_token_size + strlen(lck->servicepath) + 1 ); + if (lck->filename == NULL) { + smb_panic("talloc_strdup failed\n"); + } /* * Ensure that each entry has a real process attached. -- cgit From b6b84f98c0420f45c498b025d9edbeb7f830205a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 11 Nov 2006 17:05:11 +0000 Subject: r19668: Convert the locking params to use struct share_param instead of snum (This used to be commit 609dbec600048718b86cd1ecdc2ce49bbdeb803c) --- source3/locking/locking.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index fbe22f4e1d..13c7724656 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -80,8 +80,7 @@ BOOL is_locked(files_struct *fsp, SMB_BIG_UINT offset, enum brl_type lock_type) { - int snum = SNUM(fsp->conn); - int strict_locking = lp_strict_locking(snum); + int strict_locking = lp_strict_locking(fsp->conn->params); enum brl_flavour lock_flav = lp_posix_cifsu_locktype(); BOOL ret = True; @@ -89,7 +88,7 @@ BOOL is_locked(files_struct *fsp, return False; } - if (!lp_locking(snum) || !strict_locking) { + if (!lp_locking(fsp->conn->params) || !strict_locking) { return False; } @@ -156,7 +155,7 @@ NTSTATUS query_lock(files_struct *fsp, return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } - if (!lp_locking(SNUM(fsp->conn))) { + if (!lp_locking(fsp->conn->params)) { return NT_STATUS_OK; } @@ -197,7 +196,7 @@ struct byte_range_lock *do_lock(files_struct *fsp, return NULL; } - if (!lp_locking(SNUM(fsp->conn))) { + if (!lp_locking(fsp->conn->params)) { *perr = NT_STATUS_OK; return NULL; } @@ -243,7 +242,7 @@ NTSTATUS do_unlock(files_struct *fsp, return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } - if (!lp_locking(SNUM(fsp->conn))) { + if (!lp_locking(fsp->conn->params)) { return NT_STATUS_OK; } @@ -290,7 +289,7 @@ NTSTATUS do_lock_cancel(files_struct *fsp, NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE; } - if (!lp_locking(SNUM(fsp->conn))) { + if (!lp_locking(fsp->conn->params)) { return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } @@ -327,7 +326,7 @@ void locking_close_file(files_struct *fsp) { struct byte_range_lock *br_lck; - if (!lp_locking(SNUM(fsp->conn))) { + if (!lp_locking(fsp->conn->params)) { return; } -- cgit From fd37f98158161406229b728a7c767121a30e254f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Jan 2007 06:19:24 +0000 Subject: r20873: Some correctness fixes w.r.t. Samba4 torture BASE-DELETE. Allow us to correctly refuse to set delete on close on a non-empty directory. There are still some delete-on-close wrinkles to be fixed, but I understand how to do that better now. I'll fix this tomorrow. Jeremy. (This used to be commit 029635885825a5562e7974a6f5675cce3bf1b5dc) --- source3/locking/locking.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 13c7724656..111fc98bbe 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1152,6 +1152,46 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close, return NT_STATUS_ACCESS_DENIED; } + /* Don't allow delete on close for non-empty directories. */ + if (fsp->is_directory) { + long offset = 0; + NTSTATUS status; + SMB_STRUCT_STAT st; + struct dptr_struct *dirptr; + const char *name; + + status = dptr_create(fsp->conn, + fsp->fsp_name, + False, + True, + 0, + "*", + True, + 0, + &dirptr); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* Read 3 entries. Ignore first 2 (they're . and .. ) */ + name = dptr_ReadDirName(dirptr, &offset, &st); + if (!name) { + dptr_CloseDir(dirptr); + return NT_STATUS_ACCESS_DENIED; + } + name = dptr_ReadDirName(dirptr, &offset, &st); + if (!name) { + dptr_CloseDir(dirptr); + return NT_STATUS_ACCESS_DENIED; + } + name = dptr_ReadDirName(dirptr, &offset, &st); + dptr_CloseDir(dirptr); + if (name) { + DEBUG(10,("can_set_delete_on_close: got name %s - can't delete\n", name )); + return NT_STATUS_DIRECTORY_NOT_EMPTY; + } + } + return NT_STATUS_OK; } -- cgit From c9a14ea19f812d86266bfa9e6ce8b32f7b4ff19f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Jan 2007 21:51:52 +0000 Subject: r20883: W00t! I now understand how "delete on close" really works - even with the strange "initial delete on close" semantics. The "initial delete on close" flag isn't committed to the share mode db until the handle is closed, and is discarded if any real "delete on close" was set. This allows me to remove the "initial_delete_on_close" flag from the share db, and move it into a BOOL in files_struct. Warning ! You must do a make clean after this. Cope with the wrinkle in directory delete on close which is done differently from files. We now pass all Samba4 smbtortute BASE-DELETE tests except for the one checking that files can't be created in a directory which has the delete on close set (possibly expensive to fix). Jeremy. (This used to be commit f2df77a1497958c1ea791f1d2f4446b5fc3389b3) --- source3/locking/locking.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 111fc98bbe..56d18a63ef 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -473,14 +473,11 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) data = (struct locking_data *)dbuf.dptr; lck->delete_on_close = data->u.s.delete_on_close; - lck->initial_delete_on_close = data->u.s.initial_delete_on_close; lck->num_share_modes = data->u.s.num_share_mode_entries; DEBUG(10, ("parse_share_modes: delete_on_close: %d, " - "initial_delete_on_close: %d, " "num_share_modes: %d\n", lck->delete_on_close, - lck->initial_delete_on_close, lck->num_share_modes)); if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) { @@ -635,11 +632,9 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) ZERO_STRUCTP(data); data->u.s.num_share_mode_entries = lck->num_share_modes; data->u.s.delete_on_close = lck->delete_on_close; - data->u.s.initial_delete_on_close = lck->initial_delete_on_close; data->u.s.delete_token_size = delete_token_size; - DEBUG(10, ("unparse_share_modes: del: %d, initial del %d, tok = %u, num: %d\n", + DEBUG(10, ("unparse_share_modes: del: %d, tok = %u, num: %d\n", data->u.s.delete_on_close, - data->u.s.initial_delete_on_close, (unsigned int)data->u.s.delete_token_size, data->u.s.num_share_mode_entries)); memcpy(result.dptr + sizeof(*data), lck->share_modes, @@ -734,7 +729,6 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, lck->share_modes = NULL; lck->delete_token = NULL; lck->delete_on_close = False; - lck->initial_delete_on_close = False; lck->fresh = False; lck->modified = False; @@ -1251,11 +1245,22 @@ void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok changed the delete on close flag. This will be noticed in the close code, the last closer will delete the file if flag is set. - Note that setting this to any value clears the initial_delete_on_close flag. - If delete_on_close is True this makes a copy of any UNIX_USER_TOKEN into the - lck entry. + This makes a copy of any UNIX_USER_TOKEN into the + lck entry. This function is used when the lock is already granted. ****************************************************************************/ +void set_delete_on_close_lck(struct share_mode_lock *lck, BOOL delete_on_close, UNIX_USER_TOKEN *tok) +{ + if (lck->delete_on_close != delete_on_close) { + set_delete_on_close_token(lck, tok); + lck->delete_on_close = delete_on_close; + if (delete_on_close) { + SMB_ASSERT(lck->delete_token != NULL); + } + lck->modified = True; + } +} + BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKEN *tok) { struct share_mode_lock *lck; @@ -1274,19 +1279,7 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKE return False; } - if (lck->delete_on_close != delete_on_close) { - set_delete_on_close_token(lck, tok); - lck->delete_on_close = delete_on_close; - if (delete_on_close) { - SMB_ASSERT(lck->delete_token != NULL); - } - lck->modified = True; - } - - if (lck->initial_delete_on_close) { - lck->initial_delete_on_close = False; - lck->modified = True; - } + set_delete_on_close_lck(lck, delete_on_close, tok); TALLOC_FREE(lck); return True; -- cgit From aacd16e7c4bea5018560eea09d55f2a6473be84d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 19 Jan 2007 21:46:12 +0000 Subject: r20916: Add in the delete on close final fix - but only enabled with -DDEVELOPER. Jeremy. (This used to be commit 7f817067a70930ee3502ea3373173e0c23733253) --- source3/locking/locking.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 56d18a63ef..d2e8b7ef59 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1281,6 +1281,10 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKE set_delete_on_close_lck(lck, delete_on_close, tok); + if (fsp->is_directory) { + send_stat_cache_delete_message(fsp->fsp_name); + } + TALLOC_FREE(lck); return True; } -- cgit From 7a5fa7f12ec439ef5a4af29aa86498f799b6b9a5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Feb 2007 21:05:34 +0000 Subject: r21191: Add in the POSIX open/mkdir/unlink calls. Move more error code returns to NTSTATUS. Client test code to follow... See if this passes the build-farm before I add it into 3.0.25. Jeremy. (This used to be commit 83dbbdff345fa9e427c9579183f4380004bf3dd7) --- source3/locking/locking.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d2e8b7ef59..39cc991b5f 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -81,7 +81,7 @@ BOOL is_locked(files_struct *fsp, enum brl_type lock_type) { int strict_locking = lp_strict_locking(fsp->conn->params); - enum brl_flavour lock_flav = lp_posix_cifsu_locktype(); + enum brl_flavour lock_flav = lp_posix_cifsu_locktype(fsp); BOOL ret = True; if (count == 0) { @@ -426,13 +426,14 @@ char *share_mode_str(int num, struct share_mode_entry *e) slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: %s " "pid = %s, share_access = 0x%x, private_options = 0x%x, " "access_mask = 0x%x, mid = 0x%x, type= 0x%x, file_id = %lu, " - "uid = %u, dev = 0x%x, inode = %.0f", + "uid = %u, flags = %u, dev = 0x%x, inode = %.0f", num, e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "", procid_str_static(&e->pid), e->share_access, e->private_options, e->access_mask, e->op_mid, e->op_type, e->share_file_id, - (unsigned int)e->uid, (unsigned int)e->dev, (double)e->inode ); + (unsigned int)e->uid, (unsigned int)e->flags, + (unsigned int)e->dev, (double)e->inode ); return share_str; } @@ -912,6 +913,7 @@ static void fill_share_mode_entry(struct share_mode_entry *e, e->inode = fsp->inode; e->share_file_id = fsp->fh->file_id; e->uid = (uint32)uid; + e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0; } static void fill_deferred_open_entry(struct share_mode_entry *e, @@ -927,6 +929,7 @@ static void fill_deferred_open_entry(struct share_mode_entry *e, e->dev = dev; e->inode = ino; e->uid = (uint32)-1; + e->flags = 0; } static void add_share_mode_entry(struct share_mode_lock *lck, -- cgit From 86e5659abac9938e7ac0cea989ca33e807b3e181 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 9 Feb 2007 02:03:39 +0000 Subject: r21257: Better fix for bug #4188 : Windows Vista RC1 and RC2 can't delete directory on Samba share based on work by Joe Meadows . Jeremy. (This used to be commit 2dab8928769938ab79da7b7ce2d165fc388f9b00) --- source3/locking/locking.c | 37 +------------------------------------ 1 file changed, 1 insertion(+), 36 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 39cc991b5f..ffac43aff5 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1151,42 +1151,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close, /* Don't allow delete on close for non-empty directories. */ if (fsp->is_directory) { - long offset = 0; - NTSTATUS status; - SMB_STRUCT_STAT st; - struct dptr_struct *dirptr; - const char *name; - - status = dptr_create(fsp->conn, - fsp->fsp_name, - False, - True, - 0, - "*", - True, - 0, - &dirptr); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* Read 3 entries. Ignore first 2 (they're . and .. ) */ - name = dptr_ReadDirName(dirptr, &offset, &st); - if (!name) { - dptr_CloseDir(dirptr); - return NT_STATUS_ACCESS_DENIED; - } - name = dptr_ReadDirName(dirptr, &offset, &st); - if (!name) { - dptr_CloseDir(dirptr); - return NT_STATUS_ACCESS_DENIED; - } - name = dptr_ReadDirName(dirptr, &offset, &st); - dptr_CloseDir(dirptr); - if (name) { - DEBUG(10,("can_set_delete_on_close: got name %s - can't delete\n", name )); - return NT_STATUS_DIRECTORY_NOT_EMPTY; - } + return can_delete_directory(fsp->conn, fsp->fsp_name); } return NT_STATUS_OK; -- cgit From 242927bd5cae1d2ab8739b1c424e702ab97726b5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 5 Mar 2007 20:09:27 +0000 Subject: r21706: get_delete_on_close_flag() is the perfect candidate for tdb_parse_record() (This used to be commit b73685d20751ac343faab79332552cd7ee92d831) --- source3/locking/locking.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index ffac43aff5..7326ea08c0 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -858,15 +858,29 @@ BOOL rename_share_filename(struct share_mode_lock *lck, return True; } -BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode) +static int pull_delete_on_close_flag(TDB_DATA key, TDB_DATA dbuf, + void *private_data) { - BOOL result; - struct share_mode_lock *lck = get_share_mode_lock(NULL, dev, inode, NULL, NULL); - if (!lck) { - return False; + BOOL *result = (BOOL *)private_data; + struct locking_data *data; + + if (dbuf.dsize < sizeof(struct locking_data)) { + smb_panic("PANIC: parse_share_modes: buffer too short.\n"); } - result = lck->delete_on_close; - TALLOC_FREE(lck); + + data = (struct locking_data *)dbuf.dptr; + + *result = data->u.s.delete_on_close; + return 0; +} + +BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode) +{ + TDB_DATA key = locking_key(dev, inode); + BOOL result = False; + + tdb_parse_record(tdb, key, pull_delete_on_close_flag, + (void *)&result); return result; } -- cgit From 94a1b230f3323e55fa23f20b464964eaac643882 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 6 Mar 2007 10:40:18 +0000 Subject: r21723: Make use of the per-hashchain "freelists" (This used to be commit f3421ae4cfa263c0e7a8e934b40342ee9885d239) --- source3/locking/locking.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 7326ea08c0..6c4e896a2a 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -363,6 +363,9 @@ BOOL locking_init(int read_only) return False; } + /* Activate the per-hashchain freelist */ + tdb_set_max_dead(tdb, 5); + if (!posix_locking_init(read_only)) return False; -- cgit From 640ab28d78dac5c2bcee8b641c8971fcbcd87dfa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Mar 2007 21:59:51 +0000 Subject: r21724: Optimization pointed out by Volker. If we don't have any outstanding locks or blocking locks then we don't need to read the lock db. on close. Jeremy. (This used to be commit 1b063496f93f78347a6e67549bde54c845499a7d) --- source3/locking/locking.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 6c4e896a2a..304932cf32 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -222,6 +222,12 @@ struct byte_range_lock *do_lock(files_struct *fsp, lock_flav, blocking_lock); + /* blocking ie. pending, locks also count here, + * as this is an efficiency counter to avoid checking + * the lock db. on close. JRA. */ + + fsp->current_lock_count++; + return br_lck; } @@ -268,6 +274,9 @@ NTSTATUS do_unlock(files_struct *fsp, return NT_STATUS_RANGE_NOT_LOCKED; } + SMB_ASSERT(fsp->current_lock_count > 0); + fsp->current_lock_count--; + return NT_STATUS_OK; } @@ -315,6 +324,9 @@ NTSTATUS do_lock_cancel(files_struct *fsp, return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } + SMB_ASSERT(fsp->current_lock_count > 0); + fsp->current_lock_count++; + return NT_STATUS_OK; } @@ -330,6 +342,14 @@ void locking_close_file(files_struct *fsp) return; } + /* If we have not outstanding locks or pending + * locks then we don't need to look in the lock db. + */ + + if (fsp->current_lock_count == 0) { + return; + } + br_lck = brl_get_locks(NULL,fsp); if (br_lck) { -- cgit From cda247e9d44f42115929411de3f810ae859134a0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Mar 2007 22:14:09 +0000 Subject: r21726: Fix stupid cut-n-paste typo. Thanks to volker for being on the ball..... :-). Jeremy. (This used to be commit 84ed7bcbe6dc14b18a7e913b153c82da1856a835) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 304932cf32..37e6dbc4e5 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -325,7 +325,7 @@ NTSTATUS do_lock_cancel(files_struct *fsp, } SMB_ASSERT(fsp->current_lock_count > 0); - fsp->current_lock_count++; + fsp->current_lock_count--; return NT_STATUS_OK; } -- cgit From bc2b6436d0f5f3e9ffdfaeb7f1b32996a83d5478 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Mar 2007 09:35:51 +0000 Subject: r22009: change TDB_DATA from char * to unsigned char * and fix all compiler warnings in the users metze (This used to be commit 3a28443079c141a6ce8182c65b56ca210e34f37f) --- source3/locking/locking.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 37e6dbc4e5..dc1d607155 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -433,7 +433,7 @@ static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode) memset(&key, '\0', sizeof(key)); key.dev = dev; key.ino = inode; - kbuf.dptr = (char *)&key; + kbuf.dptr = (uint8 *)&key; kbuf.dsize = sizeof(key); return kbuf; } @@ -532,7 +532,7 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) /* Get any delete token. */ if (data->u.s.delete_token_size) { - char *p = dbuf.dptr + sizeof(*data) + + uint8 *p = dbuf.dptr + sizeof(*data) + (lck->num_share_modes * sizeof(struct share_mode_entry)); @@ -578,7 +578,7 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) } /* Save off the associated service path and filename. */ - lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) + + lck->servicepath = talloc_strdup(lck, (const char *)dbuf.dptr + sizeof(*data) + (lck->num_share_modes * sizeof(struct share_mode_entry)) + data->u.s.delete_token_size ); @@ -586,7 +586,7 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) smb_panic("talloc_strdup failed\n"); } - lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) + + lck->filename = talloc_strdup(lck, (const char *)dbuf.dptr + sizeof(*data) + (lck->num_share_modes * sizeof(struct share_mode_entry)) + data->u.s.delete_token_size + @@ -646,7 +646,7 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) delete_token_size + sp_len + 1 + strlen(lck->filename) + 1; - result.dptr = TALLOC_ARRAY(lck, char, result.dsize); + result.dptr = TALLOC_ARRAY(lck, uint8, result.dsize); if (result.dptr == NULL) { smb_panic("talloc failed\n"); @@ -668,7 +668,7 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) /* Store any delete on close token. */ if (lck->delete_token) { - char *p = result.dptr + offset; + uint8 *p = result.dptr + offset; memcpy(p, &lck->delete_token->uid, sizeof(uid_t)); p += sizeof(uid_t); @@ -683,10 +683,10 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) offset = p - result.dptr; } - safe_strcpy(result.dptr + offset, lck->servicepath, + safe_strcpy((char *)result.dptr + offset, lck->servicepath, result.dsize - offset - 1); offset += sp_len + 1; - safe_strcpy(result.dptr + offset, lck->filename, + safe_strcpy((char *)result.dptr + offset, lck->filename, result.dsize - offset - 1); if (DEBUGLEVEL >= 10) { @@ -1318,10 +1318,10 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, data = (struct locking_data *)dbuf.dptr; shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data)); - sharepath = dbuf.dptr + sizeof(*data) + + sharepath = (const char *)dbuf.dptr + sizeof(*data) + data->u.s.num_share_mode_entries*sizeof(*shares) + data->u.s.delete_token_size; - fname = dbuf.dptr + sizeof(*data) + + fname = (const char *)dbuf.dptr + sizeof(*data) + data->u.s.num_share_mode_entries*sizeof(*shares) + data->u.s.delete_token_size + strlen(sharepath) + 1; -- cgit From 12ba88574bf91bdcc4447bfc3d429b799064bfd9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 Apr 2007 23:18:41 +0000 Subject: r22542: Move over to using the _strict varients of the talloc calls. No functional changes. Looks bigger than it is :-). Jeremy. (This used to be commit f6fa3080fee1b20df9f1968500840a88cf0ee592) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index dc1d607155..c548d6eecb 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -521,7 +521,7 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) } lck->share_modes = (struct share_mode_entry *) - talloc_memdup(lck, dbuf.dptr+sizeof(*data), + TALLOC_MEMDUP(lck, dbuf.dptr+sizeof(*data), lck->num_share_modes * sizeof(struct share_mode_entry)); -- cgit From b92064fcfd804b861e2f5125078812d83b9120a6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 May 2007 13:01:28 +0000 Subject: r22846: Chunk one to replace message_send_pid with messaging_send: Deep inside locking/locking.c we have to send retry messages to timed lock holders. The majority of this patch passes a "struct messaging_context" down there. No functional change, survives make test. (This used to be commit bbb508414683eeddd2ee0d2d36fe620118180bbb) --- source3/locking/locking.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index c548d6eecb..28a7fab97d 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -180,7 +180,8 @@ NTSTATUS query_lock(files_struct *fsp, Utility function called by locking requests. ****************************************************************************/ -struct byte_range_lock *do_lock(files_struct *fsp, +struct byte_range_lock *do_lock(struct messaging_context *msg_ctx, + files_struct *fsp, uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, @@ -213,7 +214,8 @@ struct byte_range_lock *do_lock(files_struct *fsp, return NULL; } - *perr = brl_lock(br_lck, + *perr = brl_lock(msg_ctx, + br_lck, lock_pid, procid_self(), offset, @@ -235,7 +237,8 @@ struct byte_range_lock *do_lock(files_struct *fsp, Utility function called by unlocking requests. ****************************************************************************/ -NTSTATUS do_unlock(files_struct *fsp, +NTSTATUS do_unlock(struct messaging_context *msg_ctx, + files_struct *fsp, uint32 lock_pid, SMB_BIG_UINT count, SMB_BIG_UINT offset, @@ -260,7 +263,8 @@ NTSTATUS do_unlock(files_struct *fsp, return NT_STATUS_NO_MEMORY; } - ok = brl_unlock(br_lck, + ok = brl_unlock(msg_ctx, + br_lck, lock_pid, procid_self(), offset, @@ -334,7 +338,8 @@ NTSTATUS do_lock_cancel(files_struct *fsp, Remove any locks on this fd. Called from file_close(). ****************************************************************************/ -void locking_close_file(files_struct *fsp) +void locking_close_file(struct messaging_context *msg_ctx, + files_struct *fsp) { struct byte_range_lock *br_lck; @@ -354,7 +359,7 @@ void locking_close_file(files_struct *fsp) if (br_lck) { cancel_pending_lock_requests_by_fid(fsp, br_lck); - brl_close_fnum(br_lck); + brl_close_fnum(msg_ctx, br_lck); TALLOC_FREE(br_lck); } } @@ -805,7 +810,8 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, Based on an initial code idea from SATOH Fumiyasu ********************************************************************/ -BOOL rename_share_filename(struct share_mode_lock *lck, +BOOL rename_share_filename(struct messaging_context *msg_ctx, + struct share_mode_lock *lck, const char *servicepath, const char *newname) { @@ -814,6 +820,7 @@ BOOL rename_share_filename(struct share_mode_lock *lck, size_t msg_len; char *frm = NULL; int i; + DATA_BLOB msg; if (!lck) { return False; @@ -857,6 +864,8 @@ BOOL rename_share_filename(struct share_mode_lock *lck, safe_strcpy(&frm[16], lck->servicepath, sp_len); safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len); + msg = data_blob_const(frm, msg_len); + /* Send the messages. */ for (i=0; inum_share_modes; i++) { struct share_mode_entry *se = &lck->share_modes[i]; @@ -874,8 +883,7 @@ BOOL rename_share_filename(struct share_mode_lock *lck, (unsigned int)lck->dev, (double)lck->ino, lck->servicepath, lck->filename )); - message_send_pid(se->pid, MSG_SMB_FILE_RENAME, - frm, msg_len, True); + messaging_send(msg_ctx, se->pid, MSG_SMB_FILE_RENAME, &msg); } return True; -- cgit From 01a7017d7b0e0cbc3b0923c43b7fe3f0b01aac0b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 19 May 2007 20:57:12 +0000 Subject: r23014: For all branches, ensure that if we're blocked on a POSIX lock we know nothing about that we retry the lock every 10 seconds instead of waiting for the standard select timeout. This is how we used to (and are supposed to) work. Jeremy. (This used to be commit fa18fc25a50cf13c687ae88e7e5e2dda1120e017) --- source3/locking/locking.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 28a7fab97d..56ff3b9790 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -188,7 +188,8 @@ struct byte_range_lock *do_lock(struct messaging_context *msg_ctx, enum brl_type lock_type, enum brl_flavour lock_flav, BOOL blocking_lock, - NTSTATUS *perr) + NTSTATUS *perr, + uint32 *plock_pid) { struct byte_range_lock *br_lck = NULL; @@ -222,7 +223,8 @@ struct byte_range_lock *do_lock(struct messaging_context *msg_ctx, count, lock_type, lock_flav, - blocking_lock); + blocking_lock, + plock_pid); /* blocking ie. pending, locks also count here, * as this is an efficiency counter to avoid checking -- cgit From dbfd6bf8c8cc9945c4ba7e22ac44b1f33f9c7ce6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 May 2007 21:32:10 +0000 Subject: r23100: Implement the delete on close semantics I've just tested for in Samba4 smbtorture. Fix rename on an open file handle. Needed for 3.0.25a. Jeremy. (This used to be commit a301467d5f645dada27093ddfd74890b88bb4ce8) --- source3/locking/locking.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 56ff3b9790..17c6d3e9c3 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1001,10 +1001,13 @@ static void add_share_mode_entry(struct share_mode_lock *lck, } void set_share_mode(struct share_mode_lock *lck, files_struct *fsp, - uid_t uid, uint16 mid, uint16 op_type) + uid_t uid, uint16 mid, uint16 op_type, BOOL initial_delete_on_close_allowed) { struct share_mode_entry entry; fill_share_mode_entry(&entry, fsp, uid, mid, op_type); + if (initial_delete_on_close_allowed) { + entry.flags |= SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE; + } add_share_mode_entry(lck, &entry); } @@ -1204,6 +1207,22 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close, return NT_STATUS_OK; } +/**************************************************************************** + Do we have an open file handle that created this entry ? +****************************************************************************/ + +BOOL can_set_initial_delete_on_close(const struct share_mode_lock *lck) +{ + int i; + + for (i=0; inum_share_modes; i++) { + if (lck->share_modes[i].flags & SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE) { + return True; + } + } + return False; +} + /************************************************************************* Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail. (Should this be in locking.c.... ?). @@ -1304,6 +1323,31 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKE return True; } +/**************************************************************************** + Sets the allow initial delete on close flag for this share mode. +****************************************************************************/ + +BOOL set_allow_initial_delete_on_close(struct share_mode_lock *lck, files_struct *fsp, BOOL delete_on_close) +{ + struct share_mode_entry entry, *e; + + /* Don't care about the pid owner being correct here - just a search. */ + fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK); + + e = find_share_mode_entry(lck, &entry); + if (e == NULL) { + return False; + } + + if (delete_on_close) { + e->flags |= SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE; + } else { + e->flags &= ~SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE; + } + lck->modified = True; + return True; +} + struct forall_state { void (*fn)(const struct share_mode_entry *entry, const char *sharepath, -- cgit From 4db33293ab50de99484122e7050e33c5f97980a5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 May 2007 09:29:26 +0000 Subject: r23162: Make use of messaging_send_buf (This used to be commit 3f8186fe85a897b104cd825a005333259d6d008b) --- source3/locking/locking.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 17c6d3e9c3..aacb056c07 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -822,7 +822,6 @@ BOOL rename_share_filename(struct messaging_context *msg_ctx, size_t msg_len; char *frm = NULL; int i; - DATA_BLOB msg; if (!lck) { return False; @@ -866,8 +865,6 @@ BOOL rename_share_filename(struct messaging_context *msg_ctx, safe_strcpy(&frm[16], lck->servicepath, sp_len); safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len); - msg = data_blob_const(frm, msg_len); - /* Send the messages. */ for (i=0; inum_share_modes; i++) { struct share_mode_entry *se = &lck->share_modes[i]; @@ -885,7 +882,8 @@ BOOL rename_share_filename(struct messaging_context *msg_ctx, (unsigned int)lck->dev, (double)lck->ino, lck->servicepath, lck->filename )); - messaging_send(msg_ctx, se->pid, MSG_SMB_FILE_RENAME, &msg); + messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME, + (uint8 *)frm, msg_len); } return True; -- cgit From 6e5c23728cb290b8defe165fb3a0815521229328 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 May 2007 09:57:05 +0000 Subject: r23163: Convert locking.tdb to dbwrap (This used to be commit afe90224bf151acf6c7be8974408f79cfd459dbf) --- source3/locking/locking.c | 200 +++++++++++++++++++++++++--------------------- 1 file changed, 109 insertions(+), 91 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index aacb056c07..f83467ad83 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -42,7 +42,7 @@ #define DBGC_CLASS DBGC_LOCKING /* the locking database handle */ -static TDB_CONTEXT *tdb; +static struct db_context *lock_db; /**************************************************************************** Debugging aids :-). @@ -376,23 +376,21 @@ BOOL locking_init(int read_only) { brl_init(read_only); - if (tdb) + if (lock_db) return True; - tdb = tdb_open_log(lock_path("locking.tdb"), - lp_open_files_db_hash_size(), - TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST), - read_only?O_RDONLY:O_RDWR|O_CREAT, - 0644); + lock_db = db_open(NULL, lock_path("locking.tdb"), + lp_open_files_db_hash_size(), + TDB_DEFAULT + |(read_only?0x0:TDB_CLEAR_IF_FIRST) + |TDB_VOLATILE, + read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); - if (!tdb) { + if (!lock_db) { DEBUG(0,("ERROR: Failed to initialise locking database\n")); return False; } - /* Activate the per-hashchain freelist */ - tdb_set_max_dead(tdb, 5); - if (!posix_locking_init(read_only)) return False; @@ -407,15 +405,11 @@ BOOL locking_init(int read_only) BOOL locking_end(void) { - BOOL ret = True; - brl_shutdown(open_read_only); - if (tdb) { - if (tdb_close(tdb) != 0) - ret = False; + if (lock_db) { + TALLOC_FREE(lock_db); } - - return ret; + return True; } /******************************************************************* @@ -705,11 +699,11 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) static int share_mode_lock_destructor(struct share_mode_lock *lck) { - TDB_DATA key = locking_key(lck->dev, lck->ino); + NTSTATUS status; TDB_DATA data; if (!lck->modified) { - goto done; + return 0; } data = unparse_share_modes(lck); @@ -717,38 +711,34 @@ static int share_mode_lock_destructor(struct share_mode_lock *lck) if (data.dptr == NULL) { if (!lck->fresh) { /* There has been an entry before, delete it */ - if (tdb_delete(tdb, key) == -1) { + + status = lck->record->delete_rec(lck->record); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("delete_rec returned %s\n", + nt_errstr(status))); smb_panic("Could not delete share entry\n"); } } goto done; } - if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) { + status = lck->record->store(lck->record, data, TDB_REPLACE); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("store returned %s\n", nt_errstr(status))); smb_panic("Could not store share mode entry\n"); } done: - tdb_chainunlock(tdb, key); return 0; } -struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, - SMB_DEV_T dev, SMB_INO_T ino, - const char *servicepath, - const char *fname) +static BOOL fill_share_mode_lock(struct share_mode_lock *lck, + SMB_DEV_T dev, SMB_INO_T ino, + const char *servicepath, + const char *fname, + TDB_DATA share_mode_data) { - struct share_mode_lock *lck; - TDB_DATA key = locking_key(dev, ino); - TDB_DATA data; - - lck = TALLOC_P(mem_ctx, struct share_mode_lock); - if (lck == NULL) { - DEBUG(0, ("talloc failed\n")); - return NULL; - } - /* Ensure we set every field here as the destructor must be valid even if parse_share_modes fails. */ @@ -763,44 +753,86 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, lck->fresh = False; lck->modified = False; - if (tdb_chainlock(tdb, key) != 0) { - DEBUG(3, ("Could not lock share entry\n")); - TALLOC_FREE(lck); - return NULL; - } - - /* We must set the destructor immediately after the chainlock - ensure the lock is cleaned up on any of the error return - paths below. */ - - talloc_set_destructor(lck, share_mode_lock_destructor); - - data = tdb_fetch(tdb, key); - lck->fresh = (data.dptr == NULL); + lck->fresh = (share_mode_data.dptr == NULL); if (lck->fresh) { - if (fname == NULL || servicepath == NULL) { - TALLOC_FREE(lck); - return NULL; + return False; } lck->filename = talloc_strdup(lck, fname); lck->servicepath = talloc_strdup(lck, servicepath); if (lck->filename == NULL || lck->servicepath == NULL) { DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(lck); - return NULL; + return False; } } else { - if (!parse_share_modes(data, lck)) { + if (!parse_share_modes(share_mode_data, lck)) { DEBUG(0, ("Could not parse share modes\n")); - TALLOC_FREE(lck); - SAFE_FREE(data.dptr); - return NULL; + return False; } } - SAFE_FREE(data.dptr); + return True; +} + +struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, + SMB_DEV_T dev, SMB_INO_T ino, + const char *servicepath, + const char *fname) +{ + struct share_mode_lock *lck; + TDB_DATA key = locking_key(dev, ino); + + if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) { + DEBUG(0, ("talloc failed\n")); + return NULL; + } + + if (!(lck->record = lock_db->fetch_locked(lock_db, lck, key))) { + DEBUG(3, ("Could not lock share entry\n")); + TALLOC_FREE(lck); + return NULL; + } + + if (!fill_share_mode_lock(lck, dev, ino, servicepath, fname, + lck->record->value)) { + DEBUG(3, ("fill_share_mode_lock failed\n")); + TALLOC_FREE(lck); + return NULL; + } + + talloc_set_destructor(lck, share_mode_lock_destructor); + + return lck; +} + +struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, + SMB_DEV_T dev, SMB_INO_T ino, + const char *servicepath, + const char *fname) +{ + struct share_mode_lock *lck; + TDB_DATA key = locking_key(dev, ino); + TDB_DATA data; + + if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) { + DEBUG(0, ("talloc failed\n")); + return NULL; + } + + if (lock_db->fetch(lock_db, lck, key, &data) == -1) { + DEBUG(3, ("Could not fetch share entry\n")); + TALLOC_FREE(lck); + return NULL; + } + + if (!fill_share_mode_lock(lck, dev, ino, servicepath, fname, data)) { + DEBUG(3, ("fill_share_mode_lock failed\n")); + TALLOC_FREE(lck); + return NULL; + } + + TALLOC_FREE(data.dptr); return lck; } @@ -889,29 +921,16 @@ BOOL rename_share_filename(struct messaging_context *msg_ctx, return True; } -static int pull_delete_on_close_flag(TDB_DATA key, TDB_DATA dbuf, - void *private_data) -{ - BOOL *result = (BOOL *)private_data; - struct locking_data *data; - - if (dbuf.dsize < sizeof(struct locking_data)) { - smb_panic("PANIC: parse_share_modes: buffer too short.\n"); - } - - data = (struct locking_data *)dbuf.dptr; - - *result = data->u.s.delete_on_close; - return 0; -} - BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode) { - TDB_DATA key = locking_key(dev, inode); - BOOL result = False; - - tdb_parse_record(tdb, key, pull_delete_on_close_flag, - (void *)&result); + BOOL result; + struct share_mode_lock *lck; + + if (!(lck = fetch_share_mode_unlocked(NULL, dev, inode, NULL, NULL))) { + return False; + } + result = lck->delete_on_close; + TALLOC_FREE(lck); return result; } @@ -1354,8 +1373,7 @@ struct forall_state { void *private_data; }; -static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, - void *_state) +static int traverse_fn(struct db_record *rec, void *_state) { struct forall_state *state = (struct forall_state *)_state; struct locking_data *data; @@ -1365,15 +1383,15 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, int i; /* Ensure this is a locking_key record. */ - if (kbuf.dsize != sizeof(struct locking_key)) + if (rec->key.dsize != sizeof(struct locking_key)) return 0; - data = (struct locking_data *)dbuf.dptr; - shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data)); - sharepath = (const char *)dbuf.dptr + sizeof(*data) + + data = (struct locking_data *)rec->value.dptr; + shares = (struct share_mode_entry *)(rec->value.dptr + sizeof(*data)); + sharepath = (const char *)rec->value.dptr + sizeof(*data) + data->u.s.num_share_mode_entries*sizeof(*shares) + data->u.s.delete_token_size; - fname = (const char *)dbuf.dptr + sizeof(*data) + + fname = (const char *)rec->value.dptr + sizeof(*data) + data->u.s.num_share_mode_entries*sizeof(*shares) + data->u.s.delete_token_size + strlen(sharepath) + 1; @@ -1396,11 +1414,11 @@ int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, { struct forall_state state; - if (tdb == NULL) + if (lock_db == NULL) return 0; state.fn = fn; state.private_data = private_data; - return tdb_traverse(tdb, traverse_fn, (void *)&state); + return lock_db->traverse(lock_db, traverse_fn, (void *)&state); } -- cgit From 1e6af7084bafe29021b0ad2ee49c3bbf90e350ca Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 May 2007 10:25:23 +0000 Subject: r23164: Minor cosmetic checkin (This used to be commit 8de1ac9fadb1b0dcac28eef32f7826e9e3a7eca4) --- source3/locking/locking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index f83467ad83..cc6957b4e3 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -382,8 +382,8 @@ BOOL locking_init(int read_only) lock_db = db_open(NULL, lock_path("locking.tdb"), lp_open_files_db_hash_size(), TDB_DEFAULT - |(read_only?0x0:TDB_CLEAR_IF_FIRST) - |TDB_VOLATILE, + |TDB_VOLATILE + |(read_only?0x0:TDB_CLEAR_IF_FIRST), read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); if (!lock_db) { -- cgit From e8156439f24137b5418baad20a7f00f6949cfe29 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 May 2007 09:30:34 +0000 Subject: r23183: Check in a change made by Tridge: This replaces the internal explicit dev/ino file id representation by a "struct file_id". This is necessary as cluster file systems and NFS don't necessarily assign the same device number to the shared file system. With this structure in place we can now easily add different schemes to map a file to a unique 64-bit device node. Jeremy, you might note that I did not change the external interface of smb_share_modes.c. Volker (This used to be commit 9b10dbbd5de8813fc15ebbb6be9b18010ffe8139) --- source3/locking/locking.c | 86 +++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 51 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index cc6957b4e3..c02304addf 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -416,24 +416,11 @@ BOOL locking_end(void) Form a static locking key for a dev/inode pair. ******************************************************************/ -/* key and data records in the tdb locking database */ -struct locking_key { - SMB_DEV_T dev; - SMB_INO_T ino; -}; - -/******************************************************************* - Form a static locking key for a dev/inode pair. -******************************************************************/ - -static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode) +static TDB_DATA locking_key(struct file_id id) { - static struct locking_key key; + static struct file_id key; TDB_DATA kbuf; - - memset(&key, '\0', sizeof(key)); - key.dev = dev; - key.ino = inode; + key = id; kbuf.dptr = (uint8 *)&key; kbuf.dsize = sizeof(key); return kbuf; @@ -449,15 +436,15 @@ char *share_mode_str(int num, struct share_mode_entry *e) slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: %s " "pid = %s, share_access = 0x%x, private_options = 0x%x, " - "access_mask = 0x%x, mid = 0x%x, type= 0x%x, file_id = %lu, " - "uid = %u, flags = %u, dev = 0x%x, inode = %.0f", + "access_mask = 0x%x, mid = 0x%x, type= 0x%x, gen_id = %lu, " + "uid = %u, flags = %u, file_id %s", num, e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "", procid_str_static(&e->pid), e->share_access, e->private_options, e->access_mask, e->op_mid, e->op_type, e->share_file_id, (unsigned int)e->uid, (unsigned int)e->flags, - (unsigned int)e->dev, (double)e->inode ); + file_id_static_string(&e->id)); return share_str; } @@ -734,7 +721,7 @@ static int share_mode_lock_destructor(struct share_mode_lock *lck) } static BOOL fill_share_mode_lock(struct share_mode_lock *lck, - SMB_DEV_T dev, SMB_INO_T ino, + struct file_id id, const char *servicepath, const char *fname, TDB_DATA share_mode_data) @@ -744,8 +731,7 @@ static BOOL fill_share_mode_lock(struct share_mode_lock *lck, lck->servicepath = NULL; lck->filename = NULL; - lck->dev = dev; - lck->ino = ino; + lck->id = id; lck->num_share_modes = 0; lck->share_modes = NULL; lck->delete_token = NULL; @@ -776,12 +762,15 @@ static BOOL fill_share_mode_lock(struct share_mode_lock *lck, } struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, - SMB_DEV_T dev, SMB_INO_T ino, + struct file_id id, const char *servicepath, const char *fname) { struct share_mode_lock *lck; - TDB_DATA key = locking_key(dev, ino); + TDB_DATA key; + + key.dptr = (unsigned char *)&id; + key.dsize = sizeof(id); if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) { DEBUG(0, ("talloc failed\n")); @@ -794,7 +783,7 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, return NULL; } - if (!fill_share_mode_lock(lck, dev, ino, servicepath, fname, + if (!fill_share_mode_lock(lck, id, servicepath, fname, lck->record->value)) { DEBUG(3, ("fill_share_mode_lock failed\n")); TALLOC_FREE(lck); @@ -807,12 +796,12 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, } struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, - SMB_DEV_T dev, SMB_INO_T ino, + struct file_id id, const char *servicepath, const char *fname) { struct share_mode_lock *lck; - TDB_DATA key = locking_key(dev, ino); + TDB_DATA key = locking_key(id); TDB_DATA data; if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) { @@ -826,7 +815,7 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, return NULL; } - if (!fill_share_mode_lock(lck, dev, ino, servicepath, fname, data)) { + if (!fill_share_mode_lock(lck, id, servicepath, fname, data)) { DEBUG(3, ("fill_share_mode_lock failed\n")); TALLOC_FREE(lck); return NULL; @@ -889,8 +878,7 @@ BOOL rename_share_filename(struct messaging_context *msg_ctx, return False; } - SDEV_T_VAL(frm,0,lck->dev); - SINO_T_VAL(frm,8,lck->ino); + push_file_id_16(frm, &lck->id); DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len )); @@ -909,10 +897,10 @@ BOOL rename_share_filename(struct messaging_context *msg_ctx, } DEBUG(10,("rename_share_filename: sending rename message to pid %s " - "dev %x, inode %.0f sharepath %s newname %s\n", - procid_str_static(&se->pid), - (unsigned int)lck->dev, (double)lck->ino, - lck->servicepath, lck->filename )); + "file_id %s sharepath %s newname %s\n", + procid_str_static(&se->pid), + file_id_static_string(&lck->id), + lck->servicepath, lck->filename )); messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME, (uint8 *)frm, msg_len); @@ -921,12 +909,12 @@ BOOL rename_share_filename(struct messaging_context *msg_ctx, return True; } -BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode) +BOOL get_delete_on_close_flag(struct file_id id) { BOOL result; struct share_mode_lock *lck; - if (!(lck = fetch_share_mode_unlocked(NULL, dev, inode, NULL, NULL))) { + if (!(lck = fetch_share_mode_unlocked(NULL, id, NULL, NULL))) { return False; } result = lck->delete_on_close; @@ -973,16 +961,15 @@ static void fill_share_mode_entry(struct share_mode_entry *e, e->op_type = op_type; e->time.tv_sec = fsp->open_time.tv_sec; e->time.tv_usec = fsp->open_time.tv_usec; - e->dev = fsp->dev; - e->inode = fsp->inode; - e->share_file_id = fsp->fh->file_id; + e->id = fsp->file_id; + e->share_file_id = fsp->fh->gen_id; e->uid = (uint32)uid; e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0; } static void fill_deferred_open_entry(struct share_mode_entry *e, const struct timeval request_time, - SMB_DEV_T dev, SMB_INO_T ino, uint16 mid) + struct file_id id, uint16 mid) { ZERO_STRUCTP(e); e->pid = procid_self(); @@ -990,8 +977,7 @@ static void fill_deferred_open_entry(struct share_mode_entry *e, e->op_type = DEFERRED_OPEN_ENTRY; e->time.tv_sec = request_time.tv_sec; e->time.tv_usec = request_time.tv_usec; - e->dev = dev; - e->inode = ino; + e->id = id; e->uid = (uint32)-1; e->flags = 0; } @@ -1030,10 +1016,10 @@ void set_share_mode(struct share_mode_lock *lck, files_struct *fsp, void add_deferred_open(struct share_mode_lock *lck, uint16 mid, struct timeval request_time, - SMB_DEV_T dev, SMB_INO_T ino) + struct file_id id) { struct share_mode_entry entry; - fill_deferred_open_entry(&entry, request_time, dev, ino, mid); + fill_deferred_open_entry(&entry, request_time, id, mid); add_share_mode_entry(lck, &entry); } @@ -1052,8 +1038,7 @@ static BOOL share_modes_identical(struct share_mode_entry *e1, fsp->share_access field. */ return (procid_equal(&e1->pid, &e2->pid) && - e1->dev == e2->dev && - e1->inode == e2->inode && + file_id_equal(&e1->id, &e2->id) && e1->share_file_id == e2->share_file_id ); } @@ -1062,8 +1047,7 @@ static BOOL deferred_open_identical(struct share_mode_entry *e1, { return (procid_equal(&e1->pid, &e2->pid) && (e1->op_mid == e2->op_mid) && - (e1->dev == e2->dev) && - (e1->inode == e2->inode)); + file_id_equal(&e1->id, &e2->id)); } static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck, @@ -1114,7 +1098,7 @@ void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid) struct share_mode_entry entry, *e; fill_deferred_open_entry(&entry, timeval_zero(), - lck->dev, lck->ino, mid); + lck->id, mid); e = find_share_mode_entry(lck, &entry); if (e == NULL) { @@ -1325,7 +1309,7 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKE return True; } - lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL); + lck = get_share_mode_lock(NULL, fsp->file_id, NULL, NULL); if (lck == NULL) { return False; } @@ -1383,7 +1367,7 @@ static int traverse_fn(struct db_record *rec, void *_state) int i; /* Ensure this is a locking_key record. */ - if (rec->key.dsize != sizeof(struct locking_key)) + if (rec->key.dsize != sizeof(struct file_id)) return 0; data = (struct locking_data *)rec->value.dptr; -- cgit From 48e0c62053d84b8493b3b04bfd1898cee122097e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 May 2007 18:32:49 +0000 Subject: r23222: share_mode_forall() is only for counting and status display stuff, so traverse_read is enough here (This used to be commit 40991badef046233326815e50097aa7f493790e8) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index c02304addf..47566e0393 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1404,5 +1404,5 @@ int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, state.fn = fn; state.private_data = private_data; - return lock_db->traverse(lock_db, traverse_fn, (void *)&state); + return lock_db->traverse_read(lock_db, traverse_fn, (void *)&state); } -- cgit From 184eb775ffdd6f8afa8822a889b754e5e7050e45 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 14 Jun 2007 12:03:46 +0000 Subject: r23486: Ok, this time with a hopefully successful make test in the right place: Remove two local variables (This used to be commit 575e594e936c3cb197945063309f0b424dcdefc8) --- source3/locking/locking.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 47566e0393..8070f4b9b3 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -844,10 +844,6 @@ BOOL rename_share_filename(struct messaging_context *msg_ctx, char *frm = NULL; int i; - if (!lck) { - return False; - } - DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n", servicepath, newname)); -- cgit From b1ce226af8b61ad7e3c37860a59c6715012e738b Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 15 Jun 2007 21:58:49 +0000 Subject: r23510: Tidy calls to smb_panic by removing trailing newlines. Print the failed expression in SMB_ASSERT. (This used to be commit 171dc060e2a576d724eed1ca65636bdafffd7713) --- source3/locking/locking.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 8070f4b9b3..6f7d2d53c6 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -479,7 +479,7 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) int i; if (dbuf.dsize < sizeof(struct locking_data)) { - smb_panic("PANIC: parse_share_modes: buffer too short.\n"); + smb_panic("parse_share_modes: buffer too short"); } data = (struct locking_data *)dbuf.dptr; @@ -495,7 +495,7 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) { DEBUG(0, ("invalid number of share modes: %d\n", lck->num_share_modes)); - smb_panic("PANIC: invalid number of share modes"); + smb_panic("parse_share_modes: invalid number of share modes"); } lck->share_modes = NULL; @@ -505,7 +505,7 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) if (dbuf.dsize < (sizeof(struct locking_data) + (lck->num_share_modes * sizeof(struct share_mode_entry)))) { - smb_panic("PANIC: parse_share_modes: buffer too short.\n"); + smb_panic("parse_share_modes: buffer too short"); } lck->share_modes = (struct share_mode_entry *) @@ -514,7 +514,7 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) sizeof(struct share_mode_entry)); if (lck->share_modes == NULL) { - smb_panic("talloc failed\n"); + smb_panic("parse_share_modes: talloc failed"); } } @@ -528,12 +528,12 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) ((data->u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) { DEBUG(0, ("parse_share_modes: invalid token size %d\n", data->u.s.delete_token_size)); - smb_panic("parse_share_modes: invalid token size\n"); + smb_panic("parse_share_modes: invalid token size"); } lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN); if (!lck->delete_token) { - smb_panic("talloc failed\n"); + smb_panic("parse_share_modes: talloc failed"); } /* Copy out the uid and gid. */ @@ -552,7 +552,7 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t, lck->delete_token->ngroups); if (!lck->delete_token) { - smb_panic("talloc failed\n"); + smb_panic("parse_share_modes: talloc failed"); } for (i = 0; i < lck->delete_token->ngroups; i++) { @@ -571,7 +571,7 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) sizeof(struct share_mode_entry)) + data->u.s.delete_token_size ); if (lck->servicepath == NULL) { - smb_panic("talloc_strdup failed\n"); + smb_panic("parse_share_modes: talloc_strdup failed"); } lck->filename = talloc_strdup(lck, (const char *)dbuf.dptr + sizeof(*data) + @@ -580,7 +580,7 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) data->u.s.delete_token_size + strlen(lck->servicepath) + 1 ); if (lck->filename == NULL) { - smb_panic("talloc_strdup failed\n"); + smb_panic("parse_share_modes: talloc_strdup failed"); } /* @@ -637,7 +637,7 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) result.dptr = TALLOC_ARRAY(lck, uint8, result.dsize); if (result.dptr == NULL) { - smb_panic("talloc failed\n"); + smb_panic("talloc failed"); } data = (struct locking_data *)result.dptr; @@ -703,7 +703,7 @@ static int share_mode_lock_destructor(struct share_mode_lock *lck) if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("delete_rec returned %s\n", nt_errstr(status))); - smb_panic("Could not delete share entry\n"); + smb_panic("could not delete share entry"); } } goto done; @@ -712,7 +712,7 @@ static int share_mode_lock_destructor(struct share_mode_lock *lck) status = lck->record->store(lck->record, data, TDB_REPLACE); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("store returned %s\n", nt_errstr(status))); - smb_panic("Could not store share mode entry\n"); + smb_panic("could not store share mode entry"); } done: -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 6f7d2d53c6..31679c158d 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/locking/locking.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 31679c158d..c7fb572b1d 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . Revision History: -- cgit From 44b9493418558fca03b1888a693ba516b3711e17 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 17 Jul 2007 00:50:48 +0000 Subject: r23908: Fix bug with interaction of optimization with POSIX locking. We can't do lock counts with POSIX, so stop counting if we get a POSIX lock request. Jeremy. (This used to be commit a48e4a29e6774e5e72b9b361a17207b053474521) --- source3/locking/locking.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index c7fb572b1d..8692001f44 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -40,6 +40,8 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_LOCKING +#define NO_LOCKING_COUNT (-1) + /* the locking database handle */ static struct db_context *lock_db; @@ -225,11 +227,19 @@ struct byte_range_lock *do_lock(struct messaging_context *msg_ctx, blocking_lock, plock_pid); - /* blocking ie. pending, locks also count here, - * as this is an efficiency counter to avoid checking - * the lock db. on close. JRA. */ + if (lock_flav == WINDOWS_LOCK && + fsp->current_lock_count != NO_LOCKING_COUNT) { + /* blocking ie. pending, locks also count here, + * as this is an efficiency counter to avoid checking + * the lock db. on close. JRA. */ - fsp->current_lock_count++; + fsp->current_lock_count++; + } else { + /* Notice that this has had a POSIX lock request. + * We can't count locks after this so forget them. + */ + fsp->current_lock_count = NO_LOCKING_COUNT; + } return br_lck; } @@ -279,8 +289,11 @@ NTSTATUS do_unlock(struct messaging_context *msg_ctx, return NT_STATUS_RANGE_NOT_LOCKED; } - SMB_ASSERT(fsp->current_lock_count > 0); - fsp->current_lock_count--; + if (lock_flav == WINDOWS_LOCK && + fsp->current_lock_count != NO_LOCKING_COUNT) { + SMB_ASSERT(fsp->current_lock_count > 0); + fsp->current_lock_count--; + } return NT_STATUS_OK; } @@ -329,8 +342,11 @@ NTSTATUS do_lock_cancel(files_struct *fsp, return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } - SMB_ASSERT(fsp->current_lock_count > 0); - fsp->current_lock_count--; + if (lock_flav == WINDOWS_LOCK && + fsp->current_lock_count != NO_LOCKING_COUNT) { + SMB_ASSERT(fsp->current_lock_count > 0); + fsp->current_lock_count--; + } return NT_STATUS_OK; } -- cgit From 070215ef131245eb386837c666c1884c2556a456 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 18 Jul 2007 14:03:46 +0000 Subject: r23956: merge from 3_2-ctdb-tridge: fixed a bug with dead share mode entries jra: please tell me if it's ok to merge this to 3_2_0. metze (This used to be commit 044ac6afa7a36b352f4cb203879af082d4726417) --- source3/locking/locking.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 8692001f44..e4d06b8bfd 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -937,6 +937,14 @@ BOOL is_valid_share_mode_entry(const struct share_mode_entry *e) { int num_props = 0; + if (e->op_type == UNUSED_SHARE_MODE_ENTRY) { + /* cope with dead entries from the process not + existing. These should not be considered valid, + otherwise we end up doing zero timeout sharing + violation */ + return False; + } + num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0); num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0); num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0); -- cgit From b352a4532afe91cbf885e6cf99a7e1971c05ad1d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2007 13:39:25 +0000 Subject: r24117: use locking_key() instead of forming the TDB_DATA key by hand metze (This used to be commit a7449e4ab390b3c1d9d5a0bbc466f71de17918e0) --- source3/locking/locking.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e4d06b8bfd..d79d73099b 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -782,10 +782,7 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, const char *fname) { struct share_mode_lock *lck; - TDB_DATA key; - - key.dptr = (unsigned char *)&id; - key.dsize = sizeof(id); + TDB_DATA key = locking_key(id); if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) { DEBUG(0, ("talloc failed\n")); -- cgit From 28210588edc39eb2b6cd237f11b488fa4d6b6985 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 7 Aug 2007 11:28:04 +0000 Subject: r24266: Remove the "open files database hash size" parameter This has been superseded by the "tdb_hashsize:" parameter (This used to be commit df40d336afd256f05a0ec3724cc2096fb7114d81) --- source3/locking/locking.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d79d73099b..7f1f8f41e1 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -394,8 +394,7 @@ BOOL locking_init(int read_only) if (lock_db) return True; - lock_db = db_open(NULL, lock_path("locking.tdb"), - lp_open_files_db_hash_size(), + lock_db = db_open(NULL, lock_path("locking.tdb"), 0, TDB_DEFAULT |TDB_VOLATILE |(read_only?0x0:TDB_CLEAR_IF_FIRST), -- cgit From 4ee8b2937d48308c6089fb539fdbd8625dfde360 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 10 Sep 2007 10:56:07 +0000 Subject: r25055: Add file_id_string_tos This removes file_id_string_static and file_id_string_static2 (This used to be commit 638c848c9afe374feb30e34c494f89b2a6c64f7b) --- source3/locking/locking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 7f1f8f41e1..4d6265cc7c 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -458,7 +458,7 @@ char *share_mode_str(int num, struct share_mode_entry *e) e->share_access, e->private_options, e->access_mask, e->op_mid, e->op_type, e->share_file_id, (unsigned int)e->uid, (unsigned int)e->flags, - file_id_static_string(&e->id)); + file_id_string_tos(&e->id)); return share_str; } @@ -906,7 +906,7 @@ BOOL rename_share_filename(struct messaging_context *msg_ctx, DEBUG(10,("rename_share_filename: sending rename message to pid %s " "file_id %s sharepath %s newname %s\n", procid_str_static(&se->pid), - file_id_static_string(&lck->id), + file_id_string_tos(&lck->id), lck->servicepath, lck->filename )); messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME, -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/locking/locking.c | 52 +++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 4d6265cc7c..aae297e031 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -75,7 +75,7 @@ const char *lock_flav_name(enum brl_flavour lock_flav) Called in the read/write codepath. ****************************************************************************/ -BOOL is_locked(files_struct *fsp, +bool is_locked(files_struct *fsp, uint32 smbpid, SMB_BIG_UINT count, SMB_BIG_UINT offset, @@ -83,7 +83,7 @@ BOOL is_locked(files_struct *fsp, { int strict_locking = lp_strict_locking(fsp->conn->params); enum brl_flavour lock_flav = lp_posix_cifsu_locktype(fsp); - BOOL ret = True; + bool ret = True; if (count == 0) { return False; @@ -188,7 +188,7 @@ struct byte_range_lock *do_lock(struct messaging_context *msg_ctx, SMB_BIG_UINT offset, enum brl_type lock_type, enum brl_flavour lock_flav, - BOOL blocking_lock, + bool blocking_lock, NTSTATUS *perr, uint32 *plock_pid) { @@ -255,7 +255,7 @@ NTSTATUS do_unlock(struct messaging_context *msg_ctx, SMB_BIG_UINT offset, enum brl_flavour lock_flav) { - BOOL ok = False; + bool ok = False; struct byte_range_lock *br_lck = NULL; if (!fsp->can_lock) { @@ -308,7 +308,7 @@ NTSTATUS do_lock_cancel(files_struct *fsp, SMB_BIG_UINT offset, enum brl_flavour lock_flav) { - BOOL ok = False; + bool ok = False; struct byte_range_lock *br_lck = NULL; if (!fsp->can_lock) { @@ -387,7 +387,7 @@ void locking_close_file(struct messaging_context *msg_ctx, static int open_read_only; -BOOL locking_init(int read_only) +bool locking_init(int read_only) { brl_init(read_only); @@ -417,7 +417,7 @@ BOOL locking_init(int read_only) Deinitialize the share_mode management. ******************************************************************/ -BOOL locking_end(void) +bool locking_end(void) { brl_shutdown(open_read_only); if (lock_db) { @@ -487,7 +487,7 @@ static void print_share_mode_table(struct locking_data *data) Get all share mode entries for a dev/inode pair. ********************************************************************/ -static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) +static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) { struct locking_data *data; int i; @@ -734,7 +734,7 @@ static int share_mode_lock_destructor(struct share_mode_lock *lck) return 0; } -static BOOL fill_share_mode_lock(struct share_mode_lock *lck, +static bool fill_share_mode_lock(struct share_mode_lock *lck, struct file_id id, const char *servicepath, const char *fname, @@ -844,7 +844,7 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, Based on an initial code idea from SATOH Fumiyasu ********************************************************************/ -BOOL rename_share_filename(struct messaging_context *msg_ctx, +bool rename_share_filename(struct messaging_context *msg_ctx, struct share_mode_lock *lck, const char *servicepath, const char *newname) @@ -916,9 +916,9 @@ BOOL rename_share_filename(struct messaging_context *msg_ctx, return True; } -BOOL get_delete_on_close_flag(struct file_id id) +bool get_delete_on_close_flag(struct file_id id) { - BOOL result; + bool result; struct share_mode_lock *lck; if (!(lck = fetch_share_mode_unlocked(NULL, id, NULL, NULL))) { @@ -929,7 +929,7 @@ BOOL get_delete_on_close_flag(struct file_id id) return result; } -BOOL is_valid_share_mode_entry(const struct share_mode_entry *e) +bool is_valid_share_mode_entry(const struct share_mode_entry *e) { int num_props = 0; @@ -949,12 +949,12 @@ BOOL is_valid_share_mode_entry(const struct share_mode_entry *e) return (num_props != 0); } -BOOL is_deferred_open_entry(const struct share_mode_entry *e) +bool is_deferred_open_entry(const struct share_mode_entry *e) { return (e->op_type == DEFERRED_OPEN_ENTRY); } -BOOL is_unused_share_mode_entry(const struct share_mode_entry *e) +bool is_unused_share_mode_entry(const struct share_mode_entry *e) { return (e->op_type == UNUSED_SHARE_MODE_ENTRY); } @@ -1019,7 +1019,7 @@ static void add_share_mode_entry(struct share_mode_lock *lck, } void set_share_mode(struct share_mode_lock *lck, files_struct *fsp, - uid_t uid, uint16 mid, uint16 op_type, BOOL initial_delete_on_close_allowed) + uid_t uid, uint16 mid, uint16 op_type, bool initial_delete_on_close_allowed) { struct share_mode_entry entry; fill_share_mode_entry(&entry, fsp, uid, mid, op_type); @@ -1044,7 +1044,7 @@ void add_deferred_open(struct share_mode_lock *lck, uint16 mid, not automatically a logic error if they are identical. JRA.) ********************************************************************/ -static BOOL share_modes_identical(struct share_mode_entry *e1, +static bool share_modes_identical(struct share_mode_entry *e1, struct share_mode_entry *e2) { /* We used to check for e1->share_access == e2->share_access here @@ -1057,7 +1057,7 @@ static BOOL share_modes_identical(struct share_mode_entry *e1, e1->share_file_id == e2->share_file_id ); } -static BOOL deferred_open_identical(struct share_mode_entry *e1, +static bool deferred_open_identical(struct share_mode_entry *e1, struct share_mode_entry *e2) { return (procid_equal(&e1->pid, &e2->pid) && @@ -1091,7 +1091,7 @@ static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lc entries left. ********************************************************************/ -BOOL del_share_mode(struct share_mode_lock *lck, files_struct *fsp) +bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp) { struct share_mode_entry entry, *e; @@ -1128,7 +1128,7 @@ void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid) Remove an oplock mid and mode entry from a share mode. ********************************************************************/ -BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp) +bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp) { struct share_mode_entry entry, *e; @@ -1150,7 +1150,7 @@ BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp) Downgrade a oplock type from exclusive to level II. ********************************************************************/ -BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp) +bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp) { struct share_mode_entry entry, *e; @@ -1173,7 +1173,7 @@ BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp) open_file_ntcreate. JRA. ****************************************************************************/ -NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close, +NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close, uint32 dosmode) { if (!delete_on_close) { @@ -1227,7 +1227,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close, Do we have an open file handle that created this entry ? ****************************************************************************/ -BOOL can_set_initial_delete_on_close(const struct share_mode_lock *lck) +bool can_set_initial_delete_on_close(const struct share_mode_lock *lck) { int i; @@ -1299,7 +1299,7 @@ void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok lck entry. This function is used when the lock is already granted. ****************************************************************************/ -void set_delete_on_close_lck(struct share_mode_lock *lck, BOOL delete_on_close, UNIX_USER_TOKEN *tok) +void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, UNIX_USER_TOKEN *tok) { if (lck->delete_on_close != delete_on_close) { set_delete_on_close_token(lck, tok); @@ -1311,7 +1311,7 @@ void set_delete_on_close_lck(struct share_mode_lock *lck, BOOL delete_on_close, } } -BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKEN *tok) +bool set_delete_on_close(files_struct *fsp, bool delete_on_close, UNIX_USER_TOKEN *tok) { struct share_mode_lock *lck; @@ -1343,7 +1343,7 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKE Sets the allow initial delete on close flag for this share mode. ****************************************************************************/ -BOOL set_allow_initial_delete_on_close(struct share_mode_lock *lck, files_struct *fsp, BOOL delete_on_close) +bool set_allow_initial_delete_on_close(struct share_mode_lock *lck, files_struct *fsp, bool delete_on_close) { struct share_mode_entry entry, *e; -- cgit From acb829ecc3b9af3f141425ecac032a7c722a1815 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Nov 2007 18:27:26 -0800 Subject: Add MAX_DNS_NAME_LENGTH, remove more pstrings. Jeremy. (This used to be commit a1725f4ff7ed375808c78ac661b539557748d0a5) --- source3/locking/locking.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index aae297e031..8d511e9d8f 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -444,11 +444,9 @@ static TDB_DATA locking_key(struct file_id id) Print out a share mode. ********************************************************************/ -char *share_mode_str(int num, struct share_mode_entry *e) +char *share_mode_str(TALLOC_CTX *ctx, int num, struct share_mode_entry *e) { - static pstring share_str; - - slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: %s " + return talloc_asprintf(ctx, "share_mode_entry[%d]: %s " "pid = %s, share_access = 0x%x, private_options = 0x%x, " "access_mask = 0x%x, mid = 0x%x, type= 0x%x, gen_id = %lu, " "uid = %u, flags = %u, file_id %s", @@ -459,8 +457,6 @@ char *share_mode_str(int num, struct share_mode_entry *e) e->access_mask, e->op_mid, e->op_type, e->share_file_id, (unsigned int)e->uid, (unsigned int)e->flags, file_id_string_tos(&e->id)); - - return share_str; } /******************************************************************* @@ -476,10 +472,12 @@ static void print_share_mode_table(struct locking_data *data) for (i = 0; i < num_share_modes; i++) { struct share_mode_entry entry; + char *str = share_mode_str(NULL, i, &entry); memcpy(&entry, &shares[i], sizeof(struct share_mode_entry)); DEBUG(10,("print_share_mode_table: %s\n", - share_mode_str(i, &entry))); + str ? str : "")); + TALLOC_FREE(str); } } @@ -603,14 +601,16 @@ static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) for (i = 0; i < lck->num_share_modes; i++) { struct share_mode_entry *entry_p = &lck->share_modes[i]; + char *str = share_mode_str(NULL, i, entry_p); DEBUG(10,("parse_share_modes: %s\n", - share_mode_str(i, entry_p) )); + str ? str : "")); if (!process_exists(entry_p->pid)) { DEBUG(10,("parse_share_modes: deleted %s\n", - share_mode_str(i, entry_p) )); + str ? str : "")); entry_p->op_type = UNUSED_SHARE_MODE_ENTRY; lck->modified = True; } + TALLOC_FREE(str); } return True; -- cgit From 3546d5c099981fede0b29136b3d92145a988a558 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 18 Nov 2007 14:24:54 +0100 Subject: Fix a valgrind error (This used to be commit b82120f9b7f5aad83d8b4ece0261e9693eedca0c) --- source3/locking/locking.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 8d511e9d8f..0cedff36e4 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -472,11 +472,12 @@ static void print_share_mode_table(struct locking_data *data) for (i = 0; i < num_share_modes; i++) { struct share_mode_entry entry; - char *str = share_mode_str(NULL, i, &entry); + char *str; memcpy(&entry, &shares[i], sizeof(struct share_mode_entry)); - DEBUG(10,("print_share_mode_table: %s\n", - str ? str : "")); + str = share_mode_str(NULL, i, &entry); + + DEBUG(10,("print_share_mode_table: %s\n", str ? str : "")); TALLOC_FREE(str); } } -- cgit From 815aec8241b2da93a193eb8d3b3adbfdef5c1d90 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 18 Nov 2007 14:45:19 +0100 Subject: Add a comment (This used to be commit 144014096a41de293ce7ec15f82681a469dd3aa1) --- source3/locking/locking.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 0cedff36e4..eb7531d9a0 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -474,8 +474,14 @@ static void print_share_mode_table(struct locking_data *data) struct share_mode_entry entry; char *str; + /* + * We need to memcpy the entry here due to alignment + * restrictions that are not met when directly accessing + * shares[i] + */ + memcpy(&entry, &shares[i], sizeof(struct share_mode_entry)); - str = share_mode_str(NULL, i, &entry); + str = share_mode_str(talloc_tos(), i, &entry); DEBUG(10,("print_share_mode_table: %s\n", str ? str : "")); TALLOC_FREE(str); -- cgit From 0527d3758ad7522995e1e1cc85a3c1b9ee22de52 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 5 Dec 2007 20:41:24 +0100 Subject: Remove a static (This used to be commit 1f317f471af72f8bbc6c9fdd3e79a27c59e6fb6e) --- source3/locking/locking.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index eb7531d9a0..296323f7da 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -430,14 +430,10 @@ bool locking_end(void) Form a static locking key for a dev/inode pair. ******************************************************************/ -static TDB_DATA locking_key(struct file_id id) +static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp) { - static struct file_id key; - TDB_DATA kbuf; - key = id; - kbuf.dptr = (uint8 *)&key; - kbuf.dsize = sizeof(key); - return kbuf; + *tmp = *id; + return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp)); } /******************************************************************* @@ -783,12 +779,13 @@ static bool fill_share_mode_lock(struct share_mode_lock *lck, } struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, - struct file_id id, + const struct file_id id, const char *servicepath, const char *fname) { struct share_mode_lock *lck; - TDB_DATA key = locking_key(id); + struct file_id tmp; + TDB_DATA key = locking_key(&id, &tmp); if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) { DEBUG(0, ("talloc failed\n")); @@ -814,12 +811,13 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, } struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, - struct file_id id, + const struct file_id id, const char *servicepath, const char *fname) { struct share_mode_lock *lck; - TDB_DATA key = locking_key(id); + struct file_id tmp; + TDB_DATA key = locking_key(&id, &tmp); TDB_DATA data; if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) { -- cgit From d60fac2a5a789680b6dd9f05ab15a3033ec2887c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 5 Dec 2007 20:53:22 +0100 Subject: Tiny simplifications locking.c:open_read_only was unused don't export the silly boolean flag locking_init(bool read_only) (This used to be commit 2f3c865707010bc7c463a02782dbee3dc2479da1) --- source3/locking/locking.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 296323f7da..dab21e53b3 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -385,9 +385,7 @@ void locking_close_file(struct messaging_context *msg_ctx, Initialise the locking functions. ****************************************************************************/ -static int open_read_only; - -bool locking_init(int read_only) +static bool locking_init_internal(bool read_only) { brl_init(read_only); @@ -408,22 +406,28 @@ bool locking_init(int read_only) if (!posix_locking_init(read_only)) return False; - open_read_only = read_only; - return True; } +bool locking_init(void) +{ + return locking_init_internal(false); +} + +bool locking_init_readonly(void) +{ + return locking_init_internal(true); +} + /******************************************************************* Deinitialize the share_mode management. ******************************************************************/ bool locking_end(void) { - brl_shutdown(open_read_only); - if (lock_db) { - TALLOC_FREE(lock_db); - } - return True; + brl_shutdown(); + TALLOC_FREE(lock_db); + return true; } /******************************************************************* -- cgit From a8d2664fec3867cc40894531615a9a2d8036fa25 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 4 Jan 2008 23:27:14 +0100 Subject: allocate share_mode_str only when needed (This used to be commit a98693bfa7bfe72ffa164d21b3e9636e268708aa) --- source3/locking/locking.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index dab21e53b3..270c6d2261 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -608,7 +608,10 @@ static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) for (i = 0; i < lck->num_share_modes; i++) { struct share_mode_entry *entry_p = &lck->share_modes[i]; - char *str = share_mode_str(NULL, i, entry_p); + char *str = NULL; + if (DEBUGLEVEL >= 10) { + str = share_mode_str(NULL, i, entry_p); + } DEBUG(10,("parse_share_modes: %s\n", str ? str : "")); if (!process_exists(entry_p->pid)) { -- cgit From fa6d7b42f1c85004a7c7ece4822277e8e23f32f5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 Jan 2008 12:57:10 +0100 Subject: Do not talloc_strdup filename and servicepath (This used to be commit 66be770993acf4e1673e9615bcddb21768c33e62) --- source3/locking/locking.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 270c6d2261..2ec8cd2938 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -585,22 +585,14 @@ static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) } /* Save off the associated service path and filename. */ - lck->servicepath = talloc_strdup(lck, (const char *)dbuf.dptr + sizeof(*data) + - (lck->num_share_modes * - sizeof(struct share_mode_entry)) + - data->u.s.delete_token_size ); - if (lck->servicepath == NULL) { - smb_panic("parse_share_modes: talloc_strdup failed"); - } - - lck->filename = talloc_strdup(lck, (const char *)dbuf.dptr + sizeof(*data) + - (lck->num_share_modes * - sizeof(struct share_mode_entry)) + - data->u.s.delete_token_size + - strlen(lck->servicepath) + 1 ); - if (lck->filename == NULL) { - smb_panic("parse_share_modes: talloc_strdup failed"); - } + lck->servicepath = (const char *)dbuf.dptr + sizeof(*data) + + (lck->num_share_modes * sizeof(struct share_mode_entry)) + + data->u.s.delete_token_size; + + lck->filename = (const char *)dbuf.dptr + sizeof(*data) + + (lck->num_share_modes * sizeof(struct share_mode_entry)) + + data->u.s.delete_token_size + + strlen(lck->servicepath) + 1; /* * Ensure that each entry has a real process attached. -- cgit From 3cc3b9e1879d3d9714ac2914364418a140e8389c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 6 Jan 2008 14:21:25 +0100 Subject: use talloc_tos in a few more places (This used to be commit 65dd869bea351010c67f02046ae4134bdada1a4c) --- source3/locking/locking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 2ec8cd2938..ce7ba8fa66 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -925,7 +925,7 @@ bool get_delete_on_close_flag(struct file_id id) bool result; struct share_mode_lock *lck; - if (!(lck = fetch_share_mode_unlocked(NULL, id, NULL, NULL))) { + if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id, NULL, NULL))) { return False; } result = lck->delete_on_close; @@ -1328,7 +1328,7 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, UNIX_USER_TOKE return True; } - lck = get_share_mode_lock(NULL, fsp->file_id, NULL, NULL); + lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL); if (lck == NULL) { return False; } -- cgit From 5ddb2abf7611a93960056075ea56f992329c3678 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 6 Jan 2008 16:15:45 +0100 Subject: Some more talloc_tos() (This used to be commit 444e35e7df1f13fc285183da8fb41b30ad99a3fa) --- source3/locking/locking.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index ce7ba8fa66..113b994bc7 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -102,7 +102,7 @@ bool is_locked(files_struct *fsp, DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name )); ret = False; } else { - struct byte_range_lock *br_lck = brl_get_locks_readonly(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp); if (!br_lck) { return False; } @@ -116,7 +116,7 @@ bool is_locked(files_struct *fsp, TALLOC_FREE(br_lck); } } else { - struct byte_range_lock *br_lck = brl_get_locks_readonly(NULL, fsp); + struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp); if (!br_lck) { return False; } @@ -160,7 +160,7 @@ NTSTATUS query_lock(files_struct *fsp, return NT_STATUS_OK; } - br_lck = brl_get_locks_readonly(NULL, fsp); + br_lck = brl_get_locks_readonly(talloc_tos(), fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } @@ -210,7 +210,7 @@ struct byte_range_lock *do_lock(struct messaging_context *msg_ctx, lock_flav_name(lock_flav), lock_type_name(lock_type), (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); - br_lck = brl_get_locks(NULL, fsp); + br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { *perr = NT_STATUS_NO_MEMORY; return NULL; @@ -269,7 +269,7 @@ NTSTATUS do_unlock(struct messaging_context *msg_ctx, DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n", (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); - br_lck = brl_get_locks(NULL, fsp); + br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } @@ -323,7 +323,7 @@ NTSTATUS do_lock_cancel(files_struct *fsp, DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n", (double)offset, (double)count, fsp->fnum, fsp->fsp_name )); - br_lck = brl_get_locks(NULL, fsp); + br_lck = brl_get_locks(talloc_tos(), fsp); if (!br_lck) { return NT_STATUS_NO_MEMORY; } @@ -372,7 +372,7 @@ void locking_close_file(struct messaging_context *msg_ctx, return; } - br_lck = brl_get_locks(NULL,fsp); + br_lck = brl_get_locks(talloc_tos(),fsp); if (br_lck) { cancel_pending_lock_requests_by_fid(fsp, br_lck); -- cgit From 5a8bbc64cc7327facb2a3d136b9c9a3e15a1903a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 12 Jan 2008 23:05:23 +0100 Subject: Trivial simplification (This used to be commit 616bc34744487450edd47e212a29c0f57eabb722) --- source3/locking/locking.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 113b994bc7..bae4518575 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1281,11 +1281,7 @@ static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok) void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok) { - /* Ensure there's no token. */ - if (lck->delete_token) { - TALLOC_FREE(lck->delete_token); /* Also deletes groups... */ - lck->delete_token = NULL; - } + TALLOC_FREE(lck->delete_token); /* Also deletes groups... */ /* Copy the new token (can be NULL). */ lck->delete_token = copy_unix_token(lck, tok); -- cgit From 8d464d470a534d2914eca7287aedaa4205478ca3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 12 Jan 2008 23:06:33 +0100 Subject: Don't early delete the share mode tdb data We now refer directly to the file name in the tdb data, so don't delete it. (This used to be commit 71de4946cf00cf8b7bb2f2d92832166bee12e84a) --- source3/locking/locking.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index bae4518575..513bb31d9d 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -836,8 +836,6 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, return NULL; } - TALLOC_FREE(data.dptr); - return lck; } -- cgit From 170995493376e926b7b30791286598ad6b7af4a4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 17 Mar 2008 14:40:07 +0100 Subject: Merge leftovers of 0e1a86bc845 in 3-0-ctdb (This used to be commit 64b1625f8e3bca43504871747bef6631e1b18f44) --- source3/locking/locking.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 513bb31d9d..782e10fb7c 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -392,10 +392,9 @@ static bool locking_init_internal(bool read_only) if (lock_db) return True; - lock_db = db_open(NULL, lock_path("locking.tdb"), 0, - TDB_DEFAULT - |TDB_VOLATILE - |(read_only?0x0:TDB_CLEAR_IF_FIRST), + lock_db = db_open(NULL, lock_path("locking.tdb"), + lp_open_files_db_hash_size(), + TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST, read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); if (!lock_db) { -- cgit From 2ccf50256e31bd7b9da0f7a7c223bebca5bca062 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Mar 2008 15:32:47 +0100 Subject: locking: store the write time in the locking.tdb This is needed to implement the strange write time update logic later. We need to store 2 time timestamps to distinguish between the time the file system had before the first client opened the file and a forced timestamp update. metze (This used to be commit 6aaa2ce0eeb46f6735ec984a2e7aadde7a7f456d) --- source3/locking/locking.c | 96 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 82 insertions(+), 14 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 782e10fb7c..8d8c0347a5 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -503,12 +503,20 @@ static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) data = (struct locking_data *)dbuf.dptr; lck->delete_on_close = data->u.s.delete_on_close; + lck->old_write_time = data->u.s.old_write_time; + lck->changed_write_time = data->u.s.changed_write_time; lck->num_share_modes = data->u.s.num_share_mode_entries; - DEBUG(10, ("parse_share_modes: delete_on_close: %d, " - "num_share_modes: %d\n", - lck->delete_on_close, - lck->num_share_modes)); + DEBUG(10, ("parse_share_modes: delete_on_close: %d, owrt: %s, " + "cwrt: %s, tok: %u, num_share_modes: %d\n", + lck->delete_on_close, + timestring(debug_ctx(), + convert_timespec_to_time_t(lck->old_write_time)), + timestring(debug_ctx(), + convert_timespec_to_time_t( + lck->changed_write_time)), + (unsigned int)data->u.s.delete_token_size, + lck->num_share_modes)); if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) { DEBUG(0, ("invalid number of share modes: %d\n", @@ -659,11 +667,20 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) ZERO_STRUCTP(data); data->u.s.num_share_mode_entries = lck->num_share_modes; data->u.s.delete_on_close = lck->delete_on_close; + data->u.s.old_write_time = lck->old_write_time; + data->u.s.changed_write_time = lck->changed_write_time; data->u.s.delete_token_size = delete_token_size; - DEBUG(10, ("unparse_share_modes: del: %d, tok = %u, num: %d\n", - data->u.s.delete_on_close, - (unsigned int)data->u.s.delete_token_size, - data->u.s.num_share_mode_entries)); + + DEBUG(10,("unparse_share_modes: del: %d, owrt: %s cwrt: %s, tok: %u, " + "num: %d\n", data->u.s.delete_on_close, + timestring(debug_ctx(), + convert_timespec_to_time_t(lck->old_write_time)), + timestring(debug_ctx(), + convert_timespec_to_time_t( + lck->changed_write_time)), + (unsigned int)data->u.s.delete_token_size, + data->u.s.num_share_mode_entries)); + memcpy(result.dptr + sizeof(*data), lck->share_modes, sizeof(struct share_mode_entry)*lck->num_share_modes); offset = sizeof(*data) + @@ -739,7 +756,8 @@ static bool fill_share_mode_lock(struct share_mode_lock *lck, struct file_id id, const char *servicepath, const char *fname, - TDB_DATA share_mode_data) + TDB_DATA share_mode_data, + const struct timespec *old_write_time) { /* Ensure we set every field here as the destructor must be valid even if parse_share_modes fails. */ @@ -751,13 +769,16 @@ static bool fill_share_mode_lock(struct share_mode_lock *lck, lck->share_modes = NULL; lck->delete_token = NULL; lck->delete_on_close = False; + ZERO_STRUCT(lck->old_write_time); + ZERO_STRUCT(lck->changed_write_time); lck->fresh = False; lck->modified = False; lck->fresh = (share_mode_data.dptr == NULL); if (lck->fresh) { - if (fname == NULL || servicepath == NULL) { + if (fname == NULL || servicepath == NULL + || old_write_time == NULL) { return False; } lck->filename = talloc_strdup(lck, fname); @@ -766,6 +787,7 @@ static bool fill_share_mode_lock(struct share_mode_lock *lck, DEBUG(0, ("talloc failed\n")); return False; } + lck->old_write_time = *old_write_time; } else { if (!parse_share_modes(share_mode_data, lck)) { DEBUG(0, ("Could not parse share modes\n")); @@ -779,7 +801,8 @@ static bool fill_share_mode_lock(struct share_mode_lock *lck, struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, const struct file_id id, const char *servicepath, - const char *fname) + const char *fname, + const struct timespec *old_write_time) { struct share_mode_lock *lck; struct file_id tmp; @@ -797,7 +820,7 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, } if (!fill_share_mode_lock(lck, id, servicepath, fname, - lck->record->value)) { + lck->record->value, old_write_time)) { DEBUG(3, ("fill_share_mode_lock failed\n")); TALLOC_FREE(lck); return NULL; @@ -829,7 +852,7 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, return NULL; } - if (!fill_share_mode_lock(lck, id, servicepath, fname, data)) { + if (!fill_share_mode_lock(lck, id, servicepath, fname, data, NULL)) { DEBUG(3, ("fill_share_mode_lock failed\n")); TALLOC_FREE(lck); return NULL; @@ -917,6 +940,26 @@ bool rename_share_filename(struct messaging_context *msg_ctx, return True; } +struct timespec get_write_time(struct file_id id) +{ + struct timespec result; + struct share_mode_lock *lck; + + ZERO_STRUCT(result); + + if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id, NULL, NULL))) { + return result; + } + result = lck->changed_write_time; + + if (null_timespec(result)) { + result = lck->old_write_time; + } + + TALLOC_FREE(lck); + return result; +} + bool get_delete_on_close_flag(struct file_id id) { bool result; @@ -1321,7 +1364,8 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, UNIX_USER_TOKE return True; } - lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL); + lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, + NULL); if (lck == NULL) { return False; } @@ -1361,6 +1405,30 @@ bool set_allow_initial_delete_on_close(struct share_mode_lock *lck, files_struct return True; } +bool set_write_time(struct file_id fileid, struct timespec write_time, + bool overwrite) +{ + struct share_mode_lock *lck; + + DEBUG(5,("set_write_time: %s overwrite=%d id=%s\n", + timestring(debug_ctx(), + convert_timespec_to_time_t(write_time)), + overwrite, file_id_string_tos(&fileid))); + + lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL); + if (lck == NULL) { + return False; + } + + if (overwrite || null_timespec(lck->changed_write_time)) { + lck->modified = True; + lck->changed_write_time = write_time; + } + + TALLOC_FREE(lck); + return True; +} + struct forall_state { void (*fn)(const struct share_mode_entry *entry, const char *sharepath, -- cgit From 851cadba51b00b326c5f040f23f95932aec53105 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Apr 2008 11:40:23 +0200 Subject: locking: combine get_delete_on_close_flag() and get_write_time() into get_file_infos() This means we need to fetch the record only once. metze (This used to be commit 4130b873291d39e363184fe4e38dc1f24ebe5056) --- source3/locking/locking.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 8d8c0347a5..5faebef1fe 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -940,37 +940,40 @@ bool rename_share_filename(struct messaging_context *msg_ctx, return True; } -struct timespec get_write_time(struct file_id id) +void get_file_infos(struct file_id id, + bool *delete_on_close, + struct timespec *write_time) { - struct timespec result; struct share_mode_lock *lck; - ZERO_STRUCT(result); + if (delete_on_close) { + *delete_on_close = false; + } + + if (write_time) { + ZERO_STRUCTP(write_time); + } if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id, NULL, NULL))) { - return result; + return; } - result = lck->changed_write_time; - if (null_timespec(result)) { - result = lck->old_write_time; + if (delete_on_close) { + *delete_on_close = lck->delete_on_close; } - TALLOC_FREE(lck); - return result; -} + if (write_time) { + struct timespec wt; -bool get_delete_on_close_flag(struct file_id id) -{ - bool result; - struct share_mode_lock *lck; - - if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id, NULL, NULL))) { - return False; + wt = lck->changed_write_time; + if (null_timespec(wt)) { + wt = lck->old_write_time; + } + + *write_time = wt; } - result = lck->delete_on_close; + TALLOC_FREE(lck); - return result; } bool is_valid_share_mode_entry(const struct share_mode_entry *e) -- cgit From b430b382202858a6c52c1cacbb91910b2dd7e16c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 May 2008 17:22:10 -0700 Subject: Remove the "stat_open()" function, flag, and all associated code. It was only being (correctly) used in the can_read/can_write checks for hide unreadable/unwritable and this is more properly done using the functions in smbd/file_access.c. Preparing to do NT access checks on all file access. Jeremy. (This used to be commit 6bfb06ad95963ae2acb67c4694a98282d3b29faa) --- source3/locking/locking.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 5faebef1fe..17131d9194 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1363,10 +1363,6 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, UNIX_USER_TOKE delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name )); - if (fsp->is_stat) { - return True; - } - lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, NULL); if (lck == NULL) { -- cgit From 6811dc3fc236e62f042e43efa500cc55346c29d6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 May 2008 11:23:59 -0700 Subject: Allow server manager to close open files selected by id. Jeremy. (This used to be commit 7eeed8bb41059ec2bddedb6a71deddeec7f33af2) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 17131d9194..accd3f7014 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -443,7 +443,7 @@ static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp) Print out a share mode. ********************************************************************/ -char *share_mode_str(TALLOC_CTX *ctx, int num, struct share_mode_entry *e) +char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e) { return talloc_asprintf(ctx, "share_mode_entry[%d]: %s " "pid = %s, share_access = 0x%x, private_options = 0x%x, " -- cgit From ae923dbd4e4e5cba35b36ad353a943b826e2a2c5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 4 Jul 2008 09:28:04 +0200 Subject: Fix alignment problems on sparc, bug 5512 Patch successfully tested by Christoph Kaegi , thanks. (cherry picked from commit 9f8df16f476c49da85000b7365c8a6e33b8b71fc) (This used to be commit 82ed19ff64fc815a8ca9fbd7d3331671ecf5d12b) --- source3/locking/locking.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index accd3f7014..ca61a886a6 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -493,19 +493,19 @@ static void print_share_mode_table(struct locking_data *data) static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) { - struct locking_data *data; + struct locking_data data; int i; if (dbuf.dsize < sizeof(struct locking_data)) { smb_panic("parse_share_modes: buffer too short"); } - data = (struct locking_data *)dbuf.dptr; + memcpy(&data, dbuf.dptr, sizeof(data)); - lck->delete_on_close = data->u.s.delete_on_close; - lck->old_write_time = data->u.s.old_write_time; - lck->changed_write_time = data->u.s.changed_write_time; - lck->num_share_modes = data->u.s.num_share_mode_entries; + lck->delete_on_close = data.u.s.delete_on_close; + lck->old_write_time = data.u.s.old_write_time; + lck->changed_write_time = data.u.s.changed_write_time; + lck->num_share_modes = data.u.s.num_share_mode_entries; DEBUG(10, ("parse_share_modes: delete_on_close: %d, owrt: %s, " "cwrt: %s, tok: %u, num_share_modes: %d\n", @@ -515,7 +515,7 @@ static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) timestring(debug_ctx(), convert_timespec_to_time_t( lck->changed_write_time)), - (unsigned int)data->u.s.delete_token_size, + (unsigned int)data.u.s.delete_token_size, lck->num_share_modes)); if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) { @@ -535,7 +535,8 @@ static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) } lck->share_modes = (struct share_mode_entry *) - TALLOC_MEMDUP(lck, dbuf.dptr+sizeof(*data), + TALLOC_MEMDUP(lck, + dbuf.dptr+sizeof(struct locking_data), lck->num_share_modes * sizeof(struct share_mode_entry)); @@ -545,15 +546,15 @@ static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) } /* Get any delete token. */ - if (data->u.s.delete_token_size) { - uint8 *p = dbuf.dptr + sizeof(*data) + + if (data.u.s.delete_token_size) { + uint8 *p = dbuf.dptr + sizeof(struct locking_data) + (lck->num_share_modes * sizeof(struct share_mode_entry)); - if ((data->u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) || - ((data->u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) { + if ((data.u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) || + ((data.u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) { DEBUG(0, ("parse_share_modes: invalid token size %d\n", - data->u.s.delete_token_size)); + data.u.s.delete_token_size)); smb_panic("parse_share_modes: invalid token size"); } @@ -569,8 +570,8 @@ static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) p += sizeof(gid_t); /* Any supplementary groups ? */ - lck->delete_token->ngroups = (data->u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ? - ((data->u.s.delete_token_size - + lck->delete_token->ngroups = (data.u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ? + ((data.u.s.delete_token_size - (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0; if (lck->delete_token->ngroups) { @@ -592,13 +593,13 @@ static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) } /* Save off the associated service path and filename. */ - lck->servicepath = (const char *)dbuf.dptr + sizeof(*data) + + lck->servicepath = (const char *)dbuf.dptr + sizeof(struct locking_data) + (lck->num_share_modes * sizeof(struct share_mode_entry)) + - data->u.s.delete_token_size; + data.u.s.delete_token_size; - lck->filename = (const char *)dbuf.dptr + sizeof(*data) + + lck->filename = (const char *)dbuf.dptr + sizeof(struct locking_data) + (lck->num_share_modes * sizeof(struct share_mode_entry)) + - data->u.s.delete_token_size + + data.u.s.delete_token_size + strlen(lck->servicepath) + 1; /* -- cgit From 405b072431db3f3f8f16e4e0d2f2b1b2f1c71286 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Sep 2008 19:00:48 -0700 Subject: Write times code update. Ok, here's the fix for the write times breakage with the new tests in S4 smbtorture. The key is keeping in the share mode struct the "old_file_time" as the real write time, set by all the write and allocation calls, and the "changed_write_time" as the "sticky" write time - set by the SET_FILE_TIME calls. We can set them independently (although I kept the optimization of not setting the "old_file_time" is a "changed_write_time" was already set, as we'll never see it. This allows us to update the write time immediately on the SMBwrite truncate case, SET_END_OF_FILE and SET_ALLOCATION_SIZE calls, whilst still have the 2 second delay on the "normal" SMBwrite, SMBwriteX calls. I think in a subsequent patch I'd like to change the name of these from "old_file_time" to "write_time" and "changed_write_time" to "sticky_write_time" to make this clearer. I think I also fixed a bug in Metze's original code in that once a write timestamp had been set from a "normal" SMBwriteX call the fsp->update_write_time_triggered variable was set and then never reset - thus meaning the write timestamp would never get updated again on subsequent SMBwriteX's. The new code checks the update_write_time_event event instead, and doesn't update is there's an event already scheduled. Metze especially, please check this over for your understanding. Jeremy. (This used to be commit 6f20585419046c4aca1f7d6c863cf79eb6ae53b0) --- source3/locking/locking.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index ca61a886a6..f1f9278668 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1405,22 +1405,21 @@ bool set_allow_initial_delete_on_close(struct share_mode_lock *lck, files_struct return True; } -bool set_write_time(struct file_id fileid, struct timespec write_time, - bool overwrite) +bool set_sticky_write_time(struct file_id fileid, struct timespec write_time) { struct share_mode_lock *lck; - DEBUG(5,("set_write_time: %s overwrite=%d id=%s\n", + DEBUG(5,("set_sticky_write_time: %s id=%s\n", timestring(debug_ctx(), convert_timespec_to_time_t(write_time)), - overwrite, file_id_string_tos(&fileid))); + file_id_string_tos(&fileid))); lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL); if (lck == NULL) { return False; } - if (overwrite || null_timespec(lck->changed_write_time)) { + if (timespec_compare(&lck->changed_write_time, &write_time) != 0) { lck->modified = True; lck->changed_write_time = write_time; } @@ -1429,6 +1428,30 @@ bool set_write_time(struct file_id fileid, struct timespec write_time, return True; } +bool set_write_time(struct file_id fileid, struct timespec write_time) +{ + struct share_mode_lock *lck; + + DEBUG(5,("set_sticky_write_time: %s id=%s\n", + timestring(debug_ctx(), + convert_timespec_to_time_t(write_time)), + file_id_string_tos(&fileid))); + + lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL); + if (lck == NULL) { + return False; + } + + if (timespec_compare(&lck->old_write_time, &write_time) != 0) { + lck->modified = True; + lck->old_write_time = write_time; + } + + TALLOC_FREE(lck); + return True; +} + + struct forall_state { void (*fn)(const struct share_mode_entry *entry, const char *sharepath, -- cgit From e76cb70444a4cff5725cd0b9918b8af1f2857db2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Sep 2008 20:37:00 -0700 Subject: Fix debug message to show correct function name. Jeremy. (This used to be commit 079c75ef3c169c7a5d81bcaa0b70b6e0df2c464d) --- source3/locking/locking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index f1f9278668..368ab1687c 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1432,7 +1432,7 @@ bool set_write_time(struct file_id fileid, struct timespec write_time) { struct share_mode_lock *lck; - DEBUG(5,("set_sticky_write_time: %s id=%s\n", + DEBUG(5,("set_write_time: %s id=%s\n", timestring(debug_ctx(), convert_timespec_to_time_t(write_time)), file_id_string_tos(&fileid))); -- cgit