s3:vfs_fs_capabilities: fix a debug message
[amitay/samba.git] / source3 / modules / vfs_default.c
index 4368dcd7dad2d28ebb715995abb17605fa96c028..17237ac83fc516b7f7baca065a42277abaa63536 100644 (file)
@@ -90,15 +90,69 @@ static int vfswrap_statvfs(struct vfs_handle_struct *handle,  const char *path,
        return sys_statvfs(path, statbuf);
 }
 
-static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle)
+static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle,
+               enum timestamp_set_resolution *p_ts_res)
 {
+       connection_struct *conn = handle->conn;
+       uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
+       struct smb_filename *smb_fname_cpath = NULL;
+       NTSTATUS status;
+       int ret = -1;
+
 #if defined(DARWINOS)
        struct vfs_statvfs_struct statbuf;
        ZERO_STRUCT(statbuf);
-       sys_statvfs(handle->conn->connectpath, &statbuf);
-       return statbuf.FsCapabilities;
+       sys_statvfs(conn->connectpath, &statbuf);
+       caps = statbuf.FsCapabilities;
 #endif
-       return FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
+
+       *p_ts_res = TIMESTAMP_SET_SECONDS;
+
+       /* Work out what timestamp resolution we can
+        * use when setting a timestamp. */
+
+       status = create_synthetic_smb_fname(talloc_tos(),
+                               conn->connectpath,
+                               NULL,
+                               NULL,
+                               &smb_fname_cpath);
+       if (!NT_STATUS_IS_OK(status)) {
+               return caps;
+       }
+
+       ret = SMB_VFS_STAT(conn, smb_fname_cpath);
+       if (ret == -1) {
+               TALLOC_FREE(smb_fname_cpath);
+               return caps;
+       }
+
+       if (smb_fname_cpath->st.st_ex_mtime.tv_nsec ||
+                       smb_fname_cpath->st.st_ex_atime.tv_nsec ||
+                       smb_fname_cpath->st.st_ex_ctime.tv_nsec) {
+               /* If any of the normal UNIX directory timestamps
+                * have a non-zero tv_nsec component assume
+                * we might be able to set sub-second timestamps.
+                * See what filetime set primitives we have.
+                */
+#if defined(HAVE_UTIMENSAT)
+               *p_ts_res = TIMESTAMP_SET_NT_OR_BETTER;
+#elif defined(HAVE_UTIMES)
+               /* utimes allows msec timestamps to be set. */
+               *p_ts_res = TIMESTAMP_SET_MSEC;
+#elif defined(HAVE_UTIME)
+               /* utime only allows sec timestamps to be set. */
+               *p_ts_res = TIMESTAMP_SET_SECONDS;
+#endif
+
+               DEBUG(10,("vfswrap_fs_capabilities: timestamp "
+                       "resolution of %s "
+                       "available on share %s, directory %s\n",
+                       *p_ts_res == TIMESTAMP_SET_MSEC ? "msec" : "sec",
+                       lp_servicename(conn->params->service),
+                       conn->connectpath ));
+       }
+       TALLOC_FREE(smb_fname_cpath);
+       return caps;
 }
 
 /* Directory operations */
@@ -214,13 +268,21 @@ static void vfswrap_init_search_op(vfs_handle_struct *handle,
 
 /* File operations */
 
-static int vfswrap_open(vfs_handle_struct *handle,  const char *fname,
-       files_struct *fsp, int flags, mode_t mode)
+static int vfswrap_open(vfs_handle_struct *handle,
+                       struct smb_filename *smb_fname,
+                       files_struct *fsp, int flags, mode_t mode)
 {
-       int result;
+       int result = -1;
 
        START_PROFILE(syscall_open);
-       result = sys_open(fname, flags, mode);
+
+       if (smb_fname->stream_name) {
+               errno = ENOENT;
+               goto out;
+       }
+
+       result = sys_open(smb_fname->base_name, flags, mode);
+ out:
        END_PROFILE(syscall_open);
        return result;
 }
@@ -228,8 +290,7 @@ static int vfswrap_open(vfs_handle_struct *handle,  const char *fname,
 static NTSTATUS vfswrap_create_file(vfs_handle_struct *handle,
                                    struct smb_request *req,
                                    uint16_t root_dir_fid,
-                                   const char *fname,
-                                   uint32_t create_file_flags,
+                                   struct smb_filename *smb_fname,
                                    uint32_t access_mask,
                                    uint32_t share_access,
                                    uint32_t create_disposition,
@@ -240,15 +301,14 @@ static NTSTATUS vfswrap_create_file(vfs_handle_struct *handle,
                                    struct security_descriptor *sd,
                                    struct ea_list *ea_list,
                                    files_struct **result,
-                                   int *pinfo,
-                                   SMB_STRUCT_STAT *psbuf)
+                                   int *pinfo)
 {
-       return create_file_default(handle->conn, req, root_dir_fid, fname,
-                                  create_file_flags, access_mask, share_access,
+       return create_file_default(handle->conn, req, root_dir_fid, smb_fname,
+                                  access_mask, share_access,
                                   create_disposition, create_options,
                                   file_attributes, oplock_request,
-                                  allocation_size, sd, ea_list, result, pinfo,
-                                  psbuf);
+                                  allocation_size, sd, ea_list, result,
+                                  pinfo);
 }
 
 static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp)
@@ -504,17 +564,27 @@ static int copy_reg(const char *source, const char *dest)
        return -1;
 }
 
-static int vfswrap_rename(vfs_handle_struct *handle,  const char *oldname, const char *newname)
+static int vfswrap_rename(vfs_handle_struct *handle,
+                         const struct smb_filename *smb_fname_src,
+                         const struct smb_filename *smb_fname_dst)
 {
-       int result;
+       int result = -1;
 
        START_PROFILE(syscall_rename);
-       result = rename(oldname, newname);
+
+       if (smb_fname_src->stream_name || smb_fname_dst->stream_name) {
+               errno = ENOENT;
+               goto out;
+       }
+
+       result = rename(smb_fname_src->base_name, smb_fname_dst->base_name);
        if ((result == -1) && (errno == EXDEV)) {
                /* Rename across filesystems needed. */
-               result = copy_reg(oldname, newname);
+               result = copy_reg(smb_fname_src->base_name,
+                                 smb_fname_dst->base_name);
        }
 
+ out:
        END_PROFILE(syscall_rename);
        return result;
 }
@@ -533,12 +603,20 @@ static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp)
 #endif
 }
 
-static int vfswrap_stat(vfs_handle_struct *handle,  const char *fname, SMB_STRUCT_STAT *sbuf)
+static int vfswrap_stat(vfs_handle_struct *handle,
+                       struct smb_filename *smb_fname)
 {
-       int result;
+       int result = -1;
 
        START_PROFILE(syscall_stat);
-       result = sys_stat(fname, sbuf);
+
+       if (smb_fname->stream_name) {
+               errno = ENOENT;
+               goto out;
+       }
+
+       result = sys_stat(smb_fname->base_name, &smb_fname->st);
+ out:
        END_PROFILE(syscall_stat);
        return result;
 }
@@ -553,16 +631,35 @@ static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUC
        return result;
 }
 
-int vfswrap_lstat(vfs_handle_struct *handle,  const char *path, SMB_STRUCT_STAT *sbuf)
+static int vfswrap_lstat(vfs_handle_struct *handle,
+                        struct smb_filename *smb_fname)
 {
-       int result;
+       int result = -1;
 
        START_PROFILE(syscall_lstat);
-       result = sys_lstat(path, sbuf);
+
+       if (smb_fname->stream_name) {
+               errno = ENOENT;
+               goto out;
+       }
+
+       result = sys_lstat(smb_fname->base_name, &smb_fname->st);
+ out:
        END_PROFILE(syscall_lstat);
        return result;
 }
 
+static NTSTATUS vfswrap_translate_name(vfs_handle_struct *handle,
+                                      char **mapped_name,
+                                      enum vfs_translate_direction direction)
+{
+       /* Default behavior is a NOOP */
+
+       if (*mapped_name != NULL)
+               return NT_STATUS_OK;
+
+       return NT_STATUS_INVALID_PARAMETER;
+}
 /********************************************************************
  Given a stat buffer return the allocated size on disk, taking into
  account sparse files.
@@ -596,12 +693,20 @@ static uint64_t vfswrap_get_alloc_size(vfs_handle_struct *handle,
        return result;
 }
 
-static int vfswrap_unlink(vfs_handle_struct *handle,  const char *path)
+static int vfswrap_unlink(vfs_handle_struct *handle,
+                         const struct smb_filename *smb_fname)
 {
-       int result;
+       int result = -1;
 
        START_PROFILE(syscall_unlink);
-       result = unlink(path);
+
+       if (smb_fname->stream_name) {
+               errno = ENOENT;
+               goto out;
+       }
+       result = unlink(smb_fname->base_name);
+
+ out:
        END_PROFILE(syscall_unlink);
        return result;
 }
@@ -727,34 +832,75 @@ static char *vfswrap_getwd(vfs_handle_struct *handle,  char *path)
  system will support.
 **********************************************************************/
 
-static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path,
+static int vfswrap_ntimes(vfs_handle_struct *handle,
+                         const struct smb_filename *smb_fname,
                          struct smb_file_time *ft)
 {
-       int result;
+       int result = -1;
 
        START_PROFILE(syscall_ntimes);
-#if defined(HAVE_UTIMES)
+
+       if (smb_fname->stream_name) {
+               errno = ENOENT;
+               goto out;
+       }
+
+       if (null_timespec(ft->atime)) {
+               ft->atime= smb_fname->st.st_ex_atime;
+       }
+
+       if (null_timespec(ft->mtime)) {
+               ft->mtime = smb_fname->st.st_ex_mtime;
+       }
+
+       if (!null_timespec(ft->create_time) &&
+                       lp_store_create_time(SNUM(handle->conn))) {
+               set_create_timespec_ea(handle->conn,
+                               NULL,
+                               smb_fname,
+                               ft->create_time);
+       }
+
+       if ((timespec_compare(&ft->atime,
+                               &smb_fname->st.st_ex_atime) == 0) &&
+                       (timespec_compare(&ft->mtime,
+                               &smb_fname->st.st_ex_mtime) == 0)) {
+               return 0;
+       }
+
+#if defined(HAVE_UTIMENSAT)
+       if (ft != NULL) {
+               struct timespec ts[2];
+               ts[0] = ft->atime;
+               ts[1] = ft->mtime;
+               result = utimensat(AT_FDCWD, smb_fname->base_name, ts, 0);
+       } else {
+               result = utimensat(AT_FDCWD, smb_fname->base_name, NULL, 0);
+       }
+#elif defined(HAVE_UTIMES)
        if (ft != NULL) {
                struct timeval tv[2];
                tv[0] = convert_timespec_to_timeval(ft->atime);
                tv[1] = convert_timespec_to_timeval(ft->mtime);
-               result = utimes(path, tv);
+               result = utimes(smb_fname->base_name, tv);
        } else {
-               result = utimes(path, NULL);
+               result = utimes(smb_fname->base_name, NULL);
        }
 #elif defined(HAVE_UTIME)
        if (ft != NULL) {
                struct utimbuf times;
                times.actime = convert_timespec_to_time_t(ft->atime);
                times.modtime = convert_timespec_to_time_t(ft->mtime);
-               result = utime(path, &times);
+               result = utime(smb_fname->base_name, &times);
        } else {
-               result = utime(path, NULL);
+               result = utime(smb_fname->base_name, NULL);
        }
 #else
        errno = ENOSYS;
        result = -1;
 #endif
+
+ out:
        END_PROFILE(syscall_ntimes);
        return result;
 }
@@ -796,7 +942,9 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
                uint64_t space_avail;
                uint64_t bsize,dfree,dsize;
 
-               space_avail = get_dfree_info(fsp->conn,fsp->fsp_name,false,&bsize,&dfree,&dsize);
+               space_avail = get_dfree_info(fsp->conn,
+                                            fsp->fsp_name->base_name, false,
+                                            &bsize, &dfree, &dsize);
                /* space_avail is 1k blocks */
                if (space_avail == (uint64_t)-1 ||
                                ((uint64_t)space_to_write/1024 > space_avail) ) {
@@ -916,10 +1064,10 @@ static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, S
 }
 
 static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
-                               uint32 share_mode)
+                               uint32 share_mode, uint32 access_mask)
 {
        START_PROFILE(syscall_kernel_flock);
-       kernel_flock(fsp->fh->fd, share_mode);
+       kernel_flock(fsp->fh->fd, share_mode, access_mask);
        END_PROFILE(syscall_kernel_flock);
        return 0;
 }
@@ -1032,7 +1180,8 @@ static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
        return NT_STATUS_OK;
 }
 
-static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flags)
+static int vfswrap_chflags(vfs_handle_struct *handle, const char *path,
+                          unsigned int flags)
 {
 #ifdef HAVE_CHFLAGS
        return chflags(path, flags);
@@ -1043,7 +1192,7 @@ static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flag
 }
 
 static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
-                                            SMB_STRUCT_STAT *sbuf)
+                                            const SMB_STRUCT_STAT *sbuf)
 {
        struct file_id key;
 
@@ -1081,7 +1230,21 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
                ret = SMB_VFS_FSTAT(fsp, &sbuf);
        }
        else {
-               ret = SMB_VFS_STAT(handle->conn, fname, &sbuf);
+               struct smb_filename *smb_fname = NULL;
+               NTSTATUS status;
+
+               status = create_synthetic_smb_fname(talloc_tos(), fname, NULL,
+                                                   NULL, &smb_fname);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+               if (lp_posix_pathnames()) {
+                       ret = SMB_VFS_LSTAT(handle->conn, smb_fname);
+               } else {
+                       ret = SMB_VFS_STAT(handle->conn, smb_fname);
+               }
+               sbuf = smb_fname->st;
+               TALLOC_FREE(smb_fname);
        }
 
        if (ret == -1) {
@@ -1512,270 +1675,148 @@ static int vfswrap_set_offline(struct vfs_handle_struct *handle, const char *pat
        return -1;
 }
 
-static vfs_op_tuple vfs_default_ops[] = {
-
+static struct vfs_fn_pointers vfs_default_fns = {
        /* Disk operations */
 
-       {SMB_VFS_OP(vfswrap_connect),   SMB_VFS_OP_CONNECT,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_disconnect),        SMB_VFS_OP_DISCONNECT,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_disk_free), SMB_VFS_OP_DISK_FREE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_get_quota), SMB_VFS_OP_GET_QUOTA,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_set_quota), SMB_VFS_OP_SET_QUOTA,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_statvfs),   SMB_VFS_OP_STATVFS,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_fs_capabilities), SMB_VFS_OP_FS_CAPABILITIES,
-        SMB_VFS_LAYER_OPAQUE},
+       .connect_fn = vfswrap_connect,
+       .disconnect = vfswrap_disconnect,
+       .disk_free = vfswrap_disk_free,
+       .get_quota = vfswrap_get_quota,
+       .set_quota = vfswrap_set_quota,
+       .get_shadow_copy_data = vfswrap_get_shadow_copy_data,
+       .statvfs = vfswrap_statvfs,
+       .fs_capabilities = vfswrap_fs_capabilities,
 
        /* Directory operations */
 
-       {SMB_VFS_OP(vfswrap_opendir),   SMB_VFS_OP_OPENDIR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_readdir),   SMB_VFS_OP_READDIR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_seekdir),   SMB_VFS_OP_SEEKDIR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_telldir),   SMB_VFS_OP_TELLDIR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_rewinddir), SMB_VFS_OP_REWINDDIR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_mkdir),     SMB_VFS_OP_MKDIR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_rmdir),     SMB_VFS_OP_RMDIR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_closedir),  SMB_VFS_OP_CLOSEDIR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_init_search_op), SMB_VFS_OP_INIT_SEARCH_OP,
-        SMB_VFS_LAYER_OPAQUE},
+       .opendir = vfswrap_opendir,
+       .readdir = vfswrap_readdir,
+       .seekdir = vfswrap_seekdir,
+       .telldir = vfswrap_telldir,
+       .rewind_dir = vfswrap_rewinddir,
+       .mkdir = vfswrap_mkdir,
+       .rmdir = vfswrap_rmdir,
+       .closedir = vfswrap_closedir,
+       .init_search_op = vfswrap_init_search_op,
 
        /* File operations */
 
-       {SMB_VFS_OP(vfswrap_open),      SMB_VFS_OP_OPEN,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_create_file),       SMB_VFS_OP_CREATE_FILE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_close),     SMB_VFS_OP_CLOSE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_read),      SMB_VFS_OP_READ,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_pread),     SMB_VFS_OP_PREAD,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_write),     SMB_VFS_OP_WRITE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_pwrite),    SMB_VFS_OP_PWRITE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_lseek),     SMB_VFS_OP_LSEEK,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sendfile),  SMB_VFS_OP_SENDFILE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_recvfile),  SMB_VFS_OP_RECVFILE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_rename),    SMB_VFS_OP_RENAME,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_fsync),     SMB_VFS_OP_FSYNC,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_stat),      SMB_VFS_OP_STAT,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_fstat),     SMB_VFS_OP_FSTAT,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_lstat),     SMB_VFS_OP_LSTAT,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_get_alloc_size),    SMB_VFS_OP_GET_ALLOC_SIZE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_unlink),    SMB_VFS_OP_UNLINK,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_chmod),     SMB_VFS_OP_CHMOD,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_fchmod),    SMB_VFS_OP_FCHMOD,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_chown),     SMB_VFS_OP_CHOWN,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_fchown),    SMB_VFS_OP_FCHOWN,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_lchown),    SMB_VFS_OP_LCHOWN,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_chdir),     SMB_VFS_OP_CHDIR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_getwd),     SMB_VFS_OP_GETWD,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_ntimes),    SMB_VFS_OP_NTIMES,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_ftruncate), SMB_VFS_OP_FTRUNCATE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_lock),      SMB_VFS_OP_LOCK,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_kernel_flock),      SMB_VFS_OP_KERNEL_FLOCK,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_linux_setlease),    SMB_VFS_OP_LINUX_SETLEASE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_getlock),   SMB_VFS_OP_GETLOCK,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_symlink),   SMB_VFS_OP_SYMLINK,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_readlink),  SMB_VFS_OP_READLINK,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_link),      SMB_VFS_OP_LINK,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_mknod),     SMB_VFS_OP_MKNOD,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_realpath),  SMB_VFS_OP_REALPATH,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_notify_watch),      SMB_VFS_OP_NOTIFY_WATCH,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_chflags),   SMB_VFS_OP_CHFLAGS,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_file_id_create),    SMB_VFS_OP_FILE_ID_CREATE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_streaminfo),        SMB_VFS_OP_STREAMINFO,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_get_real_filename), SMB_VFS_OP_GET_REAL_FILENAME,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_connectpath),       SMB_VFS_OP_CONNECTPATH,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_brl_lock_windows),  SMB_VFS_OP_BRL_LOCK_WINDOWS,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_brl_unlock_windows),SMB_VFS_OP_BRL_UNLOCK_WINDOWS,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_brl_cancel_windows),SMB_VFS_OP_BRL_CANCEL_WINDOWS,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_strict_lock),       SMB_VFS_OP_STRICT_LOCK,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_strict_unlock),     SMB_VFS_OP_STRICT_UNLOCK,
-        SMB_VFS_LAYER_OPAQUE},
+       .open = vfswrap_open,
+       .create_file = vfswrap_create_file,
+       .close_fn = vfswrap_close,
+       .vfs_read = vfswrap_read,
+       .pread = vfswrap_pread,
+       .write = vfswrap_write,
+       .pwrite = vfswrap_pwrite,
+       .lseek = vfswrap_lseek,
+       .sendfile = vfswrap_sendfile,
+       .recvfile = vfswrap_recvfile,
+       .rename = vfswrap_rename,
+       .fsync = vfswrap_fsync,
+       .stat = vfswrap_stat,
+       .fstat = vfswrap_fstat,
+       .lstat = vfswrap_lstat,
+       .get_alloc_size = vfswrap_get_alloc_size,
+       .unlink = vfswrap_unlink,
+       .chmod = vfswrap_chmod,
+       .fchmod = vfswrap_fchmod,
+       .chown = vfswrap_chown,
+       .fchown = vfswrap_fchown,
+       .lchown = vfswrap_lchown,
+       .chdir = vfswrap_chdir,
+       .getwd = vfswrap_getwd,
+       .ntimes = vfswrap_ntimes,
+       .ftruncate = vfswrap_ftruncate,
+       .lock = vfswrap_lock,
+       .kernel_flock = vfswrap_kernel_flock,
+       .linux_setlease = vfswrap_linux_setlease,
+       .getlock = vfswrap_getlock,
+       .symlink = vfswrap_symlink,
+       .vfs_readlink = vfswrap_readlink,
+       .link = vfswrap_link,
+       .mknod = vfswrap_mknod,
+       .realpath = vfswrap_realpath,
+       .notify_watch = vfswrap_notify_watch,
+       .chflags = vfswrap_chflags,
+       .file_id_create = vfswrap_file_id_create,
+       .streaminfo = vfswrap_streaminfo,
+       .get_real_filename = vfswrap_get_real_filename,
+       .connectpath = vfswrap_connectpath,
+       .brl_lock_windows = vfswrap_brl_lock_windows,
+       .brl_unlock_windows = vfswrap_brl_unlock_windows,
+       .brl_cancel_windows = vfswrap_brl_cancel_windows,
+       .strict_lock = vfswrap_strict_lock,
+       .strict_unlock = vfswrap_strict_unlock,
+       .translate_name = vfswrap_translate_name,
 
        /* NT ACL operations. */
 
-       {SMB_VFS_OP(vfswrap_fget_nt_acl),       SMB_VFS_OP_FGET_NT_ACL,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_get_nt_acl),        SMB_VFS_OP_GET_NT_ACL,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_fset_nt_acl),       SMB_VFS_OP_FSET_NT_ACL,
-        SMB_VFS_LAYER_OPAQUE},
+       .fget_nt_acl = vfswrap_fget_nt_acl,
+       .get_nt_acl = vfswrap_get_nt_acl,
+       .fset_nt_acl = vfswrap_fset_nt_acl,
 
        /* POSIX ACL operations. */
 
-       {SMB_VFS_OP(vfswrap_chmod_acl), SMB_VFS_OP_CHMOD_ACL,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_fchmod_acl),        SMB_VFS_OP_FCHMOD_ACL,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_get_entry), SMB_VFS_OP_SYS_ACL_GET_ENTRY,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_get_tag_type),      SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_get_permset),       SMB_VFS_OP_SYS_ACL_GET_PERMSET,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_get_qualifier),     SMB_VFS_OP_SYS_ACL_GET_QUALIFIER,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_get_file),  SMB_VFS_OP_SYS_ACL_GET_FILE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_get_fd),    SMB_VFS_OP_SYS_ACL_GET_FD,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_clear_perms),       SMB_VFS_OP_SYS_ACL_CLEAR_PERMS,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_add_perm),  SMB_VFS_OP_SYS_ACL_ADD_PERM,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_to_text),   SMB_VFS_OP_SYS_ACL_TO_TEXT,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_init),      SMB_VFS_OP_SYS_ACL_INIT,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_create_entry),      SMB_VFS_OP_SYS_ACL_CREATE_ENTRY,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_set_tag_type),      SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_set_qualifier),     SMB_VFS_OP_SYS_ACL_SET_QUALIFIER,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_set_permset),       SMB_VFS_OP_SYS_ACL_SET_PERMSET,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_valid),     SMB_VFS_OP_SYS_ACL_VALID,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_set_file),  SMB_VFS_OP_SYS_ACL_SET_FILE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_set_fd),    SMB_VFS_OP_SYS_ACL_SET_FD,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_delete_def_file),   SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_get_perm),  SMB_VFS_OP_SYS_ACL_GET_PERM,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_free_text), SMB_VFS_OP_SYS_ACL_FREE_TEXT,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_free_acl),  SMB_VFS_OP_SYS_ACL_FREE_ACL,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_sys_acl_free_qualifier),    SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER,
-        SMB_VFS_LAYER_OPAQUE},
+       .chmod_acl = vfswrap_chmod_acl,
+       .fchmod_acl = vfswrap_fchmod_acl,
+
+       .sys_acl_get_entry = vfswrap_sys_acl_get_entry,
+       .sys_acl_get_tag_type = vfswrap_sys_acl_get_tag_type,
+       .sys_acl_get_permset = vfswrap_sys_acl_get_permset,
+       .sys_acl_get_qualifier = vfswrap_sys_acl_get_qualifier,
+       .sys_acl_get_file = vfswrap_sys_acl_get_file,
+       .sys_acl_get_fd = vfswrap_sys_acl_get_fd,
+       .sys_acl_clear_perms = vfswrap_sys_acl_clear_perms,
+       .sys_acl_add_perm = vfswrap_sys_acl_add_perm,
+       .sys_acl_to_text = vfswrap_sys_acl_to_text,
+       .sys_acl_init = vfswrap_sys_acl_init,
+       .sys_acl_create_entry = vfswrap_sys_acl_create_entry,
+       .sys_acl_set_tag_type = vfswrap_sys_acl_set_tag_type,
+       .sys_acl_set_qualifier = vfswrap_sys_acl_set_qualifier,
+       .sys_acl_set_permset = vfswrap_sys_acl_set_permset,
+       .sys_acl_valid = vfswrap_sys_acl_valid,
+       .sys_acl_set_file = vfswrap_sys_acl_set_file,
+       .sys_acl_set_fd = vfswrap_sys_acl_set_fd,
+       .sys_acl_delete_def_file = vfswrap_sys_acl_delete_def_file,
+       .sys_acl_get_perm = vfswrap_sys_acl_get_perm,
+       .sys_acl_free_text = vfswrap_sys_acl_free_text,
+       .sys_acl_free_acl = vfswrap_sys_acl_free_acl,
+       .sys_acl_free_qualifier = vfswrap_sys_acl_free_qualifier,
 
        /* EA operations. */
-
-       {SMB_VFS_OP(vfswrap_getxattr),  SMB_VFS_OP_GETXATTR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_lgetxattr), SMB_VFS_OP_LGETXATTR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_fgetxattr), SMB_VFS_OP_FGETXATTR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_listxattr), SMB_VFS_OP_LISTXATTR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_llistxattr),        SMB_VFS_OP_LLISTXATTR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_flistxattr),        SMB_VFS_OP_FLISTXATTR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_removexattr),       SMB_VFS_OP_REMOVEXATTR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_lremovexattr),      SMB_VFS_OP_LREMOVEXATTR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_fremovexattr),      SMB_VFS_OP_FREMOVEXATTR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_setxattr),  SMB_VFS_OP_SETXATTR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_lsetxattr), SMB_VFS_OP_LSETXATTR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_fsetxattr), SMB_VFS_OP_FSETXATTR,
-        SMB_VFS_LAYER_OPAQUE},
-
-       {SMB_VFS_OP(vfswrap_aio_read),  SMB_VFS_OP_AIO_READ,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_aio_write), SMB_VFS_OP_AIO_WRITE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_aio_return),        SMB_VFS_OP_AIO_RETURN,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_aio_cancel), SMB_VFS_OP_AIO_CANCEL,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_aio_error), SMB_VFS_OP_AIO_ERROR,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_aio_fsync), SMB_VFS_OP_AIO_FSYNC,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_aio_suspend),SMB_VFS_OP_AIO_SUSPEND,
-        SMB_VFS_LAYER_OPAQUE},
-
-       {SMB_VFS_OP(vfswrap_aio_force), SMB_VFS_OP_AIO_FORCE,
-        SMB_VFS_LAYER_OPAQUE},
-
-       {SMB_VFS_OP(vfswrap_is_offline),SMB_VFS_OP_IS_OFFLINE,
-        SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_set_offline),SMB_VFS_OP_SET_OFFLINE,
-        SMB_VFS_LAYER_OPAQUE},
-
-       /* Finish VFS operations definition */
-
-       {SMB_VFS_OP(NULL),              SMB_VFS_OP_NOOP,
-        SMB_VFS_LAYER_NOOP}
+       .getxattr = vfswrap_getxattr,
+       .lgetxattr = vfswrap_lgetxattr,
+       .fgetxattr = vfswrap_fgetxattr,
+       .listxattr = vfswrap_listxattr,
+       .llistxattr = vfswrap_llistxattr,
+       .flistxattr = vfswrap_flistxattr,
+       .removexattr = vfswrap_removexattr,
+       .lremovexattr = vfswrap_lremovexattr,
+       .fremovexattr = vfswrap_fremovexattr,
+       .setxattr = vfswrap_setxattr,
+       .lsetxattr = vfswrap_lsetxattr,
+       .fsetxattr = vfswrap_fsetxattr,
+
+       /* aio operations */
+       .aio_read = vfswrap_aio_read,
+       .aio_write = vfswrap_aio_write,
+       .aio_return_fn = vfswrap_aio_return,
+       .aio_cancel = vfswrap_aio_cancel,
+       .aio_error_fn = vfswrap_aio_error,
+       .aio_fsync = vfswrap_aio_fsync,
+       .aio_suspend = vfswrap_aio_suspend,
+       .aio_force = vfswrap_aio_force,
+
+       /* offline operations */
+       .is_offline = vfswrap_is_offline,
+       .set_offline = vfswrap_set_offline
 };
 
 NTSTATUS vfs_default_init(void);
 NTSTATUS vfs_default_init(void)
 {
-       unsigned int needed = SMB_VFS_OP_LAST + 1; /* convert from index to count */
-
-       if (ARRAY_SIZE(vfs_default_ops) != needed) {
-               DEBUG(0, ("%s: %u ops registered, but %u ops are required\n",
-                       DEFAULT_VFS_MODULE_NAME, (unsigned int)ARRAY_SIZE(vfs_default_ops), needed));
-               smb_panic("operation(s) missing from default VFS module");
-       }
-
        return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
-                               DEFAULT_VFS_MODULE_NAME, vfs_default_ops);
+                               DEFAULT_VFS_MODULE_NAME, &vfs_default_fns);
 }
+
+