2 * Unix SMB/CIFS implementation.
5 * Copyright (C) Tim Prouty, 2008
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "onefs_config.h"
26 #define DBGC_CLASS DBGC_VFS
28 static int onefs_connect(struct vfs_handle_struct
*handle
, const char *service
,
33 ret
= onefs_load_config(handle
->conn
);
35 DEBUG(3, ("Load config failed: %s\n", strerror(errno
)));
39 return SMB_VFS_NEXT_CONNECT(handle
, service
, user
);
42 static int onefs_mkdir(vfs_handle_struct
*handle
, const char *path
,
45 /* SMB_VFS_MKDIR should never be called in vfs_onefs */
47 return SMB_VFS_NEXT_MKDIR(handle
, path
, mode
);
50 static int onefs_open(vfs_handle_struct
*handle
, const char *fname
,
51 files_struct
*fsp
, int flags
, mode_t mode
)
53 /* SMB_VFS_OPEN should never be called in vfs_onefs */
55 return SMB_VFS_NEXT_OPEN(handle
, fname
, fsp
, flags
, mode
);
58 static ssize_t
onefs_sendfile(vfs_handle_struct
*handle
, int tofd
,
59 files_struct
*fromfsp
, const DATA_BLOB
*header
,
60 SMB_OFF_T offset
, size_t count
)
64 START_PROFILE_BYTES(syscall_sendfile
, count
);
65 result
= onefs_sys_sendfile(handle
->conn
, tofd
, fromfsp
->fh
->fd
,
66 header
, offset
, count
);
67 END_PROFILE(syscall_sendfile
);
71 static ssize_t
onefs_recvfile(vfs_handle_struct
*handle
, int fromfd
,
72 files_struct
*tofsp
, SMB_OFF_T offset
,
77 START_PROFILE_BYTES(syscall_recvfile
, count
);
78 result
= onefs_sys_recvfile(fromfd
, tofsp
->fh
->fd
, offset
, count
);
79 END_PROFILE(syscall_recvfile
);
83 static uint64_t onefs_get_alloc_size(struct vfs_handle_struct
*handle
,
85 const SMB_STRUCT_STAT
*sbuf
)
89 START_PROFILE(syscall_get_alloc_size
);
91 if(S_ISDIR(sbuf
->st_mode
)) {
96 /* Just use the file size since st_blocks is unreliable on OneFS. */
97 result
= get_file_size_stat(sbuf
);
99 if (fsp
&& fsp
->initial_allocation_size
)
100 result
= MAX(result
,fsp
->initial_allocation_size
);
102 result
= smb_roundup(handle
->conn
, result
);
105 END_PROFILE(syscall_get_alloc_size
);
109 static struct file_id
onefs_file_id_create(struct vfs_handle_struct
*handle
,
110 SMB_STRUCT_STAT
*sbuf
)
114 /* the ZERO_STRUCT ensures padding doesn't break using the key as a
118 key
.devid
= sbuf
->st_dev
;
119 key
.inode
= sbuf
->st_ino
;
120 key
.extid
= sbuf
->st_snapid
;
125 static int onefs_statvfs(vfs_handle_struct
*handle
, const char *path
,
126 vfs_statvfs_struct
*statbuf
)
128 struct statvfs statvfs_buf
;
131 DEBUG(5, ("Calling SMB_STAT_VFS \n"));
132 result
= statvfs(path
, &statvfs_buf
);
133 ZERO_STRUCTP(statbuf
);
136 statbuf
->OptimalTransferSize
= statvfs_buf
.f_iosize
;
137 statbuf
->BlockSize
= statvfs_buf
.f_bsize
;
138 statbuf
->TotalBlocks
= statvfs_buf
.f_blocks
;
139 statbuf
->BlocksAvail
= statvfs_buf
.f_bfree
;
140 statbuf
->UserBlocksAvail
= statvfs_buf
.f_bavail
;
141 statbuf
->TotalFileNodes
= statvfs_buf
.f_files
;
142 statbuf
->FreeFileNodes
= statvfs_buf
.f_ffree
;
143 statbuf
->FsIdentifier
=
144 (((uint64_t)statvfs_buf
.f_fsid
.val
[0]<<32) &
145 0xffffffff00000000LL
) |
146 (uint64_t)statvfs_buf
.f_fsid
.val
[1];
151 static int onefs_get_real_filename(vfs_handle_struct
*handle
, const char *path
,
152 const char *name
, TALLOC_CTX
*mem_ctx
,
156 struct connection_struct
*conn
= handle
->conn
;
157 struct stat_extra se
;
159 char *unmangled_name
= NULL
;
160 char *full_name
= NULL
;
162 /* First demangle the name if necessary. */
163 if (!conn
->case_sensitive
&& mangle_is_mangled(name
, conn
->params
) &&
164 mangle_lookup_name_from_8_3(mem_ctx
, name
, &unmangled_name
,
166 /* Name is now unmangled. */
167 name
= unmangled_name
;
170 /* Do the case insensitive stat. */
172 se
.se_version
= ESTAT_CURRENT_VERSION
;
173 se
.se_flags
= ESTAT_CASE_INSENSITIVE
| ESTAT_SYMLINK_NOFOLLOW
;
176 if (!(full_name
= talloc_asprintf(mem_ctx
, "%s/%s", path
, name
))) {
178 DEBUG(2, ("talloc_asprintf failed\n"));
184 if ((result
= estat(full_name
? full_name
: name
, &sb
, &se
)) != 0) {
185 DEBUG(2, ("error calling estat: %s\n", strerror(errno
)));
189 *found_name
= talloc_strdup(mem_ctx
, se
.se_realname
);
190 if (*found_name
== NULL
) {
197 TALLOC_FREE(full_name
);
198 TALLOC_FREE(unmangled_name
);
202 static int onefs_ntimes(vfs_handle_struct
*handle
, const char *fname
,
203 struct smb_file_time
*ft
)
206 struct timespec times
[3];
208 if (!null_timespec(ft
->atime
)) {
210 times
[0] = ft
->atime
;
211 DEBUG(6,("**** onefs_ntimes: actime: %s.%d\n",
212 time_to_asc(convert_timespec_to_time_t(ft
->atime
)),
216 if (!null_timespec(ft
->mtime
)) {
218 times
[1] = ft
->mtime
;
219 DEBUG(6,("**** onefs_ntimes: modtime: %s.%d\n",
220 time_to_asc(convert_timespec_to_time_t(ft
->mtime
)),
224 if (!null_timespec(ft
->create_time
)) {
226 times
[2] = ft
->create_time
;
227 DEBUG(6,("**** onefs_ntimes: createtime: %s.%d\n",
228 time_to_asc(convert_timespec_to_time_t(ft
->create_time
)),
229 ft
->create_time
.tv_nsec
));
232 return onefs_vtimes_streams(handle
, fname
, flags
, times
);
235 static uint32_t onefs_fs_capabilities(struct vfs_handle_struct
*handle
)
239 if (!lp_parm_bool(SNUM(handle
->conn
), PARM_ONEFS_TYPE
,
240 PARM_IGNORE_STREAMS
, PARM_IGNORE_STREAMS_DEFAULT
)) {
241 result
|= FILE_NAMED_STREAMS
;
244 return result
| SMB_VFS_NEXT_FS_CAPABILITIES(handle
);
247 static vfs_op_tuple onefs_ops
[] = {
248 {SMB_VFS_OP(onefs_connect
), SMB_VFS_OP_CONNECT
,
249 SMB_VFS_LAYER_TRANSPARENT
},
250 {SMB_VFS_OP(onefs_fs_capabilities
), SMB_VFS_OP_FS_CAPABILITIES
,
251 SMB_VFS_LAYER_TRANSPARENT
},
252 {SMB_VFS_OP(onefs_opendir
), SMB_VFS_OP_OPENDIR
,
253 SMB_VFS_LAYER_TRANSPARENT
},
254 {SMB_VFS_OP(onefs_readdir
), SMB_VFS_OP_READDIR
,
255 SMB_VFS_LAYER_OPAQUE
},
256 {SMB_VFS_OP(onefs_seekdir
), SMB_VFS_OP_SEEKDIR
,
257 SMB_VFS_LAYER_OPAQUE
},
258 {SMB_VFS_OP(onefs_telldir
), SMB_VFS_OP_TELLDIR
,
259 SMB_VFS_LAYER_OPAQUE
},
260 {SMB_VFS_OP(onefs_rewinddir
), SMB_VFS_OP_REWINDDIR
,
261 SMB_VFS_LAYER_OPAQUE
},
262 {SMB_VFS_OP(onefs_mkdir
), SMB_VFS_OP_MKDIR
,
263 SMB_VFS_LAYER_OPAQUE
},
264 {SMB_VFS_OP(onefs_closedir
), SMB_VFS_OP_CLOSEDIR
,
265 SMB_VFS_LAYER_TRANSPARENT
},
266 {SMB_VFS_OP(onefs_init_search_op
), SMB_VFS_OP_INIT_SEARCH_OP
,
267 SMB_VFS_LAYER_OPAQUE
},
268 {SMB_VFS_OP(onefs_open
), SMB_VFS_OP_OPEN
,
269 SMB_VFS_LAYER_OPAQUE
},
270 {SMB_VFS_OP(onefs_create_file
), SMB_VFS_OP_CREATE_FILE
,
271 SMB_VFS_LAYER_OPAQUE
},
272 {SMB_VFS_OP(onefs_close
), SMB_VFS_OP_CLOSE
,
273 SMB_VFS_LAYER_TRANSPARENT
},
274 {SMB_VFS_OP(onefs_sendfile
), SMB_VFS_OP_SENDFILE
,
275 SMB_VFS_LAYER_OPAQUE
},
276 {SMB_VFS_OP(onefs_recvfile
), SMB_VFS_OP_RECVFILE
,
277 SMB_VFS_LAYER_OPAQUE
},
278 {SMB_VFS_OP(onefs_rename
), SMB_VFS_OP_RENAME
,
279 SMB_VFS_LAYER_TRANSPARENT
},
280 {SMB_VFS_OP(onefs_stat
), SMB_VFS_OP_STAT
,
281 SMB_VFS_LAYER_TRANSPARENT
},
282 {SMB_VFS_OP(onefs_fstat
), SMB_VFS_OP_FSTAT
,
283 SMB_VFS_LAYER_TRANSPARENT
},
284 {SMB_VFS_OP(onefs_lstat
), SMB_VFS_OP_LSTAT
,
285 SMB_VFS_LAYER_TRANSPARENT
},
286 {SMB_VFS_OP(onefs_get_alloc_size
), SMB_VFS_OP_GET_ALLOC_SIZE
,
287 SMB_VFS_LAYER_OPAQUE
},
288 {SMB_VFS_OP(onefs_unlink
), SMB_VFS_OP_UNLINK
,
289 SMB_VFS_LAYER_TRANSPARENT
},
290 {SMB_VFS_OP(onefs_ntimes
), SMB_VFS_OP_NTIMES
,
291 SMB_VFS_LAYER_OPAQUE
},
292 {SMB_VFS_OP(onefs_chflags
), SMB_VFS_OP_CHFLAGS
,
293 SMB_VFS_LAYER_TRANSPARENT
},
294 {SMB_VFS_OP(onefs_file_id_create
), SMB_VFS_OP_FILE_ID_CREATE
,
295 SMB_VFS_LAYER_OPAQUE
},
296 {SMB_VFS_OP(onefs_streaminfo
), SMB_VFS_OP_STREAMINFO
,
297 SMB_VFS_LAYER_OPAQUE
},
298 {SMB_VFS_OP(onefs_brl_lock_windows
), SMB_VFS_OP_BRL_LOCK_WINDOWS
,
299 SMB_VFS_LAYER_OPAQUE
},
300 {SMB_VFS_OP(onefs_brl_unlock_windows
), SMB_VFS_OP_BRL_UNLOCK_WINDOWS
,
301 SMB_VFS_LAYER_OPAQUE
},
302 {SMB_VFS_OP(onefs_brl_cancel_windows
), SMB_VFS_OP_BRL_CANCEL_WINDOWS
,
303 SMB_VFS_LAYER_OPAQUE
},
304 {SMB_VFS_OP(onefs_strict_lock
), SMB_VFS_OP_STRICT_LOCK
,
305 SMB_VFS_LAYER_OPAQUE
},
306 {SMB_VFS_OP(onefs_strict_unlock
), SMB_VFS_OP_STRICT_UNLOCK
,
307 SMB_VFS_LAYER_OPAQUE
},
308 {SMB_VFS_OP(onefs_notify_watch
), SMB_VFS_OP_NOTIFY_WATCH
,
309 SMB_VFS_LAYER_OPAQUE
},
310 {SMB_VFS_OP(onefs_fget_nt_acl
), SMB_VFS_OP_FGET_NT_ACL
,
311 SMB_VFS_LAYER_OPAQUE
},
312 {SMB_VFS_OP(onefs_get_nt_acl
), SMB_VFS_OP_GET_NT_ACL
,
313 SMB_VFS_LAYER_OPAQUE
},
314 {SMB_VFS_OP(onefs_fset_nt_acl
), SMB_VFS_OP_FSET_NT_ACL
,
315 SMB_VFS_LAYER_OPAQUE
},
316 {SMB_VFS_OP(onefs_statvfs
), SMB_VFS_OP_STATVFS
,
317 SMB_VFS_LAYER_OPAQUE
},
318 {SMB_VFS_OP(onefs_get_real_filename
), SMB_VFS_OP_GET_REAL_FILENAME
,
319 SMB_VFS_LAYER_OPAQUE
},
320 {SMB_VFS_OP(NULL
), SMB_VFS_OP_NOOP
, SMB_VFS_LAYER_NOOP
}
323 NTSTATUS
vfs_onefs_init(void)
325 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION
, "onefs",