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,
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 <http://www.gnu.org/licenses/>.
Revision History:
*/
#include "includes.h"
+#include "system/filesys.h"
+#include "locking/proto.h"
+#include "dbwrap/dbwrap.h"
+#include "dbwrap/dbwrap_rbt.h"
+#include "util_tdb.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_LOCKING
* The pending close database handle.
*/
-static TDB_CONTEXT *posix_pending_close_tdb;
+static struct db_context *posix_pending_close_db;
/****************************************************************************
First - the functions that deal with the underlying system locks - these
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)
+static bool posix_lock_in_range(off_t *offset_out, off_t *count_out,
+ uint64_t u_offset, uint64_t u_count)
{
- SMB_OFF_T offset = (SMB_OFF_T)u_offset;
- SMB_OFF_T count = (SMB_OFF_T)u_count;
+ off_t offset = (off_t)u_offset;
+ off_t count = (off_t)u_count;
/*
* For the type of system we are, attempt to
- * find the maximum positive lock offset as an SMB_OFF_T.
+ * find the maximum positive lock offset as an off_t.
*/
#if defined(MAX_POSITIVE_LOCK_OFFSET) /* Some systems have arbitrary limits. */
- SMB_OFF_T max_positive_lock_offset = (MAX_POSITIVE_LOCK_OFFSET);
-
-#elif defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS)
-
+ off_t max_positive_lock_offset = (MAX_POSITIVE_LOCK_OFFSET);
+#else
/*
- * In this case SMB_OFF_T is 64 bits,
+ * In this case off_t is 64 bits,
* and the underlying system can handle 64 bit signed locks.
*/
- SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4);
- SMB_OFF_T mask = (mask2<<1);
- SMB_OFF_T max_positive_lock_offset = ~mask;
-
-#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.
- * All offsets & counts must be 2^31 or less.
- */
-
- SMB_OFF_T max_positive_lock_offset = 0x7FFFFFFF;
-
-#endif /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */
+ off_t mask2 = ((off_t)0x4) << (SMB_OFF_T_BITS-4);
+ off_t mask = (mask2<<1);
+ off_t max_positive_lock_offset = ~mask;
+#endif
/*
* POSIX locks of length zero mean lock to end-of-file.
* Win32 locks of length zero are point probes. Ignore
* any Win32 locks of length zero. JRA.
*/
- if (count == (SMB_OFF_T)0) {
+ if (count == (off_t)0) {
DEBUG(10,("posix_lock_in_range: count = 0, ignoring.\n"));
return False;
}
* ignore this lock.
*/
- if (u_offset & ~((SMB_BIG_UINT)max_positive_lock_offset)) {
+ if (u_offset & ~((uint64_t)max_positive_lock_offset)) {
DEBUG(10,("posix_lock_in_range: (offset = %.0f) offset > %.0f and we cannot handle this. Ignoring lock.\n",
- (double)u_offset, (double)((SMB_BIG_UINT)max_positive_lock_offset) ));
+ (double)u_offset, (double)((uint64_t)max_positive_lock_offset) ));
return False;
}
* We must truncate the count to less than max_positive_lock_offset.
*/
- if (u_count & ~((SMB_BIG_UINT)max_positive_lock_offset)) {
+ if (u_count & ~((uint64_t)max_positive_lock_offset)) {
count = max_positive_lock_offset;
}
return True;
}
+bool smb_vfs_call_lock(struct vfs_handle_struct *handle,
+ struct files_struct *fsp, int op, off_t offset,
+ off_t count, int type)
+{
+ VFS_FIND(lock);
+ return handle->fns->lock_fn(handle, fsp, op, offset, count, type);
+}
+
/****************************************************************************
Actual function that does POSIX locks. Copes with 64 -> 32 bit cruft and
broken NFS implementations.
****************************************************************************/
-static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
+static bool posix_fcntl_lock(files_struct *fsp, int op, off_t offset, off_t count, int type)
{
- BOOL ret;
+ bool ret;
DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fh->fd,op,(double)offset,(double)count,type));
- ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type);
+ ret = SMB_VFS_LOCK(fsp, op, offset, count, type);
if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno == EINVAL))) {
DEBUG(0,("posix_fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n",
(double)offset,(double)count));
- DEBUG(0,("an %s error. This can happen when using 64 bit lock offsets\n", strerror(errno)));
- DEBUG(0,("on 32 bit NFS mounted file systems.\n"));
+ DEBUGADD(0,("an %s error. This can happen when using 64 bit lock offsets\n", strerror(errno)));
+ DEBUGADD(0,("on 32 bit NFS mounted file systems.\n"));
/*
* If the offset is > 0x7FFFFFFF then this will cause problems on
* 32 bit NFS mounted filesystems. Just ignore it.
*/
- if (offset & ~((SMB_OFF_T)0x7fffffff)) {
+ if (offset & ~((off_t)0x7fffffff)) {
DEBUG(0,("Offset greater than 31 bits. Returning success.\n"));
return True;
}
- if (count & ~((SMB_OFF_T)0x7fffffff)) {
+ if (count & ~((off_t)0x7fffffff)) {
/* 32 bit NFS file system, retry with smaller offset */
DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n"));
errno = 0;
count &= 0x7fffffff;
- ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type);
+ ret = SMB_VFS_LOCK(fsp, op, offset, count, type);
}
}
return ret;
}
+bool smb_vfs_call_getlock(struct vfs_handle_struct *handle,
+ struct files_struct *fsp, off_t *poffset,
+ off_t *pcount, int *ptype, pid_t *ppid)
+{
+ VFS_FIND(getlock);
+ return handle->fns->getlock_fn(handle, fsp, poffset, pcount, ptype,
+ ppid);
+}
+
/****************************************************************************
Actual function that gets POSIX locks. Copes with 64 -> 32 bit cruft and
broken NFS implementations.
****************************************************************************/
-static BOOL posix_fcntl_getlock(files_struct *fsp, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype)
+static bool posix_fcntl_getlock(files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype)
{
pid_t pid;
- BOOL ret;
+ bool ret;
DEBUG(8,("posix_fcntl_getlock %d %.0f %.0f %d\n",
fsp->fh->fd,(double)*poffset,(double)*pcount,*ptype));
- ret = SMB_VFS_GETLOCK(fsp,fsp->fh->fd,poffset,pcount,ptype,&pid);
+ ret = SMB_VFS_GETLOCK(fsp, poffset, pcount, ptype, &pid);
if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno == EINVAL))) {
DEBUG(0,("posix_fcntl_getlock: WARNING: lock request at offset %.0f, length %.0f returned\n",
(double)*poffset,(double)*pcount));
- DEBUG(0,("an %s error. This can happen when using 64 bit lock offsets\n", strerror(errno)));
- DEBUG(0,("on 32 bit NFS mounted file systems.\n"));
+ DEBUGADD(0,("an %s error. This can happen when using 64 bit lock offsets\n", strerror(errno)));
+ DEBUGADD(0,("on 32 bit NFS mounted file systems.\n"));
/*
* If the offset is > 0x7FFFFFFF then this will cause problems on
* 32 bit NFS mounted filesystems. Just ignore it.
*/
- if (*poffset & ~((SMB_OFF_T)0x7fffffff)) {
+ if (*poffset & ~((off_t)0x7fffffff)) {
DEBUG(0,("Offset greater than 31 bits. Returning success.\n"));
return True;
}
- if (*pcount & ~((SMB_OFF_T)0x7fffffff)) {
+ if (*pcount & ~((off_t)0x7fffffff)) {
/* 32 bit NFS file system, retry with smaller offset */
DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n"));
errno = 0;
*pcount &= 0x7fffffff;
- ret = SMB_VFS_GETLOCK(fsp,fsp->fh->fd,poffset,pcount,ptype,&pid);
+ ret = SMB_VFS_GETLOCK(fsp,poffset,pcount,ptype,&pid);
}
}
region is locked, False otherwise.
****************************************************************************/
-BOOL is_posix_locked(files_struct *fsp,
- SMB_BIG_UINT *pu_offset,
- SMB_BIG_UINT *pu_count,
+bool is_posix_locked(files_struct *fsp,
+ uint64_t *pu_offset,
+ uint64_t *pu_count,
enum brl_type *plock_type,
enum brl_flavour lock_flav)
{
- SMB_OFF_T offset;
- SMB_OFF_T count;
+ off_t offset;
+ off_t count;
int posix_lock_type = map_posix_lock_type(fsp,*plock_type);
- DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, type = %s\n",
- fsp->fsp_name, (double)*pu_offset, (double)*pu_count, posix_lock_type_name(*plock_type) ));
+ DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, "
+ "type = %s\n", fsp_str_dbg(fsp), (double)*pu_offset,
+ (double)*pu_count, posix_lock_type_name(*plock_type)));
/*
* If the requested lock won't fit in the POSIX range, we will
if (lock_flav == POSIX_LOCK) {
/* Only POSIX lock queries need to know the details. */
- *pu_offset = (SMB_BIG_UINT)offset;
- *pu_count = (SMB_BIG_UINT)count;
+ *pu_offset = (uint64_t)offset;
+ *pu_count = (uint64_t)count;
*plock_type = (posix_lock_type == F_RDLCK) ? READ_LOCK : WRITE_LOCK;
}
return True;
/* The key used in the in-memory POSIX databases. */
struct lock_ref_count_key {
- SMB_DEV_T device;
- SMB_INO_T inode;
+ struct file_id id;
char r;
};
-struct fd_key {
- SMB_DEV_T device;
- SMB_INO_T inode;
-};
-
-/*******************************************************************
- Form a static locking key for a dev/inode pair for the fd array.
-******************************************************************/
-
-static TDB_DATA fd_array_key(SMB_DEV_T dev, SMB_INO_T inode)
-{
- static struct fd_key key;
- TDB_DATA kbuf;
-
- memset(&key, '\0', sizeof(key));
- key.device = dev;
- key.inode = inode;
- kbuf.dptr = (uint8 *)&key;
- kbuf.dsize = sizeof(key);
- return kbuf;
-}
-
/*******************************************************************
Form a static locking key for a dev/inode pair for the lock ref count
******************************************************************/
-static TDB_DATA locking_ref_count_key(SMB_DEV_T dev, SMB_INO_T inode)
+static TDB_DATA locking_ref_count_key_fsp(files_struct *fsp,
+ struct lock_ref_count_key *tmp)
{
- static struct lock_ref_count_key key;
- TDB_DATA kbuf;
-
- memset(&key, '\0', sizeof(key));
- key.device = dev;
- key.inode = inode;
- key.r = 'r';
- kbuf.dptr = (uint8 *)&key;
- kbuf.dsize = sizeof(key);
- return kbuf;
+ ZERO_STRUCTP(tmp);
+ tmp->id = fsp->file_id;
+ tmp->r = 'r';
+ return make_tdb_data((uint8_t *)tmp, sizeof(*tmp));
}
/*******************************************************************
static TDB_DATA fd_array_key_fsp(files_struct *fsp)
{
- return fd_array_key(fsp->dev, fsp->inode);
-}
-
-/*******************************************************************
- Convenience function to get a lock ref count key from an fsp.
-******************************************************************/
-
-static TDB_DATA locking_ref_count_key_fsp(files_struct *fsp)
-{
- return locking_ref_count_key(fsp->dev, fsp->inode);
+ return make_tdb_data((uint8 *)&fsp->file_id, sizeof(fsp->file_id));
}
/*******************************************************************
Create the in-memory POSIX lock databases.
********************************************************************/
-BOOL posix_locking_init(int read_only)
+bool posix_locking_init(bool read_only)
{
- if (posix_pending_close_tdb) {
- return True;
- }
-
- if (!posix_pending_close_tdb) {
- posix_pending_close_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL,
- read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644);
+ if (posix_pending_close_db != NULL) {
+ return true;
}
- if (!posix_pending_close_tdb) {
+
+ posix_pending_close_db = db_open_rbt(NULL);
+
+ if (posix_pending_close_db == NULL) {
DEBUG(0,("Failed to open POSIX pending close database.\n"));
- return False;
+ return false;
}
- return True;
+ return true;
}
/*******************************************************************
Delete the in-memory POSIX lock databases.
********************************************************************/
-BOOL posix_locking_end(void)
+bool posix_locking_end(void)
{
- if (posix_pending_close_tdb && tdb_close(posix_pending_close_tdb) != 0) {
- return False;
- }
- return True;
+ /*
+ * Shouldn't we close all fd's here?
+ */
+ TALLOC_FREE(posix_pending_close_db);
+ return true;
}
/****************************************************************************
****************************************************************************/
/****************************************************************************
- The records in posix_pending_close_tdb are composed of an array of ints
- keyed by dev/ino pair.
- The first int is a reference count of the number of outstanding locks on
- all open fd's on this dev/ino pair. Any subsequent ints are the fd's that
- were open on this dev/ino pair that should have been closed, but can't as
- the lock ref count is non zero.
+ The records in posix_pending_close_db are composed of an array of
+ ints keyed by dev/ino pair. Those ints are the fd's that were open on
+ this dev/ino pair that should have been closed, but can't as the lock
+ ref count is non zero.
****************************************************************************/
/****************************************************************************
static void increment_windows_lock_ref_count(files_struct *fsp)
{
- TDB_DATA kbuf = locking_ref_count_key_fsp(fsp);
- TDB_DATA dbuf;
- int lock_ref_count;
+ struct lock_ref_count_key tmp;
+ int32_t lock_ref_count = 0;
+ NTSTATUS status;
- dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
- if (dbuf.dptr == NULL) {
- dbuf.dptr = (uint8 *)SMB_MALLOC_P(int);
- if (!dbuf.dptr) {
- smb_panic("increment_windows_lock_ref_count: malloc fail.\n");
- }
- memset(dbuf.dptr, '\0', sizeof(int));
- dbuf.dsize = sizeof(int);
- }
+ status = dbwrap_change_int32_atomic(
+ posix_pending_close_db, locking_ref_count_key_fsp(fsp, &tmp),
+ &lock_ref_count, 1);
- memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
- lock_ref_count++;
- memcpy(dbuf.dptr, &lock_ref_count, sizeof(int));
-
- if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
- smb_panic("increment_windows_lock_ref_count: tdb_store_fail.\n");
- }
- SAFE_FREE(dbuf.dptr);
+ SMB_ASSERT(NT_STATUS_IS_OK(status));
+ SMB_ASSERT(lock_ref_count < INT32_MAX);
DEBUG(10,("increment_windows_lock_ref_count for file now %s = %d\n",
- fsp->fsp_name, lock_ref_count ));
-}
-
-static void decrement_windows_lock_ref_count(files_struct *fsp)
-{
- TDB_DATA kbuf = locking_ref_count_key_fsp(fsp);
- TDB_DATA dbuf;
- int lock_ref_count;
-
- dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
- if (!dbuf.dptr) {
- smb_panic("decrement_windows_lock_ref_count: logic error.\n");
- }
-
- memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
- lock_ref_count--;
- memcpy(dbuf.dptr, &lock_ref_count, sizeof(int));
-
- if (lock_ref_count < 0) {
- smb_panic("decrement_windows_lock_ref_count: lock_count logic error.\n");
- }
-
- if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
- smb_panic("decrement_windows_lock_ref_count: tdb_store_fail.\n");
- }
- SAFE_FREE(dbuf.dptr);
-
- DEBUG(10,("decrement_windows_lock_ref_count for file now %s = %d\n",
- fsp->fsp_name, lock_ref_count ));
+ fsp_str_dbg(fsp), (int)lock_ref_count));
}
/****************************************************************************
Bulk delete - subtract as many locks as we've just deleted.
****************************************************************************/
-void reduce_windows_lock_ref_count(files_struct *fsp, unsigned int dcount)
+static void reduce_windows_lock_ref_count(files_struct *fsp,
+ unsigned int dcount)
{
- TDB_DATA kbuf = locking_ref_count_key_fsp(fsp);
- TDB_DATA dbuf;
- int lock_ref_count;
-
- dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
- if (!dbuf.dptr) {
- return;
- }
+ struct lock_ref_count_key tmp;
+ int32_t lock_ref_count = 0;
+ NTSTATUS status;
- memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
- lock_ref_count -= dcount;
+ status = dbwrap_change_int32_atomic(
+ posix_pending_close_db, locking_ref_count_key_fsp(fsp, &tmp),
+ &lock_ref_count, -dcount);
- if (lock_ref_count < 0) {
- smb_panic("reduce_windows_lock_ref_count: lock_count logic error.\n");
- }
- memcpy(dbuf.dptr, &lock_ref_count, sizeof(int));
-
- if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
- smb_panic("reduce_windows_lock_ref_count: tdb_store_fail.\n");
- }
- SAFE_FREE(dbuf.dptr);
+ SMB_ASSERT(NT_STATUS_IS_OK(status));
+ SMB_ASSERT(lock_ref_count >= 0);
DEBUG(10,("reduce_windows_lock_ref_count for file now %s = %d\n",
- fsp->fsp_name, lock_ref_count ));
+ fsp_str_dbg(fsp), (int)lock_ref_count));
+}
+
+static void decrement_windows_lock_ref_count(files_struct *fsp)
+{
+ reduce_windows_lock_ref_count(fsp, 1);
}
/****************************************************************************
Fetch the lock ref count.
****************************************************************************/
-static int get_windows_lock_ref_count(files_struct *fsp)
+static int32_t get_windows_lock_ref_count(files_struct *fsp)
{
- TDB_DATA kbuf = locking_ref_count_key_fsp(fsp);
- TDB_DATA dbuf;
- int lock_ref_count;
-
- dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
- if (!dbuf.dptr) {
- lock_ref_count = 0;
- } else {
- memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
+ struct lock_ref_count_key tmp;
+ NTSTATUS status;
+ int32_t lock_ref_count = 0;
+
+ status = dbwrap_fetch_int32(
+ posix_pending_close_db, locking_ref_count_key_fsp(fsp, &tmp),
+ &lock_ref_count);
+
+ if (!NT_STATUS_IS_OK(status) &&
+ !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+ DEBUG(0, ("get_windows_lock_ref_count: Error fetching "
+ "lock ref count for file %s: %s\n",
+ fsp_str_dbg(fsp), nt_errstr(status)));
}
- SAFE_FREE(dbuf.dptr);
-
- DEBUG(10,("get_windows_lock_count for file %s = %d\n",
- fsp->fsp_name, lock_ref_count ));
return lock_ref_count;
}
static void delete_windows_lock_ref_count(files_struct *fsp)
{
- TDB_DATA kbuf = locking_ref_count_key_fsp(fsp);
+ struct lock_ref_count_key tmp;
/* Not a bug if it doesn't exist - no locks were ever granted. */
- tdb_delete(posix_pending_close_tdb, kbuf);
- DEBUG(10,("delete_windows_lock_ref_count for file %s\n", fsp->fsp_name));
+
+ dbwrap_delete(posix_pending_close_db,
+ locking_ref_count_key_fsp(fsp, &tmp));
+
+ DEBUG(10,("delete_windows_lock_ref_count for file %s\n",
+ fsp_str_dbg(fsp)));
}
/****************************************************************************
static void add_fd_to_close_entry(files_struct *fsp)
{
- TDB_DATA kbuf = fd_array_key_fsp(fsp);
- TDB_DATA dbuf;
+ struct db_record *rec;
+ int *fds;
+ size_t num_fds;
+ NTSTATUS status;
+ TDB_DATA value;
- dbuf.dptr = NULL;
- dbuf.dsize = 0;
+ rec = dbwrap_fetch_locked(
+ posix_pending_close_db, talloc_tos(),
+ fd_array_key_fsp(fsp));
- dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
+ SMB_ASSERT(rec != NULL);
- dbuf.dptr = (uint8 *)SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(int));
- if (!dbuf.dptr) {
- smb_panic("add_fd_to_close_entry: Realloc fail !\n");
- }
+ value = dbwrap_record_get_value(rec);
+ SMB_ASSERT((value.dsize % sizeof(int)) == 0);
- memcpy(dbuf.dptr + dbuf.dsize, &fsp->fh->fd, sizeof(int));
- dbuf.dsize += sizeof(int);
+ num_fds = value.dsize / sizeof(int);
+ fds = talloc_array(rec, int, num_fds+1);
- if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
- smb_panic("add_fd_to_close_entry: tdb_store_fail.\n");
- }
+ SMB_ASSERT(fds != NULL);
- DEBUG(10,("add_fd_to_close_entry: added fd %d file %s\n",
- fsp->fh->fd, fsp->fsp_name ));
+ memcpy(fds, value.dptr, value.dsize);
+ fds[num_fds] = fsp->fh->fd;
- SAFE_FREE(dbuf.dptr);
+ status = dbwrap_record_store(
+ rec, make_tdb_data((uint8_t *)fds, talloc_get_size(fds)), 0);
+
+ SMB_ASSERT(NT_STATUS_IS_OK(status));
+
+ TALLOC_FREE(rec);
+
+ DEBUG(10,("add_fd_to_close_entry: added fd %d file %s\n",
+ fsp->fh->fd, fsp_str_dbg(fsp)));
}
/****************************************************************************
static void delete_close_entries(files_struct *fsp)
{
- TDB_DATA kbuf = fd_array_key_fsp(fsp);
+ struct db_record *rec;
- if (tdb_delete(posix_pending_close_tdb, kbuf) == -1) {
- smb_panic("delete_close_entries: tdb_delete fail !\n");
- }
+ rec = dbwrap_fetch_locked(
+ posix_pending_close_db, talloc_tos(),
+ fd_array_key_fsp(fsp));
+
+ SMB_ASSERT(rec != NULL);
+ dbwrap_record_delete(rec);
+ TALLOC_FREE(rec);
}
/****************************************************************************
- Get the array of POSIX pending close records for an open fsp. Caller must
- free. Returns number of entries.
+ Get the array of POSIX pending close records for an open fsp. Returns number
+ of entries.
****************************************************************************/
-static size_t get_posix_pending_close_entries(files_struct *fsp, int **entries)
+static size_t get_posix_pending_close_entries(TALLOC_CTX *mem_ctx,
+ files_struct *fsp, int **entries)
{
- TDB_DATA kbuf = fd_array_key_fsp(fsp);
TDB_DATA dbuf;
- size_t count = 0;
+ NTSTATUS status;
- *entries = NULL;
- dbuf.dptr = NULL;
+ status = dbwrap_fetch(
+ posix_pending_close_db, mem_ctx, fd_array_key_fsp(fsp),
+ &dbuf);
- dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+ *entries = NULL;
+ return 0;
+ }
+
+ SMB_ASSERT(NT_STATUS_IS_OK(status));
- if (!dbuf.dptr) {
+ if (dbuf.dsize == 0) {
+ *entries = NULL;
return 0;
}
*entries = (int *)dbuf.dptr;
- count = (size_t)(dbuf.dsize / sizeof(int));
-
- return count;
+ return (size_t)(dbuf.dsize / sizeof(int));
}
/****************************************************************************
to delete all locks on this fsp before this function is called.
****************************************************************************/
-NTSTATUS fd_close_posix(struct connection_struct *conn, files_struct *fsp)
+int fd_close_posix(struct files_struct *fsp)
{
int saved_errno = 0;
int ret;
int *fd_array = NULL;
size_t count, i;
- if (!lp_locking(fsp->conn->params) || !lp_posix_locking(conn->params)) {
+ if (!lp_locking(fsp->conn->params) ||
+ !lp_posix_locking(fsp->conn->params))
+ {
/*
* No locking or POSIX to worry about or we want POSIX semantics
* which will lose all locks on all fd's open on this dev/inode,
* just close.
*/
- ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd);
- fsp->fh->fd = -1;
- return map_nt_error_from_unix(errno);
+ return close(fsp->fh->fd);
}
if (get_windows_lock_ref_count(fsp)) {
/*
- * There are outstanding locks on this dev/inode pair on other fds.
- * Add our fd to the pending close tdb and set fsp->fh->fd to -1.
+ * There are outstanding locks on this dev/inode pair on
+ * other fds. Add our fd to the pending close tdb and set
+ * fsp->fh->fd to -1.
*/
add_fd_to_close_entry(fsp);
- fsp->fh->fd = -1;
- return NT_STATUS_OK;
+ return 0;
}
/*
* from the tdb and close them all.
*/
- count = get_posix_pending_close_entries(fsp, &fd_array);
+ count = get_posix_pending_close_entries(talloc_tos(), fsp, &fd_array);
if (count) {
- DEBUG(10,("fd_close_posix: doing close on %u fd's.\n", (unsigned int)count ));
+ DEBUG(10,("fd_close_posix: doing close on %u fd's.\n",
+ (unsigned int)count));
for(i = 0; i < count; i++) {
- if (SMB_VFS_CLOSE(fsp,fd_array[i]) == -1) {
+ if (close(fd_array[i]) == -1) {
saved_errno = errno;
}
}
delete_close_entries(fsp);
}
- SAFE_FREE(fd_array);
+ TALLOC_FREE(fd_array);
/* Don't need a lock ref count on this dev/ino anymore. */
delete_windows_lock_ref_count(fsp);
* Finally close the fd associated with this fsp.
*/
- ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd);
+ ret = close(fsp->fh->fd);
if (ret == 0 && saved_errno != 0) {
errno = saved_errno;
ret = -1;
- }
-
- fsp->fh->fd = -1;
-
- if (ret == -1) {
- return map_nt_error_from_unix(errno);
}
- return NT_STATUS_OK;
+ return ret;
}
/****************************************************************************
struct lock_list {
struct lock_list *next;
struct lock_list *prev;
- SMB_OFF_T start;
- SMB_OFF_T size;
+ off_t start;
+ off_t size;
};
/****************************************************************************
}
/* Ignore locks not owned by this process. */
- if (!procid_equal(&lock->context.pid, &lock_ctx->pid)) {
+ if (!serverid_equal(&lock->context.pid, &lock_ctx->pid)) {
continue;
}
for (l_curr = lhead; l_curr;) {
- DEBUG(10,("posix_lock_list: lock: fnum=%d: start=%.0f,size=%.0f:type=%s", lock->fnum,
+ DEBUG(10,("posix_lock_list: lock: fnum=%llu: start=%.0f,size=%.0f:type=%s",
+ (unsigned long long)lock->fnum,
(double)lock->start, (double)lock->size, posix_lock_type_name(lock->lock_type) ));
if ( (l_curr->start >= (lock->start + lock->size)) ||
| l_curr| | l_new |
+-------+ +---------+
**********************************************/
- struct lock_list *l_new = TALLOC_P(ctx, struct lock_list);
+ struct lock_list *l_new = talloc(ctx, struct lock_list);
if(l_new == NULL) {
DEBUG(0,("posix_lock_list: talloc fail.\n"));
/*
* Add into the dlink list after the l_curr point - NOT at lhead.
- * Note we can't use DLINK_ADD here as this inserts at the head of the given list.
*/
-
- l_new->prev = l_curr;
- l_new->next = l_curr->next;
- l_curr->next = l_new;
+ DLIST_ADD_AFTER(lhead, l_new, l_curr);
/* And move after the link we added. */
l_curr = l_new->next;
* This logic case should never happen. Ensure this is the
* case by forcing an abort.... Remove in production.
*/
- pstring msg;
+ char *msg = NULL;
- slprintf(msg, sizeof(msg)-1, "logic flaw in cases: l_curr: start = %.0f, size = %.0f : \
-lock: start = %.0f, size = %.0f\n", (double)l_curr->start, (double)l_curr->size, (double)lock->start, (double)lock->size );
-
- smb_panic(msg);
+ if (asprintf(&msg, "logic flaw in cases: l_curr: start = %.0f, size = %.0f : \
+lock: start = %.0f, size = %.0f", (double)l_curr->start, (double)l_curr->size, (double)lock->start, (double)lock->size ) != -1) {
+ smb_panic(msg);
+ } else {
+ smb_panic("posix_lock_list");
+ }
}
} /* end for ( l_curr = lhead; l_curr;) */
} /* end for (i=0; i<num_locks && ul_head; i++) */
lock could be granted, False if not.
****************************************************************************/
-BOOL set_posix_lock_windows_flavour(files_struct *fsp,
- SMB_BIG_UINT u_offset,
- SMB_BIG_UINT u_count,
+bool set_posix_lock_windows_flavour(files_struct *fsp,
+ uint64_t u_offset,
+ uint64_t u_count,
enum brl_type lock_type,
const struct lock_context *lock_ctx,
const struct lock_struct *plocks,
int num_locks,
int *errno_ret)
{
- SMB_OFF_T offset;
- SMB_OFF_T count;
+ off_t offset;
+ off_t count;
int posix_lock_type = map_posix_lock_type(fsp,lock_type);
- BOOL ret = True;
+ bool ret = True;
size_t lock_count;
TALLOC_CTX *l_ctx = NULL;
struct lock_list *llist = NULL;
struct lock_list *ll = NULL;
- DEBUG(5,("set_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n",
- fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) ));
+ DEBUG(5,("set_posix_lock_windows_flavour: File %s, offset = %.0f, "
+ "count = %.0f, type = %s\n", fsp_str_dbg(fsp),
+ (double)u_offset, (double)u_count,
+ posix_lock_type_name(lock_type)));
/*
* If the requested lock won't fit in the POSIX range, we will
return False;
}
- if ((ll = TALLOC_P(l_ctx, struct lock_list)) == NULL) {
+ if ((ll = talloc(l_ctx, struct lock_list)) == NULL) {
DEBUG(0,("set_posix_lock_windows_flavour: unable to talloc unlock list.\n"));
talloc_destroy(l_ctx);
return False;
DEBUG(5,("set_posix_lock_windows_flavour: Real lock: Type = %s: offset = %.0f, count = %.0f\n",
posix_lock_type_name(posix_lock_type), (double)offset, (double)count ));
- if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,posix_lock_type)) {
+ if (!posix_fcntl_lock(fsp,F_SETLK,offset,count,posix_lock_type)) {
*errno_ret = errno;
DEBUG(5,("set_posix_lock_windows_flavour: Lock fail !: Type = %s: offset = %.0f, count = %.0f. Errno = %s\n",
posix_lock_type_name(posix_lock_type), (double)offset, (double)count, strerror(errno) ));
DEBUG(5,("set_posix_lock_windows_flavour: Backing out locks: Type = %s: offset = %.0f, count = %.0f\n",
posix_lock_type_name(posix_lock_type), (double)offset, (double)count ));
- posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_UNLCK);
+ posix_fcntl_lock(fsp,F_SETLK,offset,count,F_UNLCK);
}
} else {
/* Remember the number of Windows locks we have on this dev/ino pair. */
lock could be released, False if not.
****************************************************************************/
-BOOL release_posix_lock_windows_flavour(files_struct *fsp,
- SMB_BIG_UINT u_offset,
- SMB_BIG_UINT u_count,
+bool release_posix_lock_windows_flavour(files_struct *fsp,
+ uint64_t u_offset,
+ uint64_t u_count,
enum brl_type deleted_lock_type,
const struct lock_context *lock_ctx,
const struct lock_struct *plocks,
int num_locks)
{
- SMB_OFF_T offset;
- SMB_OFF_T count;
- BOOL ret = True;
+ off_t offset;
+ off_t count;
+ bool ret = True;
TALLOC_CTX *ul_ctx = NULL;
struct lock_list *ulist = NULL;
struct lock_list *ul = NULL;
- DEBUG(5,("release_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f\n",
- fsp->fsp_name, (double)u_offset, (double)u_count ));
+ DEBUG(5,("release_posix_lock_windows_flavour: File %s, offset = %.0f, "
+ "count = %.0f\n", fsp_str_dbg(fsp),
+ (double)u_offset, (double)u_count));
/* Remember the number of Windows locks we have on this dev/ino pair. */
decrement_windows_lock_ref_count(fsp);
return False;
}
- if ((ul = TALLOC_P(ul_ctx, struct lock_list)) == NULL) {
+ if ((ul = talloc(ul_ctx, struct lock_list)) == NULL) {
DEBUG(0,("release_posix_lock_windows_flavour: unable to talloc unlock list.\n"));
talloc_destroy(ul_ctx);
return False;
DEBUG(5,("release_posix_lock_windows_flavour: downgrading lock to READ: offset = %.0f, count = %.0f\n",
(double)offset, (double)count ));
- if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_RDLCK)) {
+ if (!posix_fcntl_lock(fsp,F_SETLK,offset,count,F_RDLCK)) {
DEBUG(0,("release_posix_lock_windows_flavour: downgrade of lock failed with error %s !\n", strerror(errno) ));
talloc_destroy(ul_ctx);
return False;
DEBUG(5,("release_posix_lock_windows_flavour: Real unlock: offset = %.0f, count = %.0f\n",
(double)offset, (double)count ));
- if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_UNLCK)) {
+ if (!posix_fcntl_lock(fsp,F_SETLK,offset,count,F_UNLCK)) {
ret = False;
}
}
upper layer would have refused it.
****************************************************************************/
-BOOL set_posix_lock_posix_flavour(files_struct *fsp,
- SMB_BIG_UINT u_offset,
- SMB_BIG_UINT u_count,
+bool set_posix_lock_posix_flavour(files_struct *fsp,
+ uint64_t u_offset,
+ uint64_t u_count,
enum brl_type lock_type,
int *errno_ret)
{
- SMB_OFF_T offset;
- SMB_OFF_T count;
+ off_t offset;
+ off_t count;
int posix_lock_type = map_posix_lock_type(fsp,lock_type);
- DEBUG(5,("set_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n",
- fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) ));
+ DEBUG(5,("set_posix_lock_posix_flavour: File %s, offset = %.0f, count "
+ "= %.0f, type = %s\n", fsp_str_dbg(fsp),
+ (double)u_offset, (double)u_count,
+ posix_lock_type_name(lock_type)));
/*
* If the requested lock won't fit in the POSIX range, we will
return True;
}
- if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,posix_lock_type)) {
+ if (!posix_fcntl_lock(fsp,F_SETLK,offset,count,posix_lock_type)) {
*errno_ret = errno;
DEBUG(5,("set_posix_lock_posix_flavour: Lock fail !: Type = %s: offset = %.0f, count = %.0f. Errno = %s\n",
posix_lock_type_name(posix_lock_type), (double)offset, (double)count, strerror(errno) ));
have a different lock context.
****************************************************************************/
-BOOL release_posix_lock_posix_flavour(files_struct *fsp,
- SMB_BIG_UINT u_offset,
- SMB_BIG_UINT u_count,
+bool release_posix_lock_posix_flavour(files_struct *fsp,
+ uint64_t u_offset,
+ uint64_t u_count,
const struct lock_context *lock_ctx,
const struct lock_struct *plocks,
int num_locks)
{
- BOOL ret = True;
- SMB_OFF_T offset;
- SMB_OFF_T count;
+ bool ret = True;
+ off_t offset;
+ off_t count;
TALLOC_CTX *ul_ctx = NULL;
struct lock_list *ulist = NULL;
struct lock_list *ul = NULL;
- DEBUG(5,("release_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f\n",
- fsp->fsp_name, (double)u_offset, (double)u_count ));
+ DEBUG(5,("release_posix_lock_posix_flavour: File %s, offset = %.0f, "
+ "count = %.0f\n", fsp_str_dbg(fsp),
+ (double)u_offset, (double)u_count));
/*
* If the requested lock won't fit in the POSIX range, we will
return False;
}
- if ((ul = TALLOC_P(ul_ctx, struct lock_list)) == NULL) {
+ if ((ul = talloc(ul_ctx, struct lock_list)) == NULL) {
DEBUG(0,("release_posix_lock_windows_flavour: unable to talloc unlock list.\n"));
talloc_destroy(ul_ctx);
return False;
DEBUG(5,("release_posix_lock_posix_flavour: Real unlock: offset = %.0f, count = %.0f\n",
(double)offset, (double)count ));
- if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_UNLCK)) {
+ if (!posix_fcntl_lock(fsp,F_SETLK,offset,count,F_UNLCK)) {
ret = False;
}
}