[SCM] Samba Shared Repository - branch v3-6-test updated
Jeremy Allison
jra at samba.org
Fri Dec 17 13:26:07 MST 2010
The branch, v3-6-test has been updated
via 17baec6 Move checks inside file_set_sparse() to allow it to be called from anywhere.
via 485b8b4 file_set_sparse needs to be a handle based call.
via 659e627 s3:smbd: implement FSCTL_SET_SPARSE more correctly
via f00383b Update our attribute flags.
via 27f543a s3:smbd: add file_set_sparse() function
via 43df00a s3/vfs_gpfs: map SPARSE attribute to/from WINATTRs, too
via 669ee9b s3: remove set_sparse_flag
via 13988e4 s3: add FILE_ATTRIBUTE_SPARSE to get_stat_dos_flags
from 2e867d9 WHATSNEW: Add information on changed security defaults.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test
- Log -----------------------------------------------------------------
commit 17baec616fb66c9927902b56513e8b8389792120
Author: Jeremy Allison <jra at samba.org>
Date: Thu Dec 16 16:50:31 2010 -0800
Move checks inside file_set_sparse() to allow it to be called from anywhere.
commit 485b8b45df0768d846dcd74dddb37136a9b26535
Author: Jeremy Allison <jra at samba.org>
Date: Thu Dec 16 16:42:33 2010 -0800
file_set_sparse needs to be a handle based call.
commit 659e627424a011bb3cad33e50976036fd55c7010
Author: Björn Jacke <bj at sernet.de>
Date: Thu Nov 18 17:24:00 2010 +0100
s3:smbd: implement FSCTL_SET_SPARSE more correctly
this is a port of a patch from metze for 3.3:
We don't do the "strict allocation" when the sparse bit isn't
set, but that shouldn't matter.
We now allow windows applications to set and unset the sparse
bit.
Note that in order to implement this 100% like described
in [MS-FSA], we'd have to change our data model and support
the sparse flag per stream.
commit f00383bc3bfc190ed690b0f564a9465d8a1947ea
Author: Jeremy Allison <jra at samba.org>
Date: Fri Dec 17 10:22:58 2010 -0800
Update our attribute flags.
commit 27f543a02e6973a3a52200f7d749ca4b7aa6a87e
Author: Björn Jacke <bj at sernet.de>
Date: Tue Dec 14 10:03:07 2010 +0100
s3:smbd: add file_set_sparse() function
this is based on a patch for 3.3 from metze
commit 43df00a112b52e5a1e04e2b286b358b6bc319154
Author: Björn Jacke <bj at sernet.de>
Date: Thu Nov 18 17:22:31 2010 +0100
s3/vfs_gpfs: map SPARSE attribute to/from WINATTRs, too
commit 669ee9b2dd6591ab9bfc137060bdfb9a59dd9742
Author: Björn Jacke <bj at sernet.de>
Date: Thu Nov 18 17:03:01 2010 +0100
s3: remove set_sparse_flag
we need to determine sparseness from the sparse flag we store not from the
allocation size on the POSIX filesystem. This is how Windows works - in the
first place sparseness is a file flag, not the allocation state of the file
Signed-off-by: Stefan Metzmacher <metze at samba.org>
commit 13988e44c3402d03808e096e59c4878cefd56f84
Author: Björn Jacke <bj at sernet.de>
Date: Thu Nov 18 16:04:03 2010 +0100
s3: add FILE_ATTRIBUTE_SPARSE to get_stat_dos_flags
-----------------------------------------------------------------------
Summary of changes:
source3/include/proto.h | 3 ++
source3/include/smb.h | 7 +++-
source3/modules/vfs_gpfs.c | 10 ++++-
source3/smbd/dosmode.c | 85 ++++++++++++++++++++++++++++++++++++--------
source3/smbd/nttrans.c | 30 +++++++++++++---
5 files changed, 112 insertions(+), 23 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 0f02dfb..e26f43e 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -4622,6 +4622,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 files_struct *fsp,
+ 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/include/smb.h b/source3/include/smb.h
index 07a53de..b87caf2 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -1207,7 +1207,12 @@ struct bitmap {
#define FILE_ATTRIBUTE_OFFLINE 0x1000L
#define FILE_ATTRIBUTE_NONINDEXED 0x2000L
#define FILE_ATTRIBUTE_ENCRYPTED 0x4000L
-#define SAMBA_ATTRIBUTES_MASK 0x7F
+#define SAMBA_ATTRIBUTES_MASK (FILE_ATTRIBUTE_READONLY|\
+ FILE_ATTRIBUTE_HIDDEN|\
+ FILE_ATTRIBUTE_SYSTEM|\
+ FILE_ATTRIBUTE_DIRECTORY|\
+ FILE_ATTRIBUTE_ARCHIVE|\
+ FILE_ATTRIBUTE_SPARSE)
/* Flags - combined with attributes. */
#define FILE_FLAG_WRITE_THROUGH 0x80000000L
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index 694bde7..ffe51c3 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -970,7 +970,7 @@ static int gpfs_set_xattr(struct vfs_handle_struct *handle, const char *path,
dosmode = dosattrib.info.info3.attrib;
attrs.winAttrs = 0;
- /*Just map RD_ONLY, ARCHIVE, SYSTEM and HIDDEN. Ignore the others*/
+ /*Just map RD_ONLY, ARCHIVE, SYSTEM HIDDEN and SPARSE. Ignore the others*/
if (dosmode & FILE_ATTRIBUTE_ARCHIVE){
attrs.winAttrs |= GPFS_WINATTR_ARCHIVE;
}
@@ -983,6 +983,9 @@ static int gpfs_set_xattr(struct vfs_handle_struct *handle, const char *path,
if (dosmode & FILE_ATTRIBUTE_READONLY){
attrs.winAttrs |= GPFS_WINATTR_READONLY;
}
+ if (dosmode & FILE_ATTRIBUTE_SPARSE) {
+ attrs.winAttrs |= GPFS_WINATTR_SPARSE_FILE;
+ }
ret = set_gpfs_winattrs(CONST_DISCARD(char *, path),
@@ -1019,7 +1022,7 @@ static ssize_t gpfs_get_xattr(struct vfs_handle_struct *handle, const char *pat
DEBUG(10, ("gpfs_get_xattr:Got attributes: 0x%x\n",attrs.winAttrs));
- /*Just map RD_ONLY, ARCHIVE, SYSTEM and HIDDEN. Ignore the others*/
+ /*Just map RD_ONLY, ARCHIVE, SYSTEM, HIDDEN and SPARSE. Ignore the others*/
if (attrs.winAttrs & GPFS_WINATTR_ARCHIVE){
dosmode |= FILE_ATTRIBUTE_ARCHIVE;
}
@@ -1032,6 +1035,9 @@ static ssize_t gpfs_get_xattr(struct vfs_handle_struct *handle, const char *pat
if (attrs.winAttrs & GPFS_WINATTR_READONLY){
dosmode |= FILE_ATTRIBUTE_READONLY;
}
+ if (attrs.winAttrs & GPFS_WINATTR_SPARSE_FILE) {
+ dosmode |= FILE_ATTRIBUTE_SPARSE;
+ }
snprintf(attrstr, size, "0x%2.2x", dosmode & SAMBA_ATTRIBUTES_MASK);
DEBUG(10, ("gpfs_get_xattr: returning %s\n",attrstr));
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 7faeb44..628f887 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -20,6 +20,7 @@
#include "includes.h"
#include "librpc/gen_ndr/ndr_xattr.h"
+#include "../libcli/security/security.h"
static uint32_t filter_mode_by_protocol(uint32_t mode)
{
@@ -33,16 +34,6 @@ static uint32_t filter_mode_by_protocol(uint32_t mode)
return mode;
}
-static int set_sparse_flag(const SMB_STRUCT_STAT * const sbuf)
-{
-#if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
- if (sbuf->st_ex_size > sbuf->st_ex_blocks * (SMB_OFF_T)STAT_ST_BLOCKSIZE) {
- return FILE_ATTRIBUTE_SPARSE;
- }
-#endif
- return 0;
-}
-
static int set_link_read_only_flag(const SMB_STRUCT_STAT *const sbuf)
{
#ifdef S_ISLNK
@@ -201,7 +192,6 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn,
if (S_ISDIR(smb_fname->st.st_ex_mode))
result = aDIR | (result & aRONLY);
- result |= set_sparse_flag(&smb_fname->st);
result |= set_link_read_only_flag(&smb_fname->st);
DEBUG(8,("dos_mode_from_sbuf returning "));
@@ -555,10 +545,11 @@ static bool get_stat_dos_flags(connection_struct *conn,
*dosmode |= aSYSTEM;
if (smb_fname->st.st_ex_flags & UF_DOS_NOINDEX)
*dosmode |= FILE_ATTRIBUTE_NONINDEXED;
+ if (smb_fname->st.st_ex_flags & FILE_ATTRIBUTE_SPARSE)
+ *dosmode |= FILE_ATTRIBUTE_SPARSE;
if (S_ISDIR(smb_fname->st.st_ex_mode))
*dosmode |= aDIR;
- *dosmode |= set_sparse_flag(&smb_fname->st);
*dosmode |= set_link_read_only_flag(&smb_fname->st);
return true;
@@ -651,9 +642,7 @@ uint32 dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
#endif
if (!used_stat_dos_flags) {
/* Get the DOS attributes from an EA by preference. */
- if (get_ea_dos_attribute(conn, smb_fname, &result)) {
- result |= set_sparse_flag(&smb_fname->st);
- } else {
+ if (!get_ea_dos_attribute(conn, smb_fname, &result)) {
result |= dos_mode_from_sbuf(conn, smb_fname);
}
}
@@ -858,6 +847,72 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
return( ret );
}
+
+NTSTATUS file_set_sparse(connection_struct *conn,
+ files_struct *fsp,
+ bool sparse)
+{
+ uint32_t old_dosmode;
+ uint32_t new_dosmode;
+ NTSTATUS status;
+
+ if (!CAN_WRITE(conn)) {
+ DEBUG(9,("file_set_sparse: fname[%s] set[%u] "
+ "on readonly share[%s]\n",
+ smb_fname_str_dbg(fsp->fsp_name),
+ sparse,
+ lp_servicename(SNUM(conn))));
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
+ }
+
+ if (!(fsp->access_mask & FILE_WRITE_DATA) &&
+ !(fsp->access_mask & FILE_WRITE_ATTRIBUTES)) {
+ DEBUG(9,("file_set_sparse: fname[%s] set[%u] "
+ "access_mask[0x%08X] - access denied\n",
+ smb_fname_str_dbg(fsp->fsp_name),
+ sparse,
+ fsp->access_mask));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ DEBUG(10,("file_set_sparse: setting sparse bit %u on file %s\n",
+ sparse, smb_fname_str_dbg(fsp->fsp_name)));
+
+ if (!lp_store_dos_attributes(SNUM(conn))) {
+ return NT_STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ status = vfs_stat_fsp(fsp);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ old_dosmode = dos_mode(conn, fsp->fsp_name);
+
+ 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, fsp->fsp_name,
+ new_dosmode)) {
+ if (errno == 0) {
+ errno = EIO;
+ }
+ return map_nt_error_from_unix(errno);
+ }
+
+ notify_fname(conn, NOTIFY_ACTION_MODIFIED,
+ FILE_NOTIFY_CHANGE_ATTRIBUTES,
+ fsp->fsp_name->base_name);
+
+ return NT_STATUS_OK;
+}
+
/*******************************************************************
Wrapper around the VFS ntimes that possibly allows DOS semantics rather
than POSIX.
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index ad58533..cccb47a 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -2107,14 +2107,34 @@ static void call_nt_transact_ioctl(connection_struct *conn,
switch (function) {
case FSCTL_SET_SPARSE:
- /* pretend this succeeded - tho strictly we should
- mark the file sparse (if the local fs supports it)
- so we can know if we need to pre-allocate or not */
+ {
+ bool set_sparse = true;
+ NTSTATUS status;
+
+ if (data_count >= 1 && pdata[0] == 0) {
+ set_sparse = false;
+ }
+
+ DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X]set[%u]\n",
+ fidnum, set_sparse));
+
+ if (!check_fsp_open(conn, req, fsp)) {
+ return;
+ }
+
+ status = file_set_sparse(conn, fsp, set_sparse);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(9,("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n",
+ smb_fname_str_dbg(fsp->fsp_name), set_sparse, nt_errstr(status)));
+ reply_nterror(req, status);
+ return;
+ }
- DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
+ DEBUG(10,("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n",
+ smb_fname_str_dbg(fsp->fsp_name), set_sparse, nt_errstr(status)));
send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
return;
-
+ }
case FSCTL_CREATE_OR_GET_OBJECT_ID:
{
unsigned char objid[16];
--
Samba Shared Repository
More information about the samba-cvs
mailing list