s3 OneFS: Add .snapshot directory configuration handling
[ira/wip.git] / source3 / modules / vfs_onefs.c
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);
 }