summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2010-12-20 17:58:33 -0800
committerJeremy Allison <jra@samba.org>2010-12-21 04:12:22 +0100
commit0a5f4f523fe3dcb90033ee53c838ad6030f608b4 (patch)
treee7bc21a1ab8d57241730a1601f6079948444e2d3
parent4820c97e9ea00e73f3188f9834a03913ed74df80 (diff)
downloadsamba-0a5f4f523fe3dcb90033ee53c838ad6030f608b4.tar.gz
samba-0a5f4f523fe3dcb90033ee53c838ad6030f608b4.tar.bz2
samba-0a5f4f523fe3dcb90033ee53c838ad6030f608b4.zip
Keep track of the sparse status of an open file handle. Allows bypass of
strict allocation on sparse files. Files opened as POSIX opens are always sparse. Autobuild-User: Jeremy Allison <jra@samba.org> Autobuild-Date: Tue Dec 21 04:12:22 CET 2010 on sn-devel-104
-rw-r--r--source3/include/smb.h1
-rw-r--r--source3/modules/vfs_default.c2
-rw-r--r--source3/smbd/dosmode.c2
-rw-r--r--source3/smbd/fileio.c3
-rw-r--r--source3/smbd/open.c9
5 files changed, 15 insertions, 2 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 2b397cc307..8d12fb967d 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -344,6 +344,7 @@ typedef struct files_struct {
bool initial_delete_on_close; /* Only set at NTCreateX if file was created. */
bool delete_on_close;
bool posix_open;
+ bool is_sparse;
struct smb_filename *fsp_name;
struct vfs_fsp_data *vfs_extension;
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 54f38c3714..9cca349413 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -895,7 +895,7 @@ static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_O
START_PROFILE(syscall_ftruncate);
- if (lp_strict_allocate(SNUM(fsp->conn))) {
+ if (lp_strict_allocate(SNUM(fsp->conn)) && !fsp->is_sparse) {
result = strict_allocate_ftruncate(handle, fsp, len);
END_PROFILE(syscall_ftruncate);
return result;
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 2c6dcd00c6..cf95348583 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -911,6 +911,8 @@ NTSTATUS file_set_sparse(connection_struct *conn,
FILE_NOTIFY_CHANGE_ATTRIBUTES,
fsp->fsp_name->base_name);
+ fsp->is_sparse = sparse;
+
return NT_STATUS_OK;
}
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index aec6554436..da40013bc5 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -128,7 +128,8 @@ static ssize_t real_write_file(struct smb_request *req,
ret = vfs_write_data(req, fsp, data, n);
} else {
fsp->fh->pos = pos;
- if (pos && lp_strict_allocate(SNUM(fsp->conn))) {
+ if (pos && lp_strict_allocate(SNUM(fsp->conn) &&
+ !fsp->is_sparse)) {
if (vfs_fill_sparse(fsp, pos) == -1) {
return -1;
}
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 80756d6641..32a08b5967 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -2221,6 +2221,15 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
}
}
+ /* Determine sparse flag. */
+ if (posix_open) {
+ /* POSIX opens are sparse by default. */
+ fsp->is_sparse = true;
+ } else {
+ fsp->is_sparse = (file_existed &&
+ (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE));
+ }
+
/*
* Take care of inherited ACLs on created files - if default ACL not
* selected.