mirror of
https://github.com/samba-team/samba.git
synced 2025-12-10 04:23:50 +03:00
r21324: Add linux setlease to the vfs layer. Next round, as Volker points out,
it should be abstracted a little higher up so other os'es can have an entry, but it will take a bit more work. Thanks to Chetan Shringarpure and Mathias Dietz. I didn't increment the vfs number again because the kernel change notify stuff hasn't been released yet anyway.
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
bc77622134
commit
9463211bf3
@@ -168,6 +168,10 @@ enum profile_stats_values
|
||||
#define syscall_kernel_flock_count __profile_stats_value(PR_VALUE_SYSCALL_KERNEL_FLOCK, count)
|
||||
#define syscall_kernel_flock_time __profile_stats_value(PR_VALUE_SYSCALL_KERNEL_FLOCK, time)
|
||||
|
||||
PR_VALUE_SYSCALL_LINUX_SETLEASE,
|
||||
#define syscall_linux_setlease_count __profile_stats_value(PR_VALUE_SYSCALL_LINUX_SETLEASE, count)
|
||||
#define syscall_linux_setlease_time __profile_stats_value(PR_VALUE_SYSCALL_LINUX_SETLEASE, time)
|
||||
|
||||
PR_VALUE_SYSCALL_FCNTL_GETLOCK,
|
||||
#define syscall_fcntl_getlock_count __profile_stats_value(PR_VALUE_SYSCALL_FCNTL_GETLOCK, count)
|
||||
#define syscall_fcntl_getlock_time __profile_stats_value(PR_VALUE_SYSCALL_FCNTL_GETLOCK, time)
|
||||
|
||||
@@ -65,7 +65,8 @@
|
||||
/* Changed to version 17 as we removed redundant connection_struct parameters. --jpeach */
|
||||
/* Changed to version 18 to add fsp parameter to the open call -- jpeach
|
||||
Also include kernel_flock call - jmcd */
|
||||
/* Changed to version 19, kernel change notify has been merged */
|
||||
/* Changed to version 19, kernel change notify has been merged
|
||||
Also included linux setlease call - jmcd */
|
||||
#define SMB_VFS_INTERFACE_VERSION 19
|
||||
|
||||
|
||||
@@ -147,6 +148,7 @@ typedef enum _vfs_op_type {
|
||||
SMB_VFS_OP_FTRUNCATE,
|
||||
SMB_VFS_OP_LOCK,
|
||||
SMB_VFS_OP_KERNEL_FLOCK,
|
||||
SMB_VFS_OP_LINUX_SETLEASE,
|
||||
SMB_VFS_OP_GETLOCK,
|
||||
SMB_VFS_OP_SYMLINK,
|
||||
SMB_VFS_OP_READLINK,
|
||||
@@ -271,6 +273,7 @@ struct vfs_ops {
|
||||
int (*ftruncate)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset);
|
||||
BOOL (*lock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
|
||||
int (*kernel_flock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 share_mode);
|
||||
int (*linux_setlease)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, int leasetype);
|
||||
BOOL (*getlock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid);
|
||||
int (*symlink)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath);
|
||||
int (*readlink)(struct vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz);
|
||||
@@ -393,6 +396,7 @@ struct vfs_ops {
|
||||
struct vfs_handle_struct *ftruncate;
|
||||
struct vfs_handle_struct *lock;
|
||||
struct vfs_handle_struct *kernel_flock;
|
||||
struct vfs_handle_struct *linux_setlease;
|
||||
struct vfs_handle_struct *getlock;
|
||||
struct vfs_handle_struct *symlink;
|
||||
struct vfs_handle_struct *readlink;
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
#define SMB_VFS_FTRUNCATE(fsp, fd, offset) ((fsp)->conn->vfs.ops.ftruncate((fsp)->conn->vfs.handles.ftruncate, (fsp), (fd), (offset)))
|
||||
#define SMB_VFS_LOCK(fsp, fd, op, offset, count, type) ((fsp)->conn->vfs.ops.lock((fsp)->conn->vfs.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
|
||||
#define SMB_VFS_KERNEL_FLOCK(fsp, fd, share_mode) ((fsp)->conn->vfs.ops.kernel_flock((fsp)->conn->vfs.handles.kernel_flock, (fsp), (fd), (share_mode)))
|
||||
#define SMB_VFS_LINUX_SETLEASE(fsp, fd, leasetype) ((fsp)->conn->vfs.ops.linux_setlease((fsp)->conn->vfs.handles.linux_setlease, (fsp), (fd), (leasetype)))
|
||||
#define SMB_VFS_GETLOCK(fsp, fd, poffset, pcount, ptype, ppid) ((fsp)->conn->vfs.ops.getlock((fsp)->conn->vfs.handles.getlock, (fsp), (fd) ,(poffset), (pcount), (ptype), (ppid)))
|
||||
#define SMB_VFS_SYMLINK(conn, oldpath, newpath) ((conn)->vfs.ops.symlink((conn)->vfs.handles.symlink, (oldpath), (newpath)))
|
||||
#define SMB_VFS_READLINK(conn, path, buf, bufsiz) ((conn)->vfs.ops.readlink((conn)->vfs.handles.readlink, (path), (buf), (bufsiz)))
|
||||
@@ -185,6 +186,7 @@
|
||||
#define SMB_VFS_OPAQUE_FTRUNCATE(fsp, fd, offset) ((fsp)->conn->vfs_opaque.ops.ftruncate((fsp)->conn->vfs_opaque.handles.ftruncate, (fsp), (fd), (offset)))
|
||||
#define SMB_VFS_OPAQUE_LOCK(fsp, fd, op, offset, count, type) ((fsp)->conn->vfs_opaque.ops.lock((fsp)->conn->vfs_opaque.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
|
||||
#define SMB_VFS_OPAQUE_FLOCK(fsp, fd, share_mode) ((fsp)->conn->vfs_opaque.ops.lock((fsp)->conn->vfs_opaque.handles.kernel_flock, (fsp), (fd), (share_mode)))
|
||||
#define SMB_VFS_OPAQUE_LINUX_SETLEASE(fsp, fd, leasetype) ((fsp)->conn->vfs_opaque.ops.linux_setlease((fsp)->conn->vfs_opaque.handles.linux_setlease, (fsp), (fd), (leasetype)))
|
||||
#define SMB_VFS_OPAQUE_GETLOCK(fsp, fd, poffset, pcount, ptype, ppid) ((fsp)->conn->vfs_opaque.ops.getlock((fsp)->conn->vfs_opaque.handles.getlock, (fsp), (fd), (poffset), (pcount), (ptype), (ppid)))
|
||||
#define SMB_VFS_OPAQUE_SYMLINK(conn, oldpath, newpath) ((conn)->vfs_opaque.ops.symlink((conn)->vfs_opaque.handles.symlink, (oldpath), (newpath)))
|
||||
#define SMB_VFS_OPAQUE_READLINK(conn, path, buf, bufsiz) ((conn)->vfs_opaque.ops.readlink((conn)->vfs_opaque.handles.readlink, (path), (buf), (bufsiz)))
|
||||
@@ -300,6 +302,7 @@
|
||||
#define SMB_VFS_NEXT_FTRUNCATE(handle, fsp, fd, offset) ((handle)->vfs_next.ops.ftruncate((handle)->vfs_next.handles.ftruncate, (fsp), (fd), (offset)))
|
||||
#define SMB_VFS_NEXT_LOCK(handle, fsp, fd, op, offset, count, type) ((handle)->vfs_next.ops.lock((handle)->vfs_next.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
|
||||
#define SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, fd, share_mode)((handle)->vfs_next.ops.kernel_flock((handle)->vfs_next.handles.kernel_flock, (fsp), (fd), (share_mode)))
|
||||
#define SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, fd, leasetype)((handle)->vfs_next.ops.linux_setlease((handle)->vfs_next.handles.linux_setlease, (fsp), (fd), (leasetype)))
|
||||
#define SMB_VFS_NEXT_GETLOCK(handle, fsp, fd, poffset, pcount, ptype, ppid) ((handle)->vfs_next.ops.getlock((handle)->vfs_next.handles.getlock, (fsp), (fd), (poffset), (pcount), (ptype), (ppid)))
|
||||
#define SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath) ((handle)->vfs_next.ops.symlink((handle)->vfs_next.handles.symlink, (oldpath), (newpath)))
|
||||
#define SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz) ((handle)->vfs_next.ops.readlink((handle)->vfs_next.handles.readlink, (path), (buf), (bufsiz)))
|
||||
|
||||
@@ -783,6 +783,23 @@ 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;
|
||||
|
||||
START_PROFILE(syscall_linux_setlease);
|
||||
|
||||
/* first set the signal handler */
|
||||
if(linux_set_lease_sighandler(fd) == -1)
|
||||
return -1;
|
||||
|
||||
result = linux_setlease(fd, leasetype);
|
||||
|
||||
END_PROFILE(syscall_linux_setlease);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
|
||||
{
|
||||
int result;
|
||||
@@ -1227,6 +1244,8 @@ static vfs_op_tuple vfs_default_ops[] = {
|
||||
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,
|
||||
|
||||
@@ -160,6 +160,8 @@ static BOOL smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp, in
|
||||
static int smb_full_audit_kernel_flock(struct vfs_handle_struct *handle,
|
||||
struct files_struct *fsp, int fd,
|
||||
uint32 share_mode);
|
||||
static int smb_full_audit_linux_setlease(vfs_handle_struct *handle, files_struct *fsp,
|
||||
int fd, int leasetype);
|
||||
static BOOL smb_full_audit_getlock(vfs_handle_struct *handle, files_struct *fsp, int fd,
|
||||
SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid);
|
||||
static int smb_full_audit_symlink(vfs_handle_struct *handle,
|
||||
@@ -381,6 +383,8 @@ static vfs_op_tuple audit_op_tuples[] = {
|
||||
SMB_VFS_LAYER_LOGGER},
|
||||
{SMB_VFS_OP(smb_full_audit_kernel_flock), SMB_VFS_OP_KERNEL_FLOCK,
|
||||
SMB_VFS_LAYER_LOGGER},
|
||||
{SMB_VFS_OP(smb_full_audit_linux_setlease), SMB_VFS_OP_LINUX_SETLEASE,
|
||||
SMB_VFS_LAYER_LOGGER},
|
||||
{SMB_VFS_OP(smb_full_audit_getlock), SMB_VFS_OP_GETLOCK,
|
||||
SMB_VFS_LAYER_LOGGER},
|
||||
{SMB_VFS_OP(smb_full_audit_symlink), SMB_VFS_OP_SYMLINK,
|
||||
@@ -549,6 +553,7 @@ static struct {
|
||||
{ SMB_VFS_OP_FTRUNCATE, "ftruncate" },
|
||||
{ SMB_VFS_OP_LOCK, "lock" },
|
||||
{ SMB_VFS_OP_KERNEL_FLOCK, "kernel_flock" },
|
||||
{ SMB_VFS_OP_LINUX_SETLEASE, "linux_setlease" },
|
||||
{ SMB_VFS_OP_GETLOCK, "getlock" },
|
||||
{ SMB_VFS_OP_SYMLINK, "symlink" },
|
||||
{ SMB_VFS_OP_READLINK, "readlink" },
|
||||
@@ -1313,6 +1318,19 @@ static int smb_full_audit_kernel_flock(struct vfs_handle_struct *handle,
|
||||
return result;
|
||||
}
|
||||
|
||||
static int smb_full_audit_linux_setlease(vfs_handle_struct *handle, files_struct *fsp,
|
||||
int fd, int leasetype)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, fd, leasetype);
|
||||
|
||||
do_log(SMB_VFS_OP_LINUX_SETLEASE, (result >= 0), handle, "%s",
|
||||
fsp->fsp_name);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static BOOL smb_full_audit_getlock(vfs_handle_struct *handle, files_struct *fsp, int fd,
|
||||
SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
|
||||
{
|
||||
|
||||
@@ -52,6 +52,31 @@ static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vfs_gpfs_setlease(vfs_handle_struct *handle, files_struct *fsp,
|
||||
int fd, int leasetype)
|
||||
{
|
||||
int ret;
|
||||
|
||||
START_PROFILE(syscall_linux_setlease);
|
||||
|
||||
if ( linux_set_lease_sighandler(fd) == -1)
|
||||
return -1;
|
||||
|
||||
ret = set_gpfs_lease(fd,leasetype);
|
||||
|
||||
if ( ret < 0 ) {
|
||||
/* This must have come from GPFS not being available */
|
||||
/* or some other error, hence call the default */
|
||||
ret = linux_setlease(fd, leasetype);
|
||||
}
|
||||
|
||||
END_PROFILE(syscall_linux_setlease);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void gpfs_dumpacl(int level, struct gpfs_acl *gacl)
|
||||
{
|
||||
int i;
|
||||
@@ -592,6 +617,10 @@ static vfs_op_tuple gpfs_op_tuples[] = {
|
||||
SMB_VFS_OP_KERNEL_FLOCK,
|
||||
SMB_VFS_LAYER_OPAQUE},
|
||||
|
||||
{SMB_VFS_OP(vfs_gpfs_setlease),
|
||||
SMB_VFS_OP_LINUX_SETLEASE,
|
||||
SMB_VFS_LAYER_OPAQUE},
|
||||
|
||||
{SMB_VFS_OP(gpfsacl_fget_nt_acl),
|
||||
SMB_VFS_OP_FGET_NT_ACL,
|
||||
SMB_VFS_LAYER_TRANSPARENT},
|
||||
|
||||
@@ -289,6 +289,7 @@ BOOL profile_setup(BOOL rdonly)
|
||||
"syscall_ftruncate", /* PR_VALUE_SYSCALL_FTRUNCATE */
|
||||
"syscall_fcntl_lock", /* PR_VALUE_SYSCALL_FCNTL_LOCK */
|
||||
"syscall_kernel_flock", /* PR_VALUE_SYSCALL_KERNEL_FLOCK */
|
||||
"syscall_linux_setlease", /* PR_VALUE_SYSCALL_LINUX_SETLEASE */
|
||||
"syscall_fcntl_getlock", /* PR_VALUE_SYSCALL_FCNTL_GETLOCK */
|
||||
"syscall_readlink", /* PR_VALUE_SYSCALL_READLINK */
|
||||
"syscall_symlink", /* PR_VALUE_SYSCALL_SYMLINK */
|
||||
|
||||
@@ -102,20 +102,29 @@ static void set_capability(unsigned capability)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Call SETLEASE. If we get EACCES then we try setting up the right capability and
|
||||
try again
|
||||
****************************************************************************/
|
||||
|
||||
static int linux_setlease(int fd, int leasetype)
|
||||
/*
|
||||
Call to set the kernel lease signal handler
|
||||
*/
|
||||
int linux_set_lease_sighandler(int fd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (fcntl(fd, F_SETSIG, RT_SIGNAL_LEASE) == -1) {
|
||||
DEBUG(3,("Failed to set signal handler for kernel lease\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Call SETLEASE. If we get EACCES then we try setting up the right capability and
|
||||
try again.
|
||||
Use the SMB_VFS_LINUX_SETLEASE instead of this call directly.
|
||||
****************************************************************************/
|
||||
|
||||
int linux_setlease(int fd, int leasetype)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = fcntl(fd, F_SETLEASE, leasetype);
|
||||
if (ret == -1 && errno == EACCES) {
|
||||
set_capability(CAP_LEASE);
|
||||
@@ -156,7 +165,7 @@ static files_struct *linux_oplock_receive_message(fd_set *fds)
|
||||
|
||||
static BOOL linux_set_kernel_oplock(files_struct *fsp, int oplock_type)
|
||||
{
|
||||
if (linux_setlease(fsp->fh->fd, F_WRLCK) == -1) {
|
||||
if ( SMB_VFS_LINUX_SETLEASE(fsp,fsp->fh->fd, F_WRLCK) == -1) {
|
||||
DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, "
|
||||
"fd = %d, dev = %x, inode = %.0f. (%s)\n",
|
||||
fsp->fsp_name, fsp->fh->fd,
|
||||
@@ -194,7 +203,7 @@ static void linux_release_kernel_oplock(files_struct *fsp)
|
||||
/*
|
||||
* Remove the kernel oplock on this file.
|
||||
*/
|
||||
if (linux_setlease(fsp->fh->fd, F_UNLCK) == -1) {
|
||||
if ( SMB_VFS_LINUX_SETLEASE(fsp,fsp->fh->fd, F_UNLCK) == -1) {
|
||||
if (DEBUGLVL(0)) {
|
||||
dbgtext("linux_release_kernel_oplock: Error when "
|
||||
"removing kernel oplock on file " );
|
||||
|
||||
Reference in New Issue
Block a user