/*
* 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 .
*/
#include "includes.h"
#include "onefs_config.h"
#include
#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)
{
if ((pvfs_share_config != NULL) &&
(pvfs_share_config[snum].init_flags & config_type))
*cfg = pvfs_share_config[snum];
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) {
DEBUG(0, ("Setting process encoding failed: %s\n",
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 "
"failed: %s\n", strerror(errno)));
}
}
/**
* 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) {
DEBUG(0, ("Setting snapshot tilde failed: %s\n",
strerror(errno)));
}
}