From: Pavel Shilovsky Date: Mon, 31 Jan 2011 17:20:24 +0000 (+0300) Subject: s4: Don't grant level II oplock to a file with byte-range locks. X-Git-Url: http://git.samba.org/?a=commitdiff_plain;h=738b2abe784bc38bdaf1abc913a401e0e732e188;p=metze%2Fsamba%2Fwip.git s4: Don't grant level II oplock to a file with byte-range locks. Signed-off-by: Pavel Shilovsky Signed-off-by: Matthias Dieter Wallnöfer Reviewed-by: Stefan Metzmacher Autobuild-User: Matthias Dieter Wallnöfer Autobuild-Date: Tue Feb 15 11:09:17 CET 2011 on sn-devel-104 --- diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index a5bc5c1db4de..154494e4affa 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 75f142b6f670..e5e618d045dd 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 df95d4c4c6e4..07e7c1aa5ce1 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 da32c7f9b631..08a54f8e42be 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,