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 stat_extra se
;
158 char *full_name
= NULL
;
161 se
.se_version
= ESTAT_CURRENT_VERSION
;
162 se
.se_flags
= ESTAT_CASE_INSENSITIVE
| ESTAT_SYMLINK_NOFOLLOW
;
165 if (!(full_name
= talloc_asprintf(mem_ctx
, "%s/%s", path
, name
))) {
167 DEBUG(2, ("talloc_asprintf failed\n"));
173 if ((result
= estat(full_name
? full_name
: name
, &sb
, &se
)) != 0) {
174 DEBUG(2, ("error calling estat: %s\n", strerror(errno
)));
178 *found_name
= talloc_strdup(mem_ctx
, se
.se_realname
);
179 if (*found_name
== NULL
) {
186 TALLOC_FREE(full_name
);
190 static int onefs_ntimes(vfs_handle_struct
*handle
, const char *fname
,
191 struct smb_file_time
*ft
)
194 struct timespec times
[3];
196 if (!null_timespec(ft
->atime
)) {
198 times
[0] = ft
->atime
;
199 DEBUG(6,("**** onefs_ntimes: actime: %s.%d\n",
200 time_to_asc(convert_timespec_to_time_t(ft
->atime
)),
204 if (!null_timespec(ft
->mtime
)) {
206 times
[1] = ft
->mtime
;
207 DEBUG(6,("**** onefs_ntimes: modtime: %s.%d\n",
208 time_to_asc(convert_timespec_to_time_t(ft
->mtime
)),
212 if (!null_timespec(ft
->create_time
)) {
214 times
[2] = ft
->create_time
;
215 DEBUG(6,("**** onefs_ntimes: createtime: %s.%d\n",
216 time_to_asc(convert_timespec_to_time_t(ft
->create_time
)),
217 ft
->create_time
.tv_nsec
));
220 return onefs_vtimes_streams(handle
, fname
, flags
, times
);
223 static uint32_t onefs_fs_capabilities(struct vfs_handle_struct
*handle
)
227 if (!lp_parm_bool(SNUM(handle
->conn
), PARM_ONEFS_TYPE
,
228 PARM_IGNORE_STREAMS
, PARM_IGNORE_STREAMS_DEFAULT
)) {
229 result
|= FILE_NAMED_STREAMS
;
232 return result
| SMB_VFS_NEXT_FS_CAPABILITIES(handle
);
235 static vfs_op_tuple onefs_ops
[] = {
236 {SMB_VFS_OP(onefs_connect
), SMB_VFS_OP_CONNECT
,
237 SMB_VFS_LAYER_TRANSPARENT
},
238 {SMB_VFS_OP(onefs_fs_capabilities
), SMB_VFS_OP_FS_CAPABILITIES
,
239 SMB_VFS_LAYER_TRANSPARENT
},
240 {SMB_VFS_OP(onefs_opendir
), SMB_VFS_OP_OPENDIR
,
241 SMB_VFS_LAYER_TRANSPARENT
},
242 {SMB_VFS_OP(onefs_readdir
), SMB_VFS_OP_READDIR
,
243 SMB_VFS_LAYER_OPAQUE
},
244 {SMB_VFS_OP(onefs_seekdir
), SMB_VFS_OP_SEEKDIR
,
245 SMB_VFS_LAYER_OPAQUE
},
246 {SMB_VFS_OP(onefs_telldir
), SMB_VFS_OP_TELLDIR
,
247 SMB_VFS_LAYER_OPAQUE
},
248 {SMB_VFS_OP(onefs_rewinddir
), SMB_VFS_OP_REWINDDIR
,
249 SMB_VFS_LAYER_OPAQUE
},
250 {SMB_VFS_OP(onefs_mkdir
), SMB_VFS_OP_MKDIR
,
251 SMB_VFS_LAYER_OPAQUE
},
252 {SMB_VFS_OP(onefs_closedir
), SMB_VFS_OP_CLOSEDIR
,
253 SMB_VFS_LAYER_TRANSPARENT
},
254 {SMB_VFS_OP(onefs_init_search_op
), SMB_VFS_OP_INIT_SEARCH_OP
,
255 SMB_VFS_LAYER_OPAQUE
},
256 {SMB_VFS_OP(onefs_open
), SMB_VFS_OP_OPEN
,
257 SMB_VFS_LAYER_OPAQUE
},
258 {SMB_VFS_OP(onefs_create_file
), SMB_VFS_OP_CREATE_FILE
,
259 SMB_VFS_LAYER_OPAQUE
},
260 {SMB_VFS_OP(onefs_close
), SMB_VFS_OP_CLOSE
,
261 SMB_VFS_LAYER_TRANSPARENT
},
262 {SMB_VFS_OP(onefs_sendfile
), SMB_VFS_OP_SENDFILE
,
263 SMB_VFS_LAYER_OPAQUE
},
264 {SMB_VFS_OP(onefs_recvfile
), SMB_VFS_OP_RECVFILE
,
265 SMB_VFS_LAYER_OPAQUE
},
266 {SMB_VFS_OP(onefs_rename
), SMB_VFS_OP_RENAME
,
267 SMB_VFS_LAYER_TRANSPARENT
},
268 {SMB_VFS_OP(onefs_stat
), SMB_VFS_OP_STAT
,
269 SMB_VFS_LAYER_TRANSPARENT
},
270 {SMB_VFS_OP(onefs_fstat
), SMB_VFS_OP_FSTAT
,
271 SMB_VFS_LAYER_TRANSPARENT
},
272 {SMB_VFS_OP(onefs_lstat
), SMB_VFS_OP_LSTAT
,
273 SMB_VFS_LAYER_TRANSPARENT
},
274 {SMB_VFS_OP(onefs_get_alloc_size
), SMB_VFS_OP_GET_ALLOC_SIZE
,
275 SMB_VFS_LAYER_OPAQUE
},
276 {SMB_VFS_OP(onefs_unlink
), SMB_VFS_OP_UNLINK
,
277 SMB_VFS_LAYER_TRANSPARENT
},
278 {SMB_VFS_OP(onefs_ntimes
), SMB_VFS_OP_NTIMES
,
279 SMB_VFS_LAYER_OPAQUE
},
280 {SMB_VFS_OP(onefs_chflags
), SMB_VFS_OP_CHFLAGS
,
281 SMB_VFS_LAYER_TRANSPARENT
},
282 {SMB_VFS_OP(onefs_file_id_create
), SMB_VFS_OP_FILE_ID_CREATE
,
283 SMB_VFS_LAYER_OPAQUE
},
284 {SMB_VFS_OP(onefs_streaminfo
), SMB_VFS_OP_STREAMINFO
,
285 SMB_VFS_LAYER_OPAQUE
},
286 {SMB_VFS_OP(onefs_brl_lock_windows
), SMB_VFS_OP_BRL_LOCK_WINDOWS
,
287 SMB_VFS_LAYER_OPAQUE
},
288 {SMB_VFS_OP(onefs_brl_unlock_windows
), SMB_VFS_OP_BRL_UNLOCK_WINDOWS
,
289 SMB_VFS_LAYER_OPAQUE
},
290 {SMB_VFS_OP(onefs_brl_cancel_windows
), SMB_VFS_OP_BRL_CANCEL_WINDOWS
,
291 SMB_VFS_LAYER_OPAQUE
},
292 {SMB_VFS_OP(onefs_strict_lock
), SMB_VFS_OP_STRICT_LOCK
,
293 SMB_VFS_LAYER_OPAQUE
},
294 {SMB_VFS_OP(onefs_strict_unlock
), SMB_VFS_OP_STRICT_UNLOCK
,
295 SMB_VFS_LAYER_OPAQUE
},
296 {SMB_VFS_OP(onefs_notify_watch
), SMB_VFS_OP_NOTIFY_WATCH
,
297 SMB_VFS_LAYER_OPAQUE
},
298 {SMB_VFS_OP(onefs_fget_nt_acl
), SMB_VFS_OP_FGET_NT_ACL
,
299 SMB_VFS_LAYER_OPAQUE
},
300 {SMB_VFS_OP(onefs_get_nt_acl
), SMB_VFS_OP_GET_NT_ACL
,
301 SMB_VFS_LAYER_OPAQUE
},
302 {SMB_VFS_OP(onefs_fset_nt_acl
), SMB_VFS_OP_FSET_NT_ACL
,
303 SMB_VFS_LAYER_OPAQUE
},
304 {SMB_VFS_OP(onefs_statvfs
), SMB_VFS_OP_STATVFS
,
305 SMB_VFS_LAYER_OPAQUE
},
306 {SMB_VFS_OP(onefs_get_real_filename
), SMB_VFS_OP_GET_REAL_FILENAME
,
307 SMB_VFS_LAYER_OPAQUE
},
308 {SMB_VFS_OP(NULL
), SMB_VFS_OP_NOOP
, SMB_VFS_LAYER_NOOP
}
311 NTSTATUS
vfs_onefs_init(void)
313 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION
, "onefs",