summaryrefslogtreecommitdiff
path: root/source3/locking
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2005-07-08 04:51:27 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:58:18 -0500
commitaf8a691db11a5072865f8b03fd1cbd3aab5cb6d7 (patch)
tree0779dd2d2c6d9ea3eae0f094803f6ba3b3c56f24 /source3/locking
parent22268d79265d79b8d86d1152a7bfe2ebc8988905 (diff)
downloadsamba-af8a691db11a5072865f8b03fd1cbd3aab5cb6d7.tar.gz
samba-af8a691db11a5072865f8b03fd1cbd3aab5cb6d7.tar.bz2
samba-af8a691db11a5072865f8b03fd1cbd3aab5cb6d7.zip
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)
Diffstat (limited to 'source3/locking')
-rw-r--r--source3/locking/locking.c120
-rw-r--r--source3/locking/posix.c38
2 files changed, 90 insertions, 68 deletions
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;i<data->u.num_share_mode_entries;) {
+ for (i=0;i<data->u.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;i<data->u.num_share_mode_entries;i++) {
+ for (i=0;i<data->u.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;i<data->u.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;i<data->u.num_share_mode_entries;i++) {
+ for (i=0;i<data->u.s.num_share_mode_entries;i++) {
traverse_callback(&shares[i], name);
}
return 0;
diff --git a/source3/locking/posix.c b/source3/locking/posix.c
index 218c441028..c63992adc5 100644
--- a/source3/locking/posix.c
+++ b/source3/locking/posix.c
@@ -114,7 +114,7 @@ static BOOL add_fd_to_close_entry(files_struct *fsp)
} else
dbuf.dptr = tp;
- memcpy(dbuf.dptr + dbuf.dsize, &fsp->fd, sizeof(int));
+ memcpy(dbuf.dptr + dbuf.dsize, &fsp->fh->fd, sizeof(int));
dbuf.dsize += sizeof(int);
if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
@@ -209,8 +209,8 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
/*
* No POSIX to worry about, just close.
*/
- ret = SMB_VFS_CLOSE(fsp,fsp->fd);
- fsp->fd = -1;
+ ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd);
+ fsp->fh->fd = -1;
return ret;
}
@@ -227,7 +227,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
*/
for (i = 0; i < count; i++) {
- if (entries[i].fd != fsp->fd) {
+ if (entries[i].fd != fsp->fh->fd) {
locks_on_other_fds = True;
break;
}
@@ -237,7 +237,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
/*
* There are outstanding locks on this dev/inode pair on other fds.
- * Add our fd to the pending close tdb and set fsp->fd to -1.
+ * Add our fd to the pending close tdb and set fsp->fh->fd to -1.
*/
if (!add_fd_to_close_entry(fsp)) {
@@ -246,7 +246,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
}
SAFE_FREE(entries);
- fsp->fd = -1;
+ fsp->fh->fd = -1;
return 0;
}
@@ -282,14 +282,14 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
* Finally close the fd associated with this fsp.
*/
- ret = SMB_VFS_CLOSE(fsp,fsp->fd);
+ ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd);
if (saved_errno != 0) {
errno = saved_errno;
ret = -1;
}
- fsp->fd = -1;
+ fsp->fh->fd = -1;
return ret;
}
@@ -371,7 +371,7 @@ static BOOL add_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T s
* Add new record.
*/
- pl.fd = fsp->fd;
+ pl.fd = fsp->fh->fd;
pl.start = start;
pl.size = size;
pl.lock_type = lock_type;
@@ -455,7 +455,7 @@ static int delete_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T
for (i=0; i<count; i++) {
struct posix_lock *entry = &locks[i];
- if (entry->fd == fsp->fd &&
+ if (entry->fd == fsp->fh->fd &&
entry->start == start &&
entry->size == size) {
@@ -490,7 +490,7 @@ static int delete_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T
for (i = 0; i < count; i++) {
struct posix_lock *entry = &locks[i];
- if (fsp->fd == entry->fd &&
+ if (fsp->fh->fd == entry->fd &&
does_lock_overlap( start, size, entry->start, entry->size))
num_overlapping_records++;
}
@@ -524,13 +524,17 @@ static int map_posix_lock_type( files_struct *fsp, enum brl_type lock_type)
*/
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) {
+ }
+#if 0
+ /* We no longer open files write-only. */
+ 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;
}
+#endif
/*
* This return should be the most normal, as we attempt
@@ -652,9 +656,9 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF
{
int ret;
- DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fd,op,(double)offset,(double)count,type));
+ 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->fd,op,offset,count,type);
+ ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type);
if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno == EINVAL))) {
@@ -678,7 +682,7 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF
DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n"));
errno = 0;
count &= 0x7fffffff;
- ret = SMB_VFS_LOCK(fsp,fsp->fd,op,offset,count,type);
+ ret = SMB_VFS_LOCK(fsp,fsp->fh->fd,op,offset,count,type);
}
}
@@ -1247,7 +1251,7 @@ void posix_locking_close_file(files_struct *fsp)
}
for (i = 0; i < count; i++) {
- if (entries[i].fd != fsp->fd )
+ if (entries[i].fd != fsp->fh->fd )
break;
dump_entry(&entries[i]);
@@ -1269,7 +1273,7 @@ void posix_locking_close_file(files_struct *fsp)
for (i = 0; i < count; i++) {
struct posix_lock *pl = &entries[i];
- if (pl->fd == fsp->fd)
+ if (pl->fd == fsp->fh->fd)
release_posix_lock(fsp, (SMB_BIG_UINT)pl->start, (SMB_BIG_UINT)pl->size );
}
SAFE_FREE(entries);