[PATCH v3 07/13] vfs_btrfs: add [GET/SET]_COMPRESSION handlers
David Disseldorp
ddiss at samba.org
Tue Nov 5 04:57:57 MST 2013
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 at samba.org>
---
source3/modules/vfs_btrfs.c | 121 ++++++++++++++++++++++++++++++++++++++++++--
source3/wscript | 2 +-
2 files changed, 119 insertions(+), 4 deletions(-)
diff --git a/source3/modules/vfs_btrfs.c b/source3/modules/vfs_btrfs.c
index f854f2a..d65b46a 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 {
@@ -107,7 +112,7 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *handle
cr_args.src_length = (uint64_t)num;
ret = ioctl(dest_fsp->fh->fd, BTRFS_IOC_CLONE_RANGE, &cr_args);
- SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &dest_lck);
+ SMB_VFS_STRICT_UNLOCK(src_fsp->conn, dest_fsp, &dest_lck);
SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &src_lck);
if (ret < 0) {
/*
@@ -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 271314d..2edf5e8 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"
--
1.8.1.4
More information about the samba-technical
mailing list