s4: Don't grant level II oplock to a file with byte-range locks.
authorPavel Shilovsky <piastry@etersoft.ru>
Mon, 31 Jan 2011 17:20:24 +0000 (20:20 +0300)
committerMatthias Dieter Wallnöfer <mdw@samba.org>
Tue, 15 Feb 2011 10:09:17 +0000 (11:09 +0100)
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

source4/ntvfs/common/brlock.c
source4/ntvfs/common/brlock.h
source4/ntvfs/common/brlock_tdb.c
source4/ntvfs/posix/pvfs_open.c

index a5bc5c1db4de2df030ad66cf234fc0bfa3ccc080..154494e4affaf15e0cce0f48f0ef8dbf271d7710 100644 (file)
@@ -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);
+}
index 75f142b6f67091170438f7cf74f427414d2928d4..e5e618d045dd148d2dea1072718b6c7d07b06d40 100644 (file)
@@ -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);
 };
 
 
index df95d4c4c6e4c71bd3eed3253c5ba7f669954604..07e7c1aa5ce105a50f45678632f3bdde7cf2187c 100644 (file)
@@ -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
 };
 
 
index da32c7f9b631672ebabc0804c4bc5a6b85688721..08a54f8e42be419da0fc412df1d590dcb53dc817 100644 (file)
@@ -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,