summaryrefslogtreecommitdiffstats
path: root/source3
diff options
context:
space:
mode:
authorDavid Disseldorp <ddiss@samba.org>2013-11-18 14:54:32 +0100
committerJeremy Allison <jra@samba.org>2013-11-22 08:56:45 -0800
commit3627ed732637a3b1bf992156306d6ffc14727b46 (patch)
tree3855ef51d7b6d3a7002b05be689c6523d629908e /source3
parent4ffc85dfc561b077eb1e7afe3b3e7445ea741d2a (diff)
downloadsamba-3627ed732637a3b1bf992156306d6ffc14727b46.tar.gz
samba-3627ed732637a3b1bf992156306d6ffc14727b46.tar.xz
samba-3627ed732637a3b1bf992156306d6ffc14727b46.zip
vfs_btrfs: add [GET/SET]_COMPRESSION handlers
Translate such requests into FS_IOC_GETFLAGS and FS_IOC_SETFLAGS ioctls respectively. The module makes no distinction between compression types, only whether or not compression is enabled. Signed-off-by: David Disseldorp <ddiss@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3')
-rw-r--r--source3/modules/vfs_btrfs.c119
-rw-r--r--source3/wscript2
2 files changed, 118 insertions, 3 deletions
diff --git a/source3/modules/vfs_btrfs.c b/source3/modules/vfs_btrfs.c
index f854f2ac78f..36d6120cdcc 100644
--- a/source3/modules/vfs_btrfs.c
+++ b/source3/modules/vfs_btrfs.c
@@ -18,11 +18,16 @@
*/
#include <linux/ioctl.h>
+#include <linux/fs.h>
#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
#include "includes.h"
-#include "system/filesys.h"
#include "smbd/smbd.h"
-#include "../librpc/gen_ndr/smbXsrv.h"
+#include "librpc/gen_ndr/smbXsrv.h"
+#include "librpc/gen_ndr/ioctl.h"
#include "lib/util/tevent_ntstatus.h"
struct btrfs_ioctl_clone_range_args {
@@ -187,9 +192,119 @@ static NTSTATUS btrfs_copy_chunk_recv(struct vfs_handle_struct *handle,
return NT_STATUS_OK;
}
+/*
+ * caller must pass a non-null fsp or smb_fname. If fsp is null, then
+ * fall back to opening the corresponding file to issue the ioctl.
+ */
+static NTSTATUS btrfs_get_compression(struct vfs_handle_struct *handle,
+ TALLOC_CTX *mem_ctx,
+ struct files_struct *fsp,
+ struct smb_filename *smb_fname,
+ uint16_t *_compression_fmt)
+{
+ int ret;
+ long flags = 0;
+ int fd;
+ bool opened = false;
+ NTSTATUS status;
+
+ if ((fsp != NULL) && (fsp->fh->fd != -1)) {
+ fd = fsp->fh->fd;
+ } else if (smb_fname != NULL) {
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
+ DIR *dir = opendir(smb_fname->base_name);
+ if (dir == NULL) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ fd = dirfd(dir);
+ } else {
+ fd = open(smb_fname->base_name, O_RDONLY);
+ }
+ if (fd < 0) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ opened = true;
+ } else {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ ret = ioctl(fd, FS_IOC_GETFLAGS, &flags);
+ if (ret < 0) {
+ DEBUG(1, ("FS_IOC_GETFLAGS failed: %s, fd %lld\n",
+ strerror(errno), (long long)fd));
+ status = map_nt_error_from_unix(errno);
+ goto err_close;
+ }
+ if (flags & FS_COMPR_FL) {
+ *_compression_fmt = COMPRESSION_FORMAT_LZNT1;
+ } else {
+ *_compression_fmt = COMPRESSION_FORMAT_NONE;
+ }
+ status = NT_STATUS_OK;
+err_close:
+ if (opened) {
+ close(fd);
+ }
+
+ return status;
+}
+
+static NTSTATUS btrfs_set_compression(struct vfs_handle_struct *handle,
+ TALLOC_CTX *mem_ctx,
+ struct files_struct *fsp,
+ uint16_t compression_fmt)
+{
+ int ret;
+ long flags = 0;
+ int fd;
+ NTSTATUS status;
+
+ if ((fsp == NULL) || (fsp->fh->fd == -1)) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto err_out;
+ }
+ fd = fsp->fh->fd;
+
+ ret = ioctl(fd, FS_IOC_GETFLAGS, &flags);
+ if (ret < 0) {
+ DEBUG(1, ("FS_IOC_GETFLAGS failed: %s, fd %d\n",
+ strerror(errno), fd));
+ status = map_nt_error_from_unix(errno);
+ goto err_out;
+ }
+
+ if (compression_fmt == COMPRESSION_FORMAT_NONE) {
+ DEBUG(5, ("setting compression\n"));
+ flags &= (~FS_COMPR_FL);
+ } else if ((compression_fmt == COMPRESSION_FORMAT_DEFAULT)
+ || (compression_fmt == COMPRESSION_FORMAT_LZNT1)) {
+ DEBUG(5, ("clearing compression\n"));
+ flags |= FS_COMPR_FL;
+ } else {
+ DEBUG(1, ("invalid compression format 0x%x\n",
+ (int)compression_fmt));
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto err_out;
+ }
+
+ ret = ioctl(fd, FS_IOC_SETFLAGS, &flags);
+ if (ret < 0) {
+ DEBUG(1, ("FS_IOC_SETFLAGS failed: %s, fd %d\n",
+ strerror(errno), fd));
+ status = map_nt_error_from_unix(errno);
+ goto err_out;
+ }
+ status = NT_STATUS_OK;
+err_out:
+ return status;
+}
+
+
static struct vfs_fn_pointers btrfs_fns = {
.copy_chunk_send_fn = btrfs_copy_chunk_send,
.copy_chunk_recv_fn = btrfs_copy_chunk_recv,
+ .get_compression_fn = btrfs_get_compression,
+ .set_compression_fn = btrfs_set_compression,
};
NTSTATUS vfs_btrfs_init(void);
diff --git a/source3/wscript b/source3/wscript
index 271314d723b..2edf5e8ea71 100644
--- a/source3/wscript
+++ b/source3/wscript
@@ -1727,7 +1727,7 @@ main() {
if conf.CHECK_HEADERS('gpfs_gpl.h'):
conf.DEFINE('HAVE_GPFS', '1')
- if conf.CHECK_HEADERS('linux/ioctl.h sys/ioctl.h'):
+ if conf.CHECK_HEADERS('linux/ioctl.h sys/ioctl.h linux/fs.h'):
conf.DEFINE('HAVE_LINUX_IOCTL', '1')
conf.env['CCFLAGS_CEPHFS'] = "-D_FILE_OFFSET_BITS=64"