s3-build: only include transfer_file.h where needed.
[amitay/samba.git] / source3 / smbd / vfs.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    VFS initialisation and support functions
5    Copyright (C) Tim Potter 1999
6    Copyright (C) Alexander Bokovoy 2002
7    Copyright (C) James Peach 2006
8    Copyright (C) Volker Lendecke 2009
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23    This work was sponsored by Optifacio Software Services, Inc.
24 */
25
26 #include "includes.h"
27 #include "system/filesys.h"
28 #include "smbd/globals.h"
29 #include "memcache.h"
30 #include "transfer_file.h"
31
32 #undef DBGC_CLASS
33 #define DBGC_CLASS DBGC_VFS
34
35 static_decl_vfs;
36
37 struct vfs_init_function_entry {
38         char *name;
39         struct vfs_init_function_entry *prev, *next;
40         const struct vfs_fn_pointers *fns;
41 };
42
43 /****************************************************************************
44     maintain the list of available backends
45 ****************************************************************************/
46
47 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
48 {
49         struct vfs_init_function_entry *entry = backends;
50
51         DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
52
53         while(entry) {
54                 if (strcmp(entry->name, name)==0) return entry;
55                 entry = entry->next;
56         }
57
58         return NULL;
59 }
60
61 NTSTATUS smb_register_vfs(int version, const char *name,
62                           const struct vfs_fn_pointers *fns)
63 {
64         struct vfs_init_function_entry *entry = backends;
65
66         if ((version != SMB_VFS_INTERFACE_VERSION)) {
67                 DEBUG(0, ("Failed to register vfs module.\n"
68                           "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
69                           "current SMB_VFS_INTERFACE_VERSION is %d.\n"
70                           "Please recompile against the current Samba Version!\n",  
71                           version, SMB_VFS_INTERFACE_VERSION));
72                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
73         }
74
75         if (!name || !name[0]) {
76                 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
77                 return NT_STATUS_INVALID_PARAMETER;
78         }
79
80         if (vfs_find_backend_entry(name)) {
81                 DEBUG(0,("VFS module %s already loaded!\n", name));
82                 return NT_STATUS_OBJECT_NAME_COLLISION;
83         }
84
85         entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
86         entry->name = smb_xstrdup(name);
87         entry->fns = fns;
88
89         DLIST_ADD(backends, entry);
90         DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
91         return NT_STATUS_OK;
92 }
93
94 /****************************************************************************
95   initialise default vfs hooks
96 ****************************************************************************/
97
98 static void vfs_init_default(connection_struct *conn)
99 {
100         DEBUG(3, ("Initialising default vfs hooks\n"));
101         vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
102 }
103
104 /****************************************************************************
105   initialise custom vfs hooks
106  ****************************************************************************/
107
108 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
109 {
110         char *module_path = NULL;
111         char *module_name = NULL;
112         char *module_param = NULL, *p;
113         vfs_handle_struct *handle;
114         const struct vfs_init_function_entry *entry;
115
116         if (!conn||!vfs_object||!vfs_object[0]) {
117                 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
118                           "empty vfs_object!\n"));
119                 return False;
120         }
121
122         if(!backends) {
123                 static_init_vfs;
124         }
125
126         DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
127
128         module_path = smb_xstrdup(vfs_object);
129
130         p = strchr_m(module_path, ':');
131
132         if (p) {
133                 *p = 0;
134                 module_param = p+1;
135                 trim_char(module_param, ' ', ' ');
136         }
137
138         trim_char(module_path, ' ', ' ');
139
140         module_name = smb_xstrdup(module_path);
141
142         if ((module_name[0] == '/') &&
143             (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
144
145                 /*
146                  * Extract the module name from the path. Just use the base
147                  * name of the last path component.
148                  */
149
150                 SAFE_FREE(module_name);
151                 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
152
153                 p = strchr_m(module_name, '.');
154
155                 if (p != NULL) {
156                         *p = '\0';
157                 }
158         }
159
160         /* First, try to load the module with the new module system */
161         entry = vfs_find_backend_entry(module_name);
162         if (!entry) {
163                 NTSTATUS status;
164
165                 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
166                           vfs_object));
167
168                 status = smb_probe_module("vfs", module_path);
169                 if (!NT_STATUS_IS_OK(status)) {
170                         DEBUG(0, ("error probing vfs module '%s': %s\n",
171                                   module_path, nt_errstr(status)));
172                         goto fail;
173                 }
174
175                 entry = vfs_find_backend_entry(module_name);
176                 if (!entry) {
177                         DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
178                         goto fail;
179                 }
180         }
181
182         DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
183
184         handle = TALLOC_ZERO_P(conn, vfs_handle_struct);
185         if (!handle) {
186                 DEBUG(0,("TALLOC_ZERO() failed!\n"));
187                 goto fail;
188         }
189         handle->conn = conn;
190         handle->fns = entry->fns;
191         if (module_param) {
192                 handle->param = talloc_strdup(conn, module_param);
193         }
194         DLIST_ADD(conn->vfs_handles, handle);
195
196         SAFE_FREE(module_path);
197         SAFE_FREE(module_name);
198         return True;
199
200  fail:
201         SAFE_FREE(module_path);
202         SAFE_FREE(module_name);
203         return False;
204 }
205
206 /*****************************************************************
207  Allow VFS modules to extend files_struct with VFS-specific state.
208  This will be ok for small numbers of extensions, but might need to
209  be refactored if it becomes more widely used.
210 ******************************************************************/
211
212 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
213
214 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
215                                    files_struct *fsp, size_t ext_size,
216                                    void (*destroy_fn)(void *p_data))
217 {
218         struct vfs_fsp_data *ext;
219         void * ext_data;
220
221         /* Prevent VFS modules adding multiple extensions. */
222         if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
223                 return ext_data;
224         }
225
226         ext = (struct vfs_fsp_data *)TALLOC_ZERO(
227                 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
228         if (ext == NULL) {
229                 return NULL;
230         }
231
232         ext->owner = handle;
233         ext->next = fsp->vfs_extension;
234         ext->destroy = destroy_fn;
235         fsp->vfs_extension = ext;
236         return EXT_DATA_AREA(ext);
237 }
238
239 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
240 {
241         struct vfs_fsp_data *curr;
242         struct vfs_fsp_data *prev;
243
244         for (curr = fsp->vfs_extension, prev = NULL;
245              curr;
246              prev = curr, curr = curr->next) {
247                 if (curr->owner == handle) {
248                     if (prev) {
249                             prev->next = curr->next;
250                     } else {
251                             fsp->vfs_extension = curr->next;
252                     }
253                     if (curr->destroy) {
254                             curr->destroy(EXT_DATA_AREA(curr));
255                     }
256                     TALLOC_FREE(curr);
257                     return;
258                 }
259         }
260 }
261
262 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
263 {
264         struct vfs_fsp_data *head;
265
266         for (head = fsp->vfs_extension; head; head = head->next) {
267                 if (head->owner == handle) {
268                         return head;
269                 }
270         }
271
272         return NULL;
273 }
274
275 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
276 {
277         struct vfs_fsp_data *head;
278
279         head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
280         if (head != NULL) {
281                 return EXT_DATA_AREA(head);
282         }
283
284         return NULL;
285 }
286
287 #undef EXT_DATA_AREA
288
289 /*****************************************************************
290  Generic VFS init.
291 ******************************************************************/
292
293 bool smbd_vfs_init(connection_struct *conn)
294 {
295         const char **vfs_objects;
296         unsigned int i = 0;
297         int j = 0;
298
299         /* Normal share - initialise with disk access functions */
300         vfs_init_default(conn);
301         vfs_objects = lp_vfs_objects(SNUM(conn));
302
303         /* Override VFS functions if 'vfs object' was not specified*/
304         if (!vfs_objects || !vfs_objects[0])
305                 return True;
306
307         for (i=0; vfs_objects[i] ;) {
308                 i++;
309         }
310
311         for (j=i-1; j >= 0; j--) {
312                 if (!vfs_init_custom(conn, vfs_objects[j])) {
313                         DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
314                         return False;
315                 }
316         }
317         return True;
318 }
319
320 /*******************************************************************
321  Check if a file exists in the vfs.
322 ********************************************************************/
323
324 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
325 {
326         /* Only return OK if stat was successful and S_ISREG */
327         if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
328             S_ISREG(smb_fname->st.st_ex_mode)) {
329                 return NT_STATUS_OK;
330         }
331
332         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
333 }
334
335 /****************************************************************************
336  Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
337 ****************************************************************************/
338
339 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
340 {
341         size_t total=0;
342
343         while (total < byte_count)
344         {
345                 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
346                                            byte_count - total);
347
348                 if (ret == 0) return total;
349                 if (ret == -1) {
350                         if (errno == EINTR)
351                                 continue;
352                         else
353                                 return -1;
354                 }
355                 total += ret;
356         }
357         return (ssize_t)total;
358 }
359
360 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
361                 size_t byte_count, SMB_OFF_T offset)
362 {
363         size_t total=0;
364
365         while (total < byte_count)
366         {
367                 ssize_t ret = SMB_VFS_PREAD(fsp, buf + total,
368                                         byte_count - total, offset + total);
369
370                 if (ret == 0) return total;
371                 if (ret == -1) {
372                         if (errno == EINTR)
373                                 continue;
374                         else
375                                 return -1;
376                 }
377                 total += ret;
378         }
379         return (ssize_t)total;
380 }
381
382 /****************************************************************************
383  Write data to a fd on the vfs.
384 ****************************************************************************/
385
386 ssize_t vfs_write_data(struct smb_request *req,
387                         files_struct *fsp,
388                         const char *buffer,
389                         size_t N)
390 {
391         size_t total=0;
392         ssize_t ret;
393
394         if (req && req->unread_bytes) {
395                 SMB_ASSERT(req->unread_bytes == N);
396                 /* VFS_RECVFILE must drain the socket
397                  * before returning. */
398                 req->unread_bytes = 0;
399                 return SMB_VFS_RECVFILE(req->sconn->sock,
400                                         fsp,
401                                         (SMB_OFF_T)-1,
402                                         N);
403         }
404
405         while (total < N) {
406                 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
407
408                 if (ret == -1)
409                         return -1;
410                 if (ret == 0)
411                         return total;
412
413                 total += ret;
414         }
415         return (ssize_t)total;
416 }
417
418 ssize_t vfs_pwrite_data(struct smb_request *req,
419                         files_struct *fsp,
420                         const char *buffer,
421                         size_t N,
422                         SMB_OFF_T offset)
423 {
424         size_t total=0;
425         ssize_t ret;
426
427         if (req && req->unread_bytes) {
428                 SMB_ASSERT(req->unread_bytes == N);
429                 /* VFS_RECVFILE must drain the socket
430                  * before returning. */
431                 req->unread_bytes = 0;
432                 return SMB_VFS_RECVFILE(req->sconn->sock,
433                                         fsp,
434                                         offset,
435                                         N);
436         }
437
438         while (total < N) {
439                 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
440                                      offset + total);
441
442                 if (ret == -1)
443                         return -1;
444                 if (ret == 0)
445                         return total;
446
447                 total += ret;
448         }
449         return (ssize_t)total;
450 }
451 /****************************************************************************
452  An allocate file space call using the vfs interface.
453  Allocates space for a file from a filedescriptor.
454  Returns 0 on success, -1 on failure.
455 ****************************************************************************/
456
457 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
458 {
459         int ret;
460         connection_struct *conn = fsp->conn;
461         uint64_t space_avail;
462         uint64_t bsize,dfree,dsize;
463         NTSTATUS status;
464
465         /*
466          * Actually try and commit the space on disk....
467          */
468
469         DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
470                   fsp_str_dbg(fsp), (double)len));
471
472         if (((SMB_OFF_T)len) < 0) {
473                 DEBUG(0,("vfs_allocate_file_space: %s negative len "
474                          "requested.\n", fsp_str_dbg(fsp)));
475                 errno = EINVAL;
476                 return -1;
477         }
478
479         status = vfs_stat_fsp(fsp);
480         if (!NT_STATUS_IS_OK(status)) {
481                 return -1;
482         }
483
484         if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
485                 return 0;
486
487         if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
488                 /* Shrink - use ftruncate. */
489
490                 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
491                           "size %.0f\n", fsp_str_dbg(fsp),
492                           (double)fsp->fsp_name->st.st_ex_size));
493
494                 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
495
496                 flush_write_cache(fsp, SIZECHANGE_FLUSH);
497                 if ((ret = SMB_VFS_FTRUNCATE(fsp, (SMB_OFF_T)len)) != -1) {
498                         set_filelen_write_cache(fsp, len);
499                 }
500
501                 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
502
503                 return ret;
504         }
505
506         if (!lp_strict_allocate(SNUM(fsp->conn)))
507                 return 0;
508
509         /* Grow - we need to test if we have enough space. */
510
511         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
512
513         /* See if we have a syscall that will allocate beyond end-of-file
514            without changing EOF. */
515         ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
516
517         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
518
519         if (ret == 0) {
520                 /* We changed the allocation size on disk, but not
521                    EOF - exactly as required. We're done ! */
522                 return 0;
523         }
524
525         len -= fsp->fsp_name->st.st_ex_size;
526         len /= 1024; /* Len is now number of 1k blocks needed. */
527         space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
528                                      &bsize, &dfree, &dsize);
529         if (space_avail == (uint64_t)-1) {
530                 return -1;
531         }
532
533         DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
534                   "needed blocks = %.0f, space avail = %.0f\n",
535                   fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
536                   (double)space_avail));
537
538         if (len > space_avail) {
539                 errno = ENOSPC;
540                 return -1;
541         }
542
543         return 0;
544 }
545
546 /****************************************************************************
547  A vfs set_filelen call.
548  set the length of a file from a filedescriptor.
549  Returns 0 on success, -1 on failure.
550 ****************************************************************************/
551
552 int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
553 {
554         int ret;
555
556         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
557
558         DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
559                   fsp_str_dbg(fsp), (double)len));
560         flush_write_cache(fsp, SIZECHANGE_FLUSH);
561         if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
562                 set_filelen_write_cache(fsp, len);
563                 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
564                              FILE_NOTIFY_CHANGE_SIZE
565                              | FILE_NOTIFY_CHANGE_ATTRIBUTES,
566                              fsp->fsp_name->base_name);
567         }
568
569         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
570
571         return ret;
572 }
573
574 /****************************************************************************
575  A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
576  fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
577  as this is also called from the default SMB_VFS_FTRUNCATE code.
578  Always extends the file size.
579  Returns 0 on success, errno on failure.
580 ****************************************************************************/
581
582 #define SPARSE_BUF_WRITE_SIZE (32*1024)
583
584 int vfs_slow_fallocate(files_struct *fsp, SMB_OFF_T offset, SMB_OFF_T len)
585 {
586         ssize_t pwrite_ret;
587         size_t total = 0;
588
589         if (!sparse_buf) {
590                 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
591                 if (!sparse_buf) {
592                         errno = ENOMEM;
593                         return ENOMEM;
594                 }
595         }
596
597         while (total < len) {
598                 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
599
600                 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
601                 if (pwrite_ret == -1) {
602                         DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
603                                   "%s failed with error %s\n",
604                                   fsp_str_dbg(fsp), strerror(errno)));
605                         return errno;
606                 }
607                 total += pwrite_ret;
608         }
609
610         return 0;
611 }
612
613 /****************************************************************************
614  A vfs fill sparse call.
615  Writes zeros from the end of file to len, if len is greater than EOF.
616  Used only by strict_sync.
617  Returns 0 on success, -1 on failure.
618 ****************************************************************************/
619
620 int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
621 {
622         int ret;
623         NTSTATUS status;
624         SMB_OFF_T offset;
625         size_t num_to_write;
626
627         status = vfs_stat_fsp(fsp);
628         if (!NT_STATUS_IS_OK(status)) {
629                 return -1;
630         }
631
632         if (len <= fsp->fsp_name->st.st_ex_size) {
633                 return 0;
634         }
635
636 #ifdef S_ISFIFO
637         if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
638                 return 0;
639         }
640 #endif
641
642         DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
643                   "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
644                   (double)fsp->fsp_name->st.st_ex_size, (double)len,
645                   (double)(len - fsp->fsp_name->st.st_ex_size)));
646
647         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
648
649         flush_write_cache(fsp, SIZECHANGE_FLUSH);
650
651         offset = fsp->fsp_name->st.st_ex_size;
652         num_to_write = len - fsp->fsp_name->st.st_ex_size;
653
654         /* Only do this on non-stream file handles. */
655         if (fsp->base_fsp == NULL) {
656                 /* for allocation try fallocate first. This can fail on some
657                  * platforms e.g. when the filesystem doesn't support it and no
658                  * emulation is being done by the libc (like on AIX with JFS1). In that
659                  * case we do our own emulation. fallocate implementations can
660                  * return ENOTSUP or EINVAL in cases like that. */
661                 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
662                                 offset, num_to_write);
663                 if (ret == ENOSPC) {
664                         errno = ENOSPC;
665                         ret = -1;
666                         goto out;
667                 }
668                 if (ret == 0) {
669                         goto out;
670                 }
671                 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
672                         "error %d. Falling back to slow manual allocation\n", ret));
673         }
674
675         ret = vfs_slow_fallocate(fsp, offset, num_to_write);
676         if (ret != 0) {
677                 errno = ret;
678                 ret = -1;
679         }
680
681  out:
682
683         if (ret == 0) {
684                 set_filelen_write_cache(fsp, len);
685         }
686
687         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
688         return ret;
689 }
690
691 /****************************************************************************
692  Transfer some data (n bytes) between two file_struct's.
693 ****************************************************************************/
694
695 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
696 {
697         struct files_struct *fsp = (struct files_struct *)file;
698
699         return SMB_VFS_READ(fsp, buf, len);
700 }
701
702 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
703 {
704         struct files_struct *fsp = (struct files_struct *)file;
705
706         return SMB_VFS_WRITE(fsp, buf, len);
707 }
708
709 SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n)
710 {
711         return transfer_file_internal((void *)in, (void *)out, n,
712                                       vfs_read_fn, vfs_write_fn);
713 }
714
715 /*******************************************************************
716  A vfs_readdir wrapper which just returns the file name.
717 ********************************************************************/
718
719 const char *vfs_readdirname(connection_struct *conn, void *p,
720                             SMB_STRUCT_STAT *sbuf, char **talloced)
721 {
722         SMB_STRUCT_DIRENT *ptr= NULL;
723         const char *dname;
724         char *translated;
725         NTSTATUS status;
726
727         if (!p)
728                 return(NULL);
729
730         ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
731         if (!ptr)
732                 return(NULL);
733
734         dname = ptr->d_name;
735
736
737 #ifdef NEXT2
738         if (telldir(p) < 0)
739                 return(NULL);
740 #endif
741
742 #ifdef HAVE_BROKEN_READDIR_NAME
743         /* using /usr/ucb/cc is BAD */
744         dname = dname - 2;
745 #endif
746
747         status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
748                                         talloc_tos(), &translated);
749         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
750                 *talloced = NULL;
751                 return dname;
752         }
753         *talloced = translated;
754         if (!NT_STATUS_IS_OK(status)) {
755                 return NULL;
756         }
757         return translated;
758 }
759
760 /*******************************************************************
761  A wrapper for vfs_chdir().
762 ********************************************************************/
763
764 int vfs_ChDir(connection_struct *conn, const char *path)
765 {
766         int res;
767
768         if (!LastDir) {
769                 LastDir = SMB_STRDUP("");
770         }
771
772         if (strcsequal(path,"."))
773                 return(0);
774
775         if (*path == '/' && strcsequal(LastDir,path))
776                 return(0);
777
778         DEBUG(4,("vfs_ChDir to %s\n",path));
779
780         res = SMB_VFS_CHDIR(conn,path);
781         if (!res) {
782                 SAFE_FREE(LastDir);
783                 LastDir = SMB_STRDUP(path);
784         }
785         return(res);
786 }
787
788 /*******************************************************************
789  Return the absolute current directory path - given a UNIX pathname.
790  Note that this path is returned in DOS format, not UNIX
791  format. Note this can be called with conn == NULL.
792 ********************************************************************/
793
794 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
795 {
796         char s[PATH_MAX+1];
797         char *result = NULL;
798         DATA_BLOB cache_value;
799         struct file_id key;
800         struct smb_filename *smb_fname_dot = NULL;
801         struct smb_filename *smb_fname_full = NULL;
802         NTSTATUS status;
803
804         *s = 0;
805
806         if (!lp_getwd_cache()) {
807                 goto nocache;
808         }
809
810         status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
811                                             &smb_fname_dot);
812         if (!NT_STATUS_IS_OK(status)) {
813                 errno = map_errno_from_nt_status(status);
814                 goto out;
815         }
816
817         if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
818                 /*
819                  * Known to fail for root: the directory may be NFS-mounted
820                  * and exported with root_squash (so has no root access).
821                  */
822                 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
823                          "(NFS problem ?)\n", strerror(errno) ));
824                 goto nocache;
825         }
826
827         key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
828
829         if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
830                              data_blob_const(&key, sizeof(key)),
831                              &cache_value)) {
832                 goto nocache;
833         }
834
835         SMB_ASSERT((cache_value.length > 0)
836                    && (cache_value.data[cache_value.length-1] == '\0'));
837
838         status = create_synthetic_smb_fname(ctx, (char *)cache_value.data,
839                                             NULL, NULL, &smb_fname_full);
840         if (!NT_STATUS_IS_OK(status)) {
841                 errno = map_errno_from_nt_status(status);
842                 goto out;
843         }
844
845         if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
846             (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
847             (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
848             (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
849                 /*
850                  * Ok, we're done
851                  */
852                 result = talloc_strdup(ctx, smb_fname_full->base_name);
853                 if (result == NULL) {
854                         errno = ENOMEM;
855                 }
856                 goto out;
857         }
858
859  nocache:
860
861         /*
862          * We don't have the information to hand so rely on traditional
863          * methods. The very slow getcwd, which spawns a process on some
864          * systems, or the not quite so bad getwd.
865          */
866
867         if (!SMB_VFS_GETWD(conn,s)) {
868                 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
869                           strerror(errno)));
870                 goto out;
871         }
872
873         if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
874                 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
875
876                 memcache_add(smbd_memcache(), GETWD_CACHE,
877                              data_blob_const(&key, sizeof(key)),
878                              data_blob_const(s, strlen(s)+1));
879         }
880
881         result = talloc_strdup(ctx, s);
882         if (result == NULL) {
883                 errno = ENOMEM;
884         }
885
886  out:
887         TALLOC_FREE(smb_fname_dot);
888         TALLOC_FREE(smb_fname_full);
889         return result;
890 }
891
892 /*******************************************************************
893  Reduce a file name, removing .. elements and checking that
894  it is below dir in the heirachy. This uses realpath.
895 ********************************************************************/
896
897 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
898 {
899         char *resolved_name = NULL;
900         char *p = NULL;
901
902         DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
903
904         resolved_name = SMB_VFS_REALPATH(conn,fname);
905
906         if (!resolved_name) {
907                 switch (errno) {
908                         case ENOTDIR:
909                                 DEBUG(3,("check_reduced_name: Component not a "
910                                          "directory in getting realpath for "
911                                          "%s\n", fname));
912                                 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
913                         case ENOENT:
914                         {
915                                 TALLOC_CTX *ctx = talloc_tos();
916                                 char *tmp_fname = NULL;
917                                 char *last_component = NULL;
918                                 /* Last component didn't exist. Remove it and try and canonicalise the directory. */
919
920                                 tmp_fname = talloc_strdup(ctx, fname);
921                                 if (!tmp_fname) {
922                                         return NT_STATUS_NO_MEMORY;
923                                 }
924                                 p = strrchr_m(tmp_fname, '/');
925                                 if (p) {
926                                         *p++ = '\0';
927                                         last_component = p;
928                                 } else {
929                                         last_component = tmp_fname;
930                                         tmp_fname = talloc_strdup(ctx,
931                                                         ".");
932                                         if (!tmp_fname) {
933                                                 return NT_STATUS_NO_MEMORY;
934                                         }
935                                 }
936
937                                 resolved_name = SMB_VFS_REALPATH(conn,tmp_fname);
938                                 if (!resolved_name) {
939                                         NTSTATUS status = map_nt_error_from_unix(errno);
940
941                                         if (errno == ENOENT || errno == ENOTDIR) {
942                                                 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
943                                         }
944
945                                         DEBUG(3,("check_reduce_name: "
946                                                  "couldn't get realpath for "
947                                                  "%s (%s)\n",
948                                                 fname,
949                                                 nt_errstr(status)));
950                                         return status;
951                                 }
952                                 tmp_fname = talloc_asprintf(ctx,
953                                                 "%s/%s",
954                                                 resolved_name,
955                                                 last_component);
956                                 if (!tmp_fname) {
957                                         return NT_STATUS_NO_MEMORY;
958                                 }
959                                 SAFE_FREE(resolved_name);
960                                 resolved_name = SMB_STRDUP(tmp_fname);
961                                 if (!resolved_name) {
962                                         DEBUG(0, ("check_reduced_name: malloc "
963                                                   "fail for %s\n", tmp_fname));
964                                         return NT_STATUS_NO_MEMORY;
965                                 }
966                                 break;
967                         }
968                         default:
969                                 DEBUG(3,("check_reduced_name: couldn't get "
970                                          "realpath for %s\n", fname));
971                                 return map_nt_error_from_unix(errno);
972                 }
973         }
974
975         DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
976                   resolved_name));
977
978         if (*resolved_name != '/') {
979                 DEBUG(0,("check_reduced_name: realpath doesn't return "
980                          "absolute paths !\n"));
981                 SAFE_FREE(resolved_name);
982                 return NT_STATUS_OBJECT_NAME_INVALID;
983         }
984
985         /* Check for widelinks allowed. */
986         if (!lp_widelinks(SNUM(conn))) {
987                     const char *conn_rootdir;
988
989                     conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
990                     if (conn_rootdir == NULL) {
991                             DEBUG(2, ("check_reduced_name: Could not get "
992                                       "conn_rootdir\n"));
993                             SAFE_FREE(resolved_name);
994                             return NT_STATUS_ACCESS_DENIED;
995                     }
996
997                     if (strncmp(conn_rootdir, resolved_name,
998                                 strlen(conn_rootdir)) != 0) {
999                             DEBUG(2, ("check_reduced_name: Bad access "
1000                                       "attempt: %s is a symlink outside the "
1001                                       "share path\n", fname));
1002                             DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1003                             DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1004                             SAFE_FREE(resolved_name);
1005                             return NT_STATUS_ACCESS_DENIED;
1006                     }
1007         }
1008
1009         /* Check if we are allowing users to follow symlinks */
1010         /* Patch from David Clerc <David.Clerc@cui.unige.ch>
1011                 University of Geneva */
1012
1013 #ifdef S_ISLNK
1014         if (!lp_symlinks(SNUM(conn))) {
1015                 struct smb_filename *smb_fname = NULL;
1016                 NTSTATUS status;
1017
1018                 status = create_synthetic_smb_fname(talloc_tos(), fname, NULL,
1019                                                     NULL, &smb_fname);
1020                 if (!NT_STATUS_IS_OK(status)) {
1021                         SAFE_FREE(resolved_name);
1022                         return status;
1023                 }
1024
1025                 if ( (SMB_VFS_LSTAT(conn, smb_fname) != -1) &&
1026                                 (S_ISLNK(smb_fname->st.st_ex_mode)) ) {
1027                         SAFE_FREE(resolved_name);
1028                         DEBUG(3,("check_reduced_name: denied: file path name "
1029                                  "%s is a symlink\n",resolved_name));
1030                         TALLOC_FREE(smb_fname);
1031                         return NT_STATUS_ACCESS_DENIED;
1032                 }
1033                 TALLOC_FREE(smb_fname);
1034         }
1035 #endif
1036
1037         DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1038                  resolved_name));
1039         SAFE_FREE(resolved_name);
1040         return NT_STATUS_OK;
1041 }
1042
1043 /**
1044  * XXX: This is temporary and there should be no callers of this once
1045  * smb_filename is plumbed through all path based operations.
1046  */
1047 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1048                        SMB_STRUCT_STAT *psbuf)
1049 {
1050         struct smb_filename *smb_fname = NULL;
1051         NTSTATUS status;
1052         int ret;
1053
1054         status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1055                                                   &smb_fname);
1056         if (!NT_STATUS_IS_OK(status)) {
1057                 errno = map_errno_from_nt_status(status);
1058                 return -1;
1059         }
1060
1061         if (lp_posix_pathnames()) {
1062                 ret = SMB_VFS_LSTAT(conn, smb_fname);
1063         } else {
1064                 ret = SMB_VFS_STAT(conn, smb_fname);
1065         }
1066
1067         if (ret != -1) {
1068                 *psbuf = smb_fname->st;
1069         }
1070
1071         TALLOC_FREE(smb_fname);
1072         return ret;
1073 }
1074
1075 /**
1076  * XXX: This is temporary and there should be no callers of this once
1077  * smb_filename is plumbed through all path based operations.
1078  */
1079 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1080                         SMB_STRUCT_STAT *psbuf)
1081 {
1082         struct smb_filename *smb_fname = NULL;
1083         NTSTATUS status;
1084         int ret;
1085
1086         status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1087                                                   &smb_fname);
1088         if (!NT_STATUS_IS_OK(status)) {
1089                 errno = map_errno_from_nt_status(status);
1090                 return -1;
1091         }
1092
1093         ret = SMB_VFS_LSTAT(conn, smb_fname);
1094         if (ret != -1) {
1095                 *psbuf = smb_fname->st;
1096         }
1097
1098         TALLOC_FREE(smb_fname);
1099         return ret;
1100 }
1101
1102 /**
1103  * Ensure LSTAT is called for POSIX paths.
1104  */
1105
1106 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1107 {
1108         int ret;
1109
1110         if(fsp->fh->fd == -1) {
1111                 if (fsp->posix_open) {
1112                         ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1113                 } else {
1114                         ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1115                 }
1116                 if (ret == -1) {
1117                         return map_nt_error_from_unix(errno);
1118                 }
1119         } else {
1120                 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1121                         return map_nt_error_from_unix(errno);
1122                 }
1123         }
1124         return NT_STATUS_OK;
1125 }
1126
1127 /*
1128   generate a file_id from a stat structure
1129  */
1130 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1131 {
1132         return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1133 }
1134
1135 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1136                          const char *service, const char *user)
1137 {
1138         VFS_FIND(connect_fn);
1139         return handle->fns->connect_fn(handle, service, user);
1140 }
1141
1142 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1143 {
1144         VFS_FIND(disconnect);
1145         handle->fns->disconnect(handle);
1146 }
1147
1148 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1149                                 const char *path, bool small_query,
1150                                 uint64_t *bsize, uint64_t *dfree,
1151                                 uint64_t *dsize)
1152 {
1153         VFS_FIND(disk_free);
1154         return handle->fns->disk_free(handle, path, small_query, bsize, dfree,
1155                                       dsize);
1156 }
1157
1158 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1159                            enum SMB_QUOTA_TYPE qtype, unid_t id,
1160                            SMB_DISK_QUOTA *qt)
1161 {
1162         VFS_FIND(get_quota);
1163         return handle->fns->get_quota(handle, qtype, id, qt);
1164 }
1165
1166 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1167                            enum SMB_QUOTA_TYPE qtype, unid_t id,
1168                            SMB_DISK_QUOTA *qt)
1169 {
1170         VFS_FIND(set_quota);
1171         return handle->fns->set_quota(handle, qtype, id, qt);
1172 }
1173
1174 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1175                                       struct files_struct *fsp,
1176                                       SHADOW_COPY_DATA *shadow_copy_data,
1177                                       bool labels)
1178 {
1179         VFS_FIND(get_shadow_copy_data);
1180         return handle->fns->get_shadow_copy_data(handle, fsp, shadow_copy_data,
1181                                                  labels);
1182 }
1183 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1184                          struct vfs_statvfs_struct *statbuf)
1185 {
1186         VFS_FIND(statvfs);
1187         return handle->fns->statvfs(handle, path, statbuf);
1188 }
1189
1190 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1191                         enum timestamp_set_resolution *p_ts_res)
1192 {
1193         VFS_FIND(fs_capabilities);
1194         return handle->fns->fs_capabilities(handle, p_ts_res);
1195 }
1196
1197 SMB_STRUCT_DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1198                                      const char *fname, const char *mask,
1199                                      uint32 attributes)
1200 {
1201         VFS_FIND(opendir);
1202         return handle->fns->opendir(handle, fname, mask, attributes);
1203 }
1204
1205 SMB_STRUCT_DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1206                                         struct files_struct *fsp,
1207                                         const char *mask,
1208                                         uint32 attributes)
1209 {
1210         VFS_FIND(fdopendir);
1211         return handle->fns->fdopendir(handle, fsp, mask, attributes);
1212 }
1213
1214 SMB_STRUCT_DIRENT *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1215                                               SMB_STRUCT_DIR *dirp,
1216                                               SMB_STRUCT_STAT *sbuf)
1217 {
1218         VFS_FIND(readdir);
1219         return handle->fns->readdir(handle, dirp, sbuf);
1220 }
1221
1222 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1223                           SMB_STRUCT_DIR *dirp, long offset)
1224 {
1225         VFS_FIND(seekdir);
1226         handle->fns->seekdir(handle, dirp, offset);
1227 }
1228
1229 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1230                           SMB_STRUCT_DIR *dirp)
1231 {
1232         VFS_FIND(telldir);
1233         return handle->fns->telldir(handle, dirp);
1234 }
1235
1236 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1237                              SMB_STRUCT_DIR *dirp)
1238 {
1239         VFS_FIND(rewind_dir);
1240         handle->fns->rewind_dir(handle, dirp);
1241 }
1242
1243 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1244                        mode_t mode)
1245 {
1246         VFS_FIND(mkdir);
1247         return handle->fns->mkdir(handle, path, mode);
1248 }
1249
1250 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1251 {
1252         VFS_FIND(rmdir);
1253         return handle->fns->rmdir(handle, path);
1254 }
1255
1256 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1257                           SMB_STRUCT_DIR *dir)
1258 {
1259         VFS_FIND(closedir);
1260         return handle->fns->closedir(handle, dir);
1261 }
1262
1263 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1264                                  SMB_STRUCT_DIR *dirp)
1265 {
1266         VFS_FIND(init_search_op);
1267         handle->fns->init_search_op(handle, dirp);
1268 }
1269
1270 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1271                       struct smb_filename *smb_fname, struct files_struct *fsp,
1272                       int flags, mode_t mode)
1273 {
1274         VFS_FIND(open);
1275         return handle->fns->open(handle, smb_fname, fsp, flags, mode);
1276 }
1277
1278 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1279                                   struct smb_request *req,
1280                                   uint16_t root_dir_fid,
1281                                   struct smb_filename *smb_fname,
1282                                   uint32_t access_mask,
1283                                   uint32_t share_access,
1284                                   uint32_t create_disposition,
1285                                   uint32_t create_options,
1286                                   uint32_t file_attributes,
1287                                   uint32_t oplock_request,
1288                                   uint64_t allocation_size,
1289                                   uint32_t private_flags,
1290                                   struct security_descriptor *sd,
1291                                   struct ea_list *ea_list,
1292                                   files_struct **result,
1293                                   int *pinfo)
1294 {
1295         VFS_FIND(create_file);
1296         return handle->fns->create_file(
1297                 handle, req, root_dir_fid, smb_fname, access_mask,
1298                 share_access, create_disposition, create_options,
1299                 file_attributes, oplock_request, allocation_size,
1300                 private_flags, sd, ea_list,
1301                 result, pinfo);
1302 }
1303
1304 int smb_vfs_call_close_fn(struct vfs_handle_struct *handle,
1305                           struct files_struct *fsp)
1306 {
1307         VFS_FIND(close_fn);
1308         return handle->fns->close_fn(handle, fsp);
1309 }
1310
1311 ssize_t smb_vfs_call_vfs_read(struct vfs_handle_struct *handle,
1312                               struct files_struct *fsp, void *data, size_t n)
1313 {
1314         VFS_FIND(vfs_read);
1315         return handle->fns->vfs_read(handle, fsp, data, n);
1316 }
1317
1318 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1319                            struct files_struct *fsp, void *data, size_t n,
1320                            SMB_OFF_T offset)
1321 {
1322         VFS_FIND(pread);
1323         return handle->fns->pread(handle, fsp, data, n, offset);
1324 }
1325
1326 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1327                            struct files_struct *fsp, const void *data,
1328                            size_t n)
1329 {
1330         VFS_FIND(write);
1331         return handle->fns->write(handle, fsp, data, n);
1332 }
1333
1334 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1335                             struct files_struct *fsp, const void *data,
1336                             size_t n, SMB_OFF_T offset)
1337 {
1338         VFS_FIND(pwrite);
1339         return handle->fns->pwrite(handle, fsp, data, n, offset);
1340 }
1341
1342 SMB_OFF_T smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1343                              struct files_struct *fsp, SMB_OFF_T offset,
1344                              int whence)
1345 {
1346         VFS_FIND(lseek);
1347         return handle->fns->lseek(handle, fsp, offset, whence);
1348 }
1349
1350 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1351                               files_struct *fromfsp, const DATA_BLOB *header,
1352                               SMB_OFF_T offset, size_t count)
1353 {
1354         VFS_FIND(sendfile);
1355         return handle->fns->sendfile(handle, tofd, fromfsp, header, offset,
1356                                      count);
1357 }
1358
1359 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1360                               files_struct *tofsp, SMB_OFF_T offset,
1361                               size_t count)
1362 {
1363         VFS_FIND(recvfile);
1364         return handle->fns->recvfile(handle, fromfd, tofsp, offset, count);
1365 }
1366
1367 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1368                         const struct smb_filename *smb_fname_src,
1369                         const struct smb_filename *smb_fname_dst)
1370 {
1371         VFS_FIND(rename);
1372         return handle->fns->rename(handle, smb_fname_src, smb_fname_dst);
1373 }
1374
1375 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1376                        struct files_struct *fsp)
1377 {
1378         VFS_FIND(fsync);
1379         return handle->fns->fsync(handle, fsp);
1380 }
1381
1382 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1383                       struct smb_filename *smb_fname)
1384 {
1385         VFS_FIND(stat);
1386         return handle->fns->stat(handle, smb_fname);
1387 }
1388
1389 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1390                        struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1391 {
1392         VFS_FIND(fstat);
1393         return handle->fns->fstat(handle, fsp, sbuf);
1394 }
1395
1396 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1397                        struct smb_filename *smb_filename)
1398 {
1399         VFS_FIND(lstat);
1400         return handle->fns->lstat(handle, smb_filename);
1401 }
1402
1403 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1404                                      struct files_struct *fsp,
1405                                      const SMB_STRUCT_STAT *sbuf)
1406 {
1407         VFS_FIND(get_alloc_size);
1408         return handle->fns->get_alloc_size(handle, fsp, sbuf);
1409 }
1410
1411 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1412                         const struct smb_filename *smb_fname)
1413 {
1414         VFS_FIND(unlink);
1415         return handle->fns->unlink(handle, smb_fname);
1416 }
1417
1418 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1419                        mode_t mode)
1420 {
1421         VFS_FIND(chmod);
1422         return handle->fns->chmod(handle, path, mode);
1423 }
1424
1425 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1426                         struct files_struct *fsp, mode_t mode)
1427 {
1428         VFS_FIND(fchmod);
1429         return handle->fns->fchmod(handle, fsp, mode);
1430 }
1431
1432 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1433                        uid_t uid, gid_t gid)
1434 {
1435         VFS_FIND(chown);
1436         return handle->fns->chown(handle, path, uid, gid);
1437 }
1438
1439 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1440                         struct files_struct *fsp, uid_t uid, gid_t gid)
1441 {
1442         VFS_FIND(fchown);
1443         return handle->fns->fchown(handle, fsp, uid, gid);
1444 }
1445
1446 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1447                         uid_t uid, gid_t gid)
1448 {
1449         VFS_FIND(lchown);
1450         return handle->fns->lchown(handle, path, uid, gid);
1451 }
1452
1453 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1454 {
1455         int ret;
1456
1457         if (fsp->fh->fd != -1) {
1458                 /* Try fchown. */
1459                 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1460                 if (ret == 0) {
1461                         return NT_STATUS_OK;
1462                 }
1463                 if (ret == -1 && errno != ENOSYS) {
1464                         return map_nt_error_from_unix(errno);
1465                 }
1466         }
1467
1468         if (fsp->posix_open) {
1469                 ret = SMB_VFS_LCHOWN(fsp->conn,
1470                         fsp->fsp_name->base_name,
1471                         uid, gid);
1472         } else {
1473                 ret = SMB_VFS_CHOWN(fsp->conn,
1474                         fsp->fsp_name->base_name,
1475                         uid, gid);
1476         }
1477         if (ret == 0) {
1478                 return NT_STATUS_OK;
1479         }
1480         return map_nt_error_from_unix(errno);
1481 }
1482
1483 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1484 {
1485         VFS_FIND(chdir);
1486         return handle->fns->chdir(handle, path);
1487 }
1488
1489 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle, char *buf)
1490 {
1491         VFS_FIND(getwd);
1492         return handle->fns->getwd(handle, buf);
1493 }
1494
1495 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1496                         const struct smb_filename *smb_fname,
1497                         struct smb_file_time *ft)
1498 {
1499         VFS_FIND(ntimes);
1500         return handle->fns->ntimes(handle, smb_fname, ft);
1501 }
1502
1503 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1504                            struct files_struct *fsp, SMB_OFF_T offset)
1505 {
1506         VFS_FIND(ftruncate);
1507         return handle->fns->ftruncate(handle, fsp, offset);
1508 }
1509
1510 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1511                                 struct files_struct *fsp,
1512                                 enum vfs_fallocate_mode mode,
1513                                 SMB_OFF_T offset,
1514                                 SMB_OFF_T len)
1515 {
1516         VFS_FIND(fallocate);
1517         return handle->fns->fallocate(handle, fsp, mode, offset, len);
1518 }
1519
1520 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
1521                               struct files_struct *fsp, uint32 share_mode,
1522                               uint32_t access_mask)
1523 {
1524         VFS_FIND(kernel_flock);
1525         return handle->fns->kernel_flock(handle, fsp, share_mode,
1526                                          access_mask);
1527 }
1528
1529 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
1530                                 struct files_struct *fsp, int leasetype)
1531 {
1532         VFS_FIND(linux_setlease);
1533         return handle->fns->linux_setlease(handle, fsp, leasetype);
1534 }
1535
1536 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
1537                          const char *newpath)
1538 {
1539         VFS_FIND(symlink);
1540         return handle->fns->symlink(handle, oldpath, newpath);
1541 }
1542
1543 int smb_vfs_call_vfs_readlink(struct vfs_handle_struct *handle,
1544                               const char *path, char *buf, size_t bufsiz)
1545 {
1546         VFS_FIND(vfs_readlink);
1547         return handle->fns->vfs_readlink(handle, path, buf, bufsiz);
1548 }
1549
1550 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
1551                       const char *newpath)
1552 {
1553         VFS_FIND(link);
1554         return handle->fns->link(handle, oldpath, newpath);
1555 }
1556
1557 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
1558                        mode_t mode, SMB_DEV_T dev)
1559 {
1560         VFS_FIND(mknod);
1561         return handle->fns->mknod(handle, path, mode, dev);
1562 }
1563
1564 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
1565 {
1566         VFS_FIND(realpath);
1567         return handle->fns->realpath(handle, path);
1568 }
1569
1570 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
1571                                    struct sys_notify_context *ctx,
1572                                    struct notify_entry *e,
1573                                    void (*callback)(struct sys_notify_context *ctx,
1574                                                     void *private_data,
1575                                                     struct notify_event *ev),
1576                                    void *private_data, void *handle_p)
1577 {
1578         VFS_FIND(notify_watch);
1579         return handle->fns->notify_watch(handle, ctx, e, callback,
1580                                          private_data, handle_p);
1581 }
1582
1583 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
1584                          unsigned int flags)
1585 {
1586         VFS_FIND(chflags);
1587         return handle->fns->chflags(handle, path, flags);
1588 }
1589
1590 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
1591                                            const SMB_STRUCT_STAT *sbuf)
1592 {
1593         VFS_FIND(file_id_create);
1594         return handle->fns->file_id_create(handle, sbuf);
1595 }
1596
1597 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
1598                                  struct files_struct *fsp,
1599                                  const char *fname,
1600                                  TALLOC_CTX *mem_ctx,
1601                                  unsigned int *num_streams,
1602                                  struct stream_struct **streams)
1603 {
1604         VFS_FIND(streaminfo);
1605         return handle->fns->streaminfo(handle, fsp, fname, mem_ctx,
1606                                        num_streams, streams);
1607 }
1608
1609 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
1610                                    const char *path, const char *name,
1611                                    TALLOC_CTX *mem_ctx, char **found_name)
1612 {
1613         VFS_FIND(get_real_filename);
1614         return handle->fns->get_real_filename(handle, path, name, mem_ctx,
1615                                               found_name);
1616 }
1617
1618 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
1619                                      const char *filename)
1620 {
1621         VFS_FIND(connectpath);
1622         return handle->fns->connectpath(handle, filename);
1623 }
1624
1625 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
1626                               struct files_struct *fsp,
1627                               struct lock_struct *plock)
1628 {
1629         VFS_FIND(strict_lock);
1630         return handle->fns->strict_lock(handle, fsp, plock);
1631 }
1632
1633 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
1634                                 struct files_struct *fsp,
1635                                 struct lock_struct *plock)
1636 {
1637         VFS_FIND(strict_unlock);
1638         handle->fns->strict_unlock(handle, fsp, plock);
1639 }
1640
1641 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
1642                                      const char *name,
1643                                      enum vfs_translate_direction direction,
1644                                      TALLOC_CTX *mem_ctx,
1645                                      char **mapped_name)
1646 {
1647         VFS_FIND(translate_name);
1648         return handle->fns->translate_name(handle, name, direction, mem_ctx,
1649                                            mapped_name);
1650 }
1651
1652 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
1653                                   struct files_struct *fsp,
1654                                   uint32 security_info,
1655                                   struct security_descriptor **ppdesc)
1656 {
1657         VFS_FIND(fget_nt_acl);
1658         return handle->fns->fget_nt_acl(handle, fsp, security_info,
1659                                         ppdesc);
1660 }
1661
1662 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
1663                                  const char *name,
1664                                  uint32 security_info,
1665                                  struct security_descriptor **ppdesc)
1666 {
1667         VFS_FIND(get_nt_acl);
1668         return handle->fns->get_nt_acl(handle, name, security_info, ppdesc);
1669 }
1670
1671 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
1672                                   struct files_struct *fsp,
1673                                   uint32 security_info_sent,
1674                                   const struct security_descriptor *psd)
1675 {
1676         VFS_FIND(fset_nt_acl);
1677         return handle->fns->fset_nt_acl(handle, fsp, security_info_sent, psd);
1678 }
1679
1680 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
1681                            mode_t mode)
1682 {
1683         VFS_FIND(chmod_acl);
1684         return handle->fns->chmod_acl(handle, name, mode);
1685 }
1686
1687 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
1688                             struct files_struct *fsp, mode_t mode)
1689 {
1690         VFS_FIND(fchmod_acl);
1691         return handle->fns->fchmod_acl(handle, fsp, mode);
1692 }
1693
1694 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct *handle,
1695                                    SMB_ACL_T theacl, int entry_id,
1696                                    SMB_ACL_ENTRY_T *entry_p)
1697 {
1698         VFS_FIND(sys_acl_get_entry);
1699         return handle->fns->sys_acl_get_entry(handle, theacl, entry_id,
1700                                               entry_p);
1701 }
1702
1703 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct *handle,
1704                                       SMB_ACL_ENTRY_T entry_d,
1705                                       SMB_ACL_TAG_T *tag_type_p)
1706 {
1707         VFS_FIND(sys_acl_get_tag_type);
1708         return handle->fns->sys_acl_get_tag_type(handle, entry_d, tag_type_p);
1709 }
1710
1711 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct *handle,
1712                                      SMB_ACL_ENTRY_T entry_d,
1713                                      SMB_ACL_PERMSET_T *permset_p)
1714 {
1715         VFS_FIND(sys_acl_get_permset);
1716         return handle->fns->sys_acl_get_permset(handle, entry_d, permset_p);
1717 }
1718
1719 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct *handle,
1720                                           SMB_ACL_ENTRY_T entry_d)
1721 {
1722         VFS_FIND(sys_acl_get_qualifier);
1723         return handle->fns->sys_acl_get_qualifier(handle, entry_d);
1724 }
1725
1726 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
1727                                         const char *path_p,
1728                                         SMB_ACL_TYPE_T type)
1729 {
1730         VFS_FIND(sys_acl_get_file);
1731         return handle->fns->sys_acl_get_file(handle, path_p, type);
1732 }
1733
1734 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
1735                                       struct files_struct *fsp)
1736 {
1737         VFS_FIND(sys_acl_get_fd);
1738         return handle->fns->sys_acl_get_fd(handle, fsp);
1739 }
1740
1741 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct *handle,
1742                                      SMB_ACL_PERMSET_T permset)
1743 {
1744         VFS_FIND(sys_acl_clear_perms);
1745         return handle->fns->sys_acl_clear_perms(handle, permset);
1746 }
1747
1748 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct *handle,
1749                                   SMB_ACL_PERMSET_T permset,
1750                                   SMB_ACL_PERM_T perm)
1751 {
1752         VFS_FIND(sys_acl_add_perm);
1753         return handle->fns->sys_acl_add_perm(handle, permset, perm);
1754 }
1755
1756 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct *handle,
1757                                     SMB_ACL_T theacl, ssize_t *plen)
1758 {
1759         VFS_FIND(sys_acl_to_text);
1760         return handle->fns->sys_acl_to_text(handle, theacl, plen);
1761 }
1762
1763 SMB_ACL_T smb_vfs_call_sys_acl_init(struct vfs_handle_struct *handle,
1764                                     int count)
1765 {
1766         VFS_FIND(sys_acl_init);
1767         return handle->fns->sys_acl_init(handle, count);
1768 }
1769
1770 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct *handle,
1771                                       SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
1772 {
1773         VFS_FIND(sys_acl_create_entry);
1774         return handle->fns->sys_acl_create_entry(handle, pacl, pentry);
1775 }
1776
1777 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct *handle,
1778                                       SMB_ACL_ENTRY_T entry,
1779                                       SMB_ACL_TAG_T tagtype)
1780 {
1781         VFS_FIND(sys_acl_set_tag_type);
1782         return handle->fns->sys_acl_set_tag_type(handle, entry, tagtype);
1783 }
1784
1785 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct *handle,
1786                                        SMB_ACL_ENTRY_T entry, void *qual)
1787 {
1788         VFS_FIND(sys_acl_set_qualifier);
1789         return handle->fns->sys_acl_set_qualifier(handle, entry, qual);
1790 }
1791
1792 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct *handle,
1793                                      SMB_ACL_ENTRY_T entry,
1794                                      SMB_ACL_PERMSET_T permset)
1795 {
1796         VFS_FIND(sys_acl_set_permset);
1797         return handle->fns->sys_acl_set_permset(handle, entry, permset);
1798 }
1799
1800 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct *handle,
1801                                SMB_ACL_T theacl)
1802 {
1803         VFS_FIND(sys_acl_valid);
1804         return handle->fns->sys_acl_valid(handle, theacl);
1805 }
1806
1807 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
1808                                   const char *name, SMB_ACL_TYPE_T acltype,
1809                                   SMB_ACL_T theacl)
1810 {
1811         VFS_FIND(sys_acl_set_file);
1812         return handle->fns->sys_acl_set_file(handle, name, acltype, theacl);
1813 }
1814
1815 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
1816                                 struct files_struct *fsp, SMB_ACL_T theacl)
1817 {
1818         VFS_FIND(sys_acl_set_fd);
1819         return handle->fns->sys_acl_set_fd(handle, fsp, theacl);
1820 }
1821
1822 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
1823                                          const char *path)
1824 {
1825         VFS_FIND(sys_acl_delete_def_file);
1826         return handle->fns->sys_acl_delete_def_file(handle, path);
1827 }
1828
1829 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct *handle,
1830                                   SMB_ACL_PERMSET_T permset,
1831                                   SMB_ACL_PERM_T perm)
1832 {
1833         VFS_FIND(sys_acl_get_perm);
1834         return handle->fns->sys_acl_get_perm(handle, permset, perm);
1835 }
1836
1837 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct *handle,
1838                                    char *text)
1839 {
1840         VFS_FIND(sys_acl_free_text);
1841         return handle->fns->sys_acl_free_text(handle, text);
1842 }
1843
1844 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct *handle,
1845                                   SMB_ACL_T posix_acl)
1846 {
1847         VFS_FIND(sys_acl_free_acl);
1848         return handle->fns->sys_acl_free_acl(handle, posix_acl);
1849 }
1850
1851 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct *handle,
1852                                         void *qualifier, SMB_ACL_TAG_T tagtype)
1853 {
1854         VFS_FIND(sys_acl_free_qualifier);
1855         return handle->fns->sys_acl_free_qualifier(handle, qualifier, tagtype);
1856 }
1857
1858 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
1859                               const char *path, const char *name, void *value,
1860                               size_t size)
1861 {
1862         VFS_FIND(getxattr);
1863         return handle->fns->getxattr(handle, path, name, value, size);
1864 }
1865
1866 ssize_t smb_vfs_call_lgetxattr(struct vfs_handle_struct *handle,
1867                                const char *path, const char *name, void *value,
1868                                size_t size)
1869 {
1870         VFS_FIND(lgetxattr);
1871         return handle->fns->lgetxattr(handle, path, name, value, size);
1872 }
1873
1874 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
1875                                struct files_struct *fsp, const char *name,
1876                                void *value, size_t size)
1877 {
1878         VFS_FIND(fgetxattr);
1879         return handle->fns->fgetxattr(handle, fsp, name, value, size);
1880 }
1881
1882 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
1883                                const char *path, char *list, size_t size)
1884 {
1885         VFS_FIND(listxattr);
1886         return handle->fns->listxattr(handle, path, list, size);
1887 }
1888
1889 ssize_t smb_vfs_call_llistxattr(struct vfs_handle_struct *handle,
1890                                 const char *path, char *list, size_t size)
1891 {
1892         VFS_FIND(llistxattr);
1893         return handle->fns->llistxattr(handle, path, list, size);
1894 }
1895
1896 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
1897                                 struct files_struct *fsp, char *list,
1898                                 size_t size)
1899 {
1900         VFS_FIND(flistxattr);
1901         return handle->fns->flistxattr(handle, fsp, list, size);
1902 }
1903
1904 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
1905                              const char *path, const char *name)
1906 {
1907         VFS_FIND(removexattr);
1908         return handle->fns->removexattr(handle, path, name);
1909 }
1910
1911 int smb_vfs_call_lremovexattr(struct vfs_handle_struct *handle,
1912                               const char *path, const char *name)
1913 {
1914         VFS_FIND(lremovexattr);
1915         return handle->fns->lremovexattr(handle, path, name);
1916 }
1917
1918 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
1919                               struct files_struct *fsp, const char *name)
1920 {
1921         VFS_FIND(fremovexattr);
1922         return handle->fns->fremovexattr(handle, fsp, name);
1923 }
1924
1925 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
1926                           const char *name, const void *value, size_t size,
1927                           int flags)
1928 {
1929         VFS_FIND(setxattr);
1930         return handle->fns->setxattr(handle, path, name, value, size, flags);
1931 }
1932
1933 int smb_vfs_call_lsetxattr(struct vfs_handle_struct *handle, const char *path,
1934                            const char *name, const void *value, size_t size,
1935                            int flags)
1936 {
1937         VFS_FIND(lsetxattr);
1938         return handle->fns->lsetxattr(handle, path, name, value, size, flags);
1939 }
1940
1941 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
1942                            struct files_struct *fsp, const char *name,
1943                            const void *value, size_t size, int flags)
1944 {
1945         VFS_FIND(fsetxattr);
1946         return handle->fns->fsetxattr(handle, fsp, name, value, size, flags);
1947 }
1948
1949 int smb_vfs_call_aio_read(struct vfs_handle_struct *handle,
1950                           struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1951 {
1952         VFS_FIND(aio_read);
1953         return handle->fns->aio_read(handle, fsp, aiocb);
1954 }
1955
1956 int smb_vfs_call_aio_write(struct vfs_handle_struct *handle,
1957                            struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1958 {
1959         VFS_FIND(aio_write);
1960         return handle->fns->aio_write(handle, fsp, aiocb);
1961 }
1962
1963 ssize_t smb_vfs_call_aio_return_fn(struct vfs_handle_struct *handle,
1964                                    struct files_struct *fsp,
1965                                    SMB_STRUCT_AIOCB *aiocb)
1966 {
1967         VFS_FIND(aio_return_fn);
1968         return handle->fns->aio_return_fn(handle, fsp, aiocb);
1969 }
1970
1971 int smb_vfs_call_aio_cancel(struct vfs_handle_struct *handle,
1972                             struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
1973 {
1974         VFS_FIND(aio_cancel);
1975         return handle->fns->aio_cancel(handle, fsp, aiocb);
1976 }
1977
1978 int smb_vfs_call_aio_error_fn(struct vfs_handle_struct *handle,
1979                               struct files_struct *fsp,
1980                               SMB_STRUCT_AIOCB *aiocb)
1981 {
1982         VFS_FIND(aio_error_fn);
1983         return handle->fns->aio_error_fn(handle, fsp, aiocb);
1984 }
1985
1986 int smb_vfs_call_aio_fsync(struct vfs_handle_struct *handle,
1987                            struct files_struct *fsp, int op,
1988                            SMB_STRUCT_AIOCB *aiocb)
1989 {
1990         VFS_FIND(aio_fsync);
1991         return handle->fns->aio_fsync(handle, fsp, op, aiocb);
1992 }
1993
1994 int smb_vfs_call_aio_suspend(struct vfs_handle_struct *handle,
1995                              struct files_struct *fsp,
1996                              const SMB_STRUCT_AIOCB * const aiocb[], int n,
1997                              const struct timespec *timeout)
1998 {
1999         VFS_FIND(aio_suspend);
2000         return handle->fns->aio_suspend(handle, fsp, aiocb, n, timeout);
2001 }
2002
2003 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2004                             struct files_struct *fsp)
2005 {
2006         VFS_FIND(aio_force);
2007         return handle->fns->aio_force(handle, fsp);
2008 }
2009
2010 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2011                              const struct smb_filename *fname,
2012                              SMB_STRUCT_STAT *sbuf)
2013 {
2014         VFS_FIND(is_offline);
2015         return handle->fns->is_offline(handle, fname, sbuf);
2016 }
2017
2018 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2019                              const struct smb_filename *fname)
2020 {
2021         VFS_FIND(set_offline);
2022         return handle->fns->set_offline(handle, fname);
2023 }