2006-07-11 22:01:26 +04:00
/*
Unix SMB / CIFS implementation .
Wrap disk only vfs functions to sidestep dodgy compilers .
Copyright ( C ) Tim Potter 1998
2007-03-06 02:40:03 +03:00
Copyright ( C ) Jeremy Allison 2007
2006-07-11 22:01:26 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2006-07-11 22:01:26 +04:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-07-11 22:01:26 +04:00
*/
# include "includes.h"
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_VFS
/* Check for NULL pointer parameters in vfswrap_* functions */
/* We don't want to have NULL function pointers lying around. Someone
is sure to try and execute them . These stubs are used to prevent
this possibility . */
static int vfswrap_connect ( vfs_handle_struct * handle , const char * service , const char * user )
{
return 0 ; /* Return >= 0 for success */
}
static void vfswrap_disconnect ( vfs_handle_struct * handle )
{
}
/* Disk operations */
2008-10-14 03:59:36 +04:00
static uint64_t vfswrap_disk_free ( vfs_handle_struct * handle , const char * path , bool small_query , uint64_t * bsize ,
uint64_t * dfree , uint64_t * dsize )
2006-07-11 22:01:26 +04:00
{
2008-10-14 03:59:36 +04:00
uint64_t result ;
2006-07-11 22:01:26 +04:00
result = sys_disk_free ( handle - > conn , path , small_query , bsize , dfree , dsize ) ;
return result ;
}
static int vfswrap_get_quota ( struct vfs_handle_struct * handle , enum SMB_QUOTA_TYPE qtype , unid_t id , SMB_DISK_QUOTA * qt )
{
# ifdef HAVE_SYS_QUOTAS
int result ;
START_PROFILE ( syscall_get_quota ) ;
result = sys_get_quota ( handle - > conn - > connectpath , qtype , id , qt ) ;
END_PROFILE ( syscall_get_quota ) ;
return result ;
# else
errno = ENOSYS ;
return - 1 ;
# endif
}
static int vfswrap_set_quota ( struct vfs_handle_struct * handle , enum SMB_QUOTA_TYPE qtype , unid_t id , SMB_DISK_QUOTA * qt )
{
# ifdef HAVE_SYS_QUOTAS
int result ;
START_PROFILE ( syscall_set_quota ) ;
result = sys_set_quota ( handle - > conn - > connectpath , qtype , id , qt ) ;
END_PROFILE ( syscall_set_quota ) ;
return result ;
# else
errno = ENOSYS ;
return - 1 ;
# endif
}
2007-10-19 04:40:25 +04:00
static int vfswrap_get_shadow_copy_data ( struct vfs_handle_struct * handle , struct files_struct * fsp , SHADOW_COPY_DATA * shadow_copy_data , bool labels )
2006-07-11 22:01:26 +04:00
{
errno = ENOSYS ;
return - 1 ; /* Not implemented. */
}
static int vfswrap_statvfs ( struct vfs_handle_struct * handle , const char * path , vfs_statvfs_struct * statbuf )
{
return sys_statvfs ( path , statbuf ) ;
}
2009-08-25 07:57:37 +04:00
static uint32_t vfswrap_fs_capabilities ( struct vfs_handle_struct * handle ,
enum timestamp_set_resolution * p_ts_res )
2008-01-21 17:10:44 +03:00
{
2009-08-25 07:57:37 +04:00
connection_struct * conn = handle - > conn ;
uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES ;
struct smb_filename * smb_fname_cpath = NULL ;
NTSTATUS status ;
int ret = - 1 ;
2008-01-21 17:10:44 +03:00
# if defined(DARWINOS)
2008-01-21 20:07:38 +03:00
struct vfs_statvfs_struct statbuf ;
ZERO_STRUCT ( statbuf ) ;
2009-08-25 07:57:37 +04:00
sys_statvfs ( conn - > connectpath , & statbuf ) ;
caps = statbuf . FsCapabilities ;
2008-01-21 17:10:44 +03:00
# endif
2009-08-25 07:57:37 +04:00
* p_ts_res = TIMESTAMP_SET_SECONDS ;
/* Work out what timestamp resolution we can
* use when setting a timestamp . */
status = create_synthetic_smb_fname ( talloc_tos ( ) ,
conn - > connectpath ,
NULL ,
NULL ,
& smb_fname_cpath ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return caps ;
}
ret = SMB_VFS_STAT ( conn , smb_fname_cpath ) ;
if ( ret = = - 1 ) {
TALLOC_FREE ( smb_fname_cpath ) ;
return caps ;
}
if ( smb_fname_cpath - > st . st_ex_mtime . tv_nsec | |
smb_fname_cpath - > st . st_ex_atime . tv_nsec | |
smb_fname_cpath - > st . st_ex_ctime . tv_nsec ) {
/* If any of the normal UNIX directory timestamps
* have a non - zero tv_nsec component assume
* we might be able to set sub - second timestamps .
* See what filetime set primitives we have .
*/
2009-11-04 13:15:31 +03:00
# if defined(HAVE_UTIMENSAT)
* p_ts_res = TIMESTAMP_SET_NT_OR_BETTER ;
# elif defined(HAVE_UTIMES)
2009-08-25 07:57:37 +04:00
/* utimes allows msec timestamps to be set. */
* p_ts_res = TIMESTAMP_SET_MSEC ;
# elif defined(HAVE_UTIME)
/* utime only allows sec timestamps to be set. */
2009-09-10 00:54:47 +04:00
* p_ts_res = TIMESTAMP_SET_SECONDS ;
2009-08-25 07:57:37 +04:00
# endif
DEBUG ( 10 , ( " vfswrap_fs_capabilities: timestamp "
" resolution of %s "
" available on share %s, directory %s \n " ,
* p_ts_res = = TIMESTAMP_SET_MSEC ? " msec " : " sec " ,
2009-11-11 02:13:14 +03:00
lp_servicename ( conn - > params - > service ) ,
2009-08-25 07:57:37 +04:00
conn - > connectpath ) ) ;
}
TALLOC_FREE ( smb_fname_cpath ) ;
return caps ;
2008-01-21 17:10:44 +03:00
}
2006-07-11 22:01:26 +04:00
/* Directory operations */
static SMB_STRUCT_DIR * vfswrap_opendir ( vfs_handle_struct * handle , const char * fname , const char * mask , uint32 attr )
{
SMB_STRUCT_DIR * result ;
START_PROFILE ( syscall_opendir ) ;
result = sys_opendir ( fname ) ;
END_PROFILE ( syscall_opendir ) ;
return result ;
}
2009-01-23 07:14:38 +03:00
static SMB_STRUCT_DIRENT * vfswrap_readdir ( vfs_handle_struct * handle ,
SMB_STRUCT_DIR * dirp ,
SMB_STRUCT_STAT * sbuf )
2006-07-11 22:01:26 +04:00
{
SMB_STRUCT_DIRENT * result ;
START_PROFILE ( syscall_readdir ) ;
result = sys_readdir ( dirp ) ;
2009-01-23 07:14:38 +03:00
/* Default Posix readdir() does not give us stat info.
* Set to invalid to indicate we didn ' t return this info . */
if ( sbuf )
SET_STAT_INVALID ( * sbuf ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_readdir ) ;
return result ;
}
static void vfswrap_seekdir ( vfs_handle_struct * handle , SMB_STRUCT_DIR * dirp , long offset )
{
START_PROFILE ( syscall_seekdir ) ;
sys_seekdir ( dirp , offset ) ;
END_PROFILE ( syscall_seekdir ) ;
}
static long vfswrap_telldir ( vfs_handle_struct * handle , SMB_STRUCT_DIR * dirp )
{
long result ;
START_PROFILE ( syscall_telldir ) ;
result = sys_telldir ( dirp ) ;
END_PROFILE ( syscall_telldir ) ;
return result ;
}
static void vfswrap_rewinddir ( vfs_handle_struct * handle , SMB_STRUCT_DIR * dirp )
{
START_PROFILE ( syscall_rewinddir ) ;
sys_rewinddir ( dirp ) ;
END_PROFILE ( syscall_rewinddir ) ;
}
static int vfswrap_mkdir ( vfs_handle_struct * handle , const char * path , mode_t mode )
{
int result ;
2007-10-19 04:40:25 +04:00
bool has_dacl = False ;
2008-12-24 15:41:42 +03:00
char * parent = NULL ;
2006-07-11 22:01:26 +04:00
START_PROFILE ( syscall_mkdir ) ;
2008-12-24 15:41:42 +03:00
if ( lp_inherit_acls ( SNUM ( handle - > conn ) )
2008-12-24 15:51:47 +03:00
& & parent_dirname ( talloc_tos ( ) , path , & parent , NULL )
2008-12-24 15:41:42 +03:00
& & ( has_dacl = directory_has_default_acl ( handle - > conn , parent ) ) )
2006-07-11 22:01:26 +04:00
mode = 0777 ;
2008-12-24 15:41:42 +03:00
TALLOC_FREE ( parent ) ;
2006-07-11 22:01:26 +04:00
result = mkdir ( path , mode ) ;
if ( result = = 0 & & ! has_dacl ) {
/*
* We need to do this as the default behavior of POSIX ACLs
* is to set the mask to be the requested group permission
* bits , not the group permission bits to be the requested
* group permission bits . This is not what we want , as it will
* mess up any inherited ACL bits that were set . JRA .
*/
int saved_errno = errno ; /* We may get ENOSYS */
if ( ( SMB_VFS_CHMOD_ACL ( handle - > conn , path , mode ) = = - 1 ) & & ( errno = = ENOSYS ) )
errno = saved_errno ;
}
END_PROFILE ( syscall_mkdir ) ;
return result ;
}
static int vfswrap_rmdir ( vfs_handle_struct * handle , const char * path )
{
int result ;
START_PROFILE ( syscall_rmdir ) ;
result = rmdir ( path ) ;
END_PROFILE ( syscall_rmdir ) ;
return result ;
}
static int vfswrap_closedir ( vfs_handle_struct * handle , SMB_STRUCT_DIR * dirp )
{
int result ;
START_PROFILE ( syscall_closedir ) ;
result = sys_closedir ( dirp ) ;
END_PROFILE ( syscall_closedir ) ;
return result ;
}
2009-02-03 08:37:51 +03:00
static void vfswrap_init_search_op ( vfs_handle_struct * handle ,
SMB_STRUCT_DIR * dirp )
{
/* Default behavior is a NOOP */
}
2006-07-11 22:01:26 +04:00
/* File operations */
2009-06-16 23:01:13 +04:00
static int vfswrap_open ( vfs_handle_struct * handle ,
struct smb_filename * smb_fname ,
files_struct * fsp , int flags , mode_t mode )
2006-07-11 22:01:26 +04:00
{
2009-07-21 22:35:17 +04:00
int result = - 1 ;
2006-07-11 22:01:26 +04:00
START_PROFILE ( syscall_open ) ;
2009-06-16 23:01:13 +04:00
2009-07-21 22:35:17 +04:00
if ( smb_fname - > stream_name ) {
errno = ENOENT ;
goto out ;
2009-06-16 23:01:13 +04:00
}
2009-07-21 22:35:17 +04:00
result = sys_open ( smb_fname - > base_name , flags , mode ) ;
out :
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_open ) ;
return result ;
}
2008-10-21 04:43:45 +04:00
static NTSTATUS vfswrap_create_file ( vfs_handle_struct * handle ,
struct smb_request * req ,
uint16_t root_dir_fid ,
2009-06-12 23:54:11 +04:00
struct smb_filename * smb_fname ,
2008-10-21 04:43:45 +04:00
uint32_t access_mask ,
uint32_t share_access ,
uint32_t create_disposition ,
uint32_t create_options ,
uint32_t file_attributes ,
uint32_t oplock_request ,
uint64_t allocation_size ,
struct security_descriptor * sd ,
struct ea_list * ea_list ,
files_struct * * result ,
2009-06-12 23:54:11 +04:00
int * pinfo )
2008-10-21 04:43:45 +04:00
{
2009-06-12 23:54:11 +04:00
return create_file_default ( handle - > conn , req , root_dir_fid , smb_fname ,
access_mask , share_access ,
2008-10-21 04:43:45 +04:00
create_disposition , create_options ,
file_attributes , oplock_request ,
2009-06-12 23:54:11 +04:00
allocation_size , sd , ea_list , result ,
pinfo ) ;
2008-10-21 04:43:45 +04:00
}
2008-01-11 16:19:28 +03:00
static int vfswrap_close ( vfs_handle_struct * handle , files_struct * fsp )
2006-07-11 22:01:26 +04:00
{
2008-01-11 15:28:28 +03:00
int result ;
2006-07-11 22:01:26 +04:00
START_PROFILE ( syscall_close ) ;
2008-01-11 14:18:33 +03:00
result = fd_close_posix ( fsp ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_close ) ;
2008-01-11 15:28:28 +03:00
return result ;
2006-07-11 22:01:26 +04:00
}
2008-01-10 17:33:51 +03:00
static ssize_t vfswrap_read ( vfs_handle_struct * handle , files_struct * fsp , void * data , size_t n )
2006-07-11 22:01:26 +04:00
{
ssize_t result ;
START_PROFILE_BYTES ( syscall_read , n ) ;
2008-01-10 17:33:51 +03:00
result = sys_read ( fsp - > fh - > fd , data , n ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_read ) ;
return result ;
}
2008-01-07 02:14:19 +03:00
static ssize_t vfswrap_pread ( vfs_handle_struct * handle , files_struct * fsp , void * data ,
2006-07-11 22:01:26 +04:00
size_t n , SMB_OFF_T offset )
{
ssize_t result ;
# if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
START_PROFILE_BYTES ( syscall_pread , n ) ;
2008-01-07 02:14:19 +03:00
result = sys_pread ( fsp - > fh - > fd , data , n , offset ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_pread ) ;
if ( result = = - 1 & & errno = = ESPIPE ) {
/* Maintain the fiction that pipes can be seeked (sought?) on. */
2008-01-10 17:33:51 +03:00
result = SMB_VFS_READ ( fsp , data , n ) ;
2006-07-11 22:01:26 +04:00
fsp - > fh - > pos = 0 ;
}
# else /* HAVE_PREAD */
SMB_OFF_T curr ;
int lerrno ;
2008-01-07 12:15:08 +03:00
curr = SMB_VFS_LSEEK ( fsp , 0 , SEEK_CUR ) ;
2006-07-11 22:01:26 +04:00
if ( curr = = - 1 & & errno = = ESPIPE ) {
/* Maintain the fiction that pipes can be seeked (sought?) on. */
2008-01-10 17:33:51 +03:00
result = SMB_VFS_READ ( fsp , data , n ) ;
2006-07-11 22:01:26 +04:00
fsp - > fh - > pos = 0 ;
return result ;
}
2008-01-07 12:15:08 +03:00
if ( SMB_VFS_LSEEK ( fsp , offset , SEEK_SET ) = = - 1 ) {
2006-07-11 22:01:26 +04:00
return - 1 ;
}
errno = 0 ;
2008-01-10 17:33:51 +03:00
result = SMB_VFS_READ ( fsp , data , n ) ;
2006-07-11 22:01:26 +04:00
lerrno = errno ;
2008-01-07 12:15:08 +03:00
SMB_VFS_LSEEK ( fsp , curr , SEEK_SET ) ;
2006-07-11 22:01:26 +04:00
errno = lerrno ;
# endif /* HAVE_PREAD */
return result ;
}
2008-01-10 17:49:35 +03:00
static ssize_t vfswrap_write ( vfs_handle_struct * handle , files_struct * fsp , const void * data , size_t n )
2006-07-11 22:01:26 +04:00
{
ssize_t result ;
START_PROFILE_BYTES ( syscall_write , n ) ;
2008-01-10 17:49:35 +03:00
result = sys_write ( fsp - > fh - > fd , data , n ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_write ) ;
return result ;
}
2008-01-07 11:23:04 +03:00
static ssize_t vfswrap_pwrite ( vfs_handle_struct * handle , files_struct * fsp , const void * data ,
2006-07-11 22:01:26 +04:00
size_t n , SMB_OFF_T offset )
{
ssize_t result ;
# if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
START_PROFILE_BYTES ( syscall_pwrite , n ) ;
2008-01-07 11:23:04 +03:00
result = sys_pwrite ( fsp - > fh - > fd , data , n , offset ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_pwrite ) ;
if ( result = = - 1 & & errno = = ESPIPE ) {
/* Maintain the fiction that pipes can be sought on. */
2008-01-10 17:49:35 +03:00
result = SMB_VFS_WRITE ( fsp , data , n ) ;
2006-07-11 22:01:26 +04:00
}
# else /* HAVE_PWRITE */
SMB_OFF_T curr ;
int lerrno ;
2008-01-07 12:15:08 +03:00
curr = SMB_VFS_LSEEK ( fsp , 0 , SEEK_CUR ) ;
2006-07-11 22:01:26 +04:00
if ( curr = = - 1 ) {
return - 1 ;
}
2008-01-07 12:15:08 +03:00
if ( SMB_VFS_LSEEK ( fsp , offset , SEEK_SET ) = = - 1 ) {
2006-07-11 22:01:26 +04:00
return - 1 ;
}
2008-01-10 17:49:35 +03:00
result = SMB_VFS_WRITE ( fsp , data , n ) ;
2006-07-11 22:01:26 +04:00
lerrno = errno ;
2008-01-07 12:15:08 +03:00
SMB_VFS_LSEEK ( fsp , curr , SEEK_SET ) ;
2006-07-11 22:01:26 +04:00
errno = lerrno ;
# endif /* HAVE_PWRITE */
return result ;
}
2008-01-07 12:15:08 +03:00
static SMB_OFF_T vfswrap_lseek ( vfs_handle_struct * handle , files_struct * fsp , SMB_OFF_T offset , int whence )
2006-07-11 22:01:26 +04:00
{
SMB_OFF_T result = 0 ;
START_PROFILE ( syscall_lseek ) ;
/* Cope with 'stat' file opens. */
2008-01-07 12:15:08 +03:00
if ( fsp - > fh - > fd ! = - 1 )
result = sys_lseek ( fsp - > fh - > fd , offset , whence ) ;
2006-07-11 22:01:26 +04:00
/*
* We want to maintain the fiction that we can seek
* on a fifo for file system purposes . This allows
* people to set up UNIX fifo ' s that feed data to Windows
* applications . JRA .
*/
if ( ( result = = - 1 ) & & ( errno = = ESPIPE ) ) {
result = 0 ;
errno = 0 ;
}
END_PROFILE ( syscall_lseek ) ;
return result ;
}
2008-01-11 02:51:19 +03:00
static ssize_t vfswrap_sendfile ( vfs_handle_struct * handle , int tofd , files_struct * fromfsp , const DATA_BLOB * hdr ,
2006-07-11 22:01:26 +04:00
SMB_OFF_T offset , size_t n )
{
ssize_t result ;
START_PROFILE_BYTES ( syscall_sendfile , n ) ;
2008-01-11 02:51:19 +03:00
result = sys_sendfile ( tofd , fromfsp - > fh - > fd , hdr , offset , n ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_sendfile ) ;
return result ;
}
2007-10-30 03:16:13 +03:00
static ssize_t vfswrap_recvfile ( vfs_handle_struct * handle ,
int fromfd ,
2008-01-11 03:26:54 +03:00
files_struct * tofsp ,
2007-10-30 03:16:13 +03:00
SMB_OFF_T offset ,
size_t n )
{
ssize_t result ;
START_PROFILE_BYTES ( syscall_recvfile , n ) ;
2008-01-11 03:26:54 +03:00
result = sys_recvfile ( fromfd , tofsp - > fh - > fd , offset , n ) ;
2007-10-30 03:16:13 +03:00
END_PROFILE ( syscall_recvfile ) ;
return result ;
}
2006-07-11 22:01:26 +04:00
/*********************************************************
For rename across filesystems Patch from Warren Birnbaum
< warrenb @ hpcvscdp . cv . hp . com >
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int copy_reg ( const char * source , const char * dest )
{
SMB_STRUCT_STAT source_stats ;
int saved_errno ;
int ifd = - 1 ;
int ofd = - 1 ;
2009-11-27 17:10:23 +03:00
if ( sys_lstat ( source , & source_stats , false ) = = - 1 )
2006-07-11 22:01:26 +04:00
return - 1 ;
2009-05-14 17:34:42 +04:00
if ( ! S_ISREG ( source_stats . st_ex_mode ) )
2006-07-11 22:01:26 +04:00
return - 1 ;
if ( ( ifd = sys_open ( source , O_RDONLY , 0 ) ) < 0 )
return - 1 ;
if ( unlink ( dest ) & & errno ! = ENOENT )
return - 1 ;
# ifdef O_NOFOLLOW
if ( ( ofd = sys_open ( dest , O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW , 0600 ) ) < 0 )
# else
if ( ( ofd = sys_open ( dest , O_WRONLY | O_CREAT | O_TRUNC , 0600 ) ) < 0 )
# endif
goto err ;
if ( transfer_file ( ifd , ofd , ( size_t ) - 1 ) = = - 1 )
goto err ;
/*
* Try to preserve ownership . For non - root it might fail , but that ' s ok .
* But root probably wants to know , e . g . if NFS disallows it .
*/
# ifdef HAVE_FCHOWN
2009-05-14 17:34:42 +04:00
if ( ( fchown ( ofd , source_stats . st_ex_uid , source_stats . st_ex_gid ) = = - 1 ) & & ( errno ! = EPERM ) )
2006-07-11 22:01:26 +04:00
# else
2009-05-14 17:34:42 +04:00
if ( ( chown ( dest , source_stats . st_ex_uid , source_stats . st_ex_gid ) = = - 1 ) & & ( errno ! = EPERM ) )
2006-07-11 22:01:26 +04:00
# endif
goto err ;
/*
* fchown turns off set [ ug ] id bits for non - root ,
* so do the chmod last .
*/
# if defined(HAVE_FCHMOD)
2009-05-14 17:34:42 +04:00
if ( fchmod ( ofd , source_stats . st_ex_mode & 07777 ) )
2006-07-11 22:01:26 +04:00
# else
2009-05-14 17:34:42 +04:00
if ( chmod ( dest , source_stats . st_ex_mode & 07777 ) )
2006-07-11 22:01:26 +04:00
# endif
goto err ;
if ( close ( ifd ) = = - 1 )
goto err ;
if ( close ( ofd ) = = - 1 )
return - 1 ;
/* Try to copy the old file's modtime and access time. */
{
struct utimbuf tv ;
2009-05-14 17:34:42 +04:00
tv . actime = convert_timespec_to_time_t ( source_stats . st_ex_atime ) ;
tv . modtime = convert_timespec_to_time_t ( source_stats . st_ex_mtime ) ;
2006-07-11 22:01:26 +04:00
utime ( dest , & tv ) ;
}
if ( unlink ( source ) = = - 1 )
return - 1 ;
return 0 ;
err :
saved_errno = errno ;
if ( ifd ! = - 1 )
close ( ifd ) ;
if ( ofd ! = - 1 )
close ( ofd ) ;
errno = saved_errno ;
return - 1 ;
}
2009-07-01 04:04:38 +04:00
static int vfswrap_rename ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname_src ,
const struct smb_filename * smb_fname_dst )
2006-07-11 22:01:26 +04:00
{
2009-07-02 20:27:44 +04:00
int result = - 1 ;
2006-07-11 22:01:26 +04:00
START_PROFILE ( syscall_rename ) ;
2009-07-01 04:04:38 +04:00
if ( smb_fname_src - > stream_name | | smb_fname_dst - > stream_name ) {
errno = ENOENT ;
goto out ;
}
result = rename ( smb_fname_src - > base_name , smb_fname_dst - > base_name ) ;
2008-02-25 15:00:24 +03:00
if ( ( result = = - 1 ) & & ( errno = = EXDEV ) ) {
2006-07-11 22:01:26 +04:00
/* Rename across filesystems needed. */
2009-07-01 04:04:38 +04:00
result = copy_reg ( smb_fname_src - > base_name ,
smb_fname_dst - > base_name ) ;
2006-07-11 22:01:26 +04:00
}
2009-07-01 04:04:38 +04:00
out :
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_rename ) ;
return result ;
}
2008-01-07 14:49:02 +03:00
static int vfswrap_fsync ( vfs_handle_struct * handle , files_struct * fsp )
2006-07-11 22:01:26 +04:00
{
# ifdef HAVE_FSYNC
int result ;
START_PROFILE ( syscall_fsync ) ;
2008-01-07 14:49:02 +03:00
result = fsync ( fsp - > fh - > fd ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_fsync ) ;
return result ;
# else
return 0 ;
# endif
}
2009-06-23 02:26:56 +04:00
static int vfswrap_stat ( vfs_handle_struct * handle ,
struct smb_filename * smb_fname )
2006-07-11 22:01:26 +04:00
{
2009-07-21 22:35:17 +04:00
int result = - 1 ;
2006-07-11 22:01:26 +04:00
START_PROFILE ( syscall_stat ) ;
2009-06-23 02:26:56 +04:00
2009-07-21 22:35:17 +04:00
if ( smb_fname - > stream_name ) {
errno = ENOENT ;
goto out ;
2009-06-23 02:26:56 +04:00
}
2009-11-27 14:42:39 +03:00
result = sys_stat ( smb_fname - > base_name , & smb_fname - > st ,
2009-11-27 17:44:50 +03:00
lp_fake_dir_create_times ( SNUM ( handle - > conn ) ) ) ;
2009-07-21 22:35:17 +04:00
out :
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_stat ) ;
return result ;
}
2008-01-07 15:21:26 +03:00
static int vfswrap_fstat ( vfs_handle_struct * handle , files_struct * fsp , SMB_STRUCT_STAT * sbuf )
2006-07-11 22:01:26 +04:00
{
int result ;
START_PROFILE ( syscall_fstat ) ;
2009-11-27 14:42:39 +03:00
result = sys_fstat ( fsp - > fh - > fd ,
2009-11-27 17:44:50 +03:00
sbuf , lp_fake_dir_create_times ( SNUM ( handle - > conn ) ) ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_fstat ) ;
return result ;
}
2009-06-23 02:26:56 +04:00
static int vfswrap_lstat ( vfs_handle_struct * handle ,
struct smb_filename * smb_fname )
2006-07-11 22:01:26 +04:00
{
2009-07-21 22:35:17 +04:00
int result = - 1 ;
2006-07-11 22:01:26 +04:00
START_PROFILE ( syscall_lstat ) ;
2009-06-23 02:26:56 +04:00
2009-07-21 22:35:17 +04:00
if ( smb_fname - > stream_name ) {
errno = ENOENT ;
goto out ;
2009-06-23 02:26:56 +04:00
}
2009-11-27 14:42:39 +03:00
result = sys_lstat ( smb_fname - > base_name , & smb_fname - > st ,
2009-11-27 17:44:50 +03:00
lp_fake_dir_create_times ( SNUM ( handle - > conn ) ) ) ;
2009-07-21 22:35:17 +04:00
out :
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_lstat ) ;
return result ;
}
2009-11-16 11:49:23 +03:00
static NTSTATUS vfswrap_translate_name ( struct vfs_handle_struct * handle ,
const char * name ,
enum vfs_translate_direction direction ,
TALLOC_CTX * mem_ctx ,
char * * mapped_name )
2009-08-27 01:56:09 +04:00
{
2009-11-16 11:49:23 +03:00
return NT_STATUS_NONE_MAPPED ;
2009-08-27 01:56:09 +04:00
}
2009-11-16 11:49:23 +03:00
2009-01-27 02:39:40 +03:00
/********************************************************************
Given a stat buffer return the allocated size on disk , taking into
account sparse files .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static uint64_t vfswrap_get_alloc_size ( vfs_handle_struct * handle ,
struct files_struct * fsp ,
const SMB_STRUCT_STAT * sbuf )
{
uint64_t result ;
START_PROFILE ( syscall_get_alloc_size ) ;
2009-05-14 17:34:42 +04:00
if ( S_ISDIR ( sbuf - > st_ex_mode ) ) {
2009-01-27 02:39:40 +03:00
result = 0 ;
goto out ;
}
# if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
2009-05-14 17:34:42 +04:00
result = ( uint64_t ) STAT_ST_BLOCKSIZE * ( uint64_t ) sbuf - > st_ex_blocks ;
2009-01-27 02:39:40 +03:00
# else
result = get_file_size_stat ( sbuf ) ;
# endif
if ( fsp & & fsp - > initial_allocation_size )
result = MAX ( result , fsp - > initial_allocation_size ) ;
result = smb_roundup ( handle - > conn , result ) ;
out :
END_PROFILE ( syscall_get_alloc_size ) ;
return result ;
}
2009-07-02 20:27:44 +04:00
static int vfswrap_unlink ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname )
2006-07-11 22:01:26 +04:00
{
2009-07-02 20:27:44 +04:00
int result = - 1 ;
2006-07-11 22:01:26 +04:00
START_PROFILE ( syscall_unlink ) ;
2009-07-02 20:27:44 +04:00
if ( smb_fname - > stream_name ) {
errno = ENOENT ;
goto out ;
}
result = unlink ( smb_fname - > base_name ) ;
out :
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_unlink ) ;
return result ;
}
static int vfswrap_chmod ( vfs_handle_struct * handle , const char * path , mode_t mode )
{
int result ;
START_PROFILE ( syscall_chmod ) ;
/*
* We need to do this due to the fact that the default POSIX ACL
* chmod modifies the ACL * mask * for the group owner , not the
* group owner bits directly . JRA .
*/
{
int saved_errno = errno ; /* We might get ENOSYS */
if ( ( result = SMB_VFS_CHMOD_ACL ( handle - > conn , path , mode ) ) = = 0 ) {
END_PROFILE ( syscall_chmod ) ;
return result ;
}
/* Error - return the old errno. */
errno = saved_errno ;
}
result = chmod ( path , mode ) ;
END_PROFILE ( syscall_chmod ) ;
return result ;
}
2008-01-07 15:44:37 +03:00
static int vfswrap_fchmod ( vfs_handle_struct * handle , files_struct * fsp , mode_t mode )
2006-07-11 22:01:26 +04:00
{
int result ;
START_PROFILE ( syscall_fchmod ) ;
/*
* We need to do this due to the fact that the default POSIX ACL
* chmod modifies the ACL * mask * for the group owner , not the
* group owner bits directly . JRA .
*/
{
int saved_errno = errno ; /* We might get ENOSYS */
2008-01-08 03:14:24 +03:00
if ( ( result = SMB_VFS_FCHMOD_ACL ( fsp , mode ) ) = = 0 ) {
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_fchmod ) ;
return result ;
}
/* Error - return the old errno. */
errno = saved_errno ;
}
# if defined(HAVE_FCHMOD)
2008-01-07 15:44:37 +03:00
result = fchmod ( fsp - > fh - > fd , mode ) ;
2006-07-11 22:01:26 +04:00
# else
result = - 1 ;
errno = ENOSYS ;
# endif
END_PROFILE ( syscall_fchmod ) ;
return result ;
}
2007-05-24 03:55:12 +04:00
static int vfswrap_chown ( vfs_handle_struct * handle , const char * path , uid_t uid , gid_t gid )
2006-07-11 22:01:26 +04:00
{
int result ;
START_PROFILE ( syscall_chown ) ;
2008-11-01 05:29:06 +03:00
result = chown ( path , uid , gid ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_chown ) ;
return result ;
}
2008-01-07 16:26:00 +03:00
static int vfswrap_fchown ( vfs_handle_struct * handle , files_struct * fsp , uid_t uid , gid_t gid )
2006-07-11 22:01:26 +04:00
{
# ifdef HAVE_FCHOWN
int result ;
START_PROFILE ( syscall_fchown ) ;
2008-01-07 16:26:00 +03:00
result = fchown ( fsp - > fh - > fd , uid , gid ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_fchown ) ;
return result ;
# else
errno = ENOSYS ;
return - 1 ;
# endif
}
2007-05-24 03:55:12 +04:00
static int vfswrap_lchown ( vfs_handle_struct * handle , const char * path , uid_t uid , gid_t gid )
{
int result ;
START_PROFILE ( syscall_lchown ) ;
2008-11-01 05:39:20 +03:00
result = lchown ( path , uid , gid ) ;
2007-05-24 03:55:12 +04:00
END_PROFILE ( syscall_lchown ) ;
return result ;
}
2006-07-11 22:01:26 +04:00
static int vfswrap_chdir ( vfs_handle_struct * handle , const char * path )
{
int result ;
START_PROFILE ( syscall_chdir ) ;
result = chdir ( path ) ;
END_PROFILE ( syscall_chdir ) ;
return result ;
}
static char * vfswrap_getwd ( vfs_handle_struct * handle , char * path )
{
char * result ;
START_PROFILE ( syscall_getwd ) ;
result = sys_getwd ( path ) ;
END_PROFILE ( syscall_getwd ) ;
return result ;
}
2007-03-06 02:40:03 +03:00
/*********************************************************************
nsec timestamp resolution call . Convert down to whatever the underlying
system will support .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-07-03 00:39:20 +04:00
static int vfswrap_ntimes ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
2009-01-24 01:40:19 +03:00
struct smb_file_time * ft )
2006-07-11 22:01:26 +04:00
{
2009-07-03 00:39:20 +04:00
int result = - 1 ;
2006-07-11 22:01:26 +04:00
2007-03-06 02:40:03 +03:00
START_PROFILE ( syscall_ntimes ) ;
2009-07-03 00:39:20 +04:00
if ( smb_fname - > stream_name ) {
errno = ENOENT ;
goto out ;
}
2009-08-07 23:38:31 +04:00
if ( null_timespec ( ft - > atime ) ) {
ft - > atime = smb_fname - > st . st_ex_atime ;
}
if ( null_timespec ( ft - > mtime ) ) {
ft - > mtime = smb_fname - > st . st_ex_mtime ;
}
2009-11-18 01:55:02 +03:00
if ( ! null_timespec ( ft - > create_time ) ) {
2009-08-25 07:57:37 +04:00
set_create_timespec_ea ( handle - > conn ,
smb_fname ,
ft - > create_time ) ;
}
2009-08-07 23:38:31 +04:00
if ( ( timespec_compare ( & ft - > atime ,
& smb_fname - > st . st_ex_atime ) = = 0 ) & &
( timespec_compare ( & ft - > mtime ,
& smb_fname - > st . st_ex_mtime ) = = 0 ) ) {
return 0 ;
}
2009-11-04 13:15:31 +03:00
# if defined(HAVE_UTIMENSAT)
if ( ft ! = NULL ) {
struct timespec ts [ 2 ] ;
ts [ 0 ] = ft - > atime ;
ts [ 1 ] = ft - > mtime ;
result = utimensat ( AT_FDCWD , smb_fname - > base_name , ts , 0 ) ;
} else {
result = utimensat ( AT_FDCWD , smb_fname - > base_name , NULL , 0 ) ;
}
# elif defined(HAVE_UTIMES)
2009-01-24 01:40:19 +03:00
if ( ft ! = NULL ) {
2007-03-06 02:40:03 +03:00
struct timeval tv [ 2 ] ;
2009-01-24 01:40:19 +03:00
tv [ 0 ] = convert_timespec_to_timeval ( ft - > atime ) ;
tv [ 1 ] = convert_timespec_to_timeval ( ft - > mtime ) ;
2009-07-03 00:39:20 +04:00
result = utimes ( smb_fname - > base_name , tv ) ;
2008-07-16 02:26:36 +04:00
} else {
2009-07-03 00:39:20 +04:00
result = utimes ( smb_fname - > base_name , NULL ) ;
2007-03-06 02:40:03 +03:00
}
# elif defined(HAVE_UTIME)
2009-01-24 01:40:19 +03:00
if ( ft ! = NULL ) {
2007-03-24 01:23:09 +03:00
struct utimbuf times ;
2009-01-24 01:40:19 +03:00
times . actime = convert_timespec_to_time_t ( ft - > atime ) ;
times . modtime = convert_timespec_to_time_t ( ft - > mtime ) ;
2009-07-03 00:39:20 +04:00
result = utime ( smb_fname - > base_name , & times ) ;
2008-07-16 02:26:36 +04:00
} else {
2009-07-03 00:39:20 +04:00
result = utime ( smb_fname - > base_name , NULL ) ;
2007-03-06 02:40:03 +03:00
}
# else
errno = ENOSYS ;
result = - 1 ;
# endif
2009-08-13 00:00:54 +04:00
2009-07-03 00:39:20 +04:00
out :
2007-03-06 02:40:03 +03:00
END_PROFILE ( syscall_ntimes ) ;
2006-07-11 22:01:26 +04:00
return result ;
}
/*********************************************************************
A version of ftruncate that will write the space on disk if strict
allocate is set .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-01-07 17:55:09 +03:00
static int strict_allocate_ftruncate ( vfs_handle_struct * handle , files_struct * fsp , SMB_OFF_T len )
2006-07-11 22:01:26 +04:00
{
SMB_STRUCT_STAT st ;
2008-01-07 12:15:08 +03:00
SMB_OFF_T currpos = SMB_VFS_LSEEK ( fsp , 0 , SEEK_CUR ) ;
2006-07-11 22:01:26 +04:00
unsigned char zero_space [ 4096 ] ;
SMB_OFF_T space_to_write ;
2009-12-03 04:32:47 +03:00
uint64_t space_avail ;
uint64_t bsize , dfree , dsize ;
2006-07-11 22:01:26 +04:00
if ( currpos = = - 1 )
return - 1 ;
2008-01-07 15:21:26 +03:00
if ( SMB_VFS_FSTAT ( fsp , & st ) = = - 1 )
2006-07-11 22:01:26 +04:00
return - 1 ;
# ifdef S_ISFIFO
2009-05-14 17:34:42 +04:00
if ( S_ISFIFO ( st . st_ex_mode ) )
2006-07-11 22:01:26 +04:00
return 0 ;
# endif
2009-05-14 17:34:42 +04:00
if ( st . st_ex_size = = len )
2006-07-11 22:01:26 +04:00
return 0 ;
/* Shrink - just ftruncate. */
2009-05-14 17:34:42 +04:00
if ( st . st_ex_size > len )
2008-01-07 17:55:09 +03:00
return sys_ftruncate ( fsp - > fh - > fd , len ) ;
2006-07-11 22:01:26 +04:00
2009-12-08 12:30:03 +03:00
space_to_write = len - st . st_ex_size ;
2009-12-02 17:13:37 +03:00
/* for allocation try posix_fallocate first. This can fail on some
platforms e . g . when the filesystem doesn ' t support it and no
emulation is being done by the libc ( like on AIX with JFS1 ) . In that
case we do our own emulation . posix_fallocate implementations can
return ENOTSUP or EINVAL in cases like that . */
# if defined(HAVE_POSIX_FALLOCATE)
{
2009-12-08 12:30:03 +03:00
int ret = sys_posix_fallocate ( fsp - > fh - > fd , st . st_ex_size , space_to_write ) ;
2009-12-02 17:13:37 +03:00
if ( ret = = ENOSPC ) {
errno = ENOSPC ;
return - 1 ;
}
if ( ret = = 0 ) {
return 0 ;
}
DEBUG ( 10 , ( " strict_allocate_ftruncate: sys_posix_fallocate "
" failed with error %d. "
" Falling back to slow manual allocation \n " , ret ) ) ;
}
# endif
2008-12-25 23:13:12 +03:00
/* available disk space is enough or not? */
2009-12-03 04:32:47 +03:00
space_avail = get_dfree_info ( fsp - > conn ,
fsp - > fsp_name - > base_name , false ,
& bsize , & dfree , & dsize ) ;
/* space_avail is 1k blocks */
if ( space_avail = = ( uint64_t ) - 1 | |
( ( uint64_t ) space_to_write / 1024 > space_avail ) ) {
errno = ENOSPC ;
return - 1 ;
2008-12-25 23:13:12 +03:00
}
2006-07-11 22:01:26 +04:00
/* Write out the real space on disk. */
2009-05-14 17:34:42 +04:00
if ( SMB_VFS_LSEEK ( fsp , st . st_ex_size , SEEK_SET ) ! = st . st_ex_size )
2006-07-11 22:01:26 +04:00
return - 1 ;
memset ( zero_space , ' \0 ' , sizeof ( zero_space ) ) ;
while ( space_to_write > 0 ) {
SMB_OFF_T retlen ;
SMB_OFF_T current_len_to_write = MIN ( sizeof ( zero_space ) , space_to_write ) ;
2008-01-10 17:49:35 +03:00
retlen = SMB_VFS_WRITE ( fsp , ( char * ) zero_space , current_len_to_write ) ;
2006-07-11 22:01:26 +04:00
if ( retlen < = 0 )
return - 1 ;
space_to_write - = retlen ;
}
/* Seek to where we were */
2008-01-07 12:15:08 +03:00
if ( SMB_VFS_LSEEK ( fsp , currpos , SEEK_SET ) ! = currpos )
2006-07-11 22:01:26 +04:00
return - 1 ;
return 0 ;
}
2008-01-07 17:55:09 +03:00
static int vfswrap_ftruncate ( vfs_handle_struct * handle , files_struct * fsp , SMB_OFF_T len )
2006-07-11 22:01:26 +04:00
{
int result = - 1 ;
SMB_STRUCT_STAT st ;
char c = 0 ;
SMB_OFF_T currpos ;
START_PROFILE ( syscall_ftruncate ) ;
if ( lp_strict_allocate ( SNUM ( fsp - > conn ) ) ) {
2008-01-07 18:12:03 +03:00
result = strict_allocate_ftruncate ( handle , fsp , len ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_ftruncate ) ;
return result ;
}
/* we used to just check HAVE_FTRUNCATE_EXTEND and only use
sys_ftruncate if the system supports it . Then I discovered that
you can have some filesystems that support ftruncate
expansion and some that don ' t ! On Linux fat can ' t do
ftruncate extend but ext2 can . */
2008-01-07 17:55:09 +03:00
result = sys_ftruncate ( fsp - > fh - > fd , len ) ;
2006-07-11 22:01:26 +04:00
if ( result = = 0 )
goto done ;
/* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
extend a file with ftruncate . Provide alternate implementation
for this */
2008-01-07 12:15:08 +03:00
currpos = SMB_VFS_LSEEK ( fsp , 0 , SEEK_CUR ) ;
2006-07-11 22:01:26 +04:00
if ( currpos = = - 1 ) {
goto done ;
}
/* Do an fstat to see if the file is longer than the requested
size in which case the ftruncate above should have
succeeded or shorter , in which case seek to len - 1 and
write 1 byte of zero */
2008-01-07 15:21:26 +03:00
if ( SMB_VFS_FSTAT ( fsp , & st ) = = - 1 ) {
2006-07-11 22:01:26 +04:00
goto done ;
}
# ifdef S_ISFIFO
2009-05-14 17:34:42 +04:00
if ( S_ISFIFO ( st . st_ex_mode ) ) {
2006-07-11 22:01:26 +04:00
result = 0 ;
goto done ;
}
# endif
2009-05-14 17:34:42 +04:00
if ( st . st_ex_size = = len ) {
2006-07-11 22:01:26 +04:00
result = 0 ;
goto done ;
}
2009-05-14 17:34:42 +04:00
if ( st . st_ex_size > len ) {
2006-07-11 22:01:26 +04:00
/* the sys_ftruncate should have worked */
goto done ;
}
2008-01-07 12:15:08 +03:00
if ( SMB_VFS_LSEEK ( fsp , len - 1 , SEEK_SET ) ! = len - 1 )
2006-07-11 22:01:26 +04:00
goto done ;
2008-01-10 17:49:35 +03:00
if ( SMB_VFS_WRITE ( fsp , & c , 1 ) ! = 1 )
2006-07-11 22:01:26 +04:00
goto done ;
/* Seek to where we were */
2008-01-07 12:15:08 +03:00
if ( SMB_VFS_LSEEK ( fsp , currpos , SEEK_SET ) ! = currpos )
2006-07-11 22:01:26 +04:00
goto done ;
result = 0 ;
done :
END_PROFILE ( syscall_ftruncate ) ;
return result ;
}
2008-01-07 18:38:23 +03:00
static bool vfswrap_lock ( vfs_handle_struct * handle , files_struct * fsp , int op , SMB_OFF_T offset , SMB_OFF_T count , int type )
2006-07-11 22:01:26 +04:00
{
2007-10-19 04:40:25 +04:00
bool result ;
2006-07-11 22:01:26 +04:00
2007-05-15 18:58:01 +04:00
START_PROFILE ( syscall_fcntl_lock ) ;
2008-01-07 18:38:23 +03:00
result = fcntl_lock ( fsp - > fh - > fd , op , offset , count , type ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_fcntl_lock ) ;
return result ;
}
2008-01-07 19:14:20 +03:00
static int vfswrap_kernel_flock ( vfs_handle_struct * handle , files_struct * fsp ,
2009-10-06 19:14:56 +04:00
uint32 share_mode , uint32 access_mask )
2006-11-09 23:29:31 +03:00
{
START_PROFILE ( syscall_kernel_flock ) ;
2009-10-06 19:14:56 +04:00
kernel_flock ( fsp - > fh - > fd , share_mode , access_mask ) ;
2006-11-09 23:29:31 +03:00
END_PROFILE ( syscall_kernel_flock ) ;
return 0 ;
}
2008-01-08 00:18:50 +03:00
static bool vfswrap_getlock ( vfs_handle_struct * handle , files_struct * fsp , SMB_OFF_T * poffset , SMB_OFF_T * pcount , int * ptype , pid_t * ppid )
2006-07-11 22:01:26 +04:00
{
2007-10-19 04:40:25 +04:00
bool result ;
2006-07-11 22:01:26 +04:00
START_PROFILE ( syscall_fcntl_getlock ) ;
2008-01-08 00:18:50 +03:00
result = fcntl_getlock ( fsp - > fh - > fd , poffset , pcount , ptype , ppid ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_fcntl_getlock ) ;
return result ;
}
2008-01-07 23:47:53 +03:00
static int vfswrap_linux_setlease ( vfs_handle_struct * handle , files_struct * fsp ,
2007-02-14 05:37:14 +03:00
int leasetype )
{
2007-03-02 23:56:18 +03:00
int result = - 1 ;
2007-02-14 05:37:14 +03:00
START_PROFILE ( syscall_linux_setlease ) ;
2007-07-19 08:37:38 +04:00
# ifdef HAVE_KERNEL_OPLOCKS_LINUX
2007-02-14 05:37:14 +03:00
/* first set the signal handler */
2008-01-07 23:47:53 +03:00
if ( linux_set_lease_sighandler ( fsp - > fh - > fd ) = = - 1 ) {
2007-02-14 05:37:14 +03:00
return - 1 ;
2007-07-19 08:37:38 +04:00
}
2007-02-14 05:37:14 +03:00
2008-01-07 23:47:53 +03:00
result = linux_setlease ( fsp - > fh - > fd , leasetype ) ;
2007-03-02 23:56:18 +03:00
# else
errno = ENOSYS ;
2007-02-14 17:25:56 +03:00
# endif
2007-02-14 05:37:14 +03:00
END_PROFILE ( syscall_linux_setlease ) ;
return result ;
}
2006-07-11 22:01:26 +04:00
static int vfswrap_symlink ( vfs_handle_struct * handle , const char * oldpath , const char * newpath )
{
int result ;
START_PROFILE ( syscall_symlink ) ;
2008-11-01 05:35:58 +03:00
result = symlink ( oldpath , newpath ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_symlink ) ;
return result ;
}
static int vfswrap_readlink ( vfs_handle_struct * handle , const char * path , char * buf , size_t bufsiz )
{
int result ;
START_PROFILE ( syscall_readlink ) ;
2008-11-01 05:35:58 +03:00
result = readlink ( path , buf , bufsiz ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_readlink ) ;
return result ;
}
static int vfswrap_link ( vfs_handle_struct * handle , const char * oldpath , const char * newpath )
{
int result ;
START_PROFILE ( syscall_link ) ;
2008-11-01 05:30:47 +03:00
result = link ( oldpath , newpath ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_link ) ;
return result ;
}
static int vfswrap_mknod ( vfs_handle_struct * handle , const char * pathname , mode_t mode , SMB_DEV_T dev )
{
int result ;
START_PROFILE ( syscall_mknod ) ;
result = sys_mknod ( pathname , mode , dev ) ;
END_PROFILE ( syscall_mknod ) ;
return result ;
}
static char * vfswrap_realpath ( vfs_handle_struct * handle , const char * path , char * resolved_path )
{
char * result ;
START_PROFILE ( syscall_realpath ) ;
2008-11-01 05:42:27 +03:00
result = realpath ( path , resolved_path ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( syscall_realpath ) ;
return result ;
}
2007-02-01 16:36:02 +03:00
static NTSTATUS vfswrap_notify_watch ( vfs_handle_struct * vfs_handle ,
struct sys_notify_context * ctx ,
struct notify_entry * e ,
void ( * callback ) ( struct sys_notify_context * ctx ,
void * private_data ,
struct notify_event * ev ) ,
void * private_data , void * handle )
{
2007-02-02 20:48:21 +03:00
/*
* So far inotify is the only supported default notify mechanism . If
* another platform like the the BSD ' s or a proprietary Unix comes
* along and wants another default , we can play the same trick we
* played with Posix ACLs .
*
* Until that is the case , hard - code inotify here .
*/
2007-02-01 16:36:02 +03:00
# ifdef HAVE_INOTIFY
2007-02-01 18:11:06 +03:00
if ( lp_kernel_change_notify ( ctx - > conn - > params ) ) {
return inotify_watch ( ctx , e , callback , private_data , handle ) ;
}
2007-02-01 16:36:02 +03:00
# endif
2007-02-01 18:11:06 +03:00
/*
* Do nothing , leave everything to notify_internal . c
*/
return NT_STATUS_OK ;
2007-02-01 16:36:02 +03:00
}
2009-07-19 04:32:44 +04:00
static int vfswrap_chflags ( vfs_handle_struct * handle , const char * path ,
unsigned int flags )
2007-03-08 04:40:49 +03:00
{
2007-03-23 22:31:11 +03:00
# ifdef HAVE_CHFLAGS
return chflags ( path , flags ) ;
# else
2007-03-09 00:30:15 +03:00
errno = ENOSYS ;
return - 1 ;
2007-03-23 22:31:11 +03:00
# endif
2007-03-08 04:40:49 +03:00
}
2009-02-16 10:38:53 +03:00
static struct file_id vfswrap_file_id_create ( struct vfs_handle_struct * handle ,
2009-07-19 04:32:44 +04:00
const SMB_STRUCT_STAT * sbuf )
2007-08-02 12:53:24 +04:00
{
2009-02-16 10:38:53 +03:00
struct file_id key ;
/* the ZERO_STRUCT ensures padding doesn't break using the key as a
* blob */
ZERO_STRUCT ( key ) ;
2009-05-14 17:34:42 +04:00
key . devid = sbuf - > st_ex_dev ;
key . inode = sbuf - > st_ex_ino ;
2009-02-16 10:45:28 +03:00
/* key.extid is unused by default. */
2009-02-16 10:38:53 +03:00
return key ;
2007-08-02 12:53:24 +04:00
}
2008-01-19 22:41:15 +03:00
static NTSTATUS vfswrap_streaminfo ( vfs_handle_struct * handle ,
struct files_struct * fsp ,
const char * fname ,
TALLOC_CTX * mem_ctx ,
unsigned int * pnum_streams ,
struct stream_struct * * pstreams )
{
SMB_STRUCT_STAT sbuf ;
unsigned int num_streams = 0 ;
struct stream_struct * streams = NULL ;
int ret ;
if ( ( fsp ! = NULL ) & & ( fsp - > is_directory ) ) {
/*
* No default streams on directories
*/
goto done ;
}
if ( ( fsp ! = NULL ) & & ( fsp - > fh - > fd ! = - 1 ) ) {
ret = SMB_VFS_FSTAT ( fsp , & sbuf ) ;
}
else {
2009-11-15 12:46:23 +03:00
struct smb_filename smb_fname ;
ZERO_STRUCT ( smb_fname ) ;
smb_fname . base_name = discard_const_p ( char , fname ) ;
2009-07-07 02:26:57 +04:00
2009-10-02 03:54:06 +04:00
if ( lp_posix_pathnames ( ) ) {
2009-11-15 12:46:23 +03:00
ret = SMB_VFS_LSTAT ( handle - > conn , & smb_fname ) ;
2009-10-02 03:54:06 +04:00
} else {
2009-11-15 12:46:23 +03:00
ret = SMB_VFS_STAT ( handle - > conn , & smb_fname ) ;
2009-10-02 03:54:06 +04:00
}
2009-11-15 12:46:23 +03:00
sbuf = smb_fname . st ;
2008-01-19 22:41:15 +03:00
}
if ( ret = = - 1 ) {
return map_nt_error_from_unix ( errno ) ;
}
2009-05-14 17:34:42 +04:00
if ( S_ISDIR ( sbuf . st_ex_mode ) ) {
2008-01-19 22:41:15 +03:00
goto done ;
}
streams = talloc ( mem_ctx , struct stream_struct ) ;
if ( streams = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2009-05-14 17:34:42 +04:00
streams - > size = sbuf . st_ex_size ;
2009-01-27 02:39:40 +03:00
streams - > alloc_size = SMB_VFS_GET_ALLOC_SIZE ( handle - > conn , fsp , & sbuf ) ;
2008-01-19 22:41:15 +03:00
streams - > name = talloc_strdup ( streams , " ::$DATA " ) ;
if ( streams - > name = = NULL ) {
TALLOC_FREE ( streams ) ;
return NT_STATUS_NO_MEMORY ;
}
num_streams = 1 ;
done :
* pnum_streams = num_streams ;
* pstreams = streams ;
return NT_STATUS_OK ;
}
2008-12-10 05:17:19 +03:00
static int vfswrap_get_real_filename ( struct vfs_handle_struct * handle ,
const char * path ,
const char * name ,
TALLOC_CTX * mem_ctx ,
char * * found_name )
{
2009-05-02 04:28:38 +04:00
/*
* Don ' t fall back to get_real_filename so callers can differentiate
* between a full directory scan and an actual case - insensitive stat .
*/
errno = EOPNOTSUPP ;
return - 1 ;
2008-12-10 05:17:19 +03:00
}
2009-05-28 21:20:14 +04:00
static const char * vfswrap_connectpath ( struct vfs_handle_struct * handle ,
const char * fname )
{
return handle - > conn - > connectpath ;
}
2009-02-10 08:51:29 +03:00
static NTSTATUS vfswrap_brl_lock_windows ( struct vfs_handle_struct * handle ,
struct byte_range_lock * br_lck ,
struct lock_struct * plock ,
bool blocking_lock ,
struct blocking_lock_record * blr )
{
SMB_ASSERT ( plock - > lock_flav = = WINDOWS_LOCK ) ;
/* Note: blr is not used in the default implementation. */
return brl_lock_windows_default ( br_lck , plock , blocking_lock ) ;
}
static bool vfswrap_brl_unlock_windows ( struct vfs_handle_struct * handle ,
struct messaging_context * msg_ctx ,
struct byte_range_lock * br_lck ,
const struct lock_struct * plock )
{
SMB_ASSERT ( plock - > lock_flav = = WINDOWS_LOCK ) ;
return brl_unlock_windows_default ( msg_ctx , br_lck , plock ) ;
}
static bool vfswrap_brl_cancel_windows ( struct vfs_handle_struct * handle ,
struct byte_range_lock * br_lck ,
struct lock_struct * plock ,
struct blocking_lock_record * blr )
{
SMB_ASSERT ( plock - > lock_flav = = WINDOWS_LOCK ) ;
/* Note: blr is not used in the default implementation. */
return brl_lock_cancel_default ( br_lck , plock ) ;
}
2009-03-14 00:15:28 +03:00
static bool vfswrap_strict_lock ( struct vfs_handle_struct * handle ,
files_struct * fsp ,
struct lock_struct * plock )
{
SMB_ASSERT ( plock - > lock_type = = READ_LOCK | |
plock - > lock_type = = WRITE_LOCK ) ;
return strict_lock_default ( fsp , plock ) ;
}
static void vfswrap_strict_unlock ( struct vfs_handle_struct * handle ,
files_struct * fsp ,
struct lock_struct * plock )
{
SMB_ASSERT ( plock - > lock_type = = READ_LOCK | |
plock - > lock_type = = WRITE_LOCK ) ;
2009-03-14 08:01:36 +03:00
strict_unlock_default ( fsp , plock ) ;
2009-03-14 00:15:28 +03:00
}
2009-02-10 08:51:29 +03:00
/* NT ACL operations. */
2007-10-13 23:06:49 +04:00
static NTSTATUS vfswrap_fget_nt_acl ( vfs_handle_struct * handle ,
2008-01-05 04:16:15 +03:00
files_struct * fsp ,
2007-10-13 23:06:49 +04:00
uint32 security_info , SEC_DESC * * ppdesc )
2006-07-11 22:01:26 +04:00
{
2007-10-13 23:06:49 +04:00
NTSTATUS result ;
2006-07-11 22:01:26 +04:00
START_PROFILE ( fget_nt_acl ) ;
2007-11-06 10:01:31 +03:00
result = posix_fget_nt_acl ( fsp , security_info , ppdesc ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( fget_nt_acl ) ;
return result ;
}
2007-10-13 23:06:49 +04:00
static NTSTATUS vfswrap_get_nt_acl ( vfs_handle_struct * handle ,
2007-12-05 11:53:10 +03:00
const char * name ,
2007-10-13 23:06:49 +04:00
uint32 security_info , SEC_DESC * * ppdesc )
2006-07-11 22:01:26 +04:00
{
2007-10-13 23:06:49 +04:00
NTSTATUS result ;
2006-07-11 22:01:26 +04:00
START_PROFILE ( get_nt_acl ) ;
2007-12-05 11:53:10 +03:00
result = posix_get_nt_acl ( handle - > conn , name , security_info , ppdesc ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( get_nt_acl ) ;
return result ;
}
2008-10-08 04:50:01 +04:00
static NTSTATUS vfswrap_fset_nt_acl ( vfs_handle_struct * handle , files_struct * fsp , uint32 security_info_sent , const SEC_DESC * psd )
2006-07-11 22:01:26 +04:00
{
2007-06-27 02:49:10 +04:00
NTSTATUS result ;
2006-07-11 22:01:26 +04:00
START_PROFILE ( fset_nt_acl ) ;
result = set_nt_acl ( fsp , security_info_sent , psd ) ;
END_PROFILE ( fset_nt_acl ) ;
return result ;
}
static int vfswrap_chmod_acl ( vfs_handle_struct * handle , const char * name , mode_t mode )
{
# ifdef HAVE_NO_ACL
errno = ENOSYS ;
return - 1 ;
# else
int result ;
START_PROFILE ( chmod_acl ) ;
result = chmod_acl ( handle - > conn , name , mode ) ;
END_PROFILE ( chmod_acl ) ;
return result ;
# endif
}
2008-01-08 03:14:24 +03:00
static int vfswrap_fchmod_acl ( vfs_handle_struct * handle , files_struct * fsp , mode_t mode )
2006-07-11 22:01:26 +04:00
{
# ifdef HAVE_NO_ACL
errno = ENOSYS ;
return - 1 ;
# else
int result ;
START_PROFILE ( fchmod_acl ) ;
2008-01-08 03:14:24 +03:00
result = fchmod_acl ( fsp , mode ) ;
2006-07-11 22:01:26 +04:00
END_PROFILE ( fchmod_acl ) ;
return result ;
# endif
}
static int vfswrap_sys_acl_get_entry ( vfs_handle_struct * handle , SMB_ACL_T theacl , int entry_id , SMB_ACL_ENTRY_T * entry_p )
{
return sys_acl_get_entry ( theacl , entry_id , entry_p ) ;
}
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 )
{
return sys_acl_get_tag_type ( entry_d , tag_type_p ) ;
}
static int vfswrap_sys_acl_get_permset ( vfs_handle_struct * handle , SMB_ACL_ENTRY_T entry_d , SMB_ACL_PERMSET_T * permset_p )
{
return sys_acl_get_permset ( entry_d , permset_p ) ;
}
static void * vfswrap_sys_acl_get_qualifier ( vfs_handle_struct * handle , SMB_ACL_ENTRY_T entry_d )
{
return sys_acl_get_qualifier ( entry_d ) ;
}
static SMB_ACL_T vfswrap_sys_acl_get_file ( vfs_handle_struct * handle , const char * path_p , SMB_ACL_TYPE_T type )
{
2006-07-21 19:51:34 +04:00
return sys_acl_get_file ( handle , path_p , type ) ;
2006-07-11 22:01:26 +04:00
}
2008-01-08 01:53:34 +03:00
static SMB_ACL_T vfswrap_sys_acl_get_fd ( vfs_handle_struct * handle , files_struct * fsp )
2006-07-11 22:01:26 +04:00
{
2008-01-08 01:53:34 +03:00
return sys_acl_get_fd ( handle , fsp ) ;
2006-07-11 22:01:26 +04:00
}
static int vfswrap_sys_acl_clear_perms ( vfs_handle_struct * handle , SMB_ACL_PERMSET_T permset )
{
return sys_acl_clear_perms ( permset ) ;
}
static int vfswrap_sys_acl_add_perm ( vfs_handle_struct * handle , SMB_ACL_PERMSET_T permset , SMB_ACL_PERM_T perm )
{
return sys_acl_add_perm ( permset , perm ) ;
}
static char * vfswrap_sys_acl_to_text ( vfs_handle_struct * handle , SMB_ACL_T theacl , ssize_t * plen )
{
return sys_acl_to_text ( theacl , plen ) ;
}
static SMB_ACL_T vfswrap_sys_acl_init ( vfs_handle_struct * handle , int count )
{
return sys_acl_init ( count ) ;
}
static int vfswrap_sys_acl_create_entry ( vfs_handle_struct * handle , SMB_ACL_T * pacl , SMB_ACL_ENTRY_T * pentry )
{
return sys_acl_create_entry ( pacl , pentry ) ;
}
static int vfswrap_sys_acl_set_tag_type ( vfs_handle_struct * handle , SMB_ACL_ENTRY_T entry , SMB_ACL_TAG_T tagtype )
{
return sys_acl_set_tag_type ( entry , tagtype ) ;
}
static int vfswrap_sys_acl_set_qualifier ( vfs_handle_struct * handle , SMB_ACL_ENTRY_T entry , void * qual )
{
return sys_acl_set_qualifier ( entry , qual ) ;
}
static int vfswrap_sys_acl_set_permset ( vfs_handle_struct * handle , SMB_ACL_ENTRY_T entry , SMB_ACL_PERMSET_T permset )
{
return sys_acl_set_permset ( entry , permset ) ;
}
static int vfswrap_sys_acl_valid ( vfs_handle_struct * handle , SMB_ACL_T theacl )
{
return sys_acl_valid ( theacl ) ;
}
static int vfswrap_sys_acl_set_file ( vfs_handle_struct * handle , const char * name , SMB_ACL_TYPE_T acltype , SMB_ACL_T theacl )
{
2006-07-21 19:51:34 +04:00
return sys_acl_set_file ( handle , name , acltype , theacl ) ;
2006-07-11 22:01:26 +04:00
}
2008-01-08 03:54:19 +03:00
static int vfswrap_sys_acl_set_fd ( vfs_handle_struct * handle , files_struct * fsp , SMB_ACL_T theacl )
2006-07-11 22:01:26 +04:00
{
2008-01-08 03:54:19 +03:00
return sys_acl_set_fd ( handle , fsp , theacl ) ;
2006-07-11 22:01:26 +04:00
}
static int vfswrap_sys_acl_delete_def_file ( vfs_handle_struct * handle , const char * path )
{
2006-07-21 19:51:34 +04:00
return sys_acl_delete_def_file ( handle , path ) ;
2006-07-11 22:01:26 +04:00
}
static int vfswrap_sys_acl_get_perm ( vfs_handle_struct * handle , SMB_ACL_PERMSET_T permset , SMB_ACL_PERM_T perm )
{
return sys_acl_get_perm ( permset , perm ) ;
}
static int vfswrap_sys_acl_free_text ( vfs_handle_struct * handle , char * text )
{
return sys_acl_free_text ( text ) ;
}
static int vfswrap_sys_acl_free_acl ( vfs_handle_struct * handle , SMB_ACL_T posix_acl )
{
return sys_acl_free_acl ( posix_acl ) ;
}
static int vfswrap_sys_acl_free_qualifier ( vfs_handle_struct * handle , void * qualifier , SMB_ACL_TAG_T tagtype )
{
return sys_acl_free_qualifier ( qualifier , tagtype ) ;
}
/****************************************************************
Extended attribute operations .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static ssize_t vfswrap_getxattr ( struct vfs_handle_struct * handle , const char * path , const char * name , void * value , size_t size )
{
return sys_getxattr ( path , name , value , size ) ;
}
static ssize_t vfswrap_lgetxattr ( struct vfs_handle_struct * handle , const char * path , const char * name , void * value , size_t size )
{
return sys_lgetxattr ( path , name , value , size ) ;
}
2008-01-08 12:00:47 +03:00
static ssize_t vfswrap_fgetxattr ( struct vfs_handle_struct * handle , struct files_struct * fsp , const char * name , void * value , size_t size )
2006-07-11 22:01:26 +04:00
{
2008-01-08 12:00:47 +03:00
return sys_fgetxattr ( fsp - > fh - > fd , name , value , size ) ;
2006-07-11 22:01:26 +04:00
}
static ssize_t vfswrap_listxattr ( struct vfs_handle_struct * handle , const char * path , char * list , size_t size )
{
return sys_listxattr ( path , list , size ) ;
}
ssize_t vfswrap_llistxattr ( struct vfs_handle_struct * handle , const char * path , char * list , size_t size )
{
return sys_llistxattr ( path , list , size ) ;
}
2008-01-08 12:51:40 +03:00
ssize_t vfswrap_flistxattr ( struct vfs_handle_struct * handle , struct files_struct * fsp , char * list , size_t size )
2006-07-11 22:01:26 +04:00
{
2008-01-08 12:51:40 +03:00
return sys_flistxattr ( fsp - > fh - > fd , list , size ) ;
2006-07-11 22:01:26 +04:00
}
static int vfswrap_removexattr ( struct vfs_handle_struct * handle , const char * path , const char * name )
{
return sys_removexattr ( path , name ) ;
}
static int vfswrap_lremovexattr ( struct vfs_handle_struct * handle , const char * path , const char * name )
{
return sys_lremovexattr ( path , name ) ;
}
2008-01-08 13:29:09 +03:00
static int vfswrap_fremovexattr ( struct vfs_handle_struct * handle , struct files_struct * fsp , const char * name )
2006-07-11 22:01:26 +04:00
{
2008-01-08 13:29:09 +03:00
return sys_fremovexattr ( fsp - > fh - > fd , name ) ;
2006-07-11 22:01:26 +04:00
}
static int vfswrap_setxattr ( struct vfs_handle_struct * handle , const char * path , const char * name , const void * value , size_t size , int flags )
{
return sys_setxattr ( path , name , value , size , flags ) ;
}
static int vfswrap_lsetxattr ( struct vfs_handle_struct * handle , const char * path , const char * name , const void * value , size_t size , int flags )
{
return sys_lsetxattr ( path , name , value , size , flags ) ;
}
2008-01-08 13:47:33 +03:00
static int vfswrap_fsetxattr ( struct vfs_handle_struct * handle , struct files_struct * fsp , const char * name , const void * value , size_t size , int flags )
2006-07-11 22:01:26 +04:00
{
2008-01-08 13:47:33 +03:00
return sys_fsetxattr ( fsp - > fh - > fd , name , value , size , flags ) ;
2006-07-11 22:01:26 +04:00
}
static int vfswrap_aio_read ( struct vfs_handle_struct * handle , struct files_struct * fsp , SMB_STRUCT_AIOCB * aiocb )
{
2009-05-18 15:30:16 +04:00
int ret ;
/*
* aio_read must be done as root , because in the glibc aio
* implementation the helper thread needs to be able to send a signal
* to the main thread , even when it has done a seteuid ( ) to a
* different user .
*/
become_root ( ) ;
ret = sys_aio_read ( aiocb ) ;
unbecome_root ( ) ;
return ret ;
2006-07-11 22:01:26 +04:00
}
static int vfswrap_aio_write ( struct vfs_handle_struct * handle , struct files_struct * fsp , SMB_STRUCT_AIOCB * aiocb )
{
2009-05-18 15:30:16 +04:00
int ret ;
/*
* aio_write must be done as root , because in the glibc aio
* implementation the helper thread needs to be able to send a signal
* to the main thread , even when it has done a seteuid ( ) to a
* different user .
*/
become_root ( ) ;
ret = sys_aio_write ( aiocb ) ;
unbecome_root ( ) ;
return ret ;
2006-07-11 22:01:26 +04:00
}
static ssize_t vfswrap_aio_return ( struct vfs_handle_struct * handle , struct files_struct * fsp , SMB_STRUCT_AIOCB * aiocb )
{
return sys_aio_return ( aiocb ) ;
}
2008-01-08 14:20:51 +03:00
static int vfswrap_aio_cancel ( struct vfs_handle_struct * handle , struct files_struct * fsp , SMB_STRUCT_AIOCB * aiocb )
2006-07-11 22:01:26 +04:00
{
2008-01-08 14:20:51 +03:00
return sys_aio_cancel ( fsp - > fh - > fd , aiocb ) ;
2006-07-11 22:01:26 +04:00
}
static int vfswrap_aio_error ( struct vfs_handle_struct * handle , struct files_struct * fsp , SMB_STRUCT_AIOCB * aiocb )
{
return sys_aio_error ( aiocb ) ;
}
static int vfswrap_aio_fsync ( struct vfs_handle_struct * handle , struct files_struct * fsp , int op , SMB_STRUCT_AIOCB * aiocb )
{
return sys_aio_fsync ( op , aiocb ) ;
}
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 )
{
return sys_aio_suspend ( aiocb , n , timeout ) ;
}
2008-01-17 04:22:31 +03:00
static bool vfswrap_aio_force ( struct vfs_handle_struct * handle , struct files_struct * fsp )
2008-01-16 12:17:03 +03:00
{
2008-01-17 04:22:31 +03:00
return false ;
2008-01-16 12:17:03 +03:00
}
2008-01-17 14:57:35 +03:00
static bool vfswrap_is_offline ( struct vfs_handle_struct * handle , const char * path , SMB_STRUCT_STAT * sbuf )
2008-01-16 12:17:03 +03:00
{
if ( ISDOT ( path ) | | ISDOTDOT ( path ) ) {
2008-01-17 14:57:35 +03:00
return false ;
2008-01-16 12:17:03 +03:00
}
2008-01-17 04:22:31 +03:00
if ( ! lp_dmapi_support ( SNUM ( handle - > conn ) ) | | ! dmapi_have_session ( ) ) {
# if defined(ENOTSUP)
errno = ENOTSUP ;
# endif
2008-01-17 14:57:35 +03:00
return false ;
2008-01-16 12:17:03 +03:00
}
2008-01-17 04:22:31 +03:00
2008-01-17 14:57:35 +03:00
return ( dmapi_file_flags ( path ) & FILE_ATTRIBUTE_OFFLINE ) ! = 0 ;
2008-01-16 12:17:03 +03:00
}
2008-01-17 04:22:31 +03:00
static int vfswrap_set_offline ( struct vfs_handle_struct * handle , const char * path )
2008-01-16 12:17:03 +03:00
{
/* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
2008-01-17 04:22:31 +03:00
# if defined(ENOTSUP)
errno = ENOTSUP ;
# endif
2008-01-16 12:17:03 +03:00
return - 1 ;
}
2009-07-24 04:28:58 +04:00
static struct vfs_fn_pointers vfs_default_fns = {
2006-07-11 22:01:26 +04:00
/* Disk operations */
2009-07-24 04:28:58 +04:00
. connect_fn = vfswrap_connect ,
. disconnect = vfswrap_disconnect ,
. disk_free = vfswrap_disk_free ,
. get_quota = vfswrap_get_quota ,
. set_quota = vfswrap_set_quota ,
. get_shadow_copy_data = vfswrap_get_shadow_copy_data ,
. statvfs = vfswrap_statvfs ,
. fs_capabilities = vfswrap_fs_capabilities ,
2006-07-11 22:01:26 +04:00
/* Directory operations */
2009-07-24 04:28:58 +04:00
. opendir = vfswrap_opendir ,
. readdir = vfswrap_readdir ,
. seekdir = vfswrap_seekdir ,
. telldir = vfswrap_telldir ,
. rewind_dir = vfswrap_rewinddir ,
. mkdir = vfswrap_mkdir ,
. rmdir = vfswrap_rmdir ,
. closedir = vfswrap_closedir ,
. init_search_op = vfswrap_init_search_op ,
2006-07-11 22:01:26 +04:00
/* File operations */
2009-07-24 04:28:58 +04:00
. open = vfswrap_open ,
. create_file = vfswrap_create_file ,
. close_fn = vfswrap_close ,
. vfs_read = vfswrap_read ,
. pread = vfswrap_pread ,
. write = vfswrap_write ,
. pwrite = vfswrap_pwrite ,
. lseek = vfswrap_lseek ,
. sendfile = vfswrap_sendfile ,
. recvfile = vfswrap_recvfile ,
. rename = vfswrap_rename ,
. fsync = vfswrap_fsync ,
. stat = vfswrap_stat ,
. fstat = vfswrap_fstat ,
. lstat = vfswrap_lstat ,
. get_alloc_size = vfswrap_get_alloc_size ,
. unlink = vfswrap_unlink ,
. chmod = vfswrap_chmod ,
. fchmod = vfswrap_fchmod ,
. chown = vfswrap_chown ,
. fchown = vfswrap_fchown ,
. lchown = vfswrap_lchown ,
. chdir = vfswrap_chdir ,
. getwd = vfswrap_getwd ,
. ntimes = vfswrap_ntimes ,
. ftruncate = vfswrap_ftruncate ,
. lock = vfswrap_lock ,
. kernel_flock = vfswrap_kernel_flock ,
. linux_setlease = vfswrap_linux_setlease ,
. getlock = vfswrap_getlock ,
. symlink = vfswrap_symlink ,
. vfs_readlink = vfswrap_readlink ,
. link = vfswrap_link ,
. mknod = vfswrap_mknod ,
. realpath = vfswrap_realpath ,
. notify_watch = vfswrap_notify_watch ,
. chflags = vfswrap_chflags ,
. file_id_create = vfswrap_file_id_create ,
. streaminfo = vfswrap_streaminfo ,
. get_real_filename = vfswrap_get_real_filename ,
. connectpath = vfswrap_connectpath ,
. brl_lock_windows = vfswrap_brl_lock_windows ,
. brl_unlock_windows = vfswrap_brl_unlock_windows ,
. brl_cancel_windows = vfswrap_brl_cancel_windows ,
. strict_lock = vfswrap_strict_lock ,
. strict_unlock = vfswrap_strict_unlock ,
2009-08-27 01:56:09 +04:00
. translate_name = vfswrap_translate_name ,
2006-07-11 22:01:26 +04:00
/* NT ACL operations. */
2009-07-24 04:28:58 +04:00
. fget_nt_acl = vfswrap_fget_nt_acl ,
. get_nt_acl = vfswrap_get_nt_acl ,
. fset_nt_acl = vfswrap_fset_nt_acl ,
2006-07-11 22:01:26 +04:00
/* POSIX ACL operations. */
2009-07-24 04:28:58 +04:00
. chmod_acl = vfswrap_chmod_acl ,
. fchmod_acl = vfswrap_fchmod_acl ,
. sys_acl_get_entry = vfswrap_sys_acl_get_entry ,
. sys_acl_get_tag_type = vfswrap_sys_acl_get_tag_type ,
. sys_acl_get_permset = vfswrap_sys_acl_get_permset ,
. sys_acl_get_qualifier = vfswrap_sys_acl_get_qualifier ,
. sys_acl_get_file = vfswrap_sys_acl_get_file ,
. sys_acl_get_fd = vfswrap_sys_acl_get_fd ,
. sys_acl_clear_perms = vfswrap_sys_acl_clear_perms ,
. sys_acl_add_perm = vfswrap_sys_acl_add_perm ,
. sys_acl_to_text = vfswrap_sys_acl_to_text ,
. sys_acl_init = vfswrap_sys_acl_init ,
. sys_acl_create_entry = vfswrap_sys_acl_create_entry ,
. sys_acl_set_tag_type = vfswrap_sys_acl_set_tag_type ,
. sys_acl_set_qualifier = vfswrap_sys_acl_set_qualifier ,
. sys_acl_set_permset = vfswrap_sys_acl_set_permset ,
. sys_acl_valid = vfswrap_sys_acl_valid ,
. sys_acl_set_file = vfswrap_sys_acl_set_file ,
. sys_acl_set_fd = vfswrap_sys_acl_set_fd ,
. sys_acl_delete_def_file = vfswrap_sys_acl_delete_def_file ,
. sys_acl_get_perm = vfswrap_sys_acl_get_perm ,
. sys_acl_free_text = vfswrap_sys_acl_free_text ,
. sys_acl_free_acl = vfswrap_sys_acl_free_acl ,
. sys_acl_free_qualifier = vfswrap_sys_acl_free_qualifier ,
2006-07-11 22:01:26 +04:00
/* EA operations. */
2009-07-24 04:28:58 +04:00
. getxattr = vfswrap_getxattr ,
. lgetxattr = vfswrap_lgetxattr ,
. fgetxattr = vfswrap_fgetxattr ,
. listxattr = vfswrap_listxattr ,
. llistxattr = vfswrap_llistxattr ,
. flistxattr = vfswrap_flistxattr ,
. removexattr = vfswrap_removexattr ,
. lremovexattr = vfswrap_lremovexattr ,
. fremovexattr = vfswrap_fremovexattr ,
. setxattr = vfswrap_setxattr ,
. lsetxattr = vfswrap_lsetxattr ,
. fsetxattr = vfswrap_fsetxattr ,
/* aio operations */
. aio_read = vfswrap_aio_read ,
. aio_write = vfswrap_aio_write ,
. aio_return_fn = vfswrap_aio_return ,
. aio_cancel = vfswrap_aio_cancel ,
. aio_error_fn = vfswrap_aio_error ,
. aio_fsync = vfswrap_aio_fsync ,
. aio_suspend = vfswrap_aio_suspend ,
. aio_force = vfswrap_aio_force ,
/* offline operations */
. is_offline = vfswrap_is_offline ,
. set_offline = vfswrap_set_offline
2006-07-11 22:01:26 +04:00
} ;
2006-12-19 23:16:52 +03:00
NTSTATUS vfs_default_init ( void ) ;
2006-07-11 22:01:26 +04:00
NTSTATUS vfs_default_init ( void )
{
return smb_register_vfs ( SMB_VFS_INTERFACE_VERSION ,
2009-07-24 04:28:58 +04:00
DEFAULT_VFS_MODULE_NAME , & vfs_default_fns ) ;
2006-07-11 22:01:26 +04:00
}
2009-07-24 04:28:58 +04:00