summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/locking/locking.c66
-rw-r--r--source3/printing/printing.c14
-rw-r--r--source3/smbd/groupname.c1
-rw-r--r--source3/tdb/tdb.h2
4 files changed, 59 insertions, 24 deletions
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) {
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index 27219657ea..8fa9d7db25 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -77,7 +77,7 @@ BOOL print_backend_init(void)
/* handle a Samba upgrade */
tdb_writelock(tdb);
if (tdb_get_int(tdb, "INFO/version") != PRINT_DATABASE_VERSION) {
- tdb_traverse(tdb, tdb_delete, NULL);
+ tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
tdb_store_int(tdb, "INFO/version", PRINT_DATABASE_VERSION);
}
tdb_writeunlock(tdb);
@@ -276,7 +276,7 @@ static void print_queue_update(int snum)
char *path = lp_pathname(snum);
char *cmd = lp_lpqcommand(snum);
char **qlines;
- pstring tmpfile;
+ pstring tmp_file;
int numlines, i, qcount;
print_queue_struct *queue = NULL;
print_status_struct status;
@@ -285,15 +285,15 @@ static void print_queue_update(int snum)
fstring keystr;
TDB_DATA data, key;
- slprintf(tmpfile, sizeof(tmpfile), "%s/smblpq.%d", path, local_pid);
+ slprintf(tmp_file, sizeof(tmp_file), "%s/smblpq.%d", path, local_pid);
- unlink(tmpfile);
- print_run_command(snum, cmd, tmpfile,
+ unlink(tmp_file);
+ print_run_command(snum, cmd, tmp_file,
NULL, NULL, NULL, NULL);
numlines = 0;
- qlines = file_lines_load(tmpfile, &numlines);
- unlink(tmpfile);
+ qlines = file_lines_load(tmp_file, &numlines);
+ unlink(tmp_file);
/* turn the lpq output into a series of job structures */
qcount = 0;
diff --git a/source3/smbd/groupname.c b/source3/smbd/groupname.c
index fcbf5dd778..f0b11e1b36 100644
--- a/source3/smbd/groupname.c
+++ b/source3/smbd/groupname.c
@@ -193,6 +193,7 @@ Error was %s.\n", unixname, strerror(errno) ));
if(new_ep->unix_name != NULL)
free(new_ep->unix_name);
free((char *)new_ep);
+ file_lines_free(lines);
return;
}
memset((char *)&new_ep->next, '\0', sizeof(new_ep->next) );
diff --git a/source3/tdb/tdb.h b/source3/tdb/tdb.h
index b24f08b648..949a843e8a 100644
--- a/source3/tdb/tdb.h
+++ b/source3/tdb/tdb.h
@@ -59,6 +59,8 @@ typedef struct {
enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK,
TDB_ERR_OOM, TDB_ERR_EXISTS};
+typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *);
+
#if STANDALONE
TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
int open_flags, mode_t mode);