From 5d070483acf527ca20910c83d4735e1f99c32e24 Mon Sep 17 00:00:00 2001 From: todd stecher Date: Thu, 29 Jan 2009 08:08:35 -0800 Subject: s3 OneFS: Fake Timestamps This checkin enables setting arbitrary timestamps on files matching the pattern stored in smb.conf. This was a customer request for a specific workflow. Changes include: 1) configuration state machine to avoid tons of string comparisons on each and every stat. 2) Code to adjust post-stat() times to match time now, or sloptime + time now. --- source3/modules/vfs_onefs.c | 114 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) (limited to 'source3/modules/vfs_onefs.c') diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c index e2f272aa11..1f11f691a4 100644 --- a/source3/modules/vfs_onefs.c +++ b/source3/modules/vfs_onefs.c @@ -24,6 +24,118 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS +#define ONEFS_DATA_FASTBUF 10 + +struct onefs_vfs_config share_config[ONEFS_DATA_FASTBUF]; +struct onefs_vfs_config *pshare_config; + +static void onefs_load_faketimestamp_config(struct vfs_handle_struct *handle, + struct onefs_vfs_config *cfg) +{ + const char **parm; + int snum = SNUM(handle->conn); + + parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_NOW, + NULL); + + if (parm) { + cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; + set_namearray(&cfg->atime_now_list,*parm); + } + + parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_CTIME_NOW, + NULL); + + if (parm) { + cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; + set_namearray(&cfg->ctime_now_list,*parm); + } + + parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_MTIME_NOW, + NULL); + + if (parm) { + cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; + set_namearray(&cfg->mtime_now_list,*parm); + } + + parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_STATIC, + NULL); + + if (parm) { + cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; + set_namearray(&cfg->atime_static_list,*parm); + } + + parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_MTIME_STATIC, + NULL); + + if (parm) { + cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; + set_namearray(&cfg->mtime_static_list,*parm); + } + + cfg->atime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_ATIME_SLOP,0); + cfg->ctime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_CTIME_SLOP,0); + cfg->mtime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_MTIME_SLOP,0); +} + + +static int onefs_load_config(struct vfs_handle_struct *handle) +{ + int snum = SNUM(handle->conn); + int share_count = lp_numservices(); + + if (!pshare_config) { + + if (share_count <= ONEFS_DATA_FASTBUF) + pshare_config = share_config; + else { + pshare_config = SMB_MALLOC_ARRAY(struct onefs_vfs_config, + share_count); + if (!pshare_config) { + errno = ENOMEM; + return -1; + } + + memset(pshare_config, 0, + (sizeof(struct onefs_vfs_config) * share_count)); + } + } + + if ((pshare_config[snum].init_flags & + ONEFS_VFS_CONFIG_INITIALIZED) == 0) { + pshare_config[snum].init_flags = + ONEFS_VFS_CONFIG_INITIALIZED; + onefs_load_faketimestamp_config(handle, + &pshare_config[snum]); + } + + return 0; +} + +bool onefs_get_config(int snum, int config_type, + struct onefs_vfs_config *cfg) +{ + if (share_config[snum].init_flags & config_type) + *cfg = share_config[snum]; + else + return false; + + return true; +} + +static int onefs_connect(struct vfs_handle_struct *handle, const char *service, + const char *user) +{ + int ret = onefs_load_config(handle); + + if (ret) + return ret; + + return SMB_VFS_NEXT_CONNECT(handle, service, user); +} + static int onefs_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) { @@ -130,6 +242,8 @@ static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle) } static vfs_op_tuple onefs_ops[] = { + {SMB_VFS_OP(onefs_connect), SMB_VFS_OP_CONNECT, + SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(onefs_fs_capabilities), SMB_VFS_OP_FS_CAPABILITIES, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(onefs_mkdir), SMB_VFS_OP_MKDIR, -- cgit