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