Remove redundant parameter fd from SMB_VFS_PWRITE().
[ira/wip.git] / source / 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 SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle,  const char *path, bool small_query, SMB_BIG_UINT *bsize,
44                                SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
45 {
46         SMB_BIG_UINT 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 /* Directory operations */
94
95 static SMB_STRUCT_DIR *vfswrap_opendir(vfs_handle_struct *handle,  const char *fname, const char *mask, uint32 attr)
96 {
97         SMB_STRUCT_DIR *result;
98
99         START_PROFILE(syscall_opendir);
100         result = sys_opendir(fname);
101         END_PROFILE(syscall_opendir);
102         return result;
103 }
104
105 static SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp)
106 {
107         SMB_STRUCT_DIRENT *result;
108
109         START_PROFILE(syscall_readdir);
110         result = sys_readdir(dirp);
111         END_PROFILE(syscall_readdir);
112         return result;
113 }
114
115 static void vfswrap_seekdir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp, long offset)
116 {
117         START_PROFILE(syscall_seekdir);
118         sys_seekdir(dirp, offset);
119         END_PROFILE(syscall_seekdir);
120 }
121
122 static long vfswrap_telldir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp)
123 {
124         long result;
125         START_PROFILE(syscall_telldir);
126         result = sys_telldir(dirp);
127         END_PROFILE(syscall_telldir);
128         return result;
129 }
130
131 static void vfswrap_rewinddir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp)
132 {
133         START_PROFILE(syscall_rewinddir);
134         sys_rewinddir(dirp);
135         END_PROFILE(syscall_rewinddir);
136 }
137
138 static int vfswrap_mkdir(vfs_handle_struct *handle,  const char *path, mode_t mode)
139 {
140         int result;
141         bool has_dacl = False;
142
143         START_PROFILE(syscall_mkdir);
144
145         if (lp_inherit_acls(SNUM(handle->conn)) && (has_dacl = directory_has_default_acl(handle->conn, parent_dirname(path))))
146                 mode = 0777;
147
148         result = mkdir(path, mode);
149
150         if (result == 0 && !has_dacl) {
151                 /*
152                  * We need to do this as the default behavior of POSIX ACLs
153                  * is to set the mask to be the requested group permission
154                  * bits, not the group permission bits to be the requested
155                  * group permission bits. This is not what we want, as it will
156                  * mess up any inherited ACL bits that were set. JRA.
157                  */
158                 int saved_errno = errno; /* We may get ENOSYS */
159                 if ((SMB_VFS_CHMOD_ACL(handle->conn, path, mode) == -1) && (errno == ENOSYS))
160                         errno = saved_errno;
161         }
162
163         END_PROFILE(syscall_mkdir);
164         return result;
165 }
166
167 static int vfswrap_rmdir(vfs_handle_struct *handle,  const char *path)
168 {
169         int result;
170
171         START_PROFILE(syscall_rmdir);
172         result = rmdir(path);
173         END_PROFILE(syscall_rmdir);
174         return result;
175 }
176
177 static int vfswrap_closedir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp)
178 {
179         int result;
180
181         START_PROFILE(syscall_closedir);
182         result = sys_closedir(dirp);
183         END_PROFILE(syscall_closedir);
184         return result;
185 }
186
187 /* File operations */
188
189 static int vfswrap_open(vfs_handle_struct *handle,  const char *fname,
190         files_struct *fsp, int flags, mode_t mode)
191 {
192         int result;
193
194         START_PROFILE(syscall_open);
195         result = sys_open(fname, flags, mode);
196         END_PROFILE(syscall_open);
197         return result;
198 }
199
200 static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
201 {
202         int result;
203
204         START_PROFILE(syscall_close);
205
206         result = close(fd);
207         END_PROFILE(syscall_close);
208         return result;
209 }
210
211 static ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n)
212 {
213         ssize_t result;
214
215         START_PROFILE_BYTES(syscall_read, n);
216         result = sys_read(fd, data, n);
217         END_PROFILE(syscall_read);
218         return result;
219 }
220
221 static ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, void *data,
222                         size_t n, SMB_OFF_T offset)
223 {
224         ssize_t result;
225
226 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
227         START_PROFILE_BYTES(syscall_pread, n);
228         result = sys_pread(fsp->fh->fd, data, n, offset);
229         END_PROFILE(syscall_pread);
230
231         if (result == -1 && errno == ESPIPE) {
232                 /* Maintain the fiction that pipes can be seeked (sought?) on. */
233                 result = SMB_VFS_READ(fsp, fsp->fh->fd, data, n);
234                 fsp->fh->pos = 0;
235         }
236
237 #else /* HAVE_PREAD */
238         SMB_OFF_T   curr;
239         int lerrno;
240
241         curr = SMB_VFS_LSEEK(fsp, fsp->fh->fd, 0, SEEK_CUR);
242         if (curr == -1 && errno == ESPIPE) {
243                 /* Maintain the fiction that pipes can be seeked (sought?) on. */
244                 result = SMB_VFS_READ(fsp, fsp->fh->fd, data, n);
245                 fsp->fh->pos = 0;
246                 return result;
247         }
248
249         if (SMB_VFS_LSEEK(fsp, fsp->fh->fd, offset, SEEK_SET) == -1) {
250                 return -1;
251         }
252
253         errno = 0;
254         result = SMB_VFS_READ(fsp, fsp->fh->fd, data, n);
255         lerrno = errno;
256
257         SMB_VFS_LSEEK(fsp, fsp->fh->fd, curr, SEEK_SET);
258         errno = lerrno;
259
260 #endif /* HAVE_PREAD */
261
262         return result;
263 }
264
265 static ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n)
266 {
267         ssize_t result;
268
269         START_PROFILE_BYTES(syscall_write, n);
270         result = sys_write(fd, data, n);
271         END_PROFILE(syscall_write);
272         return result;
273 }
274
275 static ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, const void *data,
276                         size_t n, SMB_OFF_T offset)
277 {
278         ssize_t result;
279
280 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
281         START_PROFILE_BYTES(syscall_pwrite, n);
282         result = sys_pwrite(fsp->fh->fd, data, n, offset);
283         END_PROFILE(syscall_pwrite);
284
285         if (result == -1 && errno == ESPIPE) {
286                 /* Maintain the fiction that pipes can be sought on. */
287                 result = SMB_VFS_WRITE(fsp, fsp->fh->fd, data, n);
288         }
289
290 #else /* HAVE_PWRITE */
291         SMB_OFF_T   curr;
292         int         lerrno;
293
294         curr = SMB_VFS_LSEEK(fsp, fsp->fh->fd, 0, SEEK_CUR);
295         if (curr == -1) {
296                 return -1;
297         }
298
299         if (SMB_VFS_LSEEK(fsp, fsp->fh->fd, offset, SEEK_SET) == -1) {
300                 return -1;
301         }
302
303         result = SMB_VFS_WRITE(fsp, fsp->fh->fd, data, n);
304         lerrno = errno;
305
306         SMB_VFS_LSEEK(fsp, fsp->fh->fd, curr, SEEK_SET);
307         errno = lerrno;
308
309 #endif /* HAVE_PWRITE */
310
311         return result;
312 }
313
314 static SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
315 {
316         SMB_OFF_T result = 0;
317
318         START_PROFILE(syscall_lseek);
319
320         /* Cope with 'stat' file opens. */
321         if (filedes != -1)
322                 result = sys_lseek(filedes, offset, whence);
323
324         /*
325          * We want to maintain the fiction that we can seek
326          * on a fifo for file system purposes. This allows
327          * people to set up UNIX fifo's that feed data to Windows
328          * applications. JRA.
329          */
330
331         if((result == -1) && (errno == ESPIPE)) {
332                 result = 0;
333                 errno = 0;
334         }
335
336         END_PROFILE(syscall_lseek);
337         return result;
338 }
339
340 static ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *hdr,
341                         SMB_OFF_T offset, size_t n)
342 {
343         ssize_t result;
344
345         START_PROFILE_BYTES(syscall_sendfile, n);
346         result = sys_sendfile(tofd, fromfd, hdr, offset, n);
347         END_PROFILE(syscall_sendfile);
348         return result;
349 }
350
351 static ssize_t vfswrap_recvfile(vfs_handle_struct *handle,
352                         int fromfd,
353                         files_struct *fsp,
354                         int tofd,
355                         SMB_OFF_T offset,
356                         size_t n)
357 {
358         ssize_t result;
359
360         START_PROFILE_BYTES(syscall_recvfile, n);
361         result = sys_recvfile(fromfd, tofd, offset, n);
362         END_PROFILE(syscall_recvfile);
363         return result;
364 }
365
366 /*********************************************************
367  For rename across filesystems Patch from Warren Birnbaum
368  <warrenb@hpcvscdp.cv.hp.com>
369 **********************************************************/
370
371 static int copy_reg(const char *source, const char *dest)
372 {
373         SMB_STRUCT_STAT source_stats;
374         int saved_errno;
375         int ifd = -1;
376         int ofd = -1;
377
378         if (sys_lstat (source, &source_stats) == -1)
379                 return -1;
380
381         if (!S_ISREG (source_stats.st_mode))
382                 return -1;
383
384         if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
385                 return -1;
386
387         if (unlink (dest) && errno != ENOENT)
388                 return -1;
389
390 #ifdef O_NOFOLLOW
391         if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 )
392 #else
393         if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )
394 #endif
395                 goto err;
396
397         if (transfer_file(ifd, ofd, (size_t)-1) == -1)
398                 goto err;
399
400         /*
401          * Try to preserve ownership.  For non-root it might fail, but that's ok.
402          * But root probably wants to know, e.g. if NFS disallows it.
403          */
404
405 #ifdef HAVE_FCHOWN
406         if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
407 #else
408         if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
409 #endif
410                 goto err;
411
412         /*
413          * fchown turns off set[ug]id bits for non-root,
414          * so do the chmod last.
415          */
416
417 #if defined(HAVE_FCHMOD)
418         if (fchmod (ofd, source_stats.st_mode & 07777))
419 #else
420         if (chmod (dest, source_stats.st_mode & 07777))
421 #endif
422                 goto err;
423
424         if (close (ifd) == -1)
425                 goto err;
426
427         if (close (ofd) == -1)
428                 return -1;
429
430         /* Try to copy the old file's modtime and access time.  */
431         {
432                 struct utimbuf tv;
433
434                 tv.actime = source_stats.st_atime;
435                 tv.modtime = source_stats.st_mtime;
436                 utime(dest, &tv);
437         }
438
439         if (unlink (source) == -1)
440                 return -1;
441
442         return 0;
443
444   err:
445
446         saved_errno = errno;
447         if (ifd != -1)
448                 close(ifd);
449         if (ofd != -1)
450                 close(ofd);
451         errno = saved_errno;
452         return -1;
453 }
454
455 static int vfswrap_rename(vfs_handle_struct *handle,  const char *oldname, const char *newname)
456 {
457         int result;
458
459         START_PROFILE(syscall_rename);
460         result = rename(oldname, newname);
461         if (errno == EXDEV) {
462                 /* Rename across filesystems needed. */
463                 result = copy_reg(oldname, newname);
464         }
465
466         END_PROFILE(syscall_rename);
467         return result;
468 }
469
470 static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd)
471 {
472 #ifdef HAVE_FSYNC
473         int result;
474
475         START_PROFILE(syscall_fsync);
476         result = fsync(fd);
477         END_PROFILE(syscall_fsync);
478         return result;
479 #else
480         return 0;
481 #endif
482 }
483
484 static int vfswrap_stat(vfs_handle_struct *handle,  const char *fname, SMB_STRUCT_STAT *sbuf)
485 {
486         int result;
487
488         START_PROFILE(syscall_stat);
489         result = sys_stat(fname, sbuf);
490         END_PROFILE(syscall_stat);
491         return result;
492 }
493
494 static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
495 {
496         int result;
497
498         START_PROFILE(syscall_fstat);
499         result = sys_fstat(fd, sbuf);
500         END_PROFILE(syscall_fstat);
501         return result;
502 }
503
504 int vfswrap_lstat(vfs_handle_struct *handle,  const char *path, SMB_STRUCT_STAT *sbuf)
505 {
506         int result;
507
508         START_PROFILE(syscall_lstat);
509         result = sys_lstat(path, sbuf);
510         END_PROFILE(syscall_lstat);
511         return result;
512 }
513
514 static int vfswrap_unlink(vfs_handle_struct *handle,  const char *path)
515 {
516         int result;
517
518         START_PROFILE(syscall_unlink);
519         result = unlink(path);
520         END_PROFILE(syscall_unlink);
521         return result;
522 }
523
524 static int vfswrap_chmod(vfs_handle_struct *handle,  const char *path, mode_t mode)
525 {
526         int result;
527
528         START_PROFILE(syscall_chmod);
529
530         /*
531          * We need to do this due to the fact that the default POSIX ACL
532          * chmod modifies the ACL *mask* for the group owner, not the
533          * group owner bits directly. JRA.
534          */
535
536
537         {
538                 int saved_errno = errno; /* We might get ENOSYS */
539                 if ((result = SMB_VFS_CHMOD_ACL(handle->conn, path, mode)) == 0) {
540                         END_PROFILE(syscall_chmod);
541                         return result;
542                 }
543                 /* Error - return the old errno. */
544                 errno = saved_errno;
545         }
546
547         result = chmod(path, mode);
548         END_PROFILE(syscall_chmod);
549         return result;
550 }
551
552 static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
553 {
554         int result;
555
556         START_PROFILE(syscall_fchmod);
557
558         /*
559          * We need to do this due to the fact that the default POSIX ACL
560          * chmod modifies the ACL *mask* for the group owner, not the
561          * group owner bits directly. JRA.
562          */
563
564         {
565                 int saved_errno = errno; /* We might get ENOSYS */
566                 if ((result = SMB_VFS_FCHMOD_ACL(fsp, fd, mode)) == 0) {
567                         END_PROFILE(syscall_fchmod);
568                         return result;
569                 }
570                 /* Error - return the old errno. */
571                 errno = saved_errno;
572         }
573
574 #if defined(HAVE_FCHMOD)
575         result = fchmod(fd, mode);
576 #else
577         result = -1;
578         errno = ENOSYS;
579 #endif
580
581         END_PROFILE(syscall_fchmod);
582         return result;
583 }
584
585 static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
586 {
587         int result;
588
589         START_PROFILE(syscall_chown);
590         result = sys_chown(path, uid, gid);
591         END_PROFILE(syscall_chown);
592         return result;
593 }
594
595 static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid)
596 {
597 #ifdef HAVE_FCHOWN
598         int result;
599
600         START_PROFILE(syscall_fchown);
601         result = fchown(fd, uid, gid);
602         END_PROFILE(syscall_fchown);
603         return result;
604 #else
605         errno = ENOSYS;
606         return -1;
607 #endif
608 }
609
610 static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
611 {
612         int result;
613
614         START_PROFILE(syscall_lchown);
615         result = sys_lchown(path, uid, gid);
616         END_PROFILE(syscall_lchown);
617         return result;
618 }
619
620 static int vfswrap_chdir(vfs_handle_struct *handle,  const char *path)
621 {
622         int result;
623
624         START_PROFILE(syscall_chdir);
625         result = chdir(path);
626         END_PROFILE(syscall_chdir);
627         return result;
628 }
629
630 static char *vfswrap_getwd(vfs_handle_struct *handle,  char *path)
631 {
632         char *result;
633
634         START_PROFILE(syscall_getwd);
635         result = sys_getwd(path);
636         END_PROFILE(syscall_getwd);
637         return result;
638 }
639
640 /*********************************************************************
641  nsec timestamp resolution call. Convert down to whatever the underlying
642  system will support.
643 **********************************************************************/
644
645 static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2])
646 {
647         int result;
648
649         START_PROFILE(syscall_ntimes);
650 #if defined(HAVE_UTIMES)
651         {
652                 struct timeval tv[2];
653                 tv[0] = convert_timespec_to_timeval(ts[0]);
654                 tv[1] = convert_timespec_to_timeval(ts[1]);
655                 result = utimes(path, tv);
656         }
657 #elif defined(HAVE_UTIME)
658         {
659                 struct utimbuf times;
660                 times.actime = convert_timespec_to_time_t(ts[0]);
661                 times.modtime = convert_timespec_to_time_t(ts[1]);
662                 result = utime(path, times);
663         }
664 #else
665         errno = ENOSYS;
666         result = -1;
667 #endif
668         END_PROFILE(syscall_ntimes);
669         return result;
670 }
671
672 /*********************************************************************
673  A version of ftruncate that will write the space on disk if strict
674  allocate is set.
675 **********************************************************************/
676
677 static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
678 {
679         SMB_STRUCT_STAT st;
680         SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
681         unsigned char zero_space[4096];
682         SMB_OFF_T space_to_write;
683
684         if (currpos == -1)
685                 return -1;
686
687         if (SMB_VFS_FSTAT(fsp, fd, &st) == -1)
688                 return -1;
689
690         space_to_write = len - st.st_size;
691
692 #ifdef S_ISFIFO
693         if (S_ISFIFO(st.st_mode))
694                 return 0;
695 #endif
696
697         if (st.st_size == len)
698                 return 0;
699
700         /* Shrink - just ftruncate. */
701         if (st.st_size > len)
702                 return sys_ftruncate(fd, len);
703
704         /* Write out the real space on disk. */
705         if (SMB_VFS_LSEEK(fsp, fd, st.st_size, SEEK_SET) != st.st_size)
706                 return -1;
707
708         space_to_write = len - st.st_size;
709
710         memset(zero_space, '\0', sizeof(zero_space));
711         while ( space_to_write > 0) {
712                 SMB_OFF_T retlen;
713                 SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write);
714
715                 retlen = SMB_VFS_WRITE(fsp,fsp->fh->fd,(char *)zero_space,current_len_to_write);
716                 if (retlen <= 0)
717                         return -1;
718
719                 space_to_write -= retlen;
720         }
721
722         /* Seek to where we were */
723         if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
724                 return -1;
725
726         return 0;
727 }
728
729 static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
730 {
731         int result = -1;
732         SMB_STRUCT_STAT st;
733         char c = 0;
734         SMB_OFF_T currpos;
735
736         START_PROFILE(syscall_ftruncate);
737
738         if (lp_strict_allocate(SNUM(fsp->conn))) {
739                 result = strict_allocate_ftruncate(handle, fsp, fd, len);
740                 END_PROFILE(syscall_ftruncate);
741                 return result;
742         }
743
744         /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
745            sys_ftruncate if the system supports it. Then I discovered that
746            you can have some filesystems that support ftruncate
747            expansion and some that don't! On Linux fat can't do
748            ftruncate extend but ext2 can. */
749
750         result = sys_ftruncate(fd, len);
751         if (result == 0)
752                 goto done;
753
754         /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
755            extend a file with ftruncate. Provide alternate implementation
756            for this */
757         currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
758         if (currpos == -1) {
759                 goto done;
760         }
761
762         /* Do an fstat to see if the file is longer than the requested
763            size in which case the ftruncate above should have
764            succeeded or shorter, in which case seek to len - 1 and
765            write 1 byte of zero */
766         if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) {
767                 goto done;
768         }
769
770 #ifdef S_ISFIFO
771         if (S_ISFIFO(st.st_mode)) {
772                 result = 0;
773                 goto done;
774         }
775 #endif
776
777         if (st.st_size == len) {
778                 result = 0;
779                 goto done;
780         }
781
782         if (st.st_size > len) {
783                 /* the sys_ftruncate should have worked */
784                 goto done;
785         }
786
787         if (SMB_VFS_LSEEK(fsp, fd, len-1, SEEK_SET) != len -1)
788                 goto done;
789
790         if (SMB_VFS_WRITE(fsp, fd, &c, 1)!=1)
791                 goto done;
792
793         /* Seek to where we were */
794         if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
795                 goto done;
796         result = 0;
797
798   done:
799
800         END_PROFILE(syscall_ftruncate);
801         return result;
802 }
803
804 static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
805 {
806         bool result;
807
808         START_PROFILE(syscall_fcntl_lock);
809         result =  fcntl_lock(fd, op, offset, count, type);
810         END_PROFILE(syscall_fcntl_lock);
811         return result;
812 }
813
814 static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, int fd,
815                                 uint32 share_mode)
816 {
817         START_PROFILE(syscall_kernel_flock);
818         kernel_flock(fd, share_mode);
819         END_PROFILE(syscall_kernel_flock);
820         return 0;
821 }
822
823 static bool vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
824 {
825         bool result;
826
827         START_PROFILE(syscall_fcntl_getlock);
828         result =  fcntl_getlock(fd, poffset, pcount, ptype, ppid);
829         END_PROFILE(syscall_fcntl_getlock);
830         return result;
831 }
832
833 static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp, int fd,
834                                 int leasetype)
835 {
836         int result = -1;
837
838         START_PROFILE(syscall_linux_setlease);
839
840 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
841         /* first set the signal handler */
842         if(linux_set_lease_sighandler(fd) == -1) {
843                 return -1;
844         }
845
846         result = linux_setlease(fd, leasetype);
847 #else
848         errno = ENOSYS;
849 #endif
850         END_PROFILE(syscall_linux_setlease);
851         return result;
852 }
853
854 static int vfswrap_symlink(vfs_handle_struct *handle,  const char *oldpath, const char *newpath)
855 {
856         int result;
857
858         START_PROFILE(syscall_symlink);
859         result = sys_symlink(oldpath, newpath);
860         END_PROFILE(syscall_symlink);
861         return result;
862 }
863
864 static int vfswrap_readlink(vfs_handle_struct *handle,  const char *path, char *buf, size_t bufsiz)
865 {
866         int result;
867
868         START_PROFILE(syscall_readlink);
869         result = sys_readlink(path, buf, bufsiz);
870         END_PROFILE(syscall_readlink);
871         return result;
872 }
873
874 static int vfswrap_link(vfs_handle_struct *handle,  const char *oldpath, const char *newpath)
875 {
876         int result;
877
878         START_PROFILE(syscall_link);
879         result = sys_link(oldpath, newpath);
880         END_PROFILE(syscall_link);
881         return result;
882 }
883
884 static int vfswrap_mknod(vfs_handle_struct *handle,  const char *pathname, mode_t mode, SMB_DEV_T dev)
885 {
886         int result;
887
888         START_PROFILE(syscall_mknod);
889         result = sys_mknod(pathname, mode, dev);
890         END_PROFILE(syscall_mknod);
891         return result;
892 }
893
894 static char *vfswrap_realpath(vfs_handle_struct *handle,  const char *path, char *resolved_path)
895 {
896         char *result;
897
898         START_PROFILE(syscall_realpath);
899         result = sys_realpath(path, resolved_path);
900         END_PROFILE(syscall_realpath);
901         return result;
902 }
903
904 static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
905                                      struct sys_notify_context *ctx,
906                                      struct notify_entry *e,
907                                      void (*callback)(struct sys_notify_context *ctx, 
908                                                       void *private_data,
909                                                       struct notify_event *ev),
910                                      void *private_data, void *handle)
911 {
912         /*
913          * So far inotify is the only supported default notify mechanism. If
914          * another platform like the the BSD's or a proprietary Unix comes
915          * along and wants another default, we can play the same trick we
916          * played with Posix ACLs.
917          *
918          * Until that is the case, hard-code inotify here.
919          */
920 #ifdef HAVE_INOTIFY
921         if (lp_kernel_change_notify(ctx->conn->params)) {
922                 return inotify_watch(ctx, e, callback, private_data, handle);
923         }
924 #endif
925         /*
926          * Do nothing, leave everything to notify_internal.c
927          */
928         return NT_STATUS_OK;
929 }
930
931 static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flags)
932 {
933 #ifdef HAVE_CHFLAGS
934         return chflags(path, flags);
935 #else
936         errno = ENOSYS;
937         return -1;
938 #endif
939 }
940
941 static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle, SMB_DEV_T dev, SMB_INO_T inode)
942 {
943         return file_id_create_dev(dev, inode);
944 }
945
946 static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
947                                     files_struct *fsp,
948                                     uint32 security_info, SEC_DESC **ppdesc)
949 {
950         NTSTATUS result;
951
952         START_PROFILE(fget_nt_acl);
953         result = posix_fget_nt_acl(fsp, security_info, ppdesc);
954         END_PROFILE(fget_nt_acl);
955         return result;
956 }
957
958 static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
959                                    const char *name,
960                                    uint32 security_info, SEC_DESC **ppdesc)
961 {
962         NTSTATUS result;
963
964         START_PROFILE(get_nt_acl);
965         result = posix_get_nt_acl(handle->conn, name, security_info, ppdesc);
966         END_PROFILE(get_nt_acl);
967         return result;
968 }
969
970 static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
971 {
972         NTSTATUS result;
973
974         START_PROFILE(fset_nt_acl);
975         result = set_nt_acl(fsp, security_info_sent, psd);
976         END_PROFILE(fset_nt_acl);
977         return result;
978 }
979
980 static NTSTATUS vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
981 {
982         NTSTATUS result;
983
984         START_PROFILE(set_nt_acl);
985         result = set_nt_acl(fsp, security_info_sent, psd);
986         END_PROFILE(set_nt_acl);
987         return result;
988 }
989
990 static int vfswrap_chmod_acl(vfs_handle_struct *handle,  const char *name, mode_t mode)
991 {
992 #ifdef HAVE_NO_ACL
993         errno = ENOSYS;
994         return -1;
995 #else
996         int result;
997
998         START_PROFILE(chmod_acl);
999         result = chmod_acl(handle->conn, name, mode);
1000         END_PROFILE(chmod_acl);
1001         return result;
1002 #endif
1003 }
1004
1005 static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
1006 {
1007 #ifdef HAVE_NO_ACL
1008         errno = ENOSYS;
1009         return -1;
1010 #else
1011         int result;
1012
1013         START_PROFILE(fchmod_acl);
1014         result = fchmod_acl(fsp, fd, mode);
1015         END_PROFILE(fchmod_acl);
1016         return result;
1017 #endif
1018 }
1019
1020 static int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle,  SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1021 {
1022         return sys_acl_get_entry(theacl, entry_id, entry_p);
1023 }
1024
1025 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)
1026 {
1027         return sys_acl_get_tag_type(entry_d, tag_type_p);
1028 }
1029
1030 static int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1031 {
1032         return sys_acl_get_permset(entry_d, permset_p);
1033 }
1034
1035 static void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry_d)
1036 {
1037         return sys_acl_get_qualifier(entry_d);
1038 }
1039
1040 static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle,  const char *path_p, SMB_ACL_TYPE_T type)
1041 {
1042         return sys_acl_get_file(handle, path_p, type);
1043 }
1044
1045 static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
1046 {
1047         return sys_acl_get_fd(handle, fsp, fd);
1048 }
1049
1050 static int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset)
1051 {
1052         return sys_acl_clear_perms(permset);
1053 }
1054
1055 static int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1056 {
1057         return sys_acl_add_perm(permset, perm);
1058 }
1059
1060 static char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle,  SMB_ACL_T theacl, ssize_t *plen)
1061 {
1062         return sys_acl_to_text(theacl, plen);
1063 }
1064
1065 static SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle,  int count)
1066 {
1067         return sys_acl_init(count);
1068 }
1069
1070 static int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle,  SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
1071 {
1072         return sys_acl_create_entry(pacl, pentry);
1073 }
1074
1075 static int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
1076 {
1077         return sys_acl_set_tag_type(entry, tagtype);
1078 }
1079
1080 static int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, void *qual)
1081 {
1082         return sys_acl_set_qualifier(entry, qual);
1083 }
1084
1085 static int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
1086 {
1087         return sys_acl_set_permset(entry, permset);
1088 }
1089
1090 static int vfswrap_sys_acl_valid(vfs_handle_struct *handle,  SMB_ACL_T theacl )
1091 {
1092         return sys_acl_valid(theacl );
1093 }
1094
1095 static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle,  const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1096 {
1097         return sys_acl_set_file(handle, name, acltype, theacl);
1098 }
1099
1100 static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl)
1101 {
1102         return sys_acl_set_fd(handle, fsp, fd, theacl);
1103 }
1104
1105 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle,  const char *path)
1106 {
1107         return sys_acl_delete_def_file(handle, path);
1108 }
1109
1110 static int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1111 {
1112         return sys_acl_get_perm(permset, perm);
1113 }
1114
1115 static int vfswrap_sys_acl_free_text(vfs_handle_struct *handle,  char *text)
1116 {
1117         return sys_acl_free_text(text);
1118 }
1119
1120 static int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle,  SMB_ACL_T posix_acl)
1121 {
1122         return sys_acl_free_acl(posix_acl);
1123 }
1124
1125 static int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle,  void *qualifier, SMB_ACL_TAG_T tagtype)
1126 {
1127         return sys_acl_free_qualifier(qualifier, tagtype);
1128 }
1129
1130 /****************************************************************
1131  Extended attribute operations.
1132 *****************************************************************/
1133
1134 static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
1135 {
1136         return sys_getxattr(path, name, value, size);
1137 }
1138
1139 static ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
1140 {
1141         return sys_lgetxattr(path, name, value, size);
1142 }
1143
1144 static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size)
1145 {
1146         return sys_fgetxattr(fd, name, value, size);
1147 }
1148
1149 static ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
1150 {
1151         return sys_listxattr(path, list, size);
1152 }
1153
1154 ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
1155 {
1156         return sys_llistxattr(path, list, size);
1157 }
1158
1159 ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size)
1160 {
1161         return sys_flistxattr(fd, list, size);
1162 }
1163
1164 static int vfswrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
1165 {
1166         return sys_removexattr(path, name);
1167 }
1168
1169 static int vfswrap_lremovexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
1170 {
1171         return sys_lremovexattr(path, name);
1172 }
1173
1174 static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name)
1175 {
1176         return sys_fremovexattr(fd, name);
1177 }
1178
1179 static int vfswrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
1180 {
1181         return sys_setxattr(path, name, value, size, flags);
1182 }
1183
1184 static int vfswrap_lsetxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
1185 {
1186         return sys_lsetxattr(path, name, value, size, flags);
1187 }
1188
1189 static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags)
1190 {
1191         return sys_fsetxattr(fd, name, value, size, flags);
1192 }
1193
1194 static int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1195 {
1196         return sys_aio_read(aiocb);
1197 }
1198
1199 static int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1200 {
1201         return sys_aio_write(aiocb);
1202 }
1203
1204 static ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1205 {
1206         return sys_aio_return(aiocb);
1207 }
1208
1209 static int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_AIOCB *aiocb)
1210 {
1211         return sys_aio_cancel(fd, aiocb);
1212 }
1213
1214 static int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1215 {
1216         return sys_aio_error(aiocb);
1217 }
1218
1219 static int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb)
1220 {
1221         return sys_aio_fsync(op, aiocb);
1222 }
1223
1224 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)
1225 {
1226         return sys_aio_suspend(aiocb, n, timeout);
1227 }
1228
1229 static vfs_op_tuple vfs_default_ops[] = {
1230
1231         /* Disk operations */
1232
1233         {SMB_VFS_OP(vfswrap_connect),   SMB_VFS_OP_CONNECT,
1234          SMB_VFS_LAYER_OPAQUE},
1235         {SMB_VFS_OP(vfswrap_disconnect),        SMB_VFS_OP_DISCONNECT,
1236          SMB_VFS_LAYER_OPAQUE},
1237         {SMB_VFS_OP(vfswrap_disk_free), SMB_VFS_OP_DISK_FREE,
1238          SMB_VFS_LAYER_OPAQUE},
1239         {SMB_VFS_OP(vfswrap_get_quota), SMB_VFS_OP_GET_QUOTA,
1240          SMB_VFS_LAYER_OPAQUE},
1241         {SMB_VFS_OP(vfswrap_set_quota), SMB_VFS_OP_SET_QUOTA,
1242          SMB_VFS_LAYER_OPAQUE},
1243         {SMB_VFS_OP(vfswrap_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA,
1244          SMB_VFS_LAYER_OPAQUE},
1245         {SMB_VFS_OP(vfswrap_statvfs),   SMB_VFS_OP_STATVFS,
1246          SMB_VFS_LAYER_OPAQUE},
1247
1248         /* Directory operations */
1249
1250         {SMB_VFS_OP(vfswrap_opendir),   SMB_VFS_OP_OPENDIR,
1251          SMB_VFS_LAYER_OPAQUE},
1252         {SMB_VFS_OP(vfswrap_readdir),   SMB_VFS_OP_READDIR,
1253          SMB_VFS_LAYER_OPAQUE},
1254         {SMB_VFS_OP(vfswrap_seekdir),   SMB_VFS_OP_SEEKDIR,
1255          SMB_VFS_LAYER_OPAQUE},
1256         {SMB_VFS_OP(vfswrap_telldir),   SMB_VFS_OP_TELLDIR,
1257          SMB_VFS_LAYER_OPAQUE},
1258         {SMB_VFS_OP(vfswrap_rewinddir), SMB_VFS_OP_REWINDDIR,
1259          SMB_VFS_LAYER_OPAQUE},
1260         {SMB_VFS_OP(vfswrap_mkdir),     SMB_VFS_OP_MKDIR,
1261          SMB_VFS_LAYER_OPAQUE},
1262         {SMB_VFS_OP(vfswrap_rmdir),     SMB_VFS_OP_RMDIR,
1263          SMB_VFS_LAYER_OPAQUE},
1264         {SMB_VFS_OP(vfswrap_closedir),  SMB_VFS_OP_CLOSEDIR,
1265          SMB_VFS_LAYER_OPAQUE},
1266
1267         /* File operations */
1268
1269         {SMB_VFS_OP(vfswrap_open),      SMB_VFS_OP_OPEN,
1270          SMB_VFS_LAYER_OPAQUE},
1271         {SMB_VFS_OP(vfswrap_close),     SMB_VFS_OP_CLOSE,
1272          SMB_VFS_LAYER_OPAQUE},
1273         {SMB_VFS_OP(vfswrap_read),      SMB_VFS_OP_READ,
1274          SMB_VFS_LAYER_OPAQUE},
1275         {SMB_VFS_OP(vfswrap_pread),     SMB_VFS_OP_PREAD,
1276          SMB_VFS_LAYER_OPAQUE},
1277         {SMB_VFS_OP(vfswrap_write),     SMB_VFS_OP_WRITE,
1278          SMB_VFS_LAYER_OPAQUE},
1279         {SMB_VFS_OP(vfswrap_pwrite),    SMB_VFS_OP_PWRITE,
1280          SMB_VFS_LAYER_OPAQUE},
1281         {SMB_VFS_OP(vfswrap_lseek),     SMB_VFS_OP_LSEEK,
1282          SMB_VFS_LAYER_OPAQUE},
1283         {SMB_VFS_OP(vfswrap_sendfile),  SMB_VFS_OP_SENDFILE,
1284          SMB_VFS_LAYER_OPAQUE},
1285         {SMB_VFS_OP(vfswrap_recvfile),  SMB_VFS_OP_RECVFILE,
1286          SMB_VFS_LAYER_OPAQUE},
1287         {SMB_VFS_OP(vfswrap_rename),    SMB_VFS_OP_RENAME,
1288          SMB_VFS_LAYER_OPAQUE},
1289         {SMB_VFS_OP(vfswrap_fsync),     SMB_VFS_OP_FSYNC,
1290          SMB_VFS_LAYER_OPAQUE},
1291         {SMB_VFS_OP(vfswrap_stat),      SMB_VFS_OP_STAT,
1292          SMB_VFS_LAYER_OPAQUE},
1293         {SMB_VFS_OP(vfswrap_fstat),     SMB_VFS_OP_FSTAT,
1294          SMB_VFS_LAYER_OPAQUE},
1295         {SMB_VFS_OP(vfswrap_lstat),     SMB_VFS_OP_LSTAT,
1296          SMB_VFS_LAYER_OPAQUE},
1297         {SMB_VFS_OP(vfswrap_unlink),    SMB_VFS_OP_UNLINK,
1298          SMB_VFS_LAYER_OPAQUE},
1299         {SMB_VFS_OP(vfswrap_chmod),     SMB_VFS_OP_CHMOD,
1300          SMB_VFS_LAYER_OPAQUE},
1301         {SMB_VFS_OP(vfswrap_fchmod),    SMB_VFS_OP_FCHMOD,
1302          SMB_VFS_LAYER_OPAQUE},
1303         {SMB_VFS_OP(vfswrap_chown),     SMB_VFS_OP_CHOWN,
1304          SMB_VFS_LAYER_OPAQUE},
1305         {SMB_VFS_OP(vfswrap_fchown),    SMB_VFS_OP_FCHOWN,
1306          SMB_VFS_LAYER_OPAQUE},
1307         {SMB_VFS_OP(vfswrap_lchown),    SMB_VFS_OP_LCHOWN,
1308          SMB_VFS_LAYER_OPAQUE},
1309         {SMB_VFS_OP(vfswrap_chdir),     SMB_VFS_OP_CHDIR,
1310          SMB_VFS_LAYER_OPAQUE},
1311         {SMB_VFS_OP(vfswrap_getwd),     SMB_VFS_OP_GETWD,
1312          SMB_VFS_LAYER_OPAQUE},
1313         {SMB_VFS_OP(vfswrap_ntimes),    SMB_VFS_OP_NTIMES,
1314          SMB_VFS_LAYER_OPAQUE},
1315         {SMB_VFS_OP(vfswrap_ftruncate), SMB_VFS_OP_FTRUNCATE,
1316          SMB_VFS_LAYER_OPAQUE},
1317         {SMB_VFS_OP(vfswrap_lock),      SMB_VFS_OP_LOCK,
1318          SMB_VFS_LAYER_OPAQUE},
1319         {SMB_VFS_OP(vfswrap_kernel_flock),      SMB_VFS_OP_KERNEL_FLOCK,
1320          SMB_VFS_LAYER_OPAQUE},
1321         {SMB_VFS_OP(vfswrap_linux_setlease),    SMB_VFS_OP_LINUX_SETLEASE,
1322          SMB_VFS_LAYER_OPAQUE},
1323         {SMB_VFS_OP(vfswrap_getlock),   SMB_VFS_OP_GETLOCK,
1324          SMB_VFS_LAYER_OPAQUE},
1325         {SMB_VFS_OP(vfswrap_symlink),   SMB_VFS_OP_SYMLINK,
1326          SMB_VFS_LAYER_OPAQUE},
1327         {SMB_VFS_OP(vfswrap_readlink),  SMB_VFS_OP_READLINK,
1328          SMB_VFS_LAYER_OPAQUE},
1329         {SMB_VFS_OP(vfswrap_link),      SMB_VFS_OP_LINK,
1330          SMB_VFS_LAYER_OPAQUE},
1331         {SMB_VFS_OP(vfswrap_mknod),     SMB_VFS_OP_MKNOD,
1332          SMB_VFS_LAYER_OPAQUE},
1333         {SMB_VFS_OP(vfswrap_realpath),  SMB_VFS_OP_REALPATH,
1334          SMB_VFS_LAYER_OPAQUE},
1335         {SMB_VFS_OP(vfswrap_notify_watch),      SMB_VFS_OP_NOTIFY_WATCH,
1336          SMB_VFS_LAYER_OPAQUE},
1337         {SMB_VFS_OP(vfswrap_chflags),   SMB_VFS_OP_CHFLAGS,
1338          SMB_VFS_LAYER_OPAQUE},
1339         {SMB_VFS_OP(vfswrap_file_id_create),    SMB_VFS_OP_FILE_ID_CREATE,
1340          SMB_VFS_LAYER_OPAQUE},
1341
1342         /* NT ACL operations. */
1343
1344         {SMB_VFS_OP(vfswrap_fget_nt_acl),       SMB_VFS_OP_FGET_NT_ACL,
1345          SMB_VFS_LAYER_OPAQUE},
1346         {SMB_VFS_OP(vfswrap_get_nt_acl),        SMB_VFS_OP_GET_NT_ACL,
1347          SMB_VFS_LAYER_OPAQUE},
1348         {SMB_VFS_OP(vfswrap_fset_nt_acl),       SMB_VFS_OP_FSET_NT_ACL,
1349          SMB_VFS_LAYER_OPAQUE},
1350         {SMB_VFS_OP(vfswrap_set_nt_acl),        SMB_VFS_OP_SET_NT_ACL,
1351          SMB_VFS_LAYER_OPAQUE},
1352
1353         /* POSIX ACL operations. */
1354
1355         {SMB_VFS_OP(vfswrap_chmod_acl), SMB_VFS_OP_CHMOD_ACL,
1356          SMB_VFS_LAYER_OPAQUE},
1357         {SMB_VFS_OP(vfswrap_fchmod_acl),        SMB_VFS_OP_FCHMOD_ACL,
1358          SMB_VFS_LAYER_OPAQUE},
1359         {SMB_VFS_OP(vfswrap_sys_acl_get_entry), SMB_VFS_OP_SYS_ACL_GET_ENTRY,
1360          SMB_VFS_LAYER_OPAQUE},
1361         {SMB_VFS_OP(vfswrap_sys_acl_get_tag_type),      SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE,
1362          SMB_VFS_LAYER_OPAQUE},
1363         {SMB_VFS_OP(vfswrap_sys_acl_get_permset),       SMB_VFS_OP_SYS_ACL_GET_PERMSET,
1364          SMB_VFS_LAYER_OPAQUE},
1365         {SMB_VFS_OP(vfswrap_sys_acl_get_qualifier),     SMB_VFS_OP_SYS_ACL_GET_QUALIFIER,
1366          SMB_VFS_LAYER_OPAQUE},
1367         {SMB_VFS_OP(vfswrap_sys_acl_get_file),  SMB_VFS_OP_SYS_ACL_GET_FILE,
1368          SMB_VFS_LAYER_OPAQUE},
1369         {SMB_VFS_OP(vfswrap_sys_acl_get_fd),    SMB_VFS_OP_SYS_ACL_GET_FD,
1370          SMB_VFS_LAYER_OPAQUE},
1371         {SMB_VFS_OP(vfswrap_sys_acl_clear_perms),       SMB_VFS_OP_SYS_ACL_CLEAR_PERMS,
1372          SMB_VFS_LAYER_OPAQUE},
1373         {SMB_VFS_OP(vfswrap_sys_acl_add_perm),  SMB_VFS_OP_SYS_ACL_ADD_PERM,
1374          SMB_VFS_LAYER_OPAQUE},
1375         {SMB_VFS_OP(vfswrap_sys_acl_to_text),   SMB_VFS_OP_SYS_ACL_TO_TEXT,
1376          SMB_VFS_LAYER_OPAQUE},
1377         {SMB_VFS_OP(vfswrap_sys_acl_init),      SMB_VFS_OP_SYS_ACL_INIT,
1378          SMB_VFS_LAYER_OPAQUE},
1379         {SMB_VFS_OP(vfswrap_sys_acl_create_entry),      SMB_VFS_OP_SYS_ACL_CREATE_ENTRY,
1380          SMB_VFS_LAYER_OPAQUE},
1381         {SMB_VFS_OP(vfswrap_sys_acl_set_tag_type),      SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE,
1382          SMB_VFS_LAYER_OPAQUE},
1383         {SMB_VFS_OP(vfswrap_sys_acl_set_qualifier),     SMB_VFS_OP_SYS_ACL_SET_QUALIFIER,
1384          SMB_VFS_LAYER_OPAQUE},
1385         {SMB_VFS_OP(vfswrap_sys_acl_set_permset),       SMB_VFS_OP_SYS_ACL_SET_PERMSET,
1386          SMB_VFS_LAYER_OPAQUE},
1387         {SMB_VFS_OP(vfswrap_sys_acl_valid),     SMB_VFS_OP_SYS_ACL_VALID,
1388          SMB_VFS_LAYER_OPAQUE},
1389         {SMB_VFS_OP(vfswrap_sys_acl_set_file),  SMB_VFS_OP_SYS_ACL_SET_FILE,
1390          SMB_VFS_LAYER_OPAQUE},
1391         {SMB_VFS_OP(vfswrap_sys_acl_set_fd),    SMB_VFS_OP_SYS_ACL_SET_FD,
1392          SMB_VFS_LAYER_OPAQUE},
1393         {SMB_VFS_OP(vfswrap_sys_acl_delete_def_file),   SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
1394          SMB_VFS_LAYER_OPAQUE},
1395         {SMB_VFS_OP(vfswrap_sys_acl_get_perm),  SMB_VFS_OP_SYS_ACL_GET_PERM,
1396          SMB_VFS_LAYER_OPAQUE},
1397         {SMB_VFS_OP(vfswrap_sys_acl_free_text), SMB_VFS_OP_SYS_ACL_FREE_TEXT,
1398          SMB_VFS_LAYER_OPAQUE},
1399         {SMB_VFS_OP(vfswrap_sys_acl_free_acl),  SMB_VFS_OP_SYS_ACL_FREE_ACL,
1400          SMB_VFS_LAYER_OPAQUE},
1401         {SMB_VFS_OP(vfswrap_sys_acl_free_qualifier),    SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER,
1402          SMB_VFS_LAYER_OPAQUE},
1403
1404         /* EA operations. */
1405
1406         {SMB_VFS_OP(vfswrap_getxattr),  SMB_VFS_OP_GETXATTR,
1407          SMB_VFS_LAYER_OPAQUE},
1408         {SMB_VFS_OP(vfswrap_lgetxattr), SMB_VFS_OP_LGETXATTR,
1409          SMB_VFS_LAYER_OPAQUE},
1410         {SMB_VFS_OP(vfswrap_fgetxattr), SMB_VFS_OP_FGETXATTR,
1411          SMB_VFS_LAYER_OPAQUE},
1412         {SMB_VFS_OP(vfswrap_listxattr), SMB_VFS_OP_LISTXATTR,
1413          SMB_VFS_LAYER_OPAQUE},
1414         {SMB_VFS_OP(vfswrap_llistxattr),        SMB_VFS_OP_LLISTXATTR,
1415          SMB_VFS_LAYER_OPAQUE},
1416         {SMB_VFS_OP(vfswrap_flistxattr),        SMB_VFS_OP_FLISTXATTR,
1417          SMB_VFS_LAYER_OPAQUE},
1418         {SMB_VFS_OP(vfswrap_removexattr),       SMB_VFS_OP_REMOVEXATTR,
1419          SMB_VFS_LAYER_OPAQUE},
1420         {SMB_VFS_OP(vfswrap_lremovexattr),      SMB_VFS_OP_LREMOVEXATTR,
1421          SMB_VFS_LAYER_OPAQUE},
1422         {SMB_VFS_OP(vfswrap_fremovexattr),      SMB_VFS_OP_FREMOVEXATTR,
1423          SMB_VFS_LAYER_OPAQUE},
1424         {SMB_VFS_OP(vfswrap_setxattr),  SMB_VFS_OP_SETXATTR,
1425          SMB_VFS_LAYER_OPAQUE},
1426         {SMB_VFS_OP(vfswrap_lsetxattr), SMB_VFS_OP_LSETXATTR,
1427          SMB_VFS_LAYER_OPAQUE},
1428         {SMB_VFS_OP(vfswrap_fsetxattr), SMB_VFS_OP_FSETXATTR,
1429          SMB_VFS_LAYER_OPAQUE},
1430
1431         {SMB_VFS_OP(vfswrap_aio_read),  SMB_VFS_OP_AIO_READ,
1432          SMB_VFS_LAYER_OPAQUE},
1433         {SMB_VFS_OP(vfswrap_aio_write), SMB_VFS_OP_AIO_WRITE,
1434          SMB_VFS_LAYER_OPAQUE},
1435         {SMB_VFS_OP(vfswrap_aio_return),        SMB_VFS_OP_AIO_RETURN,
1436          SMB_VFS_LAYER_OPAQUE},
1437         {SMB_VFS_OP(vfswrap_aio_cancel), SMB_VFS_OP_AIO_CANCEL,
1438          SMB_VFS_LAYER_OPAQUE},
1439         {SMB_VFS_OP(vfswrap_aio_error), SMB_VFS_OP_AIO_ERROR,
1440          SMB_VFS_LAYER_OPAQUE},
1441         {SMB_VFS_OP(vfswrap_aio_fsync), SMB_VFS_OP_AIO_FSYNC,
1442          SMB_VFS_LAYER_OPAQUE},
1443         {SMB_VFS_OP(vfswrap_aio_suspend),SMB_VFS_OP_AIO_SUSPEND,
1444          SMB_VFS_LAYER_OPAQUE},
1445
1446         /* Finish VFS operations definition */
1447
1448         {SMB_VFS_OP(NULL),              SMB_VFS_OP_NOOP,
1449          SMB_VFS_LAYER_NOOP}
1450 };
1451
1452 NTSTATUS vfs_default_init(void);
1453 NTSTATUS vfs_default_init(void)
1454 {
1455         unsigned int needed = SMB_VFS_OP_LAST + 1; /* convert from index to count */
1456
1457         if (ARRAY_SIZE(vfs_default_ops) != needed) {
1458                 DEBUG(0, ("%s: %u ops registered, but %u ops are required\n",
1459                         DEFAULT_VFS_MODULE_NAME, (unsigned int)ARRAY_SIZE(vfs_default_ops), needed));
1460                 smb_panic("operation(s) missing from default VFS module");
1461         }
1462
1463         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
1464                                 DEFAULT_VFS_MODULE_NAME, vfs_default_ops);
1465 }