diff options
-rw-r--r-- | source3/locking/brlock.c | 44 | ||||
-rw-r--r-- | source3/locking/locking.c | 2 | ||||
-rw-r--r-- | source3/utils/status.c | 30 |
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(); } |