From 2602e5fab165d426e3a87e0cdcf8f7c67596e501 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 12 May 2006 23:10:01 +0000 Subject: [PATCH] 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) --- source3/param/loadparm.c | 8 ++++---- source3/smbd/notify.c | 14 +++++++++++++- source3/smbd/notify_hash.c | 20 +++++++++++++++++--- source3/smbd/service.c | 3 +++ 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index c4ef9ef3ea5..695e7f1aacf 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 b2d0fc33262..829ca3a736d 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 a98a028fae0..0787a3eec5e 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 ba87d0743da..7ca2380e0d3 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); -- 2.11.4.GIT