From d2c3fd1cf1f668920facfb18cc89d3093260d4e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= Date: Tue, 14 Dec 2010 10:03:07 +0100 Subject: [PATCH 4/8] s3:smbd: add file_set_sparse() function this is based on a patch for 3.3 from metze --- source3/include/proto.h | 3 ++ source3/smbd/dosmode.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 0 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 9b41321..53c1f5d 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4620,6 +4620,9 @@ int dos_attributes_to_stat_dos_flags(uint32_t dosmode); uint32 dos_mode(connection_struct *conn, struct smb_filename *smb_fname); int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname, uint32 dosmode, const char *parent_dir, bool newfile); +NTSTATUS file_set_sparse(connection_struct *conn, + struct smb_filename *smb_fname, + bool sparse); int file_ntimes(connection_struct *conn, const struct smb_filename *smb_fname, struct smb_file_time *ft); bool set_sticky_write_time_path(struct file_id fileid, struct timespec mtime); diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 2fafb15..5d6e4b4 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -846,6 +846,55 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname, return( ret ); } + +NTSTATUS file_set_sparse(connection_struct *conn, + struct smb_filename *smb_fname, + bool sparse) +{ + SMB_STRUCT_STAT st; + uint32_t old_dosmode; + uint32_t new_dosmode; + + DEBUG(10,("file_set_sparse: setting sparse bit %u on file %s\n", + sparse, smb_fname_str_dbg(smb_fname))); + + if (!lp_store_dos_attributes(SNUM(conn))) { + return NT_STATUS_INVALID_DEVICE_REQUEST; + } + + SET_STAT_INVALID(st); + + if (SMB_VFS_STAT(conn, smb_fname)) { + return map_nt_error_from_unix(errno); + } + + old_dosmode = dos_mode(conn, smb_fname); + + if (sparse && !(old_dosmode & FILE_ATTRIBUTE_SPARSE)) { + new_dosmode = old_dosmode | FILE_ATTRIBUTE_SPARSE; + } else if (!sparse && (old_dosmode & FILE_ATTRIBUTE_SPARSE)) { + new_dosmode = old_dosmode & ~FILE_ATTRIBUTE_SPARSE; + } else { + return NT_STATUS_OK; + } + + /* Store the DOS attributes in an EA. */ + if (!set_ea_dos_attribute(conn, smb_fname, + new_dosmode)) { + if (errno == 0) { + errno = EIO; + } + return map_nt_error_from_unix(errno); + } + + notify_fname(conn, NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_ATTRIBUTES, + smb_fname->base_name); + + return NT_STATUS_OK; +} + + /******************************************************************* Wrapper around the VFS ntimes that possibly allows DOS semantics rather than POSIX. -- 1.7.3.1