s3 OneFS: Add .snapshot directory configuration handling
authorTim Prouty <tprouty@samba.org>
Mon, 23 Feb 2009 22:51:17 +0000 (14:51 -0800)
committerTim Prouty <tprouty@samba.org>
Wed, 25 Feb 2009 21:57:11 +0000 (13:57 -0800)
source3/modules/onefs.h
source3/modules/onefs_streams.c
source3/modules/onefs_system.c
source3/modules/vfs_onefs.c

index 418e13d9d2b8c8121118386417d38214fe3ed3a8..a0f4fe37dee0da4734ddc067355f91cd9c6ead8a 100644 (file)
@@ -57,6 +57,16 @@ enum onefs_acl_wire_format
 #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_MTIME_NOW         "mtime now files"
@@ -99,9 +109,9 @@ enum onefs_acl_wire_format
 
 #define ONEFS_VFS_CONFIG_FAKETIMESTAMPS        0x00000001
 
-struct onefs_vfs_config
+struct onefs_vfs_share_config
 {
-       int32 init_flags;
+       uint32_t init_flags;
 
        /* data for fake timestamps */
        int atime_slop;
@@ -127,6 +137,18 @@ struct onefs_vfs_config
        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;
+};
+
 /*
  * vfs interface handlers
  */
@@ -240,7 +262,7 @@ 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);
+                     struct onefs_vfs_share_config *cfg);
 
 int onefs_rdp_add_dir_state(connection_struct *conn, SMB_STRUCT_DIR *dirp);
 
@@ -269,4 +291,8 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd,
 ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset,
                           size_t count);
 
+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_H */
index 2dcd8891eb082a00aea275fa71273d369afe3bdb..6e2794399d8afe9fad4aec282c137f969a4c3e02 100644 (file)
@@ -230,7 +230,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;
index 518a3981545212de2d4bd6823a17ab9f7f468f12..43ebed8d443c3c7ccd23a86931415d22e32add8d 100644 (file)
@@ -656,3 +656,53 @@ out:
 
        return ret;
 }
+
+/**
+ * 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)));
+       }
+}
index 60c2c977a432e370fd6e64ad268e9a9e6408531c..f81134909f8329b6f80808a6415f617c32555ccb 100644 (file)
 
 #define ONEFS_DATA_FASTBUF     10
 
-struct onefs_vfs_config share_config[ONEFS_DATA_FASTBUF];
-struct onefs_vfs_config *pshare_config;
+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 vfs_handle_struct *handle,
-                                           struct onefs_vfs_config *cfg)
+static void onefs_load_faketimestamp_config(struct connection_struct *conn,
+                                           struct onefs_vfs_share_config *cfg)
 {
        const char **parm;
-       int snum = SNUM(handle->conn);
+       int snum = SNUM(conn);
 
        parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_NOW,
                                   PARM_ATIME_NOW_DEFAULT);
@@ -83,46 +83,141 @@ static void onefs_load_faketimestamp_config(struct vfs_handle_struct *handle,
                                      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;
+       }
 
-static int onefs_load_config(struct vfs_handle_struct *handle)
+       /* 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);
+       }
+}
+
+static int onefs_load_config(connection_struct *conn)
 {
-       int snum = SNUM(handle->conn);
+       int snum = SNUM(conn);
        int share_count = lp_numservices();
 
-       if (!pshare_config) {
+       /* Share config */
+       if (!pvfs_share_config) {
 
                if (share_count <= ONEFS_DATA_FASTBUF)
-                       pshare_config = share_config;
+                       pvfs_share_config = vfs_share_config;
                else {
-                       pshare_config =
-                           SMB_MALLOC_ARRAY(struct onefs_vfs_config,
+                       pvfs_share_config =
+                           SMB_MALLOC_ARRAY(struct onefs_vfs_share_config,
                                             share_count);
-                       if (!pshare_config) {
+                       if (!pvfs_share_config) {
                                errno = ENOMEM;
                                return -1;
                        }
 
-                       memset(pshare_config, 0,
-                           (sizeof(struct onefs_vfs_config) * share_count));
+                       memset(pvfs_share_config, 0,
+                           (sizeof(struct onefs_vfs_share_config) *
+                                   share_count));
                }
        }
 
-       if ((pshare_config[snum].init_flags &
+       if ((pvfs_share_config[snum].init_flags &
                ONEFS_VFS_CONFIG_INITIALIZED) == 0) {
-                       pshare_config[snum].init_flags =
+                       pvfs_share_config[snum].init_flags =
                            ONEFS_VFS_CONFIG_INITIALIZED;
-                       onefs_load_faketimestamp_config(handle,
-                                                       &pshare_config[snum]);
+                       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_config *cfg)
+                     struct onefs_vfs_share_config *cfg)
 {
-       if (share_config[snum].init_flags & config_type)
-               *cfg = share_config[snum];
+       if (vfs_share_config[snum].init_flags & config_type)
+               *cfg = vfs_share_config[snum];
        else
                return false;
 
@@ -132,10 +227,13 @@ bool onefs_get_config(int snum, int config_type,
 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);
 }