summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2006-05-12 23:10:01 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:16:59 -0500
commit2602e5fab165d426e3a87e0cdcf8f7c67596e501 (patch)
treec439136a6659e59f4b96688b48e802ac29915ccf
parentc8baac2fd6fc9c83d44b93ff03d543353de9593c (diff)
downloadsamba-2602e5fab165d426e3a87e0cdcf8f7c67596e501.tar.gz
samba-2602e5fab165d426e3a87e0cdcf8f7c67596e501.tar.bz2
samba-2602e5fab165d426e3a87e0cdcf8f7c67596e501.zip
r15555: Make "change notify timeout" a per-share parameter - used
when there's no kernel or FAM change notify. If set to zero this will turn off change notify for the share except when we ourselves change something (renames / deletes etc. ). Designed to help on large directory shares where a new changenotify is issued between each delete. This will be fixed correctly when we move to internal change notify (eg. back-port Samba4 changenotify). Jeremy. (This used to be commit 5a17bffbcd5082fde79c241468a0ff2b5903d540)
-rw-r--r--source3/param/loadparm.c8
-rw-r--r--source3/smbd/notify.c14
-rw-r--r--source3/smbd/notify_hash.c20
-rw-r--r--source3/smbd/service.c3
4 files changed, 37 insertions, 8 deletions
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index c4ef9ef3ea..695e7f1aac 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -220,7 +220,6 @@ typedef struct {
int lm_interval;
int announce_as; /* This is initialised in init_globals */
int machine_password_timeout;
- int change_notify_timeout;
int map_to_guest;
int oplock_break_wait_time;
int winbind_cache_time;
@@ -449,6 +448,7 @@ typedef struct {
int iAioReadSize;
int iAioWriteSize;
int iMap_readonly;
+ int ichange_notify_timeout;
param_opt_struct *param_opt;
char dummy[3]; /* for alignment */
@@ -587,6 +587,7 @@ static service sDefault = {
0, /* iAioReadSize */
0, /* iAioWriteSize */
MAP_READONLY_YES, /* iMap_readonly */
+ 60, /* ichange_notify_timeout = 1 minute default. */
NULL, /* Parametric options */
@@ -996,7 +997,7 @@ static struct parm_struct parm_table[] = {
{N_("Tuning Options"), P_SEP, P_SEPARATOR},
{"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, FLAG_ADVANCED},
+ {"change notify timeout", P_INTEGER, P_LOCAL, &sDefault.ichange_notify_timeout, NULL, NULL, FLAG_ADVANCED},
{"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED},
{"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
{"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED},
@@ -1507,7 +1508,6 @@ static void init_globals(BOOL first_time_only)
Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
- Globals.change_notify_timeout = 60; /* 1 minute default. */
Globals.bKernelChangeNotify = True; /* On if we have it. */
Globals.bFamChangeNotify = True; /* On if we have it. */
Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
@@ -1934,7 +1934,6 @@ static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
-FN_GLOBAL_INTEGER(lp_change_notify_timeout, &Globals.change_notify_timeout)
FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
@@ -2066,6 +2065,7 @@ FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
+FN_LOCAL_INTEGER(lp_change_notify_timeout, ichange_notify_timeout)
FN_LOCAL_CHAR(lp_magicchar, magic_char)
FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index b2d0fc3326..829ca3a736 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -135,7 +135,19 @@ void remove_pending_change_notify_requests_by_filename(files_struct *fsp, NTSTAT
}
/****************************************************************************
- Return true if there are pending change notifies.
+ Set the current change notify timeout to the lowest value across all service
+ values.
+****************************************************************************/
+
+void set_change_notify_timeout(int val)
+{
+ if (val > 0) {
+ cnotify->select_time = MIN(cnotify->select_time, val);
+ }
+}
+
+/****************************************************************************
+ Longest time to sleep for before doing a change notify scan.
****************************************************************************/
int change_notify_timeout(void)
diff --git a/source3/smbd/notify_hash.c b/source3/smbd/notify_hash.c
index a98a028fae..0787a3eec5 100644
--- a/source3/smbd/notify_hash.c
+++ b/source3/smbd/notify_hash.c
@@ -81,6 +81,11 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
return True;
}
+ if (lp_change_notify_timeout(SNUM(conn)) <= 0) {
+ /* It change notify timeout has been disabled, never scan the directory. */
+ return True;
+ }
+
/*
* If we are to watch for changes that are only stored
* in inodes of files, not in the directory inode, we must
@@ -179,9 +184,17 @@ static BOOL hash_check_notify(connection_struct *conn, uint16 vuid, char *path,
{
struct change_data *data = (struct change_data *)datap;
struct change_data data2;
+ int cnto = lp_change_notify_timeout(SNUM(conn));
+
+ if (t && cnto <= 0) {
+ /* Change notify turned off on this share.
+ * Only scan when (t==0) - we think something changed. */
+ return False;
+ }
- if (t && t < data->last_check_time + lp_change_notify_timeout())
+ if (t && t < data->last_check_time + cnto) {
return False;
+ }
if (!change_to_user(conn,vuid))
return True;
@@ -201,8 +214,9 @@ static BOOL hash_check_notify(connection_struct *conn, uint16 vuid, char *path,
return True;
}
- if (t)
+ if (t) {
data->last_check_time = t;
+ }
change_to_root_user();
@@ -229,7 +243,7 @@ struct cnotify_fns *hash_notify_init(void)
cnotify.register_notify = hash_register_notify;
cnotify.check_notify = hash_check_notify;
cnotify.remove_notify = hash_remove_notify;
- cnotify.select_time = lp_change_notify_timeout();
+ cnotify.select_time = 60; /* Start with 1 minute default. */
cnotify.notification_fd = -1;
return &cnotify;
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index ba87d0743d..7ca2380e0d 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -930,6 +930,9 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
dbgtext( "(pid %d)\n", (int)sys_getpid() );
}
+ /* Setup the minimum value for a change notify wait time (seconds). */
+ set_change_notify_timeout(lp_change_notify_timeout(snum));
+
/* we've finished with the user stuff - go back to root */
change_to_root_user();
return(conn);