c4db8fa393f6ed6209b44fc0de58a5dabee65456
[sfrench/samba-autobuild/.git] / source3 / modules / vfs_default.c
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
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.
11
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.
16
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/>.
19 */
20
21 #include "includes.h"
22
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_VFS
25
26 /* Check for NULL pointer parameters in vfswrap_* functions */
27
28 /* We don't want to have NULL function pointers lying around.  Someone
29    is sure to try and execute them.  These stubs are used to prevent
30    this possibility. */
31
32 static int vfswrap_connect(vfs_handle_struct *handle,  const char *service, const char *user)
33 {
34     return 0;    /* Return >= 0 for success */
35 }
36
37 static void vfswrap_disconnect(vfs_handle_struct *handle)
38 {
39 }
40
41 /* Disk operations */
42
43 static uint64_t vfswrap_disk_free(vfs_handle_struct *handle,  const char *path, bool small_query, uint64_t *bsize,
44                                uint64_t *dfree, uint64_t *dsize)
45 {
46         uint64_t result;
47
48         result = sys_disk_free(handle->conn, path, small_query, bsize, dfree, dsize);
49         return result;
50 }
51
52 static int vfswrap_get_quota(struct vfs_handle_struct *handle,  enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
53 {
54 #ifdef HAVE_SYS_QUOTAS
55         int result;
56
57         START_PROFILE(syscall_get_quota);
58         result = sys_get_quota(handle->conn->connectpath, qtype, id, qt);
59         END_PROFILE(syscall_get_quota);
60         return result;
61 #else
62         errno = ENOSYS;
63         return -1;
64 #endif
65 }
66
67 static int vfswrap_set_quota(struct vfs_handle_struct *handle,  enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
68 {
69 #ifdef HAVE_SYS_QUOTAS
70         int result;
71
72         START_PROFILE(syscall_set_quota);
73         result = sys_set_quota(handle->conn->connectpath, qtype, id, qt);
74         END_PROFILE(syscall_set_quota);
75         return result;
76 #else
77         errno = ENOSYS;
78         return -1;
79 #endif
80 }
81
82 static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels)
83 {
84         errno = ENOSYS;
85         return -1;  /* Not implemented. */
86 }
87
88 static int vfswrap_statvfs(struct vfs_handle_struct *handle,  const char *path, vfs_statvfs_struct *statbuf)
89 {
90         return sys_statvfs(path, statbuf);
91 }
92
93 static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle)
94 {
95 #if defined(DARWINOS)
96         struct vfs_statvfs_struct statbuf;
97         ZERO_STRUCT(statbuf);
98         sys_statvfs(handle->conn->connectpath, &statbuf);
99         return statbuf.FsCapabilities;
100 #endif
101         return FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
102 }
103
104 /* Directory operations */
105
106 static SMB_STRUCT_DIR *vfswrap_opendir(vfs_handle_struct *handle,  const char *fname, const char *mask, uint32 attr)
107 {
108         SMB_STRUCT_DIR *result;
109
110         START_PROFILE(syscall_opendir);
111         result = sys_opendir(fname);
112         END_PROFILE(syscall_opendir);
113         return result;
114 }
115
116 static SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle,
117                                           SMB_STRUCT_DIR *dirp,
118                                           SMB_STRUCT_STAT *sbuf)
119 {
120         SMB_STRUCT_DIRENT *result;
121
122         START_PROFILE(syscall_readdir);
123         result = sys_readdir(dirp);
124         /* Default Posix readdir() does not give us stat info.
125          * Set to invalid to indicate we didn't return this info. */
126         if (sbuf)
127                 SET_STAT_INVALID(*sbuf);
128         END_PROFILE(syscall_readdir);
129         return result;
130 }
131
132 static void vfswrap_seekdir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp, long offset)
133 {
134         START_PROFILE(syscall_seekdir);
135         sys_seekdir(dirp, offset);
136         END_PROFILE(syscall_seekdir);
137 }
138
139 static long vfswrap_telldir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp)
140 {
141         long result;
142         START_PROFILE(syscall_telldir);
143         result = sys_telldir(dirp);
144         END_PROFILE(syscall_telldir);
145         return result;
146 }
147
148 static void vfswrap_rewinddir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp)
149 {
150         START_PROFILE(syscall_rewinddir);
151         sys_rewinddir(dirp);
152         END_PROFILE(syscall_rewinddir);
153 }
154
155 static int vfswrap_mkdir(vfs_handle_struct *handle,  const char *path, mode_t mode)
156 {
157         int result;
158         bool has_dacl = False;
159         char *parent = NULL;
160
161         START_PROFILE(syscall_mkdir);
162
163         if (lp_inherit_acls(SNUM(handle->conn))
164             && parent_dirname(talloc_tos(), path, &parent, NULL)
165             && (has_dacl = directory_has_default_acl(handle->conn, parent)))
166                 mode = 0777;
167
168         TALLOC_FREE(parent);
169
170         result = mkdir(path, mode);
171
172         if (result == 0 && !has_dacl) {
173                 /*
174                  * We need to do this as the default behavior of POSIX ACLs
175                  * is to set the mask to be the requested group permission
176                  * bits, not the group permission bits to be the requested
177                  * group permission bits. This is not what we want, as it will
178                  * mess up any inherited ACL bits that were set. JRA.
179                  */
180                 int saved_errno = errno; /* We may get ENOSYS */
181                 if ((SMB_VFS_CHMOD_ACL(handle->conn, path, mode) == -1) && (errno == ENOSYS))
182                         errno = saved_errno;
183         }
184
185         END_PROFILE(syscall_mkdir);
186         return result;
187 }
188
189 static int vfswrap_rmdir(vfs_handle_struct *handle,  const char *path)
190 {
191         int result;
192
193         START_PROFILE(syscall_rmdir);
194         result = rmdir(path);
195         END_PROFILE(syscall_rmdir);
196         return result;
197 }
198
199 static int vfswrap_closedir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp)
200 {
201         int result;
202
203         START_PROFILE(syscall_closedir);
204         result = sys_closedir(dirp);
205         END_PROFILE(syscall_closedir);
206         return result;
207 }
208
209 static void vfswrap_init_search_op(vfs_handle_struct *handle,
210                                    SMB_STRUCT_DIR *dirp)
211 {
212         /* Default behavior is a NOOP */
213 }
214
215 /* File operations */
216
217 static int vfswrap_open(vfs_handle_struct *handle,
218                         struct smb_filename *smb_fname,
219                         files_struct *fsp, int flags, mode_t mode)
220 {
221         int result;
222         NTSTATUS status;
223         char *fname = NULL;
224
225         START_PROFILE(syscall_open);
226
227         /*
228          * XXX: Should an error be returned if there is a stream rather than
229          * trying to open a filename with a ':'?
230          */
231         status = get_full_smb_filename(talloc_tos(), smb_fname,
232                                        &fname);
233         if (!NT_STATUS_IS_OK(status)) {
234                 errno = map_errno_from_nt_status(status);
235                 return -1;
236         }
237
238         result = sys_open(fname, flags, mode);
239
240         TALLOC_FREE(fname);
241
242         END_PROFILE(syscall_open);
243         return result;
244 }
245
246 static NTSTATUS vfswrap_create_file(vfs_handle_struct *handle,
247                                     struct smb_request *req,
248                                     uint16_t root_dir_fid,
249                                     struct smb_filename *smb_fname,
250                                     uint32_t access_mask,
251                                     uint32_t share_access,
252                                     uint32_t create_disposition,
253                                     uint32_t create_options,
254                                     uint32_t file_attributes,
255                                     uint32_t oplock_request,
256                                     uint64_t allocation_size,
257                                     struct security_descriptor *sd,
258                                     struct ea_list *ea_list,
259                                     files_struct **result,
260                                     int *pinfo)
261 {
262         return create_file_default(handle->conn, req, root_dir_fid, smb_fname,
263                                    access_mask, share_access,
264                                    create_disposition, create_options,
265                                    file_attributes, oplock_request,
266                                    allocation_size, sd, ea_list, result,
267                                    pinfo);
268 }
269
270 static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp)
271 {
272         int result;
273
274         START_PROFILE(syscall_close);
275         result = fd_close_posix(fsp);
276         END_PROFILE(syscall_close);
277         return result;
278 }
279
280 static ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n)
281 {
282         ssize_t result;
283
284         START_PROFILE_BYTES(syscall_read, n);
285         result = sys_read(fsp->fh->fd, data, n);
286         END_PROFILE(syscall_read);
287         return result;
288 }
289
290 static ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, void *data,
291                         size_t n, SMB_OFF_T offset)
292 {
293         ssize_t result;
294
295 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
296         START_PROFILE_BYTES(syscall_pread, n);
297         result = sys_pread(fsp->fh->fd, data, n, offset);
298         END_PROFILE(syscall_pread);
299
300         if (result == -1 && errno == ESPIPE) {
301                 /* Maintain the fiction that pipes can be seeked (sought?) on. */
302                 result = SMB_VFS_READ(fsp, data, n);
303                 fsp->fh->pos = 0;
304         }
305
306 #else /* HAVE_PREAD */
307         SMB_OFF_T   curr;
308         int lerrno;
309
310         curr = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
311         if (curr == -1 && errno == ESPIPE) {
312                 /* Maintain the fiction that pipes can be seeked (sought?) on. */
313                 result = SMB_VFS_READ(fsp, data, n);
314                 fsp->fh->pos = 0;
315                 return result;
316         }
317
318         if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
319                 return -1;
320         }
321
322         errno = 0;
323         result = SMB_VFS_READ(fsp, data, n);
324         lerrno = errno;
325
326         SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
327         errno = lerrno;
328
329 #endif /* HAVE_PREAD */
330
331         return result;
332 }
333
334 static ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n)
335 {
336         ssize_t result;
337
338         START_PROFILE_BYTES(syscall_write, n);
339         result = sys_write(fsp->fh->fd, data, n);
340         END_PROFILE(syscall_write);
341         return result;
342 }
343
344 static ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, const void *data,
345                         size_t n, SMB_OFF_T offset)
346 {
347         ssize_t result;
348
349 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
350         START_PROFILE_BYTES(syscall_pwrite, n);
351         result = sys_pwrite(fsp->fh->fd, data, n, offset);
352         END_PROFILE(syscall_pwrite);
353
354         if (result == -1 && errno == ESPIPE) {
355                 /* Maintain the fiction that pipes can be sought on. */
356                 result = SMB_VFS_WRITE(fsp, data, n);
357         }
358
359 #else /* HAVE_PWRITE */
360         SMB_OFF_T   curr;
361         int         lerrno;
362
363         curr = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
364         if (curr == -1) {
365                 return -1;
366         }
367
368         if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
369                 return -1;
370         }
371
372         result = SMB_VFS_WRITE(fsp, data, n);
373         lerrno = errno;
374
375         SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
376         errno = lerrno;
377
378 #endif /* HAVE_PWRITE */
379
380         return result;
381 }
382
383 static SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T offset, int whence)
384 {
385         SMB_OFF_T result = 0;
386
387         START_PROFILE(syscall_lseek);
388
389         /* Cope with 'stat' file opens. */
390         if (fsp->fh->fd != -1)
391                 result = sys_lseek(fsp->fh->fd, offset, whence);
392
393         /*
394          * We want to maintain the fiction that we can seek
395          * on a fifo for file system purposes. This allows
396          * people to set up UNIX fifo's that feed data to Windows
397          * applications. JRA.
398          */
399
400         if((result == -1) && (errno == ESPIPE)) {
401                 result = 0;
402                 errno = 0;
403         }
404
405         END_PROFILE(syscall_lseek);
406         return result;
407 }
408
409 static ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fromfsp, const DATA_BLOB *hdr,
410                         SMB_OFF_T offset, size_t n)
411 {
412         ssize_t result;
413
414         START_PROFILE_BYTES(syscall_sendfile, n);
415         result = sys_sendfile(tofd, fromfsp->fh->fd, hdr, offset, n);
416         END_PROFILE(syscall_sendfile);
417         return result;
418 }
419
420 static ssize_t vfswrap_recvfile(vfs_handle_struct *handle,
421                         int fromfd,
422                         files_struct *tofsp,
423                         SMB_OFF_T offset,
424                         size_t n)
425 {
426         ssize_t result;
427
428         START_PROFILE_BYTES(syscall_recvfile, n);
429         result = sys_recvfile(fromfd, tofsp->fh->fd, offset, n);
430         END_PROFILE(syscall_recvfile);
431         return result;
432 }
433
434 /*********************************************************
435  For rename across filesystems Patch from Warren Birnbaum
436  <warrenb@hpcvscdp.cv.hp.com>
437 **********************************************************/
438
439 static int copy_reg(const char *source, const char *dest)
440 {
441         SMB_STRUCT_STAT source_stats;
442         int saved_errno;
443         int ifd = -1;
444         int ofd = -1;
445
446         if (sys_lstat (source, &source_stats) == -1)
447                 return -1;
448
449         if (!S_ISREG (source_stats.st_ex_mode))
450                 return -1;
451
452         if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
453                 return -1;
454
455         if (unlink (dest) && errno != ENOENT)
456                 return -1;
457
458 #ifdef O_NOFOLLOW
459         if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 )
460 #else
461         if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )
462 #endif
463                 goto err;
464
465         if (transfer_file(ifd, ofd, (size_t)-1) == -1)
466                 goto err;
467
468         /*
469          * Try to preserve ownership.  For non-root it might fail, but that's ok.
470          * But root probably wants to know, e.g. if NFS disallows it.
471          */
472
473 #ifdef HAVE_FCHOWN
474         if ((fchown(ofd, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))
475 #else
476         if ((chown(dest, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM))
477 #endif
478                 goto err;
479
480         /*
481          * fchown turns off set[ug]id bits for non-root,
482          * so do the chmod last.
483          */
484
485 #if defined(HAVE_FCHMOD)
486         if (fchmod (ofd, source_stats.st_ex_mode & 07777))
487 #else
488         if (chmod (dest, source_stats.st_ex_mode & 07777))
489 #endif
490                 goto err;
491
492         if (close (ifd) == -1)
493                 goto err;
494
495         if (close (ofd) == -1)
496                 return -1;
497
498         /* Try to copy the old file's modtime and access time.  */
499         {
500                 struct utimbuf tv;
501
502                 tv.actime = convert_timespec_to_time_t(source_stats.st_ex_atime);
503                 tv.modtime = convert_timespec_to_time_t(source_stats.st_ex_mtime);
504                 utime(dest, &tv);
505         }
506
507         if (unlink (source) == -1)
508                 return -1;
509
510         return 0;
511
512   err:
513
514         saved_errno = errno;
515         if (ifd != -1)
516                 close(ifd);
517         if (ofd != -1)
518                 close(ofd);
519         errno = saved_errno;
520         return -1;
521 }
522
523 static int vfswrap_rename(vfs_handle_struct *handle,
524                           const struct smb_filename *smb_fname_src,
525                           const struct smb_filename *smb_fname_dst)
526 {
527         int result = -1;
528
529         START_PROFILE(syscall_rename);
530
531         if (smb_fname_src->stream_name || smb_fname_dst->stream_name) {
532                 errno = ENOENT;
533                 goto out;
534         }
535
536         result = rename(smb_fname_src->base_name, smb_fname_dst->base_name);
537         if ((result == -1) && (errno == EXDEV)) {
538                 /* Rename across filesystems needed. */
539                 result = copy_reg(smb_fname_src->base_name,
540                                   smb_fname_dst->base_name);
541         }
542
543  out:
544         END_PROFILE(syscall_rename);
545         return result;
546 }
547
548 static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp)
549 {
550 #ifdef HAVE_FSYNC
551         int result;
552
553         START_PROFILE(syscall_fsync);
554         result = fsync(fsp->fh->fd);
555         END_PROFILE(syscall_fsync);
556         return result;
557 #else
558         return 0;
559 #endif
560 }
561
562 static int vfswrap_stat(vfs_handle_struct *handle,
563                         struct smb_filename *smb_fname)
564 {
565         int result;
566         NTSTATUS status;
567         char *fname = NULL;
568
569         START_PROFILE(syscall_stat);
570
571         status = get_full_smb_filename(talloc_tos(), smb_fname,
572                                        &fname);
573         if (!NT_STATUS_IS_OK(status)) {
574                 errno = map_errno_from_nt_status(status);
575                 return -1;
576         }
577
578         result = sys_stat(fname, &smb_fname->st);
579
580         TALLOC_FREE(fname);
581
582         END_PROFILE(syscall_stat);
583         return result;
584 }
585
586 static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
587 {
588         int result;
589
590         START_PROFILE(syscall_fstat);
591         result = sys_fstat(fsp->fh->fd, sbuf);
592         END_PROFILE(syscall_fstat);
593         return result;
594 }
595
596 static int vfswrap_lstat(vfs_handle_struct *handle,
597                          struct smb_filename *smb_fname)
598 {
599         int result;
600         NTSTATUS status;
601         char *fname = NULL;
602
603         START_PROFILE(syscall_lstat);
604
605         status = get_full_smb_filename(talloc_tos(), smb_fname,
606                                        &fname);
607         if (!NT_STATUS_IS_OK(status)) {
608                 errno = map_errno_from_nt_status(status);
609                 return -1;
610         }
611
612         result = sys_lstat(fname, &smb_fname->st);
613
614         TALLOC_FREE(fname);
615
616         END_PROFILE(syscall_lstat);
617         return result;
618 }
619
620 /********************************************************************
621  Given a stat buffer return the allocated size on disk, taking into
622  account sparse files.
623 ********************************************************************/
624 static uint64_t vfswrap_get_alloc_size(vfs_handle_struct *handle,
625                                        struct files_struct *fsp,
626                                        const SMB_STRUCT_STAT *sbuf)
627 {
628         uint64_t result;
629
630         START_PROFILE(syscall_get_alloc_size);
631
632         if(S_ISDIR(sbuf->st_ex_mode)) {
633                 result = 0;
634                 goto out;
635         }
636
637 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
638         result = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_ex_blocks;
639 #else
640         result = get_file_size_stat(sbuf);
641 #endif
642
643         if (fsp && fsp->initial_allocation_size)
644                 result = MAX(result,fsp->initial_allocation_size);
645
646         result = smb_roundup(handle->conn, result);
647
648  out:
649         END_PROFILE(syscall_get_alloc_size);
650         return result;
651 }
652
653 static int vfswrap_unlink(vfs_handle_struct *handle,
654                           const struct smb_filename *smb_fname)
655 {
656         int result = -1;
657
658         START_PROFILE(syscall_unlink);
659
660         if (smb_fname->stream_name) {
661                 errno = ENOENT;
662                 goto out;
663         }
664         result = unlink(smb_fname->base_name);
665
666  out:
667         END_PROFILE(syscall_unlink);
668         return result;
669 }
670
671 static int vfswrap_chmod(vfs_handle_struct *handle,  const char *path, mode_t mode)
672 {
673         int result;
674
675         START_PROFILE(syscall_chmod);
676
677         /*
678          * We need to do this due to the fact that the default POSIX ACL
679          * chmod modifies the ACL *mask* for the group owner, not the
680          * group owner bits directly. JRA.
681          */
682
683
684         {
685                 int saved_errno = errno; /* We might get ENOSYS */
686                 if ((result = SMB_VFS_CHMOD_ACL(handle->conn, path, mode)) == 0) {
687                         END_PROFILE(syscall_chmod);
688                         return result;
689                 }
690                 /* Error - return the old errno. */
691                 errno = saved_errno;
692         }
693
694         result = chmod(path, mode);
695         END_PROFILE(syscall_chmod);
696         return result;
697 }
698
699 static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
700 {
701         int result;
702
703         START_PROFILE(syscall_fchmod);
704
705         /*
706          * We need to do this due to the fact that the default POSIX ACL
707          * chmod modifies the ACL *mask* for the group owner, not the
708          * group owner bits directly. JRA.
709          */
710
711         {
712                 int saved_errno = errno; /* We might get ENOSYS */
713                 if ((result = SMB_VFS_FCHMOD_ACL(fsp, mode)) == 0) {
714                         END_PROFILE(syscall_fchmod);
715                         return result;
716                 }
717                 /* Error - return the old errno. */
718                 errno = saved_errno;
719         }
720
721 #if defined(HAVE_FCHMOD)
722         result = fchmod(fsp->fh->fd, mode);
723 #else
724         result = -1;
725         errno = ENOSYS;
726 #endif
727
728         END_PROFILE(syscall_fchmod);
729         return result;
730 }
731
732 static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
733 {
734         int result;
735
736         START_PROFILE(syscall_chown);
737         result = chown(path, uid, gid);
738         END_PROFILE(syscall_chown);
739         return result;
740 }
741
742 static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid)
743 {
744 #ifdef HAVE_FCHOWN
745         int result;
746
747         START_PROFILE(syscall_fchown);
748         result = fchown(fsp->fh->fd, uid, gid);
749         END_PROFILE(syscall_fchown);
750         return result;
751 #else
752         errno = ENOSYS;
753         return -1;
754 #endif
755 }
756
757 static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
758 {
759         int result;
760
761         START_PROFILE(syscall_lchown);
762         result = lchown(path, uid, gid);
763         END_PROFILE(syscall_lchown);
764         return result;
765 }
766
767 static int vfswrap_chdir(vfs_handle_struct *handle,  const char *path)
768 {
769         int result;
770
771         START_PROFILE(syscall_chdir);
772         result = chdir(path);
773         END_PROFILE(syscall_chdir);
774         return result;
775 }
776
777 static char *vfswrap_getwd(vfs_handle_struct *handle,  char *path)
778 {
779         char *result;
780
781         START_PROFILE(syscall_getwd);
782         result = sys_getwd(path);
783         END_PROFILE(syscall_getwd);
784         return result;
785 }
786
787 /*********************************************************************
788  nsec timestamp resolution call. Convert down to whatever the underlying
789  system will support.
790 **********************************************************************/
791
792 static int vfswrap_ntimes(vfs_handle_struct *handle,
793                           const struct smb_filename *smb_fname,
794                           struct smb_file_time *ft)
795 {
796         int result = -1;
797
798         START_PROFILE(syscall_ntimes);
799
800         if (smb_fname->stream_name) {
801                 errno = ENOENT;
802                 goto out;
803         }
804
805 #if defined(HAVE_UTIMES)
806         if (ft != NULL) {
807                 struct timeval tv[2];
808                 tv[0] = convert_timespec_to_timeval(ft->atime);
809                 tv[1] = convert_timespec_to_timeval(ft->mtime);
810                 result = utimes(smb_fname->base_name, tv);
811         } else {
812                 result = utimes(smb_fname->base_name, NULL);
813         }
814 #elif defined(HAVE_UTIME)
815         if (ft != NULL) {
816                 struct utimbuf times;
817                 times.actime = convert_timespec_to_time_t(ft->atime);
818                 times.modtime = convert_timespec_to_time_t(ft->mtime);
819                 result = utime(smb_fname->base_name, &times);
820         } else {
821                 result = utime(smb_fname->base_name, NULL);
822         }
823 #else
824         errno = ENOSYS;
825         result = -1;
826 #endif
827  out:
828         END_PROFILE(syscall_ntimes);
829         return result;
830 }
831
832 /*********************************************************************
833  A version of ftruncate that will write the space on disk if strict
834  allocate is set.
835 **********************************************************************/
836
837 static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T len)
838 {
839         SMB_STRUCT_STAT st;
840         SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
841         unsigned char zero_space[4096];
842         SMB_OFF_T space_to_write;
843
844         if (currpos == -1)
845                 return -1;
846
847         if (SMB_VFS_FSTAT(fsp, &st) == -1)
848                 return -1;
849
850         space_to_write = len - st.st_ex_size;
851
852 #ifdef S_ISFIFO
853         if (S_ISFIFO(st.st_ex_mode))
854                 return 0;
855 #endif
856
857         if (st.st_ex_size == len)
858                 return 0;
859
860         /* Shrink - just ftruncate. */
861         if (st.st_ex_size > len)
862                 return sys_ftruncate(fsp->fh->fd, len);
863
864         /* available disk space is enough or not? */
865         if (lp_strict_allocate(SNUM(fsp->conn))){
866                 uint64_t space_avail;
867                 uint64_t bsize,dfree,dsize;
868
869                 space_avail = get_dfree_info(fsp->conn,fsp->fsp_name,false,&bsize,&dfree,&dsize);
870                 /* space_avail is 1k blocks */
871                 if (space_avail == (uint64_t)-1 ||
872                                 ((uint64_t)space_to_write/1024 > space_avail) ) {
873                         errno = ENOSPC;
874                         return -1;
875                 }
876         }
877
878         /* Write out the real space on disk. */
879         if (SMB_VFS_LSEEK(fsp, st.st_ex_size, SEEK_SET) != st.st_ex_size)
880                 return -1;
881
882         space_to_write = len - st.st_ex_size;
883
884         memset(zero_space, '\0', sizeof(zero_space));
885         while ( space_to_write > 0) {
886                 SMB_OFF_T retlen;
887                 SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write);
888
889                 retlen = SMB_VFS_WRITE(fsp,(char *)zero_space,current_len_to_write);
890                 if (retlen <= 0)
891                         return -1;
892
893                 space_to_write -= retlen;
894         }
895
896         /* Seek to where we were */
897         if (SMB_VFS_LSEEK(fsp, currpos, SEEK_SET) != currpos)
898                 return -1;
899
900         return 0;
901 }
902
903 static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T len)
904 {
905         int result = -1;
906         SMB_STRUCT_STAT st;
907         char c = 0;
908         SMB_OFF_T currpos;
909
910         START_PROFILE(syscall_ftruncate);
911
912         if (lp_strict_allocate(SNUM(fsp->conn))) {
913                 result = strict_allocate_ftruncate(handle, fsp, len);
914                 END_PROFILE(syscall_ftruncate);
915                 return result;
916         }
917
918         /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
919            sys_ftruncate if the system supports it. Then I discovered that
920            you can have some filesystems that support ftruncate
921            expansion and some that don't! On Linux fat can't do
922            ftruncate extend but ext2 can. */
923
924         result = sys_ftruncate(fsp->fh->fd, len);
925         if (result == 0)
926                 goto done;
927
928         /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
929            extend a file with ftruncate. Provide alternate implementation
930            for this */
931         currpos = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
932         if (currpos == -1) {
933                 goto done;
934         }
935
936         /* Do an fstat to see if the file is longer than the requested
937            size in which case the ftruncate above should have
938            succeeded or shorter, in which case seek to len - 1 and
939            write 1 byte of zero */
940         if (SMB_VFS_FSTAT(fsp, &st) == -1) {
941                 goto done;
942         }
943
944 #ifdef S_ISFIFO
945         if (S_ISFIFO(st.st_ex_mode)) {
946                 result = 0;
947                 goto done;
948         }
949 #endif
950
951         if (st.st_ex_size == len) {
952                 result = 0;
953                 goto done;
954         }
955
956         if (st.st_ex_size > len) {
957                 /* the sys_ftruncate should have worked */
958                 goto done;
959         }
960
961         if (SMB_VFS_LSEEK(fsp, len-1, SEEK_SET) != len -1)
962                 goto done;
963
964         if (SMB_VFS_WRITE(fsp, &c, 1)!=1)
965                 goto done;
966
967         /* Seek to where we were */
968         if (SMB_VFS_LSEEK(fsp, currpos, SEEK_SET) != currpos)
969                 goto done;
970         result = 0;
971
972   done:
973
974         END_PROFILE(syscall_ftruncate);
975         return result;
976 }
977
978 static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
979 {
980         bool result;
981
982         START_PROFILE(syscall_fcntl_lock);
983         result =  fcntl_lock(fsp->fh->fd, op, offset, count, type);
984         END_PROFILE(syscall_fcntl_lock);
985         return result;
986 }
987
988 static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
989                                 uint32 share_mode)
990 {
991         START_PROFILE(syscall_kernel_flock);
992         kernel_flock(fsp->fh->fd, share_mode);
993         END_PROFILE(syscall_kernel_flock);
994         return 0;
995 }
996
997 static bool vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
998 {
999         bool result;
1000
1001         START_PROFILE(syscall_fcntl_getlock);
1002         result =  fcntl_getlock(fsp->fh->fd, poffset, pcount, ptype, ppid);
1003         END_PROFILE(syscall_fcntl_getlock);
1004         return result;
1005 }
1006
1007 static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp,
1008                                 int leasetype)
1009 {
1010         int result = -1;
1011
1012         START_PROFILE(syscall_linux_setlease);
1013
1014 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
1015         /* first set the signal handler */
1016         if(linux_set_lease_sighandler(fsp->fh->fd) == -1) {
1017                 return -1;
1018         }
1019
1020         result = linux_setlease(fsp->fh->fd, leasetype);
1021 #else
1022         errno = ENOSYS;
1023 #endif
1024         END_PROFILE(syscall_linux_setlease);
1025         return result;
1026 }
1027
1028 static int vfswrap_symlink(vfs_handle_struct *handle,  const char *oldpath, const char *newpath)
1029 {
1030         int result;
1031
1032         START_PROFILE(syscall_symlink);
1033         result = symlink(oldpath, newpath);
1034         END_PROFILE(syscall_symlink);
1035         return result;
1036 }
1037
1038 static int vfswrap_readlink(vfs_handle_struct *handle,  const char *path, char *buf, size_t bufsiz)
1039 {
1040         int result;
1041
1042         START_PROFILE(syscall_readlink);
1043         result = readlink(path, buf, bufsiz);
1044         END_PROFILE(syscall_readlink);
1045         return result;
1046 }
1047
1048 static int vfswrap_link(vfs_handle_struct *handle,  const char *oldpath, const char *newpath)
1049 {
1050         int result;
1051
1052         START_PROFILE(syscall_link);
1053         result = link(oldpath, newpath);
1054         END_PROFILE(syscall_link);
1055         return result;
1056 }
1057
1058 static int vfswrap_mknod(vfs_handle_struct *handle,  const char *pathname, mode_t mode, SMB_DEV_T dev)
1059 {
1060         int result;
1061
1062         START_PROFILE(syscall_mknod);
1063         result = sys_mknod(pathname, mode, dev);
1064         END_PROFILE(syscall_mknod);
1065         return result;
1066 }
1067
1068 static char *vfswrap_realpath(vfs_handle_struct *handle,  const char *path, char *resolved_path)
1069 {
1070         char *result;
1071
1072         START_PROFILE(syscall_realpath);
1073         result = realpath(path, resolved_path);
1074         END_PROFILE(syscall_realpath);
1075         return result;
1076 }
1077
1078 static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
1079                                      struct sys_notify_context *ctx,
1080                                      struct notify_entry *e,
1081                                      void (*callback)(struct sys_notify_context *ctx, 
1082                                                       void *private_data,
1083                                                       struct notify_event *ev),
1084                                      void *private_data, void *handle)
1085 {
1086         /*
1087          * So far inotify is the only supported default notify mechanism. If
1088          * another platform like the the BSD's or a proprietary Unix comes
1089          * along and wants another default, we can play the same trick we
1090          * played with Posix ACLs.
1091          *
1092          * Until that is the case, hard-code inotify here.
1093          */
1094 #ifdef HAVE_INOTIFY
1095         if (lp_kernel_change_notify(ctx->conn->params)) {
1096                 return inotify_watch(ctx, e, callback, private_data, handle);
1097         }
1098 #endif
1099         /*
1100          * Do nothing, leave everything to notify_internal.c
1101          */
1102         return NT_STATUS_OK;
1103 }
1104
1105 static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flags)
1106 {
1107 #ifdef HAVE_CHFLAGS
1108         return chflags(path, flags);
1109 #else
1110         errno = ENOSYS;
1111         return -1;
1112 #endif
1113 }
1114
1115 static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
1116                                              SMB_STRUCT_STAT *sbuf)
1117 {
1118         struct file_id key;
1119
1120         /* the ZERO_STRUCT ensures padding doesn't break using the key as a
1121          * blob */
1122         ZERO_STRUCT(key);
1123
1124         key.devid = sbuf->st_ex_dev;
1125         key.inode = sbuf->st_ex_ino;
1126         /* key.extid is unused by default. */
1127
1128         return key;
1129 }
1130
1131 static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
1132                                    struct files_struct *fsp,
1133                                    const char *fname,
1134                                    TALLOC_CTX *mem_ctx,
1135                                    unsigned int *pnum_streams,
1136                                    struct stream_struct **pstreams)
1137 {
1138         SMB_STRUCT_STAT sbuf;
1139         unsigned int num_streams = 0;
1140         struct stream_struct *streams = NULL;
1141         int ret;
1142
1143         if ((fsp != NULL) && (fsp->is_directory)) {
1144                 /*
1145                  * No default streams on directories
1146                  */
1147                 goto done;
1148         }
1149
1150         if ((fsp != NULL) && (fsp->fh->fd != -1)) {
1151                 ret = SMB_VFS_FSTAT(fsp, &sbuf);
1152         }
1153         else {
1154                 struct smb_filename *smb_fname = NULL;
1155                 NTSTATUS status;
1156
1157                 status = create_synthetic_smb_fname(talloc_tos(), fname, NULL,
1158                                                     NULL, &smb_fname);
1159                 if (!NT_STATUS_IS_OK(status)) {
1160                         return status;
1161                 }
1162                 ret = SMB_VFS_STAT(handle->conn, smb_fname);
1163                 sbuf = smb_fname->st;
1164                 TALLOC_FREE(smb_fname);
1165         }
1166
1167         if (ret == -1) {
1168                 return map_nt_error_from_unix(errno);
1169         }
1170
1171         if (S_ISDIR(sbuf.st_ex_mode)) {
1172                 goto done;
1173         }
1174
1175         streams = talloc(mem_ctx, struct stream_struct);
1176
1177         if (streams == NULL) {
1178                 return NT_STATUS_NO_MEMORY;
1179         }
1180
1181         streams->size = sbuf.st_ex_size;
1182         streams->alloc_size = SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf);
1183
1184         streams->name = talloc_strdup(streams, "::$DATA");
1185         if (streams->name == NULL) {
1186                 TALLOC_FREE(streams);
1187                 return NT_STATUS_NO_MEMORY;
1188         }
1189
1190         num_streams = 1;
1191  done:
1192         *pnum_streams = num_streams;
1193         *pstreams = streams;
1194         return NT_STATUS_OK;
1195 }
1196
1197 static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
1198                                      const char *path,
1199                                      const char *name,
1200                                      TALLOC_CTX *mem_ctx,
1201                                      char **found_name)
1202 {
1203         /*
1204          * Don't fall back to get_real_filename so callers can differentiate
1205          * between a full directory scan and an actual case-insensitive stat.
1206          */
1207         errno = EOPNOTSUPP;
1208         return -1;
1209 }
1210
1211 static const char *vfswrap_connectpath(struct vfs_handle_struct *handle,
1212                                        const char *fname)
1213 {
1214         return handle->conn->connectpath;
1215 }
1216
1217 static NTSTATUS vfswrap_brl_lock_windows(struct vfs_handle_struct *handle,
1218                                          struct byte_range_lock *br_lck,
1219                                          struct lock_struct *plock,
1220                                          bool blocking_lock,
1221                                          struct blocking_lock_record *blr)
1222 {
1223         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1224
1225         /* Note: blr is not used in the default implementation. */
1226         return brl_lock_windows_default(br_lck, plock, blocking_lock);
1227 }
1228
1229 static bool vfswrap_brl_unlock_windows(struct vfs_handle_struct *handle,
1230                                        struct messaging_context *msg_ctx,
1231                                        struct byte_range_lock *br_lck,
1232                                        const struct lock_struct *plock)
1233 {
1234         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1235
1236         return brl_unlock_windows_default(msg_ctx, br_lck, plock);
1237 }
1238
1239 static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct *handle,
1240                                        struct byte_range_lock *br_lck,
1241                                        struct lock_struct *plock,
1242                                        struct blocking_lock_record *blr)
1243 {
1244         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1245
1246         /* Note: blr is not used in the default implementation. */
1247         return brl_lock_cancel_default(br_lck, plock);
1248 }
1249
1250 static bool vfswrap_strict_lock(struct vfs_handle_struct *handle,
1251                                 files_struct *fsp,
1252                                 struct lock_struct *plock)
1253 {
1254         SMB_ASSERT(plock->lock_type == READ_LOCK ||
1255             plock->lock_type == WRITE_LOCK);
1256
1257         return strict_lock_default(fsp, plock);
1258 }
1259
1260 static void vfswrap_strict_unlock(struct vfs_handle_struct *handle,
1261                                 files_struct *fsp,
1262                                 struct lock_struct *plock)
1263 {
1264         SMB_ASSERT(plock->lock_type == READ_LOCK ||
1265             plock->lock_type == WRITE_LOCK);
1266
1267         strict_unlock_default(fsp, plock);
1268 }
1269
1270 /* NT ACL operations. */
1271
1272 static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
1273                                     files_struct *fsp,
1274                                     uint32 security_info, SEC_DESC **ppdesc)
1275 {
1276         NTSTATUS result;
1277
1278         START_PROFILE(fget_nt_acl);
1279         result = posix_fget_nt_acl(fsp, security_info, ppdesc);
1280         END_PROFILE(fget_nt_acl);
1281         return result;
1282 }
1283
1284 static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
1285                                    const char *name,
1286                                    uint32 security_info, SEC_DESC **ppdesc)
1287 {
1288         NTSTATUS result;
1289
1290         START_PROFILE(get_nt_acl);
1291         result = posix_get_nt_acl(handle->conn, name, security_info, ppdesc);
1292         END_PROFILE(get_nt_acl);
1293         return result;
1294 }
1295
1296 static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, const SEC_DESC *psd)
1297 {
1298         NTSTATUS result;
1299
1300         START_PROFILE(fset_nt_acl);
1301         result = set_nt_acl(fsp, security_info_sent, psd);
1302         END_PROFILE(fset_nt_acl);
1303         return result;
1304 }
1305
1306 static int vfswrap_chmod_acl(vfs_handle_struct *handle,  const char *name, mode_t mode)
1307 {
1308 #ifdef HAVE_NO_ACL
1309         errno = ENOSYS;
1310         return -1;
1311 #else
1312         int result;
1313
1314         START_PROFILE(chmod_acl);
1315         result = chmod_acl(handle->conn, name, mode);
1316         END_PROFILE(chmod_acl);
1317         return result;
1318 #endif
1319 }
1320
1321 static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
1322 {
1323 #ifdef HAVE_NO_ACL
1324         errno = ENOSYS;
1325         return -1;
1326 #else
1327         int result;
1328
1329         START_PROFILE(fchmod_acl);
1330         result = fchmod_acl(fsp, mode);
1331         END_PROFILE(fchmod_acl);
1332         return result;
1333 #endif
1334 }
1335
1336 static int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle,  SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1337 {
1338         return sys_acl_get_entry(theacl, entry_id, entry_p);
1339 }
1340
1341 static int vfswrap_sys_acl_get_tag_type(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
1342 {
1343         return sys_acl_get_tag_type(entry_d, tag_type_p);
1344 }
1345
1346 static int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1347 {
1348         return sys_acl_get_permset(entry_d, permset_p);
1349 }
1350
1351 static void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry_d)
1352 {
1353         return sys_acl_get_qualifier(entry_d);
1354 }
1355
1356 static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle,  const char *path_p, SMB_ACL_TYPE_T type)
1357 {
1358         return sys_acl_get_file(handle, path_p, type);
1359 }
1360
1361 static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp)
1362 {
1363         return sys_acl_get_fd(handle, fsp);
1364 }
1365
1366 static int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset)
1367 {
1368         return sys_acl_clear_perms(permset);
1369 }
1370
1371 static int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1372 {
1373         return sys_acl_add_perm(permset, perm);
1374 }
1375
1376 static char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle,  SMB_ACL_T theacl, ssize_t *plen)
1377 {
1378         return sys_acl_to_text(theacl, plen);
1379 }
1380
1381 static SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle,  int count)
1382 {
1383         return sys_acl_init(count);
1384 }
1385
1386 static int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle,  SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
1387 {
1388         return sys_acl_create_entry(pacl, pentry);
1389 }
1390
1391 static int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
1392 {
1393         return sys_acl_set_tag_type(entry, tagtype);
1394 }
1395
1396 static int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, void *qual)
1397 {
1398         return sys_acl_set_qualifier(entry, qual);
1399 }
1400
1401 static int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
1402 {
1403         return sys_acl_set_permset(entry, permset);
1404 }
1405
1406 static int vfswrap_sys_acl_valid(vfs_handle_struct *handle,  SMB_ACL_T theacl )
1407 {
1408         return sys_acl_valid(theacl );
1409 }
1410
1411 static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle,  const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1412 {
1413         return sys_acl_set_file(handle, name, acltype, theacl);
1414 }
1415
1416 static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl)
1417 {
1418         return sys_acl_set_fd(handle, fsp, theacl);
1419 }
1420
1421 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle,  const char *path)
1422 {
1423         return sys_acl_delete_def_file(handle, path);
1424 }
1425
1426 static int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1427 {
1428         return sys_acl_get_perm(permset, perm);
1429 }
1430
1431 static int vfswrap_sys_acl_free_text(vfs_handle_struct *handle,  char *text)
1432 {
1433         return sys_acl_free_text(text);
1434 }
1435
1436 static int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle,  SMB_ACL_T posix_acl)
1437 {
1438         return sys_acl_free_acl(posix_acl);
1439 }
1440
1441 static int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle,  void *qualifier, SMB_ACL_TAG_T tagtype)
1442 {
1443         return sys_acl_free_qualifier(qualifier, tagtype);
1444 }
1445
1446 /****************************************************************
1447  Extended attribute operations.
1448 *****************************************************************/
1449
1450 static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
1451 {
1452         return sys_getxattr(path, name, value, size);
1453 }
1454
1455 static ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
1456 {
1457         return sys_lgetxattr(path, name, value, size);
1458 }
1459
1460 static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size)
1461 {
1462         return sys_fgetxattr(fsp->fh->fd, name, value, size);
1463 }
1464
1465 static ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
1466 {
1467         return sys_listxattr(path, list, size);
1468 }
1469
1470 ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
1471 {
1472         return sys_llistxattr(path, list, size);
1473 }
1474
1475 ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
1476 {
1477         return sys_flistxattr(fsp->fh->fd, list, size);
1478 }
1479
1480 static int vfswrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
1481 {
1482         return sys_removexattr(path, name);
1483 }
1484
1485 static int vfswrap_lremovexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
1486 {
1487         return sys_lremovexattr(path, name);
1488 }
1489
1490 static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name)
1491 {
1492         return sys_fremovexattr(fsp->fh->fd, name);
1493 }
1494
1495 static int vfswrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
1496 {
1497         return sys_setxattr(path, name, value, size, flags);
1498 }
1499
1500 static int vfswrap_lsetxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
1501 {
1502         return sys_lsetxattr(path, name, value, size, flags);
1503 }
1504
1505 static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags)
1506 {
1507         return sys_fsetxattr(fsp->fh->fd, name, value, size, flags);
1508 }
1509
1510 static int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1511 {
1512         int ret;
1513         /*
1514          * aio_read must be done as root, because in the glibc aio
1515          * implementation the helper thread needs to be able to send a signal
1516          * to the main thread, even when it has done a seteuid() to a
1517          * different user.
1518          */
1519         become_root();
1520         ret = sys_aio_read(aiocb);
1521         unbecome_root();
1522         return ret;
1523 }
1524
1525 static int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1526 {
1527         int ret;
1528         /*
1529          * aio_write must be done as root, because in the glibc aio
1530          * implementation the helper thread needs to be able to send a signal
1531          * to the main thread, even when it has done a seteuid() to a
1532          * different user.
1533          */
1534         become_root();
1535         ret = sys_aio_write(aiocb);
1536         unbecome_root();
1537         return ret;
1538 }
1539
1540 static ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1541 {
1542         return sys_aio_return(aiocb);
1543 }
1544
1545 static int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1546 {
1547         return sys_aio_cancel(fsp->fh->fd, aiocb);
1548 }
1549
1550 static int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1551 {
1552         return sys_aio_error(aiocb);
1553 }
1554
1555 static int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb)
1556 {
1557         return sys_aio_fsync(op, aiocb);
1558 }
1559
1560 static int vfswrap_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *timeout)
1561 {
1562         return sys_aio_suspend(aiocb, n, timeout);
1563 }
1564
1565 static bool vfswrap_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
1566 {
1567         return false;
1568 }
1569
1570 static bool vfswrap_is_offline(struct vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf)
1571 {
1572         if (ISDOT(path) || ISDOTDOT(path)) {
1573                 return false;
1574         }
1575
1576         if (!lp_dmapi_support(SNUM(handle->conn)) || !dmapi_have_session()) {
1577 #if defined(ENOTSUP)
1578                 errno = ENOTSUP;
1579 #endif
1580                 return false;
1581         }
1582
1583         return (dmapi_file_flags(path) & FILE_ATTRIBUTE_OFFLINE) != 0;
1584 }
1585
1586 static int vfswrap_set_offline(struct vfs_handle_struct *handle, const char *path)
1587 {
1588         /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
1589 #if defined(ENOTSUP)
1590         errno = ENOTSUP;
1591 #endif
1592         return -1;
1593 }
1594
1595 static vfs_op_tuple vfs_default_ops[] = {
1596
1597         /* Disk operations */
1598
1599         {SMB_VFS_OP(vfswrap_connect),   SMB_VFS_OP_CONNECT,
1600          SMB_VFS_LAYER_OPAQUE},
1601         {SMB_VFS_OP(vfswrap_disconnect),        SMB_VFS_OP_DISCONNECT,
1602          SMB_VFS_LAYER_OPAQUE},
1603         {SMB_VFS_OP(vfswrap_disk_free), SMB_VFS_OP_DISK_FREE,
1604          SMB_VFS_LAYER_OPAQUE},
1605         {SMB_VFS_OP(vfswrap_get_quota), SMB_VFS_OP_GET_QUOTA,
1606          SMB_VFS_LAYER_OPAQUE},
1607         {SMB_VFS_OP(vfswrap_set_quota), SMB_VFS_OP_SET_QUOTA,
1608          SMB_VFS_LAYER_OPAQUE},
1609         {SMB_VFS_OP(vfswrap_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA,
1610          SMB_VFS_LAYER_OPAQUE},
1611         {SMB_VFS_OP(vfswrap_statvfs),   SMB_VFS_OP_STATVFS,
1612          SMB_VFS_LAYER_OPAQUE},
1613         {SMB_VFS_OP(vfswrap_fs_capabilities), SMB_VFS_OP_FS_CAPABILITIES,
1614          SMB_VFS_LAYER_OPAQUE},
1615
1616         /* Directory operations */
1617
1618         {SMB_VFS_OP(vfswrap_opendir),   SMB_VFS_OP_OPENDIR,
1619          SMB_VFS_LAYER_OPAQUE},
1620         {SMB_VFS_OP(vfswrap_readdir),   SMB_VFS_OP_READDIR,
1621          SMB_VFS_LAYER_OPAQUE},
1622         {SMB_VFS_OP(vfswrap_seekdir),   SMB_VFS_OP_SEEKDIR,
1623          SMB_VFS_LAYER_OPAQUE},
1624         {SMB_VFS_OP(vfswrap_telldir),   SMB_VFS_OP_TELLDIR,
1625          SMB_VFS_LAYER_OPAQUE},
1626         {SMB_VFS_OP(vfswrap_rewinddir), SMB_VFS_OP_REWINDDIR,
1627          SMB_VFS_LAYER_OPAQUE},
1628         {SMB_VFS_OP(vfswrap_mkdir),     SMB_VFS_OP_MKDIR,
1629          SMB_VFS_LAYER_OPAQUE},
1630         {SMB_VFS_OP(vfswrap_rmdir),     SMB_VFS_OP_RMDIR,
1631          SMB_VFS_LAYER_OPAQUE},
1632         {SMB_VFS_OP(vfswrap_closedir),  SMB_VFS_OP_CLOSEDIR,
1633          SMB_VFS_LAYER_OPAQUE},
1634         {SMB_VFS_OP(vfswrap_init_search_op), SMB_VFS_OP_INIT_SEARCH_OP,
1635          SMB_VFS_LAYER_OPAQUE},
1636
1637         /* File operations */
1638
1639         {SMB_VFS_OP(vfswrap_open),      SMB_VFS_OP_OPEN,
1640          SMB_VFS_LAYER_OPAQUE},
1641         {SMB_VFS_OP(vfswrap_create_file),       SMB_VFS_OP_CREATE_FILE,
1642          SMB_VFS_LAYER_OPAQUE},
1643         {SMB_VFS_OP(vfswrap_close),     SMB_VFS_OP_CLOSE,
1644          SMB_VFS_LAYER_OPAQUE},
1645         {SMB_VFS_OP(vfswrap_read),      SMB_VFS_OP_READ,
1646          SMB_VFS_LAYER_OPAQUE},
1647         {SMB_VFS_OP(vfswrap_pread),     SMB_VFS_OP_PREAD,
1648          SMB_VFS_LAYER_OPAQUE},
1649         {SMB_VFS_OP(vfswrap_write),     SMB_VFS_OP_WRITE,
1650          SMB_VFS_LAYER_OPAQUE},
1651         {SMB_VFS_OP(vfswrap_pwrite),    SMB_VFS_OP_PWRITE,
1652          SMB_VFS_LAYER_OPAQUE},
1653         {SMB_VFS_OP(vfswrap_lseek),     SMB_VFS_OP_LSEEK,
1654          SMB_VFS_LAYER_OPAQUE},
1655         {SMB_VFS_OP(vfswrap_sendfile),  SMB_VFS_OP_SENDFILE,
1656          SMB_VFS_LAYER_OPAQUE},
1657         {SMB_VFS_OP(vfswrap_recvfile),  SMB_VFS_OP_RECVFILE,
1658          SMB_VFS_LAYER_OPAQUE},
1659         {SMB_VFS_OP(vfswrap_rename),    SMB_VFS_OP_RENAME,
1660          SMB_VFS_LAYER_OPAQUE},
1661         {SMB_VFS_OP(vfswrap_fsync),     SMB_VFS_OP_FSYNC,
1662          SMB_VFS_LAYER_OPAQUE},
1663         {SMB_VFS_OP(vfswrap_stat),      SMB_VFS_OP_STAT,
1664          SMB_VFS_LAYER_OPAQUE},
1665         {SMB_VFS_OP(vfswrap_fstat),     SMB_VFS_OP_FSTAT,
1666          SMB_VFS_LAYER_OPAQUE},
1667         {SMB_VFS_OP(vfswrap_lstat),     SMB_VFS_OP_LSTAT,
1668          SMB_VFS_LAYER_OPAQUE},
1669         {SMB_VFS_OP(vfswrap_get_alloc_size),    SMB_VFS_OP_GET_ALLOC_SIZE,
1670          SMB_VFS_LAYER_OPAQUE},
1671         {SMB_VFS_OP(vfswrap_unlink),    SMB_VFS_OP_UNLINK,
1672          SMB_VFS_LAYER_OPAQUE},
1673         {SMB_VFS_OP(vfswrap_chmod),     SMB_VFS_OP_CHMOD,
1674          SMB_VFS_LAYER_OPAQUE},
1675         {SMB_VFS_OP(vfswrap_fchmod),    SMB_VFS_OP_FCHMOD,
1676          SMB_VFS_LAYER_OPAQUE},
1677         {SMB_VFS_OP(vfswrap_chown),     SMB_VFS_OP_CHOWN,
1678          SMB_VFS_LAYER_OPAQUE},
1679         {SMB_VFS_OP(vfswrap_fchown),    SMB_VFS_OP_FCHOWN,
1680          SMB_VFS_LAYER_OPAQUE},
1681         {SMB_VFS_OP(vfswrap_lchown),    SMB_VFS_OP_LCHOWN,
1682          SMB_VFS_LAYER_OPAQUE},
1683         {SMB_VFS_OP(vfswrap_chdir),     SMB_VFS_OP_CHDIR,
1684          SMB_VFS_LAYER_OPAQUE},
1685         {SMB_VFS_OP(vfswrap_getwd),     SMB_VFS_OP_GETWD,
1686          SMB_VFS_LAYER_OPAQUE},
1687         {SMB_VFS_OP(vfswrap_ntimes),    SMB_VFS_OP_NTIMES,
1688          SMB_VFS_LAYER_OPAQUE},
1689         {SMB_VFS_OP(vfswrap_ftruncate), SMB_VFS_OP_FTRUNCATE,
1690          SMB_VFS_LAYER_OPAQUE},
1691         {SMB_VFS_OP(vfswrap_lock),      SMB_VFS_OP_LOCK,
1692          SMB_VFS_LAYER_OPAQUE},
1693         {SMB_VFS_OP(vfswrap_kernel_flock),      SMB_VFS_OP_KERNEL_FLOCK,
1694          SMB_VFS_LAYER_OPAQUE},
1695         {SMB_VFS_OP(vfswrap_linux_setlease),    SMB_VFS_OP_LINUX_SETLEASE,
1696          SMB_VFS_LAYER_OPAQUE},
1697         {SMB_VFS_OP(vfswrap_getlock),   SMB_VFS_OP_GETLOCK,
1698          SMB_VFS_LAYER_OPAQUE},
1699         {SMB_VFS_OP(vfswrap_symlink),   SMB_VFS_OP_SYMLINK,
1700          SMB_VFS_LAYER_OPAQUE},
1701         {SMB_VFS_OP(vfswrap_readlink),  SMB_VFS_OP_READLINK,
1702          SMB_VFS_LAYER_OPAQUE},
1703         {SMB_VFS_OP(vfswrap_link),      SMB_VFS_OP_LINK,
1704          SMB_VFS_LAYER_OPAQUE},
1705         {SMB_VFS_OP(vfswrap_mknod),     SMB_VFS_OP_MKNOD,
1706          SMB_VFS_LAYER_OPAQUE},
1707         {SMB_VFS_OP(vfswrap_realpath),  SMB_VFS_OP_REALPATH,
1708          SMB_VFS_LAYER_OPAQUE},
1709         {SMB_VFS_OP(vfswrap_notify_watch),      SMB_VFS_OP_NOTIFY_WATCH,
1710          SMB_VFS_LAYER_OPAQUE},
1711         {SMB_VFS_OP(vfswrap_chflags),   SMB_VFS_OP_CHFLAGS,
1712          SMB_VFS_LAYER_OPAQUE},
1713         {SMB_VFS_OP(vfswrap_file_id_create),    SMB_VFS_OP_FILE_ID_CREATE,
1714          SMB_VFS_LAYER_OPAQUE},
1715         {SMB_VFS_OP(vfswrap_streaminfo),        SMB_VFS_OP_STREAMINFO,
1716          SMB_VFS_LAYER_OPAQUE},
1717         {SMB_VFS_OP(vfswrap_get_real_filename), SMB_VFS_OP_GET_REAL_FILENAME,
1718          SMB_VFS_LAYER_OPAQUE},
1719         {SMB_VFS_OP(vfswrap_connectpath),       SMB_VFS_OP_CONNECTPATH,
1720          SMB_VFS_LAYER_OPAQUE},
1721         {SMB_VFS_OP(vfswrap_brl_lock_windows),  SMB_VFS_OP_BRL_LOCK_WINDOWS,
1722          SMB_VFS_LAYER_OPAQUE},
1723         {SMB_VFS_OP(vfswrap_brl_unlock_windows),SMB_VFS_OP_BRL_UNLOCK_WINDOWS,
1724          SMB_VFS_LAYER_OPAQUE},
1725         {SMB_VFS_OP(vfswrap_brl_cancel_windows),SMB_VFS_OP_BRL_CANCEL_WINDOWS,
1726          SMB_VFS_LAYER_OPAQUE},
1727         {SMB_VFS_OP(vfswrap_strict_lock),       SMB_VFS_OP_STRICT_LOCK,
1728          SMB_VFS_LAYER_OPAQUE},
1729         {SMB_VFS_OP(vfswrap_strict_unlock),     SMB_VFS_OP_STRICT_UNLOCK,
1730          SMB_VFS_LAYER_OPAQUE},
1731
1732         /* NT ACL operations. */
1733
1734         {SMB_VFS_OP(vfswrap_fget_nt_acl),       SMB_VFS_OP_FGET_NT_ACL,
1735          SMB_VFS_LAYER_OPAQUE},
1736         {SMB_VFS_OP(vfswrap_get_nt_acl),        SMB_VFS_OP_GET_NT_ACL,
1737          SMB_VFS_LAYER_OPAQUE},
1738         {SMB_VFS_OP(vfswrap_fset_nt_acl),       SMB_VFS_OP_FSET_NT_ACL,
1739          SMB_VFS_LAYER_OPAQUE},
1740
1741         /* POSIX ACL operations. */
1742
1743         {SMB_VFS_OP(vfswrap_chmod_acl), SMB_VFS_OP_CHMOD_ACL,
1744          SMB_VFS_LAYER_OPAQUE},
1745         {SMB_VFS_OP(vfswrap_fchmod_acl),        SMB_VFS_OP_FCHMOD_ACL,
1746          SMB_VFS_LAYER_OPAQUE},
1747         {SMB_VFS_OP(vfswrap_sys_acl_get_entry), SMB_VFS_OP_SYS_ACL_GET_ENTRY,
1748          SMB_VFS_LAYER_OPAQUE},
1749         {SMB_VFS_OP(vfswrap_sys_acl_get_tag_type),      SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE,
1750          SMB_VFS_LAYER_OPAQUE},
1751         {SMB_VFS_OP(vfswrap_sys_acl_get_permset),       SMB_VFS_OP_SYS_ACL_GET_PERMSET,
1752          SMB_VFS_LAYER_OPAQUE},
1753         {SMB_VFS_OP(vfswrap_sys_acl_get_qualifier),     SMB_VFS_OP_SYS_ACL_GET_QUALIFIER,
1754          SMB_VFS_LAYER_OPAQUE},
1755         {SMB_VFS_OP(vfswrap_sys_acl_get_file),  SMB_VFS_OP_SYS_ACL_GET_FILE,
1756          SMB_VFS_LAYER_OPAQUE},
1757         {SMB_VFS_OP(vfswrap_sys_acl_get_fd),    SMB_VFS_OP_SYS_ACL_GET_FD,
1758          SMB_VFS_LAYER_OPAQUE},
1759         {SMB_VFS_OP(vfswrap_sys_acl_clear_perms),       SMB_VFS_OP_SYS_ACL_CLEAR_PERMS,
1760          SMB_VFS_LAYER_OPAQUE},
1761         {SMB_VFS_OP(vfswrap_sys_acl_add_perm),  SMB_VFS_OP_SYS_ACL_ADD_PERM,
1762          SMB_VFS_LAYER_OPAQUE},
1763         {SMB_VFS_OP(vfswrap_sys_acl_to_text),   SMB_VFS_OP_SYS_ACL_TO_TEXT,
1764          SMB_VFS_LAYER_OPAQUE},
1765         {SMB_VFS_OP(vfswrap_sys_acl_init),      SMB_VFS_OP_SYS_ACL_INIT,
1766          SMB_VFS_LAYER_OPAQUE},
1767         {SMB_VFS_OP(vfswrap_sys_acl_create_entry),      SMB_VFS_OP_SYS_ACL_CREATE_ENTRY,
1768          SMB_VFS_LAYER_OPAQUE},
1769         {SMB_VFS_OP(vfswrap_sys_acl_set_tag_type),      SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE,
1770          SMB_VFS_LAYER_OPAQUE},
1771         {SMB_VFS_OP(vfswrap_sys_acl_set_qualifier),     SMB_VFS_OP_SYS_ACL_SET_QUALIFIER,
1772          SMB_VFS_LAYER_OPAQUE},
1773         {SMB_VFS_OP(vfswrap_sys_acl_set_permset),       SMB_VFS_OP_SYS_ACL_SET_PERMSET,
1774          SMB_VFS_LAYER_OPAQUE},
1775         {SMB_VFS_OP(vfswrap_sys_acl_valid),     SMB_VFS_OP_SYS_ACL_VALID,
1776          SMB_VFS_LAYER_OPAQUE},
1777         {SMB_VFS_OP(vfswrap_sys_acl_set_file),  SMB_VFS_OP_SYS_ACL_SET_FILE,
1778          SMB_VFS_LAYER_OPAQUE},
1779         {SMB_VFS_OP(vfswrap_sys_acl_set_fd),    SMB_VFS_OP_SYS_ACL_SET_FD,
1780          SMB_VFS_LAYER_OPAQUE},
1781         {SMB_VFS_OP(vfswrap_sys_acl_delete_def_file),   SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
1782          SMB_VFS_LAYER_OPAQUE},
1783         {SMB_VFS_OP(vfswrap_sys_acl_get_perm),  SMB_VFS_OP_SYS_ACL_GET_PERM,
1784          SMB_VFS_LAYER_OPAQUE},
1785         {SMB_VFS_OP(vfswrap_sys_acl_free_text), SMB_VFS_OP_SYS_ACL_FREE_TEXT,
1786          SMB_VFS_LAYER_OPAQUE},
1787         {SMB_VFS_OP(vfswrap_sys_acl_free_acl),  SMB_VFS_OP_SYS_ACL_FREE_ACL,
1788          SMB_VFS_LAYER_OPAQUE},
1789         {SMB_VFS_OP(vfswrap_sys_acl_free_qualifier),    SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER,
1790          SMB_VFS_LAYER_OPAQUE},
1791
1792         /* EA operations. */
1793
1794         {SMB_VFS_OP(vfswrap_getxattr),  SMB_VFS_OP_GETXATTR,
1795          SMB_VFS_LAYER_OPAQUE},
1796         {SMB_VFS_OP(vfswrap_lgetxattr), SMB_VFS_OP_LGETXATTR,
1797          SMB_VFS_LAYER_OPAQUE},
1798         {SMB_VFS_OP(vfswrap_fgetxattr), SMB_VFS_OP_FGETXATTR,
1799          SMB_VFS_LAYER_OPAQUE},
1800         {SMB_VFS_OP(vfswrap_listxattr), SMB_VFS_OP_LISTXATTR,
1801          SMB_VFS_LAYER_OPAQUE},
1802         {SMB_VFS_OP(vfswrap_llistxattr),        SMB_VFS_OP_LLISTXATTR,
1803          SMB_VFS_LAYER_OPAQUE},
1804         {SMB_VFS_OP(vfswrap_flistxattr),        SMB_VFS_OP_FLISTXATTR,
1805          SMB_VFS_LAYER_OPAQUE},
1806         {SMB_VFS_OP(vfswrap_removexattr),       SMB_VFS_OP_REMOVEXATTR,
1807          SMB_VFS_LAYER_OPAQUE},
1808         {SMB_VFS_OP(vfswrap_lremovexattr),      SMB_VFS_OP_LREMOVEXATTR,
1809          SMB_VFS_LAYER_OPAQUE},
1810         {SMB_VFS_OP(vfswrap_fremovexattr),      SMB_VFS_OP_FREMOVEXATTR,
1811          SMB_VFS_LAYER_OPAQUE},
1812         {SMB_VFS_OP(vfswrap_setxattr),  SMB_VFS_OP_SETXATTR,
1813          SMB_VFS_LAYER_OPAQUE},
1814         {SMB_VFS_OP(vfswrap_lsetxattr), SMB_VFS_OP_LSETXATTR,
1815          SMB_VFS_LAYER_OPAQUE},
1816         {SMB_VFS_OP(vfswrap_fsetxattr), SMB_VFS_OP_FSETXATTR,
1817          SMB_VFS_LAYER_OPAQUE},
1818
1819         {SMB_VFS_OP(vfswrap_aio_read),  SMB_VFS_OP_AIO_READ,
1820          SMB_VFS_LAYER_OPAQUE},
1821         {SMB_VFS_OP(vfswrap_aio_write), SMB_VFS_OP_AIO_WRITE,
1822          SMB_VFS_LAYER_OPAQUE},
1823         {SMB_VFS_OP(vfswrap_aio_return),        SMB_VFS_OP_AIO_RETURN,
1824          SMB_VFS_LAYER_OPAQUE},
1825         {SMB_VFS_OP(vfswrap_aio_cancel), SMB_VFS_OP_AIO_CANCEL,
1826          SMB_VFS_LAYER_OPAQUE},
1827         {SMB_VFS_OP(vfswrap_aio_error), SMB_VFS_OP_AIO_ERROR,
1828          SMB_VFS_LAYER_OPAQUE},
1829         {SMB_VFS_OP(vfswrap_aio_fsync), SMB_VFS_OP_AIO_FSYNC,
1830          SMB_VFS_LAYER_OPAQUE},
1831         {SMB_VFS_OP(vfswrap_aio_suspend),SMB_VFS_OP_AIO_SUSPEND,
1832          SMB_VFS_LAYER_OPAQUE},
1833
1834         {SMB_VFS_OP(vfswrap_aio_force), SMB_VFS_OP_AIO_FORCE,
1835          SMB_VFS_LAYER_OPAQUE},
1836
1837         {SMB_VFS_OP(vfswrap_is_offline),SMB_VFS_OP_IS_OFFLINE,
1838          SMB_VFS_LAYER_OPAQUE},
1839         {SMB_VFS_OP(vfswrap_set_offline),SMB_VFS_OP_SET_OFFLINE,
1840          SMB_VFS_LAYER_OPAQUE},
1841
1842         /* Finish VFS operations definition */
1843
1844         {SMB_VFS_OP(NULL),              SMB_VFS_OP_NOOP,
1845          SMB_VFS_LAYER_NOOP}
1846 };
1847
1848 NTSTATUS vfs_default_init(void);
1849 NTSTATUS vfs_default_init(void)
1850 {
1851         unsigned int needed = SMB_VFS_OP_LAST + 1; /* convert from index to count */
1852
1853         if (ARRAY_SIZE(vfs_default_ops) != needed) {
1854                 DEBUG(0, ("%s: %u ops registered, but %u ops are required\n",
1855                         DEFAULT_VFS_MODULE_NAME, (unsigned int)ARRAY_SIZE(vfs_default_ops), needed));
1856                 smb_panic("operation(s) missing from default VFS module");
1857         }
1858
1859         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
1860                                 DEFAULT_VFS_MODULE_NAME, vfs_default_ops);
1861 }