From: Jeremy Allison Date: Tue, 21 Dec 2010 01:58:33 +0000 (-0800) Subject: Keep track of the sparse status of an open file handle. Allows bypass of X-Git-Tag: samba-4.0.0alpha14~78 X-Git-Url: http://git.samba.org/samba.git/?a=commitdiff_plain;h=0a5f4f523fe3dcb90033ee53c838ad6030f608b4;p=ira%2Fwip.git 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 Autobuild-Date: Tue Dec 21 04:12:22 CET 2010 on sn-devel-104 --- diff --git a/source3/include/smb.h b/source3/include/smb.h index 2b397cc307d..8d12fb967d2 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 54f38c3714b..9cca3494137 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 2c6dcd00c6c..cf95348583e 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 aec6554436c..da40013bc5b 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 80756d6641f..32a08b5967c 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.