svn commit: samba r3189 - in branches/SAMBA_4_0/source:
ntvfs/common ntvfs/posix script/tests
tridge at samba.org
tridge at samba.org
Mon Oct 25 04:24:58 GMT 2004
Author: tridge
Date: 2004-10-25 04:24:58 +0000 (Mon, 25 Oct 2004)
New Revision: 3189
WebSVN: http://websvn.samba.org/websvn/changeset.php?rep=samba&path=/branches/SAMBA_4_0/source&rev=3189&nolog=1
Log:
improved the share_conflict() logic (both in terms of readability and
correctness). pvfs now passes the BASE-RENAME test.
Modified:
branches/SAMBA_4_0/source/ntvfs/common/opendb.c
branches/SAMBA_4_0/source/ntvfs/posix/pvfs_open.c
branches/SAMBA_4_0/source/ntvfs/posix/pvfs_rename.c
branches/SAMBA_4_0/source/ntvfs/posix/pvfs_unlink.c
branches/SAMBA_4_0/source/script/tests/test_posix.sh
Changeset:
Modified: branches/SAMBA_4_0/source/ntvfs/common/opendb.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/common/opendb.c 2004-10-25 04:24:06 UTC (rev 3188)
+++ branches/SAMBA_4_0/source/ntvfs/common/opendb.c 2004-10-25 04:24:58 UTC (rev 3189)
@@ -145,41 +145,38 @@
return lck;
}
-
/*
determine if two odb_entry structures conflict
*/
static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2)
{
- uint32_t m1, m2;
+#define CHECK_MASK(am, sa, right, share) if (((am) & (right)) && !((sa) & (share))) return True
- m1 = e1->access_mask & (SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_READ_DATA);
- m2 = e2->share_access &
- (NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_READ);
-
- if ((m1 & m2) != m1) {
- return True;
+ /* if either open involves no read.write or delete access then
+ it can't conflict */
+ if (!(e1->access_mask & (SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_READ_DATA | STD_RIGHT_DELETE_ACCESS))) {
+ return False;
}
+ if (!(e2->access_mask & (SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_READ_DATA | STD_RIGHT_DELETE_ACCESS))) {
+ return False;
+ }
- m1 = e2->access_mask & (SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_READ_DATA);
- m2 = e1->share_access &
- (NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_READ);
+ /* check the basic share access */
+ CHECK_MASK(e1->access_mask, e2->share_access, SA_RIGHT_FILE_WRITE_DATA, NTCREATEX_SHARE_ACCESS_WRITE);
+ CHECK_MASK(e2->access_mask, e1->share_access, SA_RIGHT_FILE_WRITE_DATA, NTCREATEX_SHARE_ACCESS_WRITE);
- if ((m1 & m2) != m1) {
- return True;
- }
+ CHECK_MASK(e1->access_mask, e2->share_access, SA_RIGHT_FILE_READ_DATA, NTCREATEX_SHARE_ACCESS_READ);
+ CHECK_MASK(e2->access_mask, e1->share_access, SA_RIGHT_FILE_READ_DATA, NTCREATEX_SHARE_ACCESS_READ);
+ CHECK_MASK(e1->access_mask, e2->share_access, STD_RIGHT_DELETE_ACCESS, NTCREATEX_SHARE_ACCESS_DELETE);
+ CHECK_MASK(e2->access_mask, e1->share_access, STD_RIGHT_DELETE_ACCESS, NTCREATEX_SHARE_ACCESS_DELETE);
+
+ /* if a delete is pending then a second open is not allowed */
if ((e1->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) ||
(e2->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) {
return True;
}
- if ((e1->access_mask & STD_RIGHT_DELETE_ACCESS) &&
- !(e2->share_access & NTCREATEX_SHARE_ACCESS_DELETE)) {
- return True;
- }
-
-
return False;
}
@@ -338,20 +335,49 @@
/*
- determine if a file is open
+ determine if a file can be opened with the given share_access,
+ create_options and access_mask
*/
-BOOL odb_is_open(struct odb_context *odb, DATA_BLOB *key)
+NTSTATUS odb_can_open(struct odb_context *odb, DATA_BLOB *key,
+ uint32_t share_access, uint32_t create_options,
+ uint32_t access_mask)
{
TDB_DATA dbuf;
TDB_DATA kbuf;
+ struct odb_entry *elist;
+ int i, count;
+ struct odb_entry e;
kbuf.dptr = key->data;
kbuf.dsize = key->length;
dbuf = tdb_fetch(odb->w->tdb, kbuf);
if (dbuf.dptr == NULL) {
- return False;
+ return NT_STATUS_OK;
}
+
+ elist = (struct odb_entry *)dbuf.dptr;
+ count = dbuf.dsize / sizeof(struct odb_entry);
+
+ if (count == 0) {
+ free(dbuf.dptr);
+ return NT_STATUS_OK;
+ }
+
+ e.server = odb->server;
+ e.tid = odb->tid;
+ e.fnum = -1;
+ e.share_access = share_access;
+ e.create_options = create_options;
+ e.access_mask = access_mask;
+
+ for (i=0;i<count;i++) {
+ if (share_conflict(elist+i, &e)) {
+ if (dbuf.dptr) free(dbuf.dptr);
+ return NT_STATUS_SHARING_VIOLATION;
+ }
+ }
+
free(dbuf.dptr);
- return True;
+ return NT_STATUS_OK;
}
Modified: branches/SAMBA_4_0/source/ntvfs/posix/pvfs_open.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/posix/pvfs_open.c 2004-10-25 04:24:06 UTC (rev 3188)
+++ branches/SAMBA_4_0/source/ntvfs/posix/pvfs_open.c 2004-10-25 04:24:58 UTC (rev 3189)
@@ -723,17 +723,24 @@
/*
- determine if a file is open - used to prevent some operations on open files
+ determine if a file can be deleted, or if it is prevented by an
+ already open file
*/
-BOOL pvfs_is_open(struct pvfs_state *pvfs, struct pvfs_filename *name)
+NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, struct pvfs_filename *name)
{
NTSTATUS status;
DATA_BLOB key;
status = pvfs_locking_key(name, name, &key);
if (!NT_STATUS_IS_OK(status)) {
- return False;
+ return NT_STATUS_NO_MEMORY;
}
- return odb_is_open(pvfs->odb_context, &key);
+ status = odb_can_open(pvfs->odb_context, &key,
+ NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE |
+ NTCREATEX_SHARE_ACCESS_DELETE,
+ 0, STD_RIGHT_DELETE_ACCESS);
+
+ return status;
}
Modified: branches/SAMBA_4_0/source/ntvfs/posix/pvfs_rename.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/posix/pvfs_rename.c 2004-10-25 04:24:06 UTC (rev 3188)
+++ branches/SAMBA_4_0/source/ntvfs/posix/pvfs_rename.c 2004-10-25 04:24:58 UTC (rev 3189)
@@ -48,11 +48,16 @@
return status;
}
- if (pvfs_is_open(pvfs, name1) ||
- pvfs_is_open(pvfs, name2)) {
- return NT_STATUS_SHARING_VIOLATION;
+ status = pvfs_can_delete(pvfs, name1);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
+ status = pvfs_can_delete(pvfs, name2);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
if (name1->has_wildcard || name2->has_wildcard) {
DEBUG(3,("Rejecting wildcard rename '%s' -> '%s'\n",
ren->rename.in.pattern1, ren->rename.in.pattern2));
Modified: branches/SAMBA_4_0/source/ntvfs/posix/pvfs_unlink.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/posix/pvfs_unlink.c 2004-10-25 04:24:06 UTC (rev 3188)
+++ branches/SAMBA_4_0/source/ntvfs/posix/pvfs_unlink.c 2004-10-25 04:24:58 UTC (rev 3189)
@@ -47,6 +47,11 @@
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
+ status = pvfs_can_delete(pvfs, name);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/* finally try the actual unlink */
if (unlink(name->full_name) == -1) {
status = pvfs_map_errno(pvfs, errno);
@@ -80,10 +85,6 @@
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- if (pvfs_is_open(pvfs, name)) {
- return NT_STATUS_SHARING_VIOLATION;
- }
-
dir = talloc_p(req, struct pvfs_dir);
if (dir == NULL) {
return NT_STATUS_NO_MEMORY;
Modified: branches/SAMBA_4_0/source/script/tests/test_posix.sh
===================================================================
--- branches/SAMBA_4_0/source/script/tests/test_posix.sh 2004-10-25 04:24:06 UTC (rev 3188)
+++ branches/SAMBA_4_0/source/script/tests/test_posix.sh 2004-10-25 04:24:58 UTC (rev 3189)
@@ -30,18 +30,18 @@
tests="BASE-FDPASS BASE-LOCK1 BASE-LOCK2 BASE-LOCK3 BASE-LOCK4"
tests="$tests BASE-LOCK5 BASE-LOCK6 BASE-LOCK7 BASE-UNLINK BASE-ATTR"
-tests="$tests BASE-TRANS2 BASE-NEGNOWAIT BASE-DIR"
+tests="$tests BASE-NEGNOWAIT BASE-DIR"
tests="$tests BASE-DENY2 BASE-TCON BASE-TCONDEV BASE-RW1"
tests="$tests BASE-DENY3 BASE-XCOPY"
tests="$tests BASE-DELETE BASE-PROPERTIES BASE-MANGLE"
tests="$tests BASE-CHKPATH BASE-SECLEAK"
tests="$tests RAW-QFSINFO RAW-QFILEINFO RAW-SFILEINFO-BUG"
-tests="$tests RAW-LOCK RAW-SEEK RAW-CONTEXT"
+tests="$tests RAW-LOCK RAW-SEEK RAW-CONTEXT BASE-RENAME"
-soon="BASE-DIR1 BASE-DENY1 BASE-VUID BASE-OPEN BASE-DEFER_OPEN BASE-RENAME BASE-OPENATTR BASE-CHARSET"
+soon="BASE-DIR1 BASE-DENY1 BASE-VUID BASE-OPEN BASE-DEFER_OPEN BASE-OPENATTR BASE-CHARSET"
soon="$soon RAW-SFILEINFO RAW-SEARCH RAW-OPEN RAW-MKDIR RAW-OPLOCK RAW-NOTIFY RAW-MUX RAW-IOCTL"
-soon="$soon RAW-CHKPATH RAW-UNLINK RAW-READ RAW-WRITE RAW-RENAME RAW-CLOSE"
+soon="$soon RAW-CHKPATH RAW-UNLINK RAW-READ RAW-WRITE RAW-RENAME RAW-CLOSE BASE-TRANS2"
for t in $tests; do
if [ ! -z "$start" -a "$start" != $t ]; then
More information about the samba-cvs
mailing list