diff -r -u reference/source/smbd/notify_hash.c samba-3.0.5rc1/source/smbd/notify_hash.c --- reference/source/smbd/notify_hash.c Fri Jul 9 03:06:11 2004 +++ samba-3.0.5rc1/source/smbd/notify_hash.c Mon Aug 2 18:04:28 2004 @@ -23,8 +23,8 @@ struct change_data { time_t last_check_time; /* time we last checked this entry */ - time_t modify_time; /* Info from the directory we're monitoring. */ - time_t status_time; /* Info from the directory we're monitoring. */ + timespec_t modify_time; /* Info from the directory we're monitoring. */ + timespec_t status_time; /* Info from the directory we're monitoring. */ time_t total_time; /* Total time of all directory entries - don't care if it wraps. */ unsigned int num_entries; /* Zero or the number of files in the directory. */ unsigned int mode_sum; @@ -31,6 +31,8 @@ unsigned char name_hash[16]; }; +#define TIMESPEC_NEQ(x, y) (((x).tv_sec != (y).tv_sec) || ((x).tv_nsec != (y).tv_nsec)) + /**************************************************************************** Create the hash we will use to determine if the contents changed. *****************************************************************************/ @@ -51,8 +53,8 @@ if(SMB_VFS_STAT(conn,path, &st) == -1) return False; - data->modify_time = st.st_mtime; - data->status_time = st.st_ctime; + data->modify_time = st.st_mtim; + data->status_time = st.st_ctim; if (old_data) { /* @@ -59,12 +61,25 @@ * Shortcut to avoid directory scan if the time * has changed - we always must return true then. */ - if (old_data->modify_time != data->modify_time || - old_data->status_time != data->status_time ) { + if (TIMESPEC_NEQ(old_data->modify_time, data->modify_time) || + TIMESPEC_NEQ(old_data->status_time, data->status_time) ) { return True; } } + /* If we are only looking at some combination of CHANGE_NAME and + * CHANGE_DIR_NAME, then we can determine this solely from the + * information in the directory entry. + * the {c,m}time tells us whether something was changed + * the nlinks field tells us whether a directory entry was changed. + */ + if (S_ISDIR(st.st_mode) && + (flags & ~(FILE_NOTIFY_CHANGE_FILE | FILE_NOTIFY_CHANGE_DIR_NAME)) == 0) + { + data->num_entries = st.st_nlink; + return True; + } + /* * If we are to watch for changes that are only stored * in inodes of files, not in the directory inode, we must @@ -170,8 +185,8 @@ } if (!notify_hash(conn, path, flags, &data2, data) || - data2.modify_time != data->modify_time || - data2.status_time != data->status_time || + TIMESPEC_NEQ(data2.modify_time, data->modify_time) || + TIMESPEC_NEQ(data2.status_time, data->status_time) || data2.total_time != data->total_time || data2.num_entries != data->num_entries || data2.mode_sum != data->mode_sum ||