summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/locking/brlock.c44
-rw-r--r--source3/locking/locking.c2
-rw-r--r--source3/utils/status.c30
3 files changed, 72 insertions, 4 deletions
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index 11766433fc..7e8adf4f86 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -90,11 +90,11 @@ static BOOL brl_conflict(struct lock_struct *lck1,
/****************************************************************************
open up the brlock.tdb database
****************************************************************************/
-void brl_init(void)
+void brl_init(int read_only)
{
if (tdb) return;
tdb = tdb_open(lock_path("brlock.tdb"), 0, TDB_CLEAR_IF_FIRST,
- O_RDWR | O_CREAT, 0644);
+ read_only?O_RDONLY:O_RDWR|O_CREAT, 0644);
if (!tdb) {
DEBUG(0,("Failed to open byte range locking database\n"));
}
@@ -329,3 +329,43 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum)
if (dbuf.dptr) free(dbuf.dptr);
tdb_unlockchain(tdb, kbuf);
}
+
+
+static void (*traverse_callback)(SMB_DEV_T dev, SMB_INO_T ino, int pid,
+ enum brl_type lock_type,
+ br_off start, br_off size);
+
+/****************************************************************************
+traverse the whole database with this function, calling traverse_callback
+on each lock
+****************************************************************************/
+static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
+{
+ struct lock_struct *locks;
+ struct lock_key *key;
+ int i;
+
+ locks = (struct lock_struct *)dbuf.dptr;
+ key = (struct lock_key *)kbuf.dptr;
+
+ for (i=0;i<dbuf.dsize/sizeof(*locks);i++) {
+ traverse_callback(key->device, key->inode,
+ locks[i].context.pid,
+ locks[i].lock_type,
+ locks[i].start,
+ locks[i].size);
+ }
+ return 0;
+}
+
+/*******************************************************************
+ Call the specified function on each lock in the database
+********************************************************************/
+int brl_forall(void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, int pid,
+ enum brl_type lock_type,
+ br_off start, br_off size))
+{
+ if (!tdb) return 0;
+ traverse_callback = fn;
+ return tdb_traverse(tdb, traverse_fn);
+}
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 5348659917..9753b5ea61 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -145,7 +145,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn,
****************************************************************************/
BOOL locking_init(int read_only)
{
- brl_init();
+ brl_init(read_only);
if (tdb) return True;
diff --git a/source3/utils/status.c b/source3/utils/status.c
index 3082402d8b..c7e52d1834 100644
--- a/source3/utils/status.c
+++ b/source3/utils/status.c
@@ -55,6 +55,7 @@ static int verbose, brief;
static int shares_only = 0; /* Added by RJS */
static int locks_only = 0; /* Added by RJS */
static BOOL processes_only=False;
+static int show_brl;
/* we need these because we link to locking*.o */
void become_root(BOOL save_dir) {}
@@ -113,6 +114,8 @@ static void print_share_mode(share_mode_entry *e, char *fname)
case DENY_DOS: printf("DENY_DOS "); break;
case DENY_READ: printf("DENY_READ "); break;
case DENY_WRITE:printf("DENY_WRITE "); break;
+ case 0xFF:
+ case DENY_FCB: printf("DENY_FCB "); break;
}
switch (e->share_mode&0xF) {
case 0: printf("RDONLY "); break;
@@ -138,6 +141,24 @@ static void print_share_mode(share_mode_entry *e, char *fname)
}
}
+static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, int pid,
+ enum brl_type lock_type,
+ br_off start, br_off size)
+{
+ static int count;
+ if (count==0) {
+ printf("Byte range locks:\n");
+ printf(" Pid dev:inode R/W start size\n");
+ printf("------------------------------------------------\n");
+ }
+ count++;
+
+ printf("%6d %05x:%05x %s %9.0f %9.0f\n",
+ (int)pid, (int)dev, (int)ino,
+ lock_type==READ_LOCK?"R":"W",
+ (double)start, (double)size);
+}
+
/*******************************************************************
dump the elements of the profile structure
@@ -238,11 +259,14 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
return(1);
}
- while ((c = getopt(argc, argv, "pdLSs:u:bP")) != EOF) {
+ while ((c = getopt(argc, argv, "pdLSs:u:bPB")) != EOF) {
switch (c) {
case 'b':
brief = 1;
break;
+ case 'B':
+ show_brl = 1;
+ break;
case 'd':
verbose = 1;
break;
@@ -340,6 +364,10 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
}
printf("\n");
+
+ if (show_brl) {
+ brl_forall(print_brl);
+ }
locking_end();
}