source: vendor/current/source3/modules/vfs_ceph.c

Last change on this file was 989, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.7

File size: 36.7 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 Wrap disk only vfs functions to sidestep dodgy compilers.
4 Copyright (C) Tim Potter 1998
5 Copyright (C) Jeremy Allison 2007
6 Copyright (C) Brian Chrisman 2011 <bchrisman@gmail.com>
7 Copyright (C) Richard Sharpe 2011 <realrichardsharpe@gmail.com>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23/*
24 * This VFS only works with the libceph.so user-space client. It is not needed
25 * if you are using the kernel client or the FUSE client.
26 *
27 * Add the following smb.conf parameter to each share that will be hosted on
28 * Ceph:
29 *
30 * vfs objects = ceph [any others you need go here]
31 */
32
33#include "includes.h"
34#include "smbd/smbd.h"
35#include <dirent.h>
36#include <sys/statvfs.h>
37#include "cephfs/libcephfs.h"
38#include "smbprofile.h"
39
40#undef DBGC_CLASS
41#define DBGC_CLASS DBGC_VFS
42
43#ifndef LIBCEPHFS_VERSION
44#define LIBCEPHFS_VERSION(maj, min, extra) ((maj << 16) + (min << 8) + extra)
45#define LIBCEPHFS_VERSION_CODE LIBCEPHFS_VERSION(0, 0, 0)
46#endif
47
48/*
49 * Use %llu whenever we have a 64bit unsigned int, and cast to (long long unsigned)
50 */
51#define llu(_var) ((long long unsigned)_var)
52
53/*
54 * Note, libceph's return code model is to return -errno! So we have to convert
55 * to what Samba expects, with is set errno to -return and return -1
56 */
57#define WRAP_RETURN(_res) \
58 errno = 0; \
59 if (_res < 0) { \
60 errno = -_res; \
61 return -1; \
62 } \
63 return _res \
64
65/*
66 * We mount only one file system and then all shares are assumed to be in that.
67 * FIXME: If we want to support more than one FS, then we have to deal with
68 * this differently.
69 *
70 * So, cmount tells us if we have been this way before and whether
71 * we need to mount ceph and cmount_cnt tells us how many times we have
72 * connected
73 */
74static struct ceph_mount_info * cmount = NULL;
75static uint32_t cmount_cnt = 0;
76
77/* Check for NULL pointer parameters in cephwrap_* functions */
78
79/* We don't want to have NULL function pointers lying around. Someone
80 is sure to try and execute them. These stubs are used to prevent
81 this possibility. */
82
83static int cephwrap_connect(struct vfs_handle_struct *handle, const char *service, const char *user)
84{
85 int ret;
86 char buf[256];
87
88 const char * conf_file;
89
90 if (cmount) {
91 handle->data = cmount; /* We have been here before */
92 cmount_cnt++;
93 return 0;
94 }
95
96 conf_file = lp_parm_const_string(SNUM(handle->conn), "ceph", "config_file", NULL);
97
98 DEBUG(2, ( "[CEPH] calling: ceph_create\n" ));
99 ret = ceph_create(&cmount, NULL);
100 if (ret)
101 goto err_out;
102
103 if (conf_file) {
104 /* Override the config file */
105 DEBUG(2, ( "[CEPH] calling: ceph_conf_read_file\n" ));
106 ret = ceph_conf_read_file(cmount, conf_file);
107 } else {
108
109 DEBUG(2, ( "[CEPH] calling: ceph_conf_read_file with %s\n", conf_file));
110 ret = ceph_conf_read_file(cmount, NULL);
111 }
112
113 if (ret)
114 goto err_out;
115
116 DEBUG(2, ( "[CEPH] calling: ceph_conf_get\n" ));
117 ret = ceph_conf_get(cmount, "log file", buf, sizeof(buf));
118 if (ret < 0)
119 goto err_out;
120
121 DEBUG(2, ("[CEPH] calling: ceph_mount\n"));
122 ret = ceph_mount(cmount, NULL);
123 if (ret < 0)
124 goto err_out;
125
126
127 /*
128 * encode mount context/state into our vfs/connection holding structure
129 * cmount is a ceph_mount_t*
130 */
131 handle->data = cmount;
132 cmount_cnt++;
133
134 return 0;
135
136err_out:
137 /*
138 * Handle the error correctly. Ceph returns -errno.
139 */
140 DEBUG(2, ("[CEPH] Error return: %s\n", strerror(-ret)));
141 WRAP_RETURN(ret);
142}
143
144static void cephwrap_disconnect(struct vfs_handle_struct *handle)
145{
146 if (!cmount) {
147 DEBUG(0, ("[CEPH] Error, ceph not mounted\n"));
148 return;
149 }
150
151 /* Should we unmount/shutdown? Only if the last disconnect? */
152 if (--cmount_cnt) {
153 DEBUG(10, ("[CEPH] Not shuting down CEPH because still more connections\n"));
154 return;
155 }
156
157 ceph_shutdown(cmount);
158
159 cmount = NULL; /* Make it safe */
160}
161
162/* Disk operations */
163
164static uint64_t cephwrap_disk_free(struct vfs_handle_struct *handle,
165 const char *path, uint64_t *bsize,
166 uint64_t *dfree, uint64_t *dsize)
167{
168 struct statvfs statvfs_buf;
169 int ret;
170
171 if (!(ret = ceph_statfs(handle->data, path, &statvfs_buf))) {
172 /*
173 * Provide all the correct values.
174 */
175 *bsize = statvfs_buf.f_bsize;
176 *dfree = statvfs_buf.f_bavail;
177 *dsize = statvfs_buf.f_blocks;
178 DEBUG(10, ("[CEPH] bsize: %llu, dfree: %llu, dsize: %llu\n",
179 llu(*bsize), llu(*dfree), llu(*dsize)));
180 return *dfree;
181 } else {
182 DEBUG(10, ("[CEPH] ceph_statfs returned %d\n", ret));
183 WRAP_RETURN(ret);
184 }
185}
186
187static int cephwrap_get_quota(struct vfs_handle_struct *handle,
188 const char *path, enum SMB_QUOTA_TYPE qtype,
189 unid_t id, SMB_DISK_QUOTA *qt)
190{
191 /* libceph: Ceph does not implement this */
192#if 0
193/* was ifdef HAVE_SYS_QUOTAS */
194 int ret;
195
196 ret = ceph_get_quota(handle->conn->connectpath, qtype, id, qt);
197
198 if (ret) {
199 errno = -ret;
200 ret = -1;
201 }
202
203 return ret;
204#else
205 errno = ENOSYS;
206 return -1;
207#endif
208}
209
210static int cephwrap_set_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
211{
212 /* libceph: Ceph does not implement this */
213#if 0
214/* was ifdef HAVE_SYS_QUOTAS */
215 int ret;
216
217 ret = ceph_set_quota(handle->conn->connectpath, qtype, id, qt);
218 if (ret) {
219 errno = -ret;
220 ret = -1;
221 }
222
223 return ret;
224#else
225 WRAP_RETURN(-ENOSYS);
226#endif
227}
228
229static int cephwrap_statvfs(struct vfs_handle_struct *handle, const char *path, vfs_statvfs_struct *statbuf)
230{
231 struct statvfs statvfs_buf;
232 int ret;
233
234 ret = ceph_statfs(handle->data, path, &statvfs_buf);
235 if (ret < 0) {
236 WRAP_RETURN(ret);
237 } else {
238 statbuf->OptimalTransferSize = statvfs_buf.f_frsize;
239 statbuf->BlockSize = statvfs_buf.f_bsize;
240 statbuf->TotalBlocks = statvfs_buf.f_blocks;
241 statbuf->BlocksAvail = statvfs_buf.f_bfree;
242 statbuf->UserBlocksAvail = statvfs_buf.f_bavail;
243 statbuf->TotalFileNodes = statvfs_buf.f_files;
244 statbuf->FreeFileNodes = statvfs_buf.f_ffree;
245 statbuf->FsIdentifier = statvfs_buf.f_fsid;
246 DEBUG(10, ("[CEPH] f_bsize: %ld, f_blocks: %ld, f_bfree: %ld, f_bavail: %ld\n",
247 (long int)statvfs_buf.f_bsize, (long int)statvfs_buf.f_blocks,
248 (long int)statvfs_buf.f_bfree, (long int)statvfs_buf.f_bavail));
249 }
250 return ret;
251}
252
253/* Directory operations */
254
255static DIR *cephwrap_opendir(struct vfs_handle_struct *handle, const char *fname, const char *mask, uint32_t attr)
256{
257 int ret = 0;
258 struct ceph_dir_result *result;
259 DEBUG(10, ("[CEPH] opendir(%p, %s)\n", handle, fname));
260
261 /* Returns NULL if it does not exist or there are problems ? */
262 ret = ceph_opendir(handle->data, fname, &result);
263 if (ret < 0) {
264 result = NULL;
265 errno = -ret; /* We return result which is NULL in this case */
266 }
267
268 DEBUG(10, ("[CEPH] opendir(...) = %d\n", ret));
269 return (DIR *) result;
270}
271
272static DIR *cephwrap_fdopendir(struct vfs_handle_struct *handle,
273 struct files_struct *fsp,
274 const char *mask,
275 uint32_t attributes)
276{
277 int ret = 0;
278 struct ceph_dir_result *result;
279 DEBUG(10, ("[CEPH] fdopendir(%p, %p)\n", handle, fsp));
280
281 ret = ceph_opendir(handle->data, fsp->fsp_name->base_name, &result);
282 if (ret < 0) {
283 result = NULL;
284 errno = -ret; /* We return result which is NULL in this case */
285 }
286
287 DEBUG(10, ("[CEPH] fdopendir(...) = %d\n", ret));
288 return (DIR *) result;
289}
290
291static struct dirent *cephwrap_readdir(struct vfs_handle_struct *handle,
292 DIR *dirp,
293 SMB_STRUCT_STAT *sbuf)
294{
295 struct dirent *result;
296
297 DEBUG(10, ("[CEPH] readdir(%p, %p)\n", handle, dirp));
298 result = ceph_readdir(handle->data, (struct ceph_dir_result *) dirp);
299 DEBUG(10, ("[CEPH] readdir(...) = %p\n", result));
300
301 /* Default Posix readdir() does not give us stat info.
302 * Set to invalid to indicate we didn't return this info. */
303 if (sbuf)
304 SET_STAT_INVALID(*sbuf);
305 return result;
306}
307
308static void cephwrap_seekdir(struct vfs_handle_struct *handle, DIR *dirp, long offset)
309{
310 DEBUG(10, ("[CEPH] seekdir(%p, %p, %ld)\n", handle, dirp, offset));
311 ceph_seekdir(handle->data, (struct ceph_dir_result *) dirp, offset);
312}
313
314static long cephwrap_telldir(struct vfs_handle_struct *handle, DIR *dirp)
315{
316 long ret;
317 DEBUG(10, ("[CEPH] telldir(%p, %p)\n", handle, dirp));
318 ret = ceph_telldir(handle->data, (struct ceph_dir_result *) dirp);
319 DEBUG(10, ("[CEPH] telldir(...) = %ld\n", ret));
320 WRAP_RETURN(ret);
321}
322
323static void cephwrap_rewinddir(struct vfs_handle_struct *handle, DIR *dirp)
324{
325 DEBUG(10, ("[CEPH] rewinddir(%p, %p)\n", handle, dirp));
326 ceph_rewinddir(handle->data, (struct ceph_dir_result *) dirp);
327}
328
329static int cephwrap_mkdir(struct vfs_handle_struct *handle, const char *path, mode_t mode)
330{
331 int result;
332 bool has_dacl = False;
333 char *parent = NULL;
334
335 DEBUG(10, ("[CEPH] mkdir(%p, %s)\n", handle, path));
336
337 if (lp_inherit_acls(SNUM(handle->conn))
338 && parent_dirname(talloc_tos(), path, &parent, NULL)
339 && (has_dacl = directory_has_default_acl(handle->conn, parent)))
340 mode = 0777;
341
342 TALLOC_FREE(parent);
343
344 result = ceph_mkdir(handle->data, path, mode);
345
346 /*
347 * Note. This order is important
348 */
349 if (result) {
350 WRAP_RETURN(result);
351 } else if (result == 0 && !has_dacl) {
352 /*
353 * We need to do this as the default behavior of POSIX ACLs
354 * is to set the mask to be the requested group permission
355 * bits, not the group permission bits to be the requested
356 * group permission bits. This is not what we want, as it will
357 * mess up any inherited ACL bits that were set. JRA.
358 */
359 int saved_errno = errno; /* We may get ENOSYS */
360 if ((SMB_VFS_CHMOD_ACL(handle->conn, path, mode) == -1) && (errno == ENOSYS))
361 errno = saved_errno;
362 }
363
364 return result;
365}
366
367static int cephwrap_rmdir(struct vfs_handle_struct *handle, const char *path)
368{
369 int result;
370
371 DEBUG(10, ("[CEPH] rmdir(%p, %s)\n", handle, path));
372 result = ceph_rmdir(handle->data, path);
373 DEBUG(10, ("[CEPH] rmdir(...) = %d\n", result));
374 WRAP_RETURN(result);
375}
376
377static int cephwrap_closedir(struct vfs_handle_struct *handle, DIR *dirp)
378{
379 int result;
380
381 DEBUG(10, ("[CEPH] closedir(%p, %p)\n", handle, dirp));
382 result = ceph_closedir(handle->data, (struct ceph_dir_result *) dirp);
383 DEBUG(10, ("[CEPH] closedir(...) = %d\n", result));
384 WRAP_RETURN(result);
385}
386
387/* File operations */
388
389static int cephwrap_open(struct vfs_handle_struct *handle,
390 struct smb_filename *smb_fname,
391 files_struct *fsp, int flags, mode_t mode)
392{
393 int result = -ENOENT;
394 DEBUG(10, ("[CEPH] open(%p, %s, %p, %d, %d)\n", handle, smb_fname_str_dbg(smb_fname), fsp, flags, mode));
395
396 if (smb_fname->stream_name) {
397 goto out;
398 }
399
400 result = ceph_open(handle->data, smb_fname->base_name, flags, mode);
401out:
402 DEBUG(10, ("[CEPH] open(...) = %d\n", result));
403 WRAP_RETURN(result);
404}
405
406static int cephwrap_close(struct vfs_handle_struct *handle, files_struct *fsp)
407{
408 int result;
409
410 DEBUG(10, ("[CEPH] close(%p, %p)\n", handle, fsp));
411 result = ceph_close(handle->data, fsp->fh->fd);
412 DEBUG(10, ("[CEPH] close(...) = %d\n", result));
413
414 WRAP_RETURN(result);
415}
416
417static ssize_t cephwrap_read(struct vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n)
418{
419 ssize_t result;
420
421 DEBUG(10, ("[CEPH] read(%p, %p, %p, %llu)\n", handle, fsp, data, llu(n)));
422
423 /* Using -1 for the offset means read/write rather than pread/pwrite */
424 result = ceph_read(handle->data, fsp->fh->fd, data, n, -1);
425 DEBUG(10, ("[CEPH] read(...) = %llu\n", llu(result)));
426 WRAP_RETURN(result);
427}
428
429static ssize_t cephwrap_pread(struct vfs_handle_struct *handle, files_struct *fsp, void *data,
430 size_t n, off_t offset)
431{
432 ssize_t result;
433
434 DEBUG(10, ("[CEPH] pread(%p, %p, %p, %llu, %llu)\n", handle, fsp, data, llu(n), llu(offset)));
435
436 result = ceph_read(handle->data, fsp->fh->fd, data, n, offset);
437 DEBUG(10, ("[CEPH] pread(...) = %llu\n", llu(result)));
438 WRAP_RETURN(result);
439}
440
441
442static ssize_t cephwrap_write(struct vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n)
443{
444 ssize_t result;
445
446 DEBUG(10, ("[CEPH] write(%p, %p, %p, %llu)\n", handle, fsp, data, llu(n)));
447
448 result = ceph_write(handle->data, fsp->fh->fd, data, n, -1);
449
450 DEBUG(10, ("[CEPH] write(...) = %llu\n", llu(result)));
451 if (result < 0) {
452 WRAP_RETURN(result);
453 }
454 fsp->fh->pos += result;
455 return result;
456}
457
458static ssize_t cephwrap_pwrite(struct vfs_handle_struct *handle, files_struct *fsp, const void *data,
459 size_t n, off_t offset)
460{
461 ssize_t result;
462
463 DEBUG(10, ("[CEPH] pwrite(%p, %p, %p, %llu, %llu)\n", handle, fsp, data, llu(n), llu(offset)));
464 result = ceph_write(handle->data, fsp->fh->fd, data, n, offset);
465 DEBUG(10, ("[CEPH] pwrite(...) = %llu\n", llu(result)));
466 WRAP_RETURN(result);
467}
468
469static off_t cephwrap_lseek(struct vfs_handle_struct *handle, files_struct *fsp, off_t offset, int whence)
470{
471 off_t result = 0;
472
473 DEBUG(10, ("[CEPH] cephwrap_lseek\n"));
474 /* Cope with 'stat' file opens. */
475 if (fsp->fh->fd != -1) {
476 result = ceph_lseek(handle->data, fsp->fh->fd, offset, whence);
477 }
478 WRAP_RETURN(result);
479}
480
481static ssize_t cephwrap_sendfile(struct vfs_handle_struct *handle, int tofd, files_struct *fromfsp, const DATA_BLOB *hdr,
482 off_t offset, size_t n)
483{
484 /*
485 * We cannot support sendfile because libceph is in user space.
486 */
487 DEBUG(10, ("[CEPH] cephwrap_sendfile\n"));
488 errno = ENOTSUP;
489 return -1;
490}
491
492static ssize_t cephwrap_recvfile(struct vfs_handle_struct *handle,
493 int fromfd,
494 files_struct *tofsp,
495 off_t offset,
496 size_t n)
497{
498 /*
499 * We cannot support recvfile because libceph is in user space.
500 */
501 DEBUG(10, ("[CEPH] cephwrap_recvfile\n"));
502 errno=ENOTSUP;
503 return -1;
504}
505
506static int cephwrap_rename(struct vfs_handle_struct *handle,
507 const struct smb_filename *smb_fname_src,
508 const struct smb_filename *smb_fname_dst)
509{
510 int result = -1;
511 DEBUG(10, ("[CEPH] cephwrap_rename\n"));
512 if (smb_fname_src->stream_name || smb_fname_dst->stream_name) {
513 errno = ENOENT;
514 return result;
515 }
516
517 result = ceph_rename(handle->data, smb_fname_src->base_name, smb_fname_dst->base_name);
518 WRAP_RETURN(result);
519}
520
521static int cephwrap_fsync(struct vfs_handle_struct *handle, files_struct *fsp)
522{
523 int result;
524 DEBUG(10, ("[CEPH] cephwrap_fsync\n"));
525 result = ceph_fsync(handle->data, fsp->fh->fd, false);
526 WRAP_RETURN(result);
527}
528
529static int cephwrap_stat(struct vfs_handle_struct *handle,
530 struct smb_filename *smb_fname)
531{
532 int result = -1;
533 struct stat stbuf;
534
535 DEBUG(10, ("[CEPH] stat(%p, %s)\n", handle, smb_fname_str_dbg(smb_fname)));
536
537 if (smb_fname->stream_name) {
538 errno = ENOENT;
539 return result;
540 }
541
542 result = ceph_stat(handle->data, smb_fname->base_name, (struct stat *) &stbuf);
543 DEBUG(10, ("[CEPH] stat(...) = %d\n", result));
544 if (result < 0) {
545 WRAP_RETURN(result);
546 } else {
547 DEBUG(10, ("[CEPH]\tstbuf = {dev = %llu, ino = %llu, mode = 0x%x, nlink = %llu, "
548 "uid = %d, gid = %d, rdev = %llu, size = %llu, blksize = %llu, "
549 "blocks = %llu, atime = %llu, mtime = %llu, ctime = %llu}\n",
550 llu(stbuf.st_dev), llu(stbuf.st_ino), stbuf.st_mode, llu(stbuf.st_nlink),
551 stbuf.st_uid, stbuf.st_gid, llu(stbuf.st_rdev), llu(stbuf.st_size), llu(stbuf.st_blksize),
552 llu(stbuf.st_blocks), llu(stbuf.st_atime), llu(stbuf.st_mtime), llu(stbuf.st_ctime)));
553 }
554 init_stat_ex_from_stat(
555 &smb_fname->st, &stbuf,
556 lp_fake_directory_create_times(SNUM(handle->conn)));
557 DEBUG(10, ("[CEPH] mode = 0x%x\n", smb_fname->st.st_ex_mode));
558 return result;
559}
560
561static int cephwrap_fstat(struct vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
562{
563 int result = -1;
564 struct stat stbuf;
565
566 DEBUG(10, ("[CEPH] fstat(%p, %d)\n", handle, fsp->fh->fd));
567 result = ceph_fstat(handle->data, fsp->fh->fd, (struct stat *) &stbuf);
568 DEBUG(10, ("[CEPH] fstat(...) = %d\n", result));
569 if (result < 0) {
570 WRAP_RETURN(result);
571 } else {
572 DEBUG(10, ("[CEPH]\tstbuf = {dev = %llu, ino = %llu, mode = 0x%x, nlink = %llu, "
573 "uid = %d, gid = %d, rdev = %llu, size = %llu, blksize = %llu, "
574 "blocks = %llu, atime = %llu, mtime = %llu, ctime = %llu}\n",
575 llu(stbuf.st_dev), llu(stbuf.st_ino), stbuf.st_mode, llu(stbuf.st_nlink),
576 stbuf.st_uid, stbuf.st_gid, llu(stbuf.st_rdev), llu(stbuf.st_size), llu(stbuf.st_blksize),
577 llu(stbuf.st_blocks), llu(stbuf.st_atime), llu(stbuf.st_mtime), llu(stbuf.st_ctime)));
578 }
579
580 init_stat_ex_from_stat(
581 sbuf, &stbuf,
582 lp_fake_directory_create_times(SNUM(handle->conn)));
583 DEBUG(10, ("[CEPH] mode = 0x%x\n", sbuf->st_ex_mode));
584 return result;
585}
586
587static int cephwrap_lstat(struct vfs_handle_struct *handle,
588 struct smb_filename *smb_fname)
589{
590 int result = -1;
591 struct stat stbuf;
592
593 DEBUG(10, ("[CEPH] lstat(%p, %s)\n", handle, smb_fname_str_dbg(smb_fname)));
594
595 if (smb_fname->stream_name) {
596 errno = ENOENT;
597 return result;
598 }
599
600 result = ceph_lstat(handle->data, smb_fname->base_name, &stbuf);
601 DEBUG(10, ("[CEPH] lstat(...) = %d\n", result));
602 if (result < 0) {
603 WRAP_RETURN(result);
604 }
605 init_stat_ex_from_stat(
606 &smb_fname->st, &stbuf,
607 lp_fake_directory_create_times(SNUM(handle->conn)));
608 return result;
609}
610
611static int cephwrap_unlink(struct vfs_handle_struct *handle,
612 const struct smb_filename *smb_fname)
613{
614 int result = -1;
615
616 DEBUG(10, ("[CEPH] unlink(%p, %s)\n", handle, smb_fname_str_dbg(smb_fname)));
617 if (smb_fname->stream_name) {
618 errno = ENOENT;
619 return result;
620 }
621 result = ceph_unlink(handle->data, smb_fname->base_name);
622 DEBUG(10, ("[CEPH] unlink(...) = %d\n", result));
623 WRAP_RETURN(result);
624}
625
626static int cephwrap_chmod(struct vfs_handle_struct *handle, const char *path, mode_t mode)
627{
628 int result;
629
630 DEBUG(10, ("[CEPH] chmod(%p, %s, %d)\n", handle, path, mode));
631
632 /*
633 * We need to do this due to the fact that the default POSIX ACL
634 * chmod modifies the ACL *mask* for the group owner, not the
635 * group owner bits directly. JRA.
636 */
637
638
639 {
640 int saved_errno = errno; /* We might get ENOSYS */
641 if ((result = SMB_VFS_CHMOD_ACL(handle->conn, path, mode)) == 0) {
642 return result;
643 }
644 /* Error - return the old errno. */
645 errno = saved_errno;
646 }
647
648 result = ceph_chmod(handle->data, path, mode);
649 DEBUG(10, ("[CEPH] chmod(...) = %d\n", result));
650 WRAP_RETURN(result);
651}
652
653static int cephwrap_fchmod(struct vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
654{
655 int result;
656
657 DEBUG(10, ("[CEPH] fchmod(%p, %p, %d)\n", handle, fsp, mode));
658
659 /*
660 * We need to do this due to the fact that the default POSIX ACL
661 * chmod modifies the ACL *mask* for the group owner, not the
662 * group owner bits directly. JRA.
663 */
664
665 {
666 int saved_errno = errno; /* We might get ENOSYS */
667 if ((result = SMB_VFS_FCHMOD_ACL(fsp, mode)) == 0) {
668 return result;
669 }
670 /* Error - return the old errno. */
671 errno = saved_errno;
672 }
673
674#if defined(HAVE_FCHMOD)
675 result = ceph_fchmod(handle->data, fsp->fh->fd, mode);
676 DEBUG(10, ("[CEPH] fchmod(...) = %d\n", result));
677 WRAP_RETURN(result);
678#else
679 errno = ENOSYS;
680#endif
681 return -1;
682}
683
684static int cephwrap_chown(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
685{
686 int result;
687 DEBUG(10, ("[CEPH] chown(%p, %s, %d, %d)\n", handle, path, uid, gid));
688 result = ceph_chown(handle->data, path, uid, gid);
689 DEBUG(10, ("[CEPH] chown(...) = %d\n", result));
690 WRAP_RETURN(result);
691}
692
693static int cephwrap_fchown(struct vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid)
694{
695 int result;
696#ifdef HAVE_FCHOWN
697
698 DEBUG(10, ("[CEPH] fchown(%p, %p, %d, %d)\n", handle, fsp, uid, gid));
699 result = ceph_fchown(handle->data, fsp->fh->fd, uid, gid);
700 DEBUG(10, ("[CEPH] fchown(...) = %d\n", result));
701 WRAP_RETURN(result);
702#else
703 errno = ENOSYS;
704 result = -1;
705#endif
706 return result;
707}
708
709static int cephwrap_lchown(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
710{
711 int result;
712
713 DEBUG(10, ("[CEPH] lchown(%p, %s, %d, %d)\n", handle, path, uid, gid));
714 result = ceph_lchown(handle->data, path, uid, gid);
715 DEBUG(10, ("[CEPH] lchown(...) = %d\n", result));
716 WRAP_RETURN(result);
717}
718
719static int cephwrap_chdir(struct vfs_handle_struct *handle, const char *path)
720{
721 int result = -1;
722 DEBUG(10, ("[CEPH] chdir(%p, %s)\n", handle, path));
723 /*
724 * If the path is just / use chdir because Ceph is below / and
725 * cannot deal with changing directory above its mount point
726 */
727 if (path && !strcmp(path, "/"))
728 return chdir(path);
729
730 result = ceph_chdir(handle->data, path);
731 DEBUG(10, ("[CEPH] chdir(...) = %d\n", result));
732 WRAP_RETURN(result);
733}
734
735static char *cephwrap_getwd(struct vfs_handle_struct *handle)
736{
737 const char *cwd = ceph_getcwd(handle->data);
738 DEBUG(10, ("[CEPH] getwd(%p) = %s\n", handle, cwd));
739 return SMB_STRDUP(cwd);
740}
741
742static int cephwrap_ntimes(struct vfs_handle_struct *handle,
743 const struct smb_filename *smb_fname,
744 struct smb_file_time *ft)
745{
746 struct utimbuf buf;
747 int result;
748
749 if (null_timespec(ft->atime)) {
750 buf.actime = smb_fname->st.st_ex_atime.tv_sec;
751 } else {
752 buf.actime = ft->atime.tv_sec;
753 }
754 if (null_timespec(ft->mtime)) {
755 buf.modtime = smb_fname->st.st_ex_mtime.tv_sec;
756 } else {
757 buf.modtime = ft->mtime.tv_sec;
758 }
759 if (!null_timespec(ft->create_time)) {
760 set_create_timespec_ea(handle->conn, smb_fname,
761 ft->create_time);
762 }
763 if (buf.actime == smb_fname->st.st_ex_atime.tv_sec &&
764 buf.modtime == smb_fname->st.st_ex_mtime.tv_sec) {
765 return 0;
766 }
767
768 result = ceph_utime(handle->data, smb_fname->base_name, &buf);
769 DEBUG(10, ("[CEPH] ntimes(%p, %s, {%ld, %ld, %ld, %ld}) = %d\n", handle, smb_fname_str_dbg(smb_fname),
770 ft->mtime.tv_sec, ft->atime.tv_sec, ft->ctime.tv_sec,
771 ft->create_time.tv_sec, result));
772 return result;
773}
774
775static int strict_allocate_ftruncate(struct vfs_handle_struct *handle, files_struct *fsp, off_t len)
776{
777 off_t space_to_write;
778 uint64_t space_avail;
779 uint64_t bsize,dfree,dsize;
780 int ret;
781 NTSTATUS status;
782 SMB_STRUCT_STAT *pst;
783
784 status = vfs_stat_fsp(fsp);
785 if (!NT_STATUS_IS_OK(status)) {
786 return -1;
787 }
788 pst = &fsp->fsp_name->st;
789
790#ifdef S_ISFIFO
791 if (S_ISFIFO(pst->st_ex_mode))
792 return 0;
793#endif
794
795 if (pst->st_ex_size == len)
796 return 0;
797
798 /* Shrink - just ftruncate. */
799 if (pst->st_ex_size > len)
800 return ftruncate(fsp->fh->fd, len);
801
802 space_to_write = len - pst->st_ex_size;
803
804 /* for allocation try fallocate first. This can fail on some
805 platforms e.g. when the filesystem doesn't support it and no
806 emulation is being done by the libc (like on AIX with JFS1). In that
807 case we do our own emulation. fallocate implementations can
808 return ENOTSUP or EINVAL in cases like that. */
809 ret = SMB_VFS_FALLOCATE(fsp, 0, pst->st_ex_size, space_to_write);
810 if (ret == -1 && errno == ENOSPC) {
811 return -1;
812 }
813 if (ret == 0) {
814 return 0;
815 }
816 DEBUG(10,("[CEPH] strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
817 "error %d. Falling back to slow manual allocation\n", errno));
818
819 /* available disk space is enough or not? */
820 space_avail =
821 get_dfree_info(fsp->conn, fsp->fsp_name, &bsize, &dfree, &dsize);
822 /* space_avail is 1k blocks */
823 if (space_avail == (uint64_t)-1 ||
824 ((uint64_t)space_to_write/1024 > space_avail) ) {
825 errno = ENOSPC;
826 return -1;
827 }
828
829 /* Write out the real space on disk. */
830 return vfs_slow_fallocate(fsp, pst->st_ex_size, space_to_write);
831}
832
833static int cephwrap_ftruncate(struct vfs_handle_struct *handle, files_struct *fsp, off_t len)
834{
835 int result = -1;
836 SMB_STRUCT_STAT st;
837 char c = 0;
838 off_t currpos;
839
840 DEBUG(10, ("[CEPH] ftruncate(%p, %p, %llu\n", handle, fsp, llu(len)));
841
842 if (lp_strict_allocate(SNUM(fsp->conn))) {
843 result = strict_allocate_ftruncate(handle, fsp, len);
844 return result;
845 }
846
847 /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
848 sys_ftruncate if the system supports it. Then I discovered that
849 you can have some filesystems that support ftruncate
850 expansion and some that don't! On Linux fat can't do
851 ftruncate extend but ext2 can. */
852
853 result = ceph_ftruncate(handle->data, fsp->fh->fd, len);
854 if (result == 0)
855 goto done;
856
857 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
858 extend a file with ftruncate. Provide alternate implementation
859 for this */
860 currpos = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
861 if (currpos == -1) {
862 goto done;
863 }
864
865 /* Do an fstat to see if the file is longer than the requested
866 size in which case the ftruncate above should have
867 succeeded or shorter, in which case seek to len - 1 and
868 write 1 byte of zero */
869 if (SMB_VFS_FSTAT(fsp, &st) == -1) {
870 goto done;
871 }
872
873#ifdef S_ISFIFO
874 if (S_ISFIFO(st.st_ex_mode)) {
875 result = 0;
876 goto done;
877 }
878#endif
879
880 if (st.st_ex_size == len) {
881 result = 0;
882 goto done;
883 }
884
885 if (st.st_ex_size > len) {
886 /* the sys_ftruncate should have worked */
887 goto done;
888 }
889
890 if (SMB_VFS_LSEEK(fsp, len-1, SEEK_SET) != len -1)
891 goto done;
892
893 if (SMB_VFS_WRITE(fsp, &c, 1)!=1)
894 goto done;
895
896 /* Seek to where we were */
897 if (SMB_VFS_LSEEK(fsp, currpos, SEEK_SET) != currpos)
898 goto done;
899 result = 0;
900
901 done:
902
903 return result;
904}
905
906static bool cephwrap_lock(struct vfs_handle_struct *handle, files_struct *fsp, int op, off_t offset, off_t count, int type)
907{
908 DEBUG(10, ("[CEPH] lock\n"));
909 return true;
910}
911
912static int cephwrap_kernel_flock(struct vfs_handle_struct *handle, files_struct *fsp,
913 uint32_t share_mode, uint32_t access_mask)
914{
915 DEBUG(10, ("[CEPH] kernel_flock\n"));
916 /*
917 * We must return zero here and pretend all is good.
918 * One day we might have this in CEPH.
919 */
920 return 0;
921}
922
923static bool cephwrap_getlock(struct vfs_handle_struct *handle, files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid)
924{
925 DEBUG(10, ("[CEPH] getlock returning false and errno=0\n"));
926
927 errno = 0;
928 return false;
929}
930
931/*
932 * We cannot let this fall through to the default, because the file might only
933 * be accessible from libceph (which is a user-space client) but the fd might
934 * be for some file the kernel knows about.
935 */
936static int cephwrap_linux_setlease(struct vfs_handle_struct *handle, files_struct *fsp,
937 int leasetype)
938{
939 int result = -1;
940
941 DEBUG(10, ("[CEPH] linux_setlease\n"));
942 errno = ENOSYS;
943 return result;
944}
945
946static int cephwrap_symlink(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath)
947{
948 int result = -1;
949 DEBUG(10, ("[CEPH] symlink(%p, %s, %s)\n", handle, oldpath, newpath));
950 result = ceph_symlink(handle->data, oldpath, newpath);
951 DEBUG(10, ("[CEPH] symlink(...) = %d\n", result));
952 WRAP_RETURN(result);
953}
954
955static int cephwrap_readlink(struct vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
956{
957 int result = -1;
958 DEBUG(10, ("[CEPH] readlink(%p, %s, %p, %llu)\n", handle, path, buf, llu(bufsiz)));
959 result = ceph_readlink(handle->data, path, buf, bufsiz);
960 DEBUG(10, ("[CEPH] readlink(...) = %d\n", result));
961 WRAP_RETURN(result);
962}
963
964static int cephwrap_link(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath)
965{
966 int result = -1;
967 DEBUG(10, ("[CEPH] link(%p, %s, %s)\n", handle, oldpath, newpath));
968 result = ceph_link(handle->data, oldpath, newpath);
969 DEBUG(10, ("[CEPH] link(...) = %d\n", result));
970 WRAP_RETURN(result);
971}
972
973static int cephwrap_mknod(struct vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev)
974{
975 int result = -1;
976 DEBUG(10, ("[CEPH] mknod(%p, %s)\n", handle, pathname));
977 result = ceph_mknod(handle->data, pathname, mode, dev);
978 DEBUG(10, ("[CEPH] mknod(...) = %d\n", result));
979 WRAP_RETURN(result);
980}
981
982/*
983 * This is a simple version of real-path ... a better version is needed to
984 * ask libceph about symbolic links.
985 */
986static char *cephwrap_realpath(struct vfs_handle_struct *handle, const char *path)
987{
988 char *result;
989 size_t len = strlen(path);
990
991 result = SMB_MALLOC_ARRAY(char, PATH_MAX+1);
992 if (len && (path[0] == '/')) {
993 int r = asprintf(&result, "%s", path);
994 if (r < 0) return NULL;
995 } else if ((len >= 2) && (path[0] == '.') && (path[1] == '/')) {
996 if (len == 2) {
997 int r = asprintf(&result, "%s",
998 handle->conn->connectpath);
999 if (r < 0) return NULL;
1000 } else {
1001 int r = asprintf(&result, "%s/%s",
1002 handle->conn->connectpath, &path[2]);
1003 if (r < 0) return NULL;
1004 }
1005 } else {
1006 int r = asprintf(&result, "%s/%s",
1007 handle->conn->connectpath, path);
1008 if (r < 0) return NULL;
1009 }
1010 DEBUG(10, ("[CEPH] realpath(%p, %s) = %s\n", handle, path, result));
1011 return result;
1012}
1013
1014static int cephwrap_chflags(struct vfs_handle_struct *handle, const char *path,
1015 unsigned int flags)
1016{
1017 errno = ENOSYS;
1018 return -1;
1019}
1020
1021static int cephwrap_get_real_filename(struct vfs_handle_struct *handle,
1022 const char *path,
1023 const char *name,
1024 TALLOC_CTX *mem_ctx,
1025 char **found_name)
1026{
1027 /*
1028 * Don't fall back to get_real_filename so callers can differentiate
1029 * between a full directory scan and an actual case-insensitive stat.
1030 */
1031 errno = EOPNOTSUPP;
1032 return -1;
1033}
1034
1035static const char *cephwrap_connectpath(struct vfs_handle_struct *handle,
1036 const char *fname)
1037{
1038 return handle->conn->connectpath;
1039}
1040
1041/****************************************************************
1042 Extended attribute operations.
1043*****************************************************************/
1044
1045static ssize_t cephwrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
1046{
1047 int ret;
1048 DEBUG(10, ("[CEPH] getxattr(%p, %s, %s, %p, %llu)\n", handle, path, name, value, llu(size)));
1049 ret = ceph_getxattr(handle->data, path, name, value, size);
1050 DEBUG(10, ("[CEPH] getxattr(...) = %d\n", ret));
1051 if (ret < 0) {
1052 WRAP_RETURN(ret);
1053 } else {
1054 return (ssize_t)ret;
1055 }
1056}
1057
1058static ssize_t cephwrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size)
1059{
1060 int ret;
1061 DEBUG(10, ("[CEPH] fgetxattr(%p, %p, %s, %p, %llu)\n", handle, fsp, name, value, llu(size)));
1062#if LIBCEPHFS_VERSION_CODE >= LIBCEPHFS_VERSION(0, 94, 0)
1063 ret = ceph_fgetxattr(handle->data, fsp->fh->fd, name, value, size);
1064#else
1065 ret = ceph_getxattr(handle->data, fsp->fsp_name->base_name, name, value, size);
1066#endif
1067 DEBUG(10, ("[CEPH] fgetxattr(...) = %d\n", ret));
1068 if (ret < 0) {
1069 WRAP_RETURN(ret);
1070 } else {
1071 return (ssize_t)ret;
1072 }
1073}
1074
1075static ssize_t cephwrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
1076{
1077 int ret;
1078 DEBUG(10, ("[CEPH] listxattr(%p, %s, %p, %llu)\n", handle, path, list, llu(size)));
1079 ret = ceph_listxattr(handle->data, path, list, size);
1080 DEBUG(10, ("[CEPH] listxattr(...) = %d\n", ret));
1081 if (ret < 0) {
1082 WRAP_RETURN(ret);
1083 } else {
1084 return (ssize_t)ret;
1085 }
1086}
1087
1088#if 0
1089static ssize_t cephwrap_llistxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
1090{
1091 int ret;
1092 DEBUG(10, ("[CEPH] llistxattr(%p, %s, %p, %llu)\n", handle, path, list, llu(size)));
1093 ret = ceph_llistxattr(handle->data, path, list, size);
1094 DEBUG(10, ("[CEPH] listxattr(...) = %d\n", ret));
1095 if (ret < 0) {
1096 WRAP_RETURN(ret);
1097 } else {
1098 return (ssize_t)ret;
1099 }
1100}
1101#endif
1102
1103static ssize_t cephwrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
1104{
1105 int ret;
1106 DEBUG(10, ("[CEPH] flistxattr(%p, %p, %s, %llu)\n", handle, fsp, list, llu(size)));
1107#if LIBCEPHFS_VERSION_CODE >= LIBCEPHFS_VERSION(0, 94, 0)
1108 ret = ceph_flistxattr(handle->data, fsp->fh->fd, list, size);
1109#else
1110 ret = ceph_listxattr(handle->data, fsp->fsp_name->base_name, list, size);
1111#endif
1112 DEBUG(10, ("[CEPH] flistxattr(...) = %d\n", ret));
1113 if (ret < 0) {
1114 WRAP_RETURN(ret);
1115 } else {
1116 return (ssize_t)ret;
1117 }
1118}
1119
1120static int cephwrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
1121{
1122 int ret;
1123 DEBUG(10, ("[CEPH] removexattr(%p, %s, %s)\n", handle, path, name));
1124 ret = ceph_removexattr(handle->data, path, name);
1125 DEBUG(10, ("[CEPH] removexattr(...) = %d\n", ret));
1126 WRAP_RETURN(ret);
1127}
1128
1129static int cephwrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name)
1130{
1131 int ret;
1132 DEBUG(10, ("[CEPH] fremovexattr(%p, %p, %s)\n", handle, fsp, name));
1133#if LIBCEPHFS_VERSION_CODE >= LIBCEPHFS_VERSION(0, 94, 0)
1134 ret = ceph_fremovexattr(handle->data, fsp->fh->fd, name);
1135#else
1136 ret = ceph_removexattr(handle->data, fsp->fsp_name->base_name, name);
1137#endif
1138 DEBUG(10, ("[CEPH] fremovexattr(...) = %d\n", ret));
1139 WRAP_RETURN(ret);
1140}
1141
1142static int cephwrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
1143{
1144 int ret;
1145 DEBUG(10, ("[CEPH] setxattr(%p, %s, %s, %p, %llu, %d)\n", handle, path, name, value, llu(size), flags));
1146 ret = ceph_setxattr(handle->data, path, name, value, size, flags);
1147 DEBUG(10, ("[CEPH] setxattr(...) = %d\n", ret));
1148 WRAP_RETURN(ret);
1149}
1150
1151static int cephwrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags)
1152{
1153 int ret;
1154 DEBUG(10, ("[CEPH] fsetxattr(%p, %p, %s, %p, %llu, %d)\n", handle, fsp, name, value, llu(size), flags));
1155#if LIBCEPHFS_VERSION_CODE >= LIBCEPHFS_VERSION(0, 94, 0)
1156 ret = ceph_fsetxattr(handle->data, fsp->fh->fd,
1157 name, value, size, flags);
1158#else
1159 ret = ceph_setxattr(handle->data, fsp->fsp_name->base_name, name, value, size, flags);
1160#endif
1161 DEBUG(10, ("[CEPH] fsetxattr(...) = %d\n", ret));
1162 WRAP_RETURN(ret);
1163}
1164
1165static bool cephwrap_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
1166{
1167
1168 /*
1169 * We do not support AIO yet.
1170 */
1171
1172 DEBUG(10, ("[CEPH] cephwrap_aio_force(%p, %p) = false (errno = ENOTSUP)\n", handle, fsp));
1173 errno = ENOTSUP;
1174 return false;
1175}
1176
1177static bool cephwrap_is_offline(struct vfs_handle_struct *handle,
1178 const struct smb_filename *fname,
1179 SMB_STRUCT_STAT *sbuf)
1180{
1181 return false;
1182}
1183
1184static int cephwrap_set_offline(struct vfs_handle_struct *handle,
1185 const struct smb_filename *fname)
1186{
1187 errno = ENOTSUP;
1188 return -1;
1189}
1190
1191static SMB_ACL_T cephwrap_sys_acl_get_file(struct vfs_handle_struct *handle,
1192 const char *path_p,
1193 SMB_ACL_TYPE_T type,
1194 TALLOC_CTX *mem_ctx)
1195{
1196 errno = ENOTSUP;
1197 return NULL;
1198}
1199
1200static SMB_ACL_T cephwrap_sys_acl_get_fd(struct vfs_handle_struct *handle,
1201 struct files_struct *fsp,
1202 TALLOC_CTX *mem_ctx)
1203{
1204 errno = ENOTSUP;
1205 return NULL;
1206}
1207
1208static int cephwrap_sys_acl_set_file(struct vfs_handle_struct *handle,
1209 const char *name,
1210 SMB_ACL_TYPE_T acltype,
1211 SMB_ACL_T theacl)
1212{
1213 errno = ENOTSUP;
1214 return -1;
1215}
1216
1217static int cephwrap_sys_acl_set_fd(struct vfs_handle_struct *handle,
1218 struct files_struct *fsp,
1219 SMB_ACL_T theacl)
1220{
1221 errno = ENOTSUP;
1222 return -1;
1223}
1224
1225static int cephwrap_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
1226 const char *path)
1227{
1228 errno = ENOTSUP;
1229 return -1;
1230}
1231
1232static struct vfs_fn_pointers ceph_fns = {
1233 /* Disk operations */
1234
1235 .connect_fn = cephwrap_connect,
1236 .disconnect_fn = cephwrap_disconnect,
1237 .disk_free_fn = cephwrap_disk_free,
1238 .get_quota_fn = cephwrap_get_quota,
1239 .set_quota_fn = cephwrap_set_quota,
1240 .statvfs_fn = cephwrap_statvfs,
1241
1242 /* Directory operations */
1243
1244 .opendir_fn = cephwrap_opendir,
1245 .fdopendir_fn = cephwrap_fdopendir,
1246 .readdir_fn = cephwrap_readdir,
1247 .seekdir_fn = cephwrap_seekdir,
1248 .telldir_fn = cephwrap_telldir,
1249 .rewind_dir_fn = cephwrap_rewinddir,
1250 .mkdir_fn = cephwrap_mkdir,
1251 .rmdir_fn = cephwrap_rmdir,
1252 .closedir_fn = cephwrap_closedir,
1253
1254 /* File operations */
1255
1256 .open_fn = cephwrap_open,
1257 .close_fn = cephwrap_close,
1258 .read_fn = cephwrap_read,
1259 .pread_fn = cephwrap_pread,
1260 .write_fn = cephwrap_write,
1261 .pwrite_fn = cephwrap_pwrite,
1262 .lseek_fn = cephwrap_lseek,
1263 .sendfile_fn = cephwrap_sendfile,
1264 .recvfile_fn = cephwrap_recvfile,
1265 .rename_fn = cephwrap_rename,
1266 .fsync_fn = cephwrap_fsync,
1267 .stat_fn = cephwrap_stat,
1268 .fstat_fn = cephwrap_fstat,
1269 .lstat_fn = cephwrap_lstat,
1270 .unlink_fn = cephwrap_unlink,
1271 .chmod_fn = cephwrap_chmod,
1272 .fchmod_fn = cephwrap_fchmod,
1273 .chown_fn = cephwrap_chown,
1274 .fchown_fn = cephwrap_fchown,
1275 .lchown_fn = cephwrap_lchown,
1276 .chdir_fn = cephwrap_chdir,
1277 .getwd_fn = cephwrap_getwd,
1278 .ntimes_fn = cephwrap_ntimes,
1279 .ftruncate_fn = cephwrap_ftruncate,
1280 .lock_fn = cephwrap_lock,
1281 .kernel_flock_fn = cephwrap_kernel_flock,
1282 .linux_setlease_fn = cephwrap_linux_setlease,
1283 .getlock_fn = cephwrap_getlock,
1284 .symlink_fn = cephwrap_symlink,
1285 .readlink_fn = cephwrap_readlink,
1286 .link_fn = cephwrap_link,
1287 .mknod_fn = cephwrap_mknod,
1288 .realpath_fn = cephwrap_realpath,
1289 .chflags_fn = cephwrap_chflags,
1290 .get_real_filename_fn = cephwrap_get_real_filename,
1291 .connectpath_fn = cephwrap_connectpath,
1292
1293 /* EA operations. */
1294 .getxattr_fn = cephwrap_getxattr,
1295 .fgetxattr_fn = cephwrap_fgetxattr,
1296 .listxattr_fn = cephwrap_listxattr,
1297 .flistxattr_fn = cephwrap_flistxattr,
1298 .removexattr_fn = cephwrap_removexattr,
1299 .fremovexattr_fn = cephwrap_fremovexattr,
1300 .setxattr_fn = cephwrap_setxattr,
1301 .fsetxattr_fn = cephwrap_fsetxattr,
1302
1303 /* Posix ACL Operations */
1304 .sys_acl_get_file_fn = cephwrap_sys_acl_get_file,
1305 .sys_acl_get_fd_fn = cephwrap_sys_acl_get_fd,
1306 .sys_acl_set_file_fn = cephwrap_sys_acl_set_file,
1307 .sys_acl_set_fd_fn = cephwrap_sys_acl_set_fd,
1308 .sys_acl_delete_def_file_fn = cephwrap_sys_acl_delete_def_file,
1309
1310 /* aio operations */
1311 .aio_force_fn = cephwrap_aio_force,
1312
1313 /* offline operations */
1314 .is_offline_fn = cephwrap_is_offline,
1315 .set_offline_fn = cephwrap_set_offline
1316};
1317
1318NTSTATUS vfs_ceph_init(void);
1319NTSTATUS vfs_ceph_init(void)
1320{
1321 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
1322 "ceph", &ceph_fns);
1323}
Note: See TracBrowser for help on using the repository browser.