diff options
Diffstat (limited to 'source3/modules')
-rw-r--r-- | source3/modules/gpfs.c | 6 | ||||
-rw-r--r-- | source3/modules/onefs.h | 110 | ||||
-rw-r--r-- | source3/modules/onefs_acl.c | 21 | ||||
-rw-r--r-- | source3/modules/onefs_cbrl.c | 27 | ||||
-rw-r--r-- | source3/modules/onefs_config.c | 276 | ||||
-rw-r--r-- | source3/modules/onefs_config.h | 160 | ||||
-rw-r--r-- | source3/modules/onefs_dir.c | 2 | ||||
-rw-r--r-- | source3/modules/onefs_notify.c | 1 | ||||
-rw-r--r-- | source3/modules/onefs_open.c | 5 | ||||
-rw-r--r-- | source3/modules/onefs_streams.c | 28 | ||||
-rw-r--r-- | source3/modules/onefs_system.c | 22 | ||||
-rw-r--r-- | source3/modules/vfs_acl_tdb.c | 89 | ||||
-rw-r--r-- | source3/modules/vfs_acl_xattr.c | 12 | ||||
-rw-r--r-- | source3/modules/vfs_gpfs.c | 5 | ||||
-rw-r--r-- | source3/modules/vfs_onefs.c | 122 | ||||
-rw-r--r-- | source3/modules/vfs_streams_depot.c | 14 | ||||
-rw-r--r-- | source3/modules/vfs_streams_xattr.c | 15 |
17 files changed, 657 insertions, 258 deletions
diff --git a/source3/modules/gpfs.c b/source3/modules/gpfs.c index 16599005b9..9fc4524654 100644 --- a/source3/modules/gpfs.c +++ b/source3/modules/gpfs.c @@ -26,6 +26,7 @@ static bool gpfs_share_modes; static bool gpfs_leases; +static bool gpfs_getrealfilename; static int (*gpfs_set_share_fn)(int fd, unsigned int allow, unsigned int deny); static int (*gpfs_set_lease_fn)(int fd, unsigned int leaseType); @@ -139,7 +140,8 @@ int smbd_gpfs_putacl(char *pathname, int flags, void *acl) int smbd_gpfs_get_realfilename_path(char *pathname, char *filenamep, int *buflen) { - if (gpfs_get_realfilename_path_fn == NULL) { + if ((!gpfs_getrealfilename) + || (gpfs_get_realfilename_path_fn == NULL)) { errno = ENOSYS; return -1; } @@ -208,6 +210,8 @@ void init_gpfs(void) gpfs_share_modes = lp_parm_bool(-1, "gpfs", "sharemodes", True); gpfs_leases = lp_parm_bool(-1, "gpfs", "leases", True); + gpfs_getrealfilename = lp_parm_bool(-1, "gpfs", "getrealfilename", + True); return; } diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h index 418e13d9d2..ebeece40ad 100644 --- a/source3/modules/onefs.h +++ b/source3/modules/onefs.h @@ -21,112 +21,6 @@ #ifndef _ONEFS_H #define _ONEFS_H -#include "includes.h" -#include "oplock_onefs.h" -#include <sys/isi_acl.h> - -/* OneFS Module smb.conf parameters and defaults */ - -/** -* Specifies when ACLs presented to Windows should be canonicalized -* into the ordering which Explorer expects. -*/ -enum onefs_acl_wire_format -{ - ACL_FORMAT_RAW, /**< Never canonicalize */ - ACL_FORMAT_WINDOWS_SD, /**< Only canonicalize synthetic ACLs */ - ACL_FORMAT_ALWAYS /**< Always canonicalize */ -}; - -#define PARM_ONEFS_TYPE "onefs" -#define PARM_ACL_WIRE_FORMAT "acl wire format" -#define PARM_ACL_WIRE_FORMAT_DEFAULT ACL_FORMAT_WINDOWS_SD -#define PARM_ALLOW_EXECUTE_ALWAYS "allow execute always" -#define PARM_ALLOW_EXECUTE_ALWAYS_DEFAULT false -#define PARM_ATIME_NOW "atime now files" -#define PARM_ATIME_NOW_DEFAULT NULL -#define PARM_ATIME_STATIC "atime static files" -#define PARM_ATIME_STATIC_DEFAULT NULL -#define PARM_ATIME_SLOP "atime now slop" -#define PARM_ATIME_SLOP_DEFAULT 0 -#define PARM_ATOMIC_SENDFILE "atomic sendfile" -#define PARM_ATOMIC_SENDFILE_DEFAULT true -#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL "creator owner gets full control" -#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL_DEFAULT true -#define PARM_CTIME_NOW "ctime now files" -#define PARM_CTIME_NOW_DEFAULT NULL -#define PARM_CTIME_SLOP "ctime now slop" -#define PARM_CTIME_SLOP_DEFAULT 0 -#define PARM_IGNORE_SACLS "ignore sacls" -#define PARM_IGNORE_SACLS_DEFAULT false -#define PARM_MTIME_NOW "mtime now files" -#define PARM_MTIME_NOW_DEFAULT NULL -#define PARM_MTIME_STATIC "mtime static files" -#define PARM_MTIME_STATIC_DEFAULT NULL -#define PARM_MTIME_SLOP "mtime now slop" -#define PARM_MTIME_SLOP_DEFAULT 0 -#define PARM_USE_READDIRPLUS "use readdirplus" -#define PARM_USE_READDIRPLUS_DEFAULT true -#define PARM_SENDFILE_LARGE_READS "sendfile large reads" -#define PARM_SENDFILE_LARGE_READS_DEFAULT false -#define PARM_SENDFILE_SAFE "sendfile safe" -#define PARM_SENDFILE_SAFE_DEFAULT true -#define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE "simple file sharing compatibility mode" -#define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE_DEFAULT false -#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE "unmappable sids deny everyone" -#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE_DEFAULT false -#define PARM_UNMAPPABLE_SIDS_IGNORE "ignore unmappable sids" -#define PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT false -#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST "unmappable sids ignore list" -#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST_DEFAULT NULL - -#define IS_CTIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ - (cfg)->ctime_now_list,(conn)->case_sensitive)) -#define IS_MTIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ - (cfg)->mtime_now_list,(conn)->case_sensitive)) -#define IS_ATIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ - (cfg)->atime_now_list,(conn)->case_sensitive)) -#define IS_MTIME_STATIC_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ - (cfg)->mtime_static_list,(conn)->case_sensitive)) -#define IS_ATIME_STATIC_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ - (cfg)->atime_static_list,(conn)->case_sensitive)) - -/* - * Store some commonly evaluated parameters to avoid loadparm pain. - */ - -#define ONEFS_VFS_CONFIG_INITIALIZED 0x00010000 - -#define ONEFS_VFS_CONFIG_FAKETIMESTAMPS 0x00000001 - -struct onefs_vfs_config -{ - int32 init_flags; - - /* data for fake timestamps */ - int atime_slop; - int ctime_slop; - int mtime_slop; - - /* Per-share list of files to fake the create time for. */ - name_compare_entry *ctime_now_list; - - /* Per-share list of files to fake the modification time for. */ - name_compare_entry *mtime_now_list; - - /* Per-share list of files to fake the access time for. */ - name_compare_entry *atime_now_list; - - /* Per-share list of files to fake the modification time for. */ - name_compare_entry *mtime_static_list; - - /* The access time will equal the create time. */ - /* The modification time will equal the create time.*/ - - /* Per-share list of files to fake the access time for. */ - name_compare_entry *atime_static_list; -}; - /* * vfs interface handlers */ @@ -233,15 +127,13 @@ NTSTATUS onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, /* * Utility functions */ +struct ifs_security_descriptor; NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, struct ifs_security_descriptor *sd, int snum); NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname, char **pbase, char **pstream); -bool onefs_get_config(int snum, int config_type, - struct onefs_vfs_config *cfg); - int onefs_rdp_add_dir_state(connection_struct *conn, SMB_STRUCT_DIR *dirp); /* diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index 7bc4a1728f..6f23d608d4 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -19,10 +19,13 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "includes.h" #include "onefs.h" +#include "onefs_config.h" #include <isi_acl/isi_acl_util.h> #include <ifs/ifs_syscalls.h> +#include <sys/isi_acl.h> const struct enum_list enum_onefs_acl_wire_format[] = { {ACL_FORMAT_RAW, "No Format"}, @@ -273,9 +276,6 @@ onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl, if (aclu_initialize_acl(acl, aces, num_aces)) goto err_free; - if (aclu_initialize_acl(acl, aces, num_aces)) - goto err_free; - /* Currently aclu_initialize_acl should copy the aces over, allowing * us to immediately free */ free(aces); @@ -614,6 +614,8 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, bool fopened = false; NTSTATUS status = NT_STATUS_OK; + START_PROFILE(syscall_get_sd); + *ppdesc = NULL; DEBUG(5, ("Getting sd for file %s. security_info=%u\n", @@ -753,6 +755,9 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, DEBUG(5, ("Finished retrieving/canonicalizing SD!\n")); /* FALLTHROUGH */ out: + + END_PROFILE(syscall_get_sd); + if (alloced && sd) { if (new_aces_alloced && sd->dacl->aces) SAFE_FREE(sd->dacl->aces); @@ -888,18 +893,20 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) { struct ifs_security_descriptor sd = {}; - int fd; + int fd = -1; bool fopened = false; NTSTATUS status; + START_PROFILE(syscall_set_sd); + DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name )); status = onefs_samba_sd_to_sd(security_info_sent, psd, &sd, SNUM(handle->conn)); if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("SD initialization failure: %s", nt_errstr(status))); - return status; + DEBUG(3, ("SD initialization failure: %s\n", nt_errstr(status))); + goto out; } fd = fsp->fh->fd; @@ -938,6 +945,8 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, /* FALLTHROUGH */ out: + END_PROFILE(syscall_set_sd); + if (fopened) close(fd); diff --git a/source3/modules/onefs_cbrl.c b/source3/modules/onefs_cbrl.c index a860023764..7311e1961e 100644 --- a/source3/modules/onefs_cbrl.c +++ b/source3/modules/onefs_cbrl.c @@ -18,6 +18,7 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "includes.h" #include "onefs.h" #include <ifs/ifs_syscalls.h> @@ -255,6 +256,8 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, struct onefs_cbrl_blr_state *bs; NTSTATUS status; + START_PROFILE(syscall_brl_lock); + SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(plock->lock_type != UNLOCK_LOCK); @@ -301,10 +304,13 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, /* ASYNC still in progress: The process_* calls will keep * calling even if we haven't gotten the lock. Keep erroring * without calling ifs_cbrl, or getting/setting an id. */ - if (bs->state == ONEFS_CBRL_ASYNC) + if (bs->state == ONEFS_CBRL_ASYNC) { goto failure; - else if (bs->state == ONEFS_CBRL_ERROR) + } + else if (bs->state == ONEFS_CBRL_ERROR) { + END_PROFILE(syscall_brl_lock); return NT_STATUS_NO_MEMORY; + } SMB_ASSERT(bs->state == ONEFS_CBRL_NONE); async = true; @@ -343,6 +349,9 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, } failure: + + END_PROFILE(syscall_brl_lock); + /* Failure - error or async. */ plock->context.smbpid = (uint32) ONEFS_BLOCKING_PID; @@ -355,6 +364,9 @@ failure: return status; success: + + END_PROFILE(syscall_brl_lock); + /* Success. */ onefs_cbrl_enumerate_blq("onefs_brl_unlock_windows"); DEBUG(10, ("returning NT_STATUS_OK.\n")); @@ -371,6 +383,8 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle, int error; int fd = br_lck->fsp->fh->fd; + START_PROFILE(syscall_brl_unlock); + SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(plock->lock_type == UNLOCK_LOCK); @@ -378,6 +392,9 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle, error = ifs_cbrl(fd, CBRL_OP_UNLOCK, CBRL_NOTYPE, plock->start, plock->size, CBRL_NOTYPE, 0, plock->context.smbpid, plock->context.tid, plock->fnum); + + END_PROFILE(syscall_brl_unlock); + if (error) { DEBUG(10, ("returning false.\n")); return false; @@ -404,6 +421,8 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, int fd = br_lck->fsp->fh->fd; struct onefs_cbrl_blr_state *bs; + START_PROFILE(syscall_brl_cancel); + SMB_ASSERT(plock); SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(blr); @@ -416,6 +435,7 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, if (bs->state == ONEFS_CBRL_DONE) { /* No-op. */ DEBUG(10, ("State=DONE, returning true\n")); + END_PROFILE(syscall_brl_cancel); return true; } @@ -427,6 +447,9 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, error = ifs_cbrl(fd, CBRL_OP_CANCEL, CBRL_NOTYPE, plock->start, plock->size, CBRL_NOTYPE, bs->id, plock->context.smbpid, plock->context.tid, plock->fnum); + + END_PROFILE(syscall_brl_cancel); + if (error) { DEBUG(10, ("returning false\n")); bs->state = ONEFS_CBRL_ERROR; diff --git a/source3/modules/onefs_config.c b/source3/modules/onefs_config.c new file mode 100644 index 0000000000..06f4b16ac1 --- /dev/null +++ b/source3/modules/onefs_config.c @@ -0,0 +1,276 @@ +/* + * 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) +{ + if (vfs_share_config[snum].init_flags & config_type) + *cfg = vfs_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", + 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", 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", + strerror(errno))); + } +} diff --git a/source3/modules/onefs_config.h b/source3/modules/onefs_config.h new file mode 100644 index 0000000000..f0f48e6379 --- /dev/null +++ b/source3/modules/onefs_config.h @@ -0,0 +1,160 @@ +/* + * Unix SMB/CIFS implementation. + * OneFS vfs module configuration and defaults + * + * Copyright (C) Steven Danneman, 2008 + * 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/>. + */ + +#ifndef _ONEFS_CONFIG_H +#define _ONEFS_CONFIG_H + +/** +* Specifies when ACLs presented to Windows should be canonicalized +* into the ordering which Explorer expects. +*/ +enum onefs_acl_wire_format +{ + ACL_FORMAT_RAW, /**< Never canonicalize */ + ACL_FORMAT_WINDOWS_SD, /**< Only canonicalize synthetic ACLs */ + ACL_FORMAT_ALWAYS /**< Always canonicalize */ +}; + +#define PARM_ONEFS_TYPE "onefs" +#define PARM_ACL_WIRE_FORMAT "acl wire format" +#define PARM_ACL_WIRE_FORMAT_DEFAULT ACL_FORMAT_WINDOWS_SD +#define PARM_ALLOW_EXECUTE_ALWAYS "allow execute always" +#define PARM_ALLOW_EXECUTE_ALWAYS_DEFAULT false +#define PARM_ATIME_NOW "atime now files" +#define PARM_ATIME_NOW_DEFAULT NULL +#define PARM_ATIME_STATIC "atime static files" +#define PARM_ATIME_STATIC_DEFAULT NULL +#define PARM_ATIME_SLOP "atime now slop" +#define PARM_ATIME_SLOP_DEFAULT 0 +#define PARM_ATOMIC_SENDFILE "atomic sendfile" +#define PARM_ATOMIC_SENDFILE_DEFAULT true +#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL "creator owner gets full control" +#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL_DEFAULT true +#define PARM_CTIME_NOW "ctime now files" +#define PARM_CTIME_NOW_DEFAULT NULL +#define PARM_CTIME_SLOP "ctime now slop" +#define PARM_CTIME_SLOP_DEFAULT 0 +#define PARM_DOT_SNAP_CHILD_ACCESSIBLE "dot snap child accessible" +#define PARM_DOT_SNAP_CHILD_ACCESSIBLE_DEFAULT true +#define PARM_DOT_SNAP_CHILD_VISIBLE "dot snap child visible" +#define PARM_DOT_SNAP_CHILD_VISIBLE_DEFAULT false +#define PARM_DOT_SNAP_ROOT_ACCESSIBLE "dot snap root accessible" +#define PARM_DOT_SNAP_ROOT_ACCESSIBLE_DEFAULT true +#define PARM_DOT_SNAP_ROOT_VISIBLE "dot snap root visible" +#define PARM_DOT_SNAP_ROOT_VISIBLE_DEFAULT true +#define PARM_DOT_SNAP_TILDE "dot snap tilde" +#define PARM_DOT_SNAP_TILDE_DEFAULT true +#define PARM_IGNORE_SACLS "ignore sacls" +#define PARM_IGNORE_SACLS_DEFAULT false +#define PARM_IGNORE_STREAMS "ignore streams" +#define PARM_IGNORE_STREAMS_DEFAULT false +#define PARM_MTIME_NOW "mtime now files" +#define PARM_MTIME_NOW_DEFAULT NULL +#define PARM_MTIME_STATIC "mtime static files" +#define PARM_MTIME_STATIC_DEFAULT NULL +#define PARM_MTIME_SLOP "mtime now slop" +#define PARM_MTIME_SLOP_DEFAULT 0 +#define PARM_USE_READDIRPLUS "use readdirplus" +#define PARM_USE_READDIRPLUS_DEFAULT true +#define PARM_SENDFILE_LARGE_READS "sendfile large reads" +#define PARM_SENDFILE_LARGE_READS_DEFAULT false +#define PARM_SENDFILE_SAFE "sendfile safe" +#define PARM_SENDFILE_SAFE_DEFAULT true +#define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE "simple file sharing compatibility mode" +#define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE_DEFAULT false +#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE "unmappable sids deny everyone" +#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE_DEFAULT false +#define PARM_UNMAPPABLE_SIDS_IGNORE "ignore unmappable sids" +#define PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT false +#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST "unmappable sids ignore list" +#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST_DEFAULT NULL + +#define IS_CTIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ + (cfg)->ctime_now_list,(conn)->case_sensitive)) +#define IS_MTIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ + (cfg)->mtime_now_list,(conn)->case_sensitive)) +#define IS_ATIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ + (cfg)->atime_now_list,(conn)->case_sensitive)) +#define IS_MTIME_STATIC_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ + (cfg)->mtime_static_list,(conn)->case_sensitive)) +#define IS_ATIME_STATIC_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ + (cfg)->atime_static_list,(conn)->case_sensitive)) + +/* + * Store some commonly evaluated parameters to avoid loadparm pain. + */ + +#define ONEFS_VFS_CONFIG_INITIALIZED 0x00010000 + +#define ONEFS_VFS_CONFIG_FAKETIMESTAMPS 0x00000001 + +struct onefs_vfs_share_config +{ + uint32_t init_flags; + + /* data for fake timestamps */ + int atime_slop; + int ctime_slop; + int mtime_slop; + + /* Per-share list of files to fake the create time for. */ + name_compare_entry *ctime_now_list; + + /* Per-share list of files to fake the modification time for. */ + name_compare_entry *mtime_now_list; + + /* Per-share list of files to fake the access time for. */ + name_compare_entry *atime_now_list; + + /* Per-share list of files to fake the modification time for. */ + name_compare_entry *mtime_static_list; + + /* The access time will equal the create time. */ + /* The modification time will equal the create time.*/ + + /* Per-share list of files to fake the access time for. */ + name_compare_entry *atime_static_list; +}; + +struct onefs_vfs_global_config +{ + uint32_t init_flags; + + /* Snapshot options */ + bool dot_snap_child_accessible; + bool dot_snap_child_visible; + bool dot_snap_root_accessible; + bool dot_snap_root_visible; + bool dot_snap_tilde; +}; + +int onefs_load_config(connection_struct *conn); + +bool onefs_get_config(int snum, int config_type, + struct onefs_vfs_share_config *cfg); + +void onefs_sys_config_enc(void); + +void onefs_sys_config_snap_opt(struct onefs_vfs_global_config *global_config); + +void onefs_sys_config_tilde(struct onefs_vfs_global_config *global_config); + +#endif /* _ONEFS_CONFIG_H */ diff --git a/source3/modules/onefs_dir.c b/source3/modules/onefs_dir.c index 83622b2bcd..68a58b3bb2 100644 --- a/source3/modules/onefs_dir.c +++ b/source3/modules/onefs_dir.c @@ -19,7 +19,9 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "includes.h" #include "onefs.h" +#include "onefs_config.h" #include <ifs/ifs_syscalls.h> diff --git a/source3/modules/onefs_notify.c b/source3/modules/onefs_notify.c index 40f690876d..3455afd4ab 100644 --- a/source3/modules/onefs_notify.c +++ b/source3/modules/onefs_notify.c @@ -33,6 +33,7 @@ * CompletionFilter and WatchTree of open SMB requests, and return notify * events back to the proper SMB requests */ +#include "includes.h" #include "onefs.h" #include <ifs/ifs_types.h> diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index 382ecc60a3..d3ba0ac979 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -32,7 +32,10 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "includes.h" #include "onefs.h" +#include "onefs_config.h" +#include "oplock_onefs.h" #include "smbd/globals.h" extern const struct generic_mapping file_generic_mapping; @@ -193,7 +196,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp, &base, &stream); } /* It's a stream, so pass in the base_fd */ - if (stream != NULL) { + if ((conn->fs_capabilities & FILE_NAMED_STREAMS) && stream != NULL) { SMB_ASSERT(fsp->base_fsp); /* diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c index 9616ca48d5..05b36d7d3c 100644 --- a/source3/modules/onefs_streams.c +++ b/source3/modules/onefs_streams.c @@ -19,7 +19,10 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "includes.h" #include "onefs.h" +#include "onefs_config.h" + #include <sys/isi_enc.h> /* @@ -160,18 +163,26 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname, char *nbase = NULL; char *nsname = NULL; + START_PROFILE(syscall_rename_at); + frame = talloc_stackframe(); ret = onefs_is_stream(oldname, &obase, &osname, &old_is_stream); - if (ret) + if (ret) { + END_PROFILE(syscall_rename_at); return ret; + } ret = onefs_is_stream(newname, &nbase, &nsname, &new_is_stream); - if (ret) + if (ret) { + END_PROFILE(syscall_rename_at); return ret; + } if (!old_is_stream && !new_is_stream) { - return SMB_VFS_NEXT_RENAME(handle, oldname, newname); + ret = SMB_VFS_NEXT_RENAME(handle, oldname, newname); + END_PROFILE(syscall_rename_at); + return ret; } dir_fd = get_stream_dir_fd(handle->conn, obase, NULL); @@ -192,6 +203,8 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname, } done: + END_PROFILE(syscall_rename_at); + saved_errno = errno; if (dir_fd >= 0) { close(dir_fd); @@ -220,7 +233,7 @@ static void merge_stat(SMB_STRUCT_STAT *stream_sbuf, static void onefs_adjust_stat_time(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf) { - struct onefs_vfs_config cfg; + struct onefs_vfs_share_config cfg; struct timeval tv_now = {0, 0}; bool static_mtime = False; bool static_atime = False; @@ -658,6 +671,11 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle, state.streams = NULL; state.num_streams = 0; + if (lp_parm_bool(SNUM(handle->conn), PARM_ONEFS_TYPE, + PARM_IGNORE_STREAMS, PARM_IGNORE_STREAMS_DEFAULT)) { + goto out; + } + /* Add the default stream. */ if (S_ISREG(sbuf.st_mode)) { if (!add_one_stream(mem_ctx, @@ -689,7 +707,7 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle, return state.status; } } - + out: *num_streams = state.num_streams; *streams = state.streams; return NT_STATUS_OK; diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c index 76df006d82..b8b059bce9 100644 --- a/source3/modules/onefs_system.c +++ b/source3/modules/onefs_system.c @@ -18,10 +18,14 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "includes.h" #include "onefs.h" +#include "onefs_config.h" +#include "oplock_onefs.h" #include <ifs/ifs_syscalls.h> #include <isi_acl/isi_acl_util.h> +#include <sys/isi_acl.h> /* * Initialize the sm_lock struct before passing it to ifs_createfile. @@ -95,6 +99,8 @@ int onefs_sys_create_file(connection_struct *conn, uint32_t onefs_dos_attributes; struct ifs_createfile_flags cf_flags = CF_FLAGS_NONE; + START_PROFILE(syscall_createfile); + /* Setup security descriptor and get secinfo. */ if (sd != NULL) { NTSTATUS status; @@ -196,6 +202,7 @@ int onefs_sys_create_file(connection_struct *conn, } out: + END_PROFILE(syscall_createfile); aclu_free_sd(pifs_sd, false); return ret_fd; @@ -307,6 +314,8 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, bool atomic = false; ssize_t ret = 0; + START_PROFILE_BYTES(syscall_sendfile, count); + if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, PARM_ATOMIC_SENDFILE, PARM_ATOMIC_SENDFILE_DEFAULT)) { @@ -320,6 +329,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, /* If the sendfile wasn't atomic, we're done. */ if (!atomic) { DEBUG(10, ("non-atomic sendfile read %ul bytes", ret)); + END_PROFILE(syscall_sendfile); return ret; } @@ -391,6 +401,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, /* Handle case 1: short read -> truncated file. */ if (ret == 0) { + END_PROFILE(syscall_sendfile); return ret; } @@ -402,6 +413,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, PARM_SENDFILE_LARGE_READS_DEFAULT)) { DEBUG(3, ("Not attempting non-atomic large sendfile: " "%lu bytes\n", count)); + END_PROFILE(syscall_sendfile); return 0; } @@ -421,6 +433,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, DEBUG(1, ("error on non-atomic large sendfile " "(%lu bytes): %s\n", count, strerror(errno))); + END_PROFILE(syscall_sendfile); return ret; } @@ -439,9 +452,11 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, PARM_SENDFILE_SAFE, PARM_SENDFILE_SAFE_DEFAULT)) { + END_PROFILE(syscall_sendfile); return -1; } + END_PROFILE(syscall_sendfile); return ret; } @@ -455,6 +470,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, count, strerror(errno))); } + END_PROFILE(syscall_sendfile); return ret; } @@ -509,10 +525,13 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, off_t rbytes; off_t wbytes; + START_PROFILE_BYTES(syscall_recvfile, count); + DEBUG(10,("onefs_recvfile: from = %d, to = %d, offset=%llu, count = " "%lu\n", fromfd, tofd, offset, count)); if (count == 0) { + END_PROFILE(syscall_recvfile); return 0; } @@ -624,6 +643,9 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, ret = total_wbytes; out: + + END_PROFILE(syscall_recvfile); + /* Make sure we always try to drain the socket. */ if (!socket_drained && count - total_rbytes) { int saved_errno = errno; diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index 909de9d7c8..a77f6d60f4 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -186,20 +186,26 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, TDB_DATA data; struct file_id id; struct db_context *db; + int ret = -1; SMB_STRUCT_STAT sbuf; SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return NT_STATUS_INTERNAL_DB_CORRUPTION); if (fsp && fsp->fh->fd != -1) { - if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { - return map_nt_error_from_unix(errno); - } + ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (SMB_VFS_STAT(handle->conn, name, &sbuf) == -1) { - return map_nt_error_from_unix(errno); + if (fsp && fsp->posix_open) { + ret = SMB_VFS_LSTAT(handle->conn, name, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, name, &sbuf); } } + + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + id = vfs_file_id_from_sbuf(handle->conn, &sbuf); /* For backwards compatibility only store the dev/inode. */ @@ -270,6 +276,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, TDB_DATA data; struct db_context *db; struct db_record *rec; + int ret = -1; DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n", (unsigned int)pblob->length, fsp->fsp_name)); @@ -278,14 +285,19 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, return NT_STATUS_INTERNAL_DB_CORRUPTION); if (fsp->fh->fd != -1) { - if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { - return map_nt_error_from_unix(errno); - } + ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (SMB_VFS_STAT(handle->conn, fsp->fsp_name, &sbuf) == -1) { - return map_nt_error_from_unix(errno); + if (fsp->posix_open) { + ret = SMB_VFS_LSTAT(handle->conn, fsp->fsp_name, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, fsp->fsp_name, &sbuf); } } + + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + id = vfs_file_id_from_sbuf(handle->conn, &sbuf); /* For backwards compatibility only store the dev/inode. */ @@ -316,6 +328,7 @@ static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle, SMB_STRUCT_STAT sbuf; struct db_context *db; struct db_record *rec; + int ret = -1; DEBUG(10,("store_acl_blob_pathname: storing blob " "length %u on file %s\n", @@ -324,7 +337,13 @@ static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle, SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return NT_STATUS_INTERNAL_DB_CORRUPTION); - if (SMB_VFS_STAT(handle->conn, fname, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, fname, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, fname, &sbuf); + } + + if (ret == -1) { return map_nt_error_from_unix(errno); } @@ -494,7 +513,11 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); + if (fsp && fsp->posix_open) { + ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); + } } if (ret == -1) { return map_nt_error_from_unix(errno); @@ -583,11 +606,17 @@ static int unlink_acl_tdb(vfs_handle_struct *handle, const char *path) { SMB_STRUCT_STAT sbuf; struct db_context *db; - int ret; + int ret = -1; SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); - if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, path, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, path, &sbuf); + } + + if (ret == -1) { return -1; } @@ -626,11 +655,17 @@ static int rmdir_acl_tdb(vfs_handle_struct *handle, const char *path) SMB_STRUCT_STAT sbuf; struct db_context *db; - int ret; + int ret = -1; SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); - if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, path, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, path, &sbuf); + } + + if (ret == -1) { return -1; } @@ -728,7 +763,11 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp, return NT_STATUS_OK; } if (fsp->is_directory || fsp->fh->fd == -1) { - ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + if (fsp->posix_open) { + ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf); + } else { + ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + } } else { ret = SMB_VFS_FSTAT(fsp, &sbuf); } @@ -813,11 +852,17 @@ static int sys_acl_set_file_tdb(vfs_handle_struct *handle, { SMB_STRUCT_STAT sbuf; struct db_context *db; - int ret; + int ret = -1; SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); - if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, path, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, path, &sbuf); + } + + if (ret == -1) { return -1; } @@ -848,7 +893,11 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle, SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); if (fsp->is_directory || fsp->fh->fd == -1) { - ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + if (fsp->posix_open) { + ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf); + } else { + ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + } } else { ret = SMB_VFS_FSTAT(fsp, &sbuf); } diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index 7c78b506f0..49e4899879 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -381,7 +381,11 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); + if (fsp && fsp->posix_open) { + ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); + } } if (ret == -1) { return map_nt_error_from_unix(errno); @@ -559,7 +563,11 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, return NT_STATUS_OK; } if (fsp->is_directory || fsp->fh->fd == -1) { - ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + if (fsp->posix_open) { + ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf); + } else { + ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + } } else { ret = SMB_VFS_FSTAT(fsp, &sbuf); } diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 1d7cdba014..3c061ece79 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -96,6 +96,11 @@ static int vfs_gpfs_get_real_filename(struct vfs_handle_struct *handle, TALLOC_FREE(full_path); + if ((result == -1) && (errno == ENOSYS)) { + return SMB_VFS_NEXT_GET_REAL_FILENAME( + handle, path, name, mem_ctx, found_name); + } + if (result == -1) { DEBUG(10, ("smbd_gpfs_get_realfilename_path returned %s\n", strerror(errno))); diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c index 60c2c977a4..2ec6e069c3 100644 --- a/source3/modules/vfs_onefs.c +++ b/source3/modules/vfs_onefs.c @@ -20,122 +20,21 @@ #include "includes.h" #include "onefs.h" +#include "onefs_config.h" #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, - 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); -} - - -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); + int ret; - if (ret) + ret = onefs_load_config(handle->conn); + if (ret) { + DEBUG(3, ("Load config failed: %s\n", strerror(errno))); return ret; + } return SMB_VFS_NEXT_CONNECT(handle, service, user); } @@ -323,7 +222,14 @@ static int onefs_ntimes(vfs_handle_struct *handle, const char *fname, static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle) { - return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_NAMED_STREAMS; + uint32_t result = 0; + + if (!lp_parm_bool(SNUM(handle->conn), PARM_ONEFS_TYPE, + PARM_IGNORE_STREAMS, PARM_IGNORE_STREAMS_DEFAULT)) { + result |= FILE_NAMED_STREAMS; + } + + return result | SMB_VFS_NEXT_FS_CAPABILITIES(handle); } static vfs_op_tuple onefs_ops[] = { diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c index 9329be7a9c..023d2b9ec0 100644 --- a/source3/modules/vfs_streams_depot.c +++ b/source3/modules/vfs_streams_depot.c @@ -494,7 +494,13 @@ static int streams_depot_unlink(vfs_handle_struct *handle, const char *fname) * We potentially need to delete the per-inode streams directory */ - if (SMB_VFS_NEXT_STAT(handle, fname, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_NEXT_LSTAT(handle, fname, &sbuf); + } else { + ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf); + } + + if (ret == -1) { return -1; } @@ -678,7 +684,11 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle, if (is_ntfs_stream_name(fname)) { return NT_STATUS_INVALID_PARAMETER; } - ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf); + if (lp_posix_pathnames()) { + ret = SMB_VFS_NEXT_LSTAT(handle, fname, &sbuf); + } else { + ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf); + } } if (ret == -1) { diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index 77ffff5fb5..3d5478d7a2 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -135,6 +135,7 @@ static bool streams_xattr_recheck(struct stream_io *sio) static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf) { + int ret = -1; struct stream_io *io = (struct stream_io *) VFS_FETCH_FSP_EXTENSION(handle, fsp); @@ -148,7 +149,13 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp, return -1; } - if (SMB_VFS_STAT(handle->conn, io->base, sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, io->base, sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, io->base, sbuf); + } + + if (ret == -1) { return -1; } @@ -719,7 +726,11 @@ static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle, if (is_ntfs_stream_name(fname)) { return NT_STATUS_INVALID_PARAMETER; } - ret = SMB_VFS_STAT(handle->conn, fname, &sbuf); + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, fname, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, fname, &sbuf); + } } if (ret == -1) { |