[GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch.
[sfrench/samba-autobuild/.git] / source3 / modules / vfs_default.c
index ae565ae98075e66620042d8992c29f75955aba96..ca27cf0ac3af4d12567c76a065616c8741fc06fc 100644 (file)
@@ -2,10 +2,11 @@
    Unix SMB/CIFS implementation.
    Wrap disk only vfs functions to sidestep dodgy compilers.
    Copyright (C) Tim Potter 1998
+   Copyright (C) Jeremy Allison 2007
 
    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
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -14,8 +15,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
@@ -567,7 +567,7 @@ static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd,
        return result;
 }
 
-static int vfswrap_chown(vfs_handle_struct *handle,  const char *path, uid_t uid, gid_t gid)
+static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
 {
        int result;
 
@@ -592,6 +592,16 @@ static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd,
 #endif
 }
 
+static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
+{
+       int result;
+
+       START_PROFILE(syscall_lchown);
+       result = sys_lchown(path, uid, gid);
+       END_PROFILE(syscall_lchown);
+       return result;
+}
+
 static int vfswrap_chdir(vfs_handle_struct *handle,  const char *path)
 {
        int result;
@@ -612,13 +622,35 @@ static char *vfswrap_getwd(vfs_handle_struct *handle,  char *path)
        return result;
 }
 
-static int vfswrap_utime(vfs_handle_struct *handle,  const char *path, struct utimbuf *times)
+/*********************************************************************
+ nsec timestamp resolution call. Convert down to whatever the underlying
+ system will support.
+**********************************************************************/
+
+static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2])
 {
        int result;
 
-       START_PROFILE(syscall_utime);
-       result = utime(path, times);
-       END_PROFILE(syscall_utime);
+       START_PROFILE(syscall_ntimes);
+#if defined(HAVE_UTIMES)
+       {
+               struct timeval tv[2];
+               tv[0] = convert_timespec_to_timeval(ts[0]);
+               tv[1] = convert_timespec_to_timeval(ts[1]);
+               result = utimes(path, tv);
+       }
+#elif defined(HAVE_UTIME)
+       {
+               struct utimbuf times;
+               times.actime = convert_timespec_to_time_t(ts[0]);
+               times.modtime = convert_timespec_to_time_t(ts[1]);
+               result = utime(path, times);
+       }
+#else
+       errno = ENOSYS;
+       result = -1;
+#endif
+       END_PROFILE(syscall_ntimes);
        return result;
 }
 
@@ -764,6 +796,15 @@ static BOOL vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, i
        return result;
 }
 
+static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, int fd,
+                               uint32 share_mode)
+{
+       START_PROFILE(syscall_kernel_flock);
+       kernel_flock(fd, share_mode);
+       END_PROFILE(syscall_kernel_flock);
+       return 0;
+}
+
 static BOOL vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
 {
        BOOL result;
@@ -774,6 +815,27 @@ static BOOL vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, int fd
        return result;
 }
 
+static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp, int fd,
+                               int leasetype)
+{
+       int result = -1;
+
+       START_PROFILE(syscall_linux_setlease);
+
+#ifdef HAVE_KERNEL_OPLOCKS_LINUX
+       /* first set the signal handler */
+       if(linux_set_lease_sighandler(fd) == -1) {
+               return -1;
+       }
+
+       result = linux_setlease(fd, leasetype);
+#else
+       errno = ENOSYS;
+#endif
+       END_PROFILE(syscall_linux_setlease);
+       return result;
+}
+
 static int vfswrap_symlink(vfs_handle_struct *handle,  const char *oldpath, const char *newpath)
 {
        int result;
@@ -824,6 +886,48 @@ static char *vfswrap_realpath(vfs_handle_struct *handle,  const char *path, char
        return result;
 }
 
+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)
+{
+       /*
+        * 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.
+        */
+#ifdef HAVE_INOTIFY
+       if (lp_kernel_change_notify(ctx->conn->params)) {
+               return inotify_watch(ctx, e, callback, private_data, handle);
+       }
+#endif
+       /*
+        * Do nothing, leave everything to notify_internal.c
+        */
+       return NT_STATUS_OK;
+}
+
+static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flags)
+{
+#ifdef HAVE_CHFLAGS
+       return chflags(path, flags);
+#else
+       errno = ENOSYS;
+       return -1;
+#endif
+}
+
+static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle, SMB_DEV_T dev, SMB_INO_T inode)
+{
+       return file_id_create_dev(dev, inode);
+}
+
 static size_t vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc)
 {
        size_t result;
@@ -844,9 +948,9 @@ static size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, c
        return result;
 }
 
-static BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
+static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
 {
-       BOOL result;
+       NTSTATUS result;
 
        START_PROFILE(fset_nt_acl);
        result = set_nt_acl(fsp, security_info_sent, psd);
@@ -854,9 +958,9 @@ static BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, in
        return result;
 }
 
-static BOOL vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
+static NTSTATUS vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
 {
-       BOOL result;
+       NTSTATUS result;
 
        START_PROFILE(set_nt_acl);
        result = set_nt_acl(fsp, security_info_sent, psd);
@@ -1179,16 +1283,22 @@ static vfs_op_tuple vfs_default_ops[] = {
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_fchown),    SMB_VFS_OP_FCHOWN,
         SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(vfswrap_lchown),    SMB_VFS_OP_LCHOWN,
+        SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_chdir),     SMB_VFS_OP_CHDIR,
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_getwd),     SMB_VFS_OP_GETWD,
         SMB_VFS_LAYER_OPAQUE},
-       {SMB_VFS_OP(vfswrap_utime),     SMB_VFS_OP_UTIME,
+       {SMB_VFS_OP(vfswrap_ntimes),    SMB_VFS_OP_NTIMES,
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_ftruncate), SMB_VFS_OP_FTRUNCATE,
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_lock),      SMB_VFS_OP_LOCK,
         SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(vfswrap_kernel_flock),      SMB_VFS_OP_KERNEL_FLOCK,
+        SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(vfswrap_linux_setlease),    SMB_VFS_OP_LINUX_SETLEASE,
+        SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_getlock),   SMB_VFS_OP_GETLOCK,
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_symlink),   SMB_VFS_OP_SYMLINK,
@@ -1201,6 +1311,12 @@ static vfs_op_tuple vfs_default_ops[] = {
         SMB_VFS_LAYER_OPAQUE},
        {SMB_VFS_OP(vfswrap_realpath),  SMB_VFS_OP_REALPATH,
         SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(vfswrap_notify_watch),      SMB_VFS_OP_NOTIFY_WATCH,
+        SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(vfswrap_chflags),   SMB_VFS_OP_CHFLAGS,
+        SMB_VFS_LAYER_OPAQUE},
+       {SMB_VFS_OP(vfswrap_file_id_create),    SMB_VFS_OP_FILE_ID_CREATE,
+        SMB_VFS_LAYER_OPAQUE},
 
        /* NT ACL operations. */
 
@@ -1312,6 +1428,7 @@ static vfs_op_tuple vfs_default_ops[] = {
         SMB_VFS_LAYER_NOOP}
 };
 
+NTSTATUS vfs_default_init(void);
 NTSTATUS vfs_default_init(void)
 {
        unsigned int needed = SMB_VFS_OP_LAST + 1; /* convert from index to count */