summaryrefslogtreecommitdiff
path: root/source4/ntvfs
diff options
context:
space:
mode:
authorPavel Shilovsky <piastry@etersoft.ru>2011-01-31 20:20:24 +0300
committerMatthias Dieter Wallnöfer <mdw@samba.org>2011-02-15 11:09:17 +0100
commit738b2abe784bc38bdaf1abc913a401e0e732e188 (patch)
tree65360ea9dabca5e165e1cbdf96426b93384bf39a /source4/ntvfs
parent3c5f537302294dc5306cffed5dcd57221ac2c96d (diff)
downloadsamba-738b2abe784bc38bdaf1abc913a401e0e732e188.tar.gz
samba-738b2abe784bc38bdaf1abc913a401e0e732e188.tar.bz2
samba-738b2abe784bc38bdaf1abc913a401e0e732e188.zip
s4: Don't grant level II oplock to a file with byte-range locks.
Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Matthias Dieter Wallnöfer <mdw@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org> Autobuild-User: Matthias Dieter Wallnöfer <mdw@samba.org> Autobuild-Date: Tue Feb 15 11:09:17 CET 2011 on sn-devel-104
Diffstat (limited to 'source4/ntvfs')
-rw-r--r--source4/ntvfs/common/brlock.c10
-rw-r--r--source4/ntvfs/common/brlock.h3
-rw-r--r--source4/ntvfs/common/brlock_tdb.c29
-rw-r--r--source4/ntvfs/posix/pvfs_open.c12
4 files changed, 52 insertions, 2 deletions
diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c
index a5bc5c1db4..154494e4af 100644
--- a/source4/ntvfs/common/brlock.c
+++ b/source4/ntvfs/common/brlock.c
@@ -125,3 +125,13 @@ NTSTATUS brl_close(struct brl_context *brl,
{
return ops->brl_close(brl, brlh);
}
+
+/*
+ Get a number of locks associated with a open file.
+*/
+NTSTATUS brl_count(struct brl_context *brl,
+ struct brl_handle *brlh,
+ int *count)
+{
+ return ops->brl_count(brl, brlh, count);
+}
diff --git a/source4/ntvfs/common/brlock.h b/source4/ntvfs/common/brlock.h
index 75f142b6f6..e5e618d045 100644
--- a/source4/ntvfs/common/brlock.h
+++ b/source4/ntvfs/common/brlock.h
@@ -46,6 +46,9 @@ struct brlock_ops {
enum brl_type );
NTSTATUS (*brl_close)(struct brl_context *,
struct brl_handle *);
+ NTSTATUS (*brl_count)(struct brl_context *,
+ struct brl_handle *,
+ int *count);
};
diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c
index df95d4c4c6..07e7c1aa5c 100644
--- a/source4/ntvfs/common/brlock_tdb.c
+++ b/source4/ntvfs/common/brlock_tdb.c
@@ -738,6 +738,32 @@ static NTSTATUS brl_tdb_close(struct brl_context *brl,
return status;
}
+static NTSTATUS brl_tdb_count(struct brl_context *brl, struct brl_handle *brlh,
+ int *count)
+{
+ TDB_DATA kbuf, dbuf;
+
+ kbuf.dptr = brlh->key.data;
+ kbuf.dsize = brlh->key.length;
+ *count = 0;
+
+ if (tdb_chainlock(brl->w->tdb, kbuf) != 0) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ dbuf = tdb_fetch(brl->w->tdb, kbuf);
+ if (!dbuf.dptr) {
+ tdb_chainunlock(brl->w->tdb, kbuf);
+ return NT_STATUS_OK;
+ }
+
+ *count = dbuf.dsize / sizeof(struct lock_struct);
+
+ free(dbuf.dptr);
+ tdb_chainunlock(brl->w->tdb, kbuf);
+
+ return NT_STATUS_OK;
+}
static const struct brlock_ops brlock_tdb_ops = {
.brl_init = brl_tdb_init,
@@ -746,7 +772,8 @@ static const struct brlock_ops brlock_tdb_ops = {
.brl_unlock = brl_tdb_unlock,
.brl_remove_pending = brl_tdb_remove_pending,
.brl_locktest = brl_tdb_locktest,
- .brl_close = brl_tdb_close
+ .brl_close = brl_tdb_close,
+ .brl_count = brl_tdb_count
};
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index da32c7f9b6..08a54f8e42 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -1197,7 +1197,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
struct pvfs_file *f;
struct ntvfs_handle *h;
NTSTATUS status;
- int fd;
+ int fd, count;
struct odb_lock *lck;
uint32_t create_options;
uint32_t create_options_must_ignore_mask;
@@ -1569,6 +1569,16 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
f->handle->fd = fd;
+ status = brl_count(f->pvfs->brl_context, f->brl_handle, &count);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(lck);
+ return status;
+ }
+
+ if (count != 0) {
+ oplock_level = OPLOCK_NONE;
+ }
+
/* now really mark the file as open */
status = odb_open_file(lck, f->handle, name->full_name,
&f->handle->fd, name->dos.write_time,