diff options
-rw-r--r-- | source3/locking/locking.c | 66 | ||||
-rw-r--r-- | source3/printing/printing.c | 14 | ||||
-rw-r--r-- | source3/smbd/groupname.c | 1 | ||||
-rw-r--r-- | source3/tdb/tdb.h | 2 |
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); |