2009-02-28 01:47:47 +03:00
/*
* Unix SMB / CIFS implementation .
* Support for OneFS
*
* Copyright ( C ) Todd Stecher , 2009
* Copyright ( C ) Tim Prouty , 2009
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "onefs_config.h"
# include <ifs/ifs_syscalls.h>
# define ONEFS_DATA_FASTBUF 10
struct onefs_vfs_share_config vfs_share_config [ ONEFS_DATA_FASTBUF ] ;
struct onefs_vfs_share_config * pvfs_share_config ;
static void onefs_load_faketimestamp_config ( struct connection_struct * conn ,
struct onefs_vfs_share_config * cfg )
{
const char * * parm ;
int snum = SNUM ( conn ) ;
parm = lp_parm_string_list ( snum , PARM_ONEFS_TYPE , PARM_ATIME_NOW ,
PARM_ATIME_NOW_DEFAULT ) ;
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 ,
PARM_CTIME_NOW_DEFAULT ) ;
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 ,
PARM_MTIME_NOW_DEFAULT ) ;
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 ,
PARM_ATIME_STATIC_DEFAULT ) ;
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 ,
PARM_MTIME_STATIC_DEFAULT ) ;
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 ,
PARM_ATIME_SLOP_DEFAULT ) ;
cfg - > ctime_slop = lp_parm_int ( snum , PARM_ONEFS_TYPE , PARM_CTIME_SLOP ,
PARM_CTIME_SLOP_DEFAULT ) ;
cfg - > mtime_slop = lp_parm_int ( snum , PARM_ONEFS_TYPE , PARM_MTIME_SLOP ,
PARM_MTIME_SLOP_DEFAULT ) ;
}
/**
* Set onefs - specific vfs global config parameters .
*
* Since changes in these parameters require calling syscalls , we only want to
* call them when the configuration actually changes .
*/
static void onefs_load_global_config ( connection_struct * conn )
{
static struct onefs_vfs_global_config global_config ;
bool dot_snap_child_accessible ;
bool dot_snap_child_visible ;
bool dot_snap_root_accessible ;
bool dot_snap_root_visible ;
bool dot_snap_tilde ;
bool reconfig_dso = false ;
bool reconfig_tilde = false ;
/* Check if this is the first time setting the config options. */
if ( ! ( global_config . init_flags & ONEFS_VFS_CONFIG_INITIALIZED ) ) {
global_config . init_flags | = ONEFS_VFS_CONFIG_INITIALIZED ;
/* Set process encoding */
onefs_sys_config_enc ( ) ;
reconfig_dso = true ;
reconfig_tilde = true ;
}
/* Get the dot snap options from the conf. */
dot_snap_child_accessible =
lp_parm_bool ( SNUM ( conn ) , PARM_ONEFS_TYPE ,
PARM_DOT_SNAP_CHILD_ACCESSIBLE ,
PARM_DOT_SNAP_CHILD_ACCESSIBLE_DEFAULT ) ;
dot_snap_child_visible =
lp_parm_bool ( SNUM ( conn ) , PARM_ONEFS_TYPE ,
PARM_DOT_SNAP_CHILD_VISIBLE ,
PARM_DOT_SNAP_CHILD_VISIBLE_DEFAULT ) ;
dot_snap_root_accessible =
lp_parm_bool ( SNUM ( conn ) , PARM_ONEFS_TYPE ,
PARM_DOT_SNAP_ROOT_ACCESSIBLE ,
PARM_DOT_SNAP_ROOT_ACCESSIBLE_DEFAULT ) ;
dot_snap_root_visible =
lp_parm_bool ( SNUM ( conn ) , PARM_ONEFS_TYPE ,
PARM_DOT_SNAP_ROOT_VISIBLE ,
PARM_DOT_SNAP_ROOT_VISIBLE_DEFAULT ) ;
dot_snap_tilde =
lp_parm_bool ( SNUM ( conn ) , PARM_ONEFS_TYPE ,
PARM_DOT_SNAP_TILDE ,
PARM_DOT_SNAP_TILDE_DEFAULT ) ;
/* Check if any of the dot snap options need updating. */
if ( dot_snap_child_accessible ! =
global_config . dot_snap_child_accessible ) {
global_config . dot_snap_child_accessible =
dot_snap_child_accessible ;
reconfig_dso = true ;
}
if ( dot_snap_child_visible ! =
global_config . dot_snap_child_visible ) {
global_config . dot_snap_child_visible =
dot_snap_child_visible ;
reconfig_dso = true ;
}
if ( dot_snap_root_accessible ! =
global_config . dot_snap_root_accessible ) {
global_config . dot_snap_root_accessible =
dot_snap_root_accessible ;
reconfig_dso = true ;
}
if ( dot_snap_root_visible ! =
global_config . dot_snap_root_visible ) {
global_config . dot_snap_root_visible =
dot_snap_root_visible ;
reconfig_dso = true ;
}
if ( dot_snap_tilde ! = global_config . dot_snap_tilde ) {
global_config . dot_snap_tilde = dot_snap_tilde ;
reconfig_tilde = true ;
}
/* If a dot snap option has changed update the process. */
if ( reconfig_dso ) {
onefs_sys_config_snap_opt ( & global_config ) ;
}
/* If the dot snap tilde option has changed update the process. */
if ( reconfig_tilde ) {
onefs_sys_config_tilde ( & global_config ) ;
}
}
int onefs_load_config ( connection_struct * conn )
{
int snum = SNUM ( conn ) ;
int share_count = lp_numservices ( ) ;
/* Share config */
if ( ! pvfs_share_config ) {
if ( share_count < = ONEFS_DATA_FASTBUF )
pvfs_share_config = vfs_share_config ;
else {
pvfs_share_config =
SMB_MALLOC_ARRAY ( struct onefs_vfs_share_config ,
share_count ) ;
if ( ! pvfs_share_config ) {
errno = ENOMEM ;
return - 1 ;
}
memset ( pvfs_share_config , 0 ,
( sizeof ( struct onefs_vfs_share_config ) *
share_count ) ) ;
}
}
if ( ( pvfs_share_config [ snum ] . init_flags &
ONEFS_VFS_CONFIG_INITIALIZED ) = = 0 ) {
pvfs_share_config [ snum ] . init_flags =
ONEFS_VFS_CONFIG_INITIALIZED ;
onefs_load_faketimestamp_config ( conn ,
& pvfs_share_config [ snum ] ) ;
}
/* Global config */
onefs_load_global_config ( conn ) ;
return 0 ;
}
bool onefs_get_config ( int snum , int config_type ,
struct onefs_vfs_share_config * cfg )
{
2009-06-16 00:16:07 +04:00
if ( ( pvfs_share_config ! = NULL ) & &
( pvfs_share_config [ snum ] . init_flags & config_type ) )
* cfg = pvfs_share_config [ snum ] ;
2009-02-28 01:47:47 +03:00
else
return false ;
return true ;
}
/**
* Set the per - process encoding , ignoring errors .
*/
void onefs_sys_config_enc ( void )
{
int ret ;
ret = enc_set_proc ( ENC_UTF8 ) ;
if ( ret ) {
2009-04-01 04:25:57 +04:00
DEBUG ( 0 , ( " Setting process encoding failed: %s \n " ,
2009-02-28 01:47:47 +03:00
strerror ( errno ) ) ) ;
}
}
/**
* Set the per - process . snpashot directory options , ignoring errors .
*/
void onefs_sys_config_snap_opt ( struct onefs_vfs_global_config * global_config )
{
struct ifs_dotsnap_options dso ;
int ret ;
dso . per_proc = 1 ;
dso . sub_accessible = global_config - > dot_snap_child_accessible ;
dso . sub_visible = global_config - > dot_snap_child_visible ;
dso . root_accessible = global_config - > dot_snap_root_accessible ;
dso . root_visible = global_config - > dot_snap_root_visible ;
ret = ifs_set_dotsnap_options ( & dso ) ;
if ( ret ) {
DEBUG ( 0 , ( " Setting snapshot visibility/accessibility "
2009-04-01 04:25:57 +04:00
" failed: %s \n " , strerror ( errno ) ) ) ;
2009-02-28 01:47:47 +03:00
}
}
/**
* Set the per - process flag saying whether or not to accept ~ snapshot
* as an alternative name for . snapshot directories .
*/
void onefs_sys_config_tilde ( struct onefs_vfs_global_config * global_config )
{
int ret ;
ret = ifs_tilde_snapshot ( global_config - > dot_snap_tilde ) ;
if ( ret ) {
2009-04-01 04:25:57 +04:00
DEBUG ( 0 , ( " Setting snapshot tilde failed: %s \n " ,
2009-02-28 01:47:47 +03:00
strerror ( errno ) ) ) ;
}
}