The Samba-Bugzilla – Attachment 5065 Details for
Bug 6942
Avoid fragmentation
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch relative to 3-5-test
0001-Use-fallocate-to-handle-strict-allocate-partial-in.patch (text/plain), 20.28 KB, created by
Olaf Flebbe
on 2009-12-08 07:04:14 UTC
(
hide
)
Description:
Patch relative to 3-5-test
Filename:
MIME Type:
Creator:
Olaf Flebbe
Created:
2009-12-08 07:04:14 UTC
Size:
20.28 KB
patch
obsolete
>From 83df10a56f455dcf4efc5a2e38d504bd252063e3 Mon Sep 17 00:00:00 2001 >From: Olaf Flebbe <o.flebbe@science-computing.de> >Date: Tue, 1 Dec 2009 15:44:38 +0100 >Subject: [PATCH] Use fallocate to handle strict allocate = partial in > order not to fragment files for CIFS write ahead mode > >--- > source3/include/local.h | 4 ++ > source3/include/proto.h | 4 +- > source3/include/smb.h | 6 ++ > source3/include/vfs.h | 6 ++- > source3/include/vfs_macros.h | 5 ++ > source3/lib/system.c | 8 ++- > source3/modules/vfs_default.c | 103 +++++++++++++++++++++++++++++++++++++- > source3/modules/vfs_full_audit.c | 16 ++++++ > source3/param/loadparm.c | 27 ++++++++-- > source3/smbd/aio.c | 48 +++++++++++++++++- > source3/smbd/fileio.c | 5 +- > source3/smbd/globals.c | 1 - > source3/smbd/globals.h | 1 - > source3/smbd/vfs.c | 54 +++++++------------ > 14 files changed, 236 insertions(+), 52 deletions(-) > >diff --git a/source3/include/local.h b/source3/include/local.h >index de54ea5..03c4c74 100644 >--- a/source3/include/local.h >+++ b/source3/include/local.h >@@ -271,6 +271,10 @@ > /* Windows minimum lock resolution timeout in ms */ > #define WINDOWS_MINIMUM_LOCK_TIMEOUT_MS 200 > >+/* When strict allocate = partial, define the limit on how far >+ * ahead we will write. */ >+#define STRICT_ALLOCATE_PARTIAL_LIMIT 0x200000 >+ > /* Maximum size of RPC data we will accept for one call. */ > #define MAX_RPC_DATA_SIZE (15*1024*1024) > >diff --git a/source3/include/proto.h b/source3/include/proto.h >index 7b575ca..2617e46 100644 >--- a/source3/include/proto.h >+++ b/source3/include/proto.h >@@ -4189,7 +4189,7 @@ bool lp_manglednames(const struct share_params *p ); > bool lp_widelinks(int ); > bool lp_symlinks(int ); > bool lp_syncalways(int ); >-bool lp_strict_allocate(int ); >+int lp_strict_allocate(int ); > bool lp_strict_sync(int ); > bool lp_map_system(int ); > bool lp_delete_readonly(int ); >@@ -7118,7 +7118,7 @@ ssize_t vfs_pwrite_data(struct smb_request *req, > SMB_OFF_T offset); > int vfs_allocate_file_space(files_struct *fsp, uint64_t len); > int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len); >-int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len); >+int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len, enum smb_strict_allocate_options sa_options); > SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n); > const char *vfs_readdirname(connection_struct *conn, void *p, > SMB_STRUCT_STAT *sbuf, char **talloced); >diff --git a/source3/include/smb.h b/source3/include/smb.h >index 4affd4a..3479397 100644 >--- a/source3/include/smb.h >+++ b/source3/include/smb.h >@@ -1938,6 +1938,12 @@ struct smb_extended_info { > char samba_version_string[SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH]; > }; > >+enum smb_strict_allocate_options { >+ STRICT_ALLOCATE_OFF=0, >+ STRICT_ALLOCATE_ON=1, >+ STRICT_ALLOCATE_PARTIAL=2 >+}; >+ > /* time info */ > struct smb_file_time { > struct timespec mtime; >diff --git a/source3/include/vfs.h b/source3/include/vfs.h >index aee84a7..0541754 100644 >--- a/source3/include/vfs.h >+++ b/source3/include/vfs.h >@@ -125,7 +125,8 @@ > * return to fs_capabilities call. JRA. */ > /* Leave at 27 - not yet released. Add translate_name VFS call to convert > UNIX names to Windows supported names -- asrinivasan. */ >-#define SMB_VFS_INTERFACE_VERSION 27 >+/* Changed to 28 - add fallocate: oflebbe */ >+#define SMB_VFS_INTERFACE_VERSION 28 > > > /* to bug old modules which are trying to compile with the old functions */ >@@ -246,6 +247,7 @@ struct vfs_fn_pointers { > const struct smb_filename *smb_fname, > struct smb_file_time *ft); > int (*ftruncate)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_OFF_T offset); >+ int (*fallocate)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_OFF_T offset, SMB_OFF_T len); > bool (*lock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type); > int (*kernel_flock)(struct vfs_handle_struct *handle, struct files_struct *fsp, > uint32 share_mode, uint32_t access_mask); >@@ -597,6 +599,8 @@ int smb_vfs_call_ntimes(struct vfs_handle_struct *handle, > struct smb_file_time *ft); > int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle, > struct files_struct *fsp, SMB_OFF_T offset); >+int smb_vfs_call_fallocate(struct vfs_handle_struct *handle, >+ struct files_struct *fsp, SMB_OFF_T offset, SMB_OFF_T len); > bool smb_vfs_call_lock(struct vfs_handle_struct *handle, > struct files_struct *fsp, int op, SMB_OFF_T offset, > SMB_OFF_T count, int type); >diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h >index c6f83bd..53fe505 100644 >--- a/source3/include/vfs_macros.h >+++ b/source3/include/vfs_macros.h >@@ -245,6 +245,11 @@ > #define SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset) \ > smb_vfs_call_ftruncate((handle)->next, (fsp), (offset)) > >+#define SMB_VFS_FALLOCATE(fsp, offset, len) \ >+ smb_vfs_call_fallocate((fsp)->conn->vfs_handles, (fsp), (offset), (len)) >+#define SMB_VFS_NEXT_FALLOCATE(handle, fsp, offset, len) \ >+ smb_vfs_call_fallocate((handle)->next, (fsp), (offset), (len)) >+ > #define SMB_VFS_LOCK(fsp, op, offset, count, type) \ > smb_vfs_call_lock((fsp)->conn->vfs_handles, (fsp), (op), (offset), (count), (type)) > #define SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type) \ >diff --git a/source3/lib/system.c b/source3/lib/system.c >index a2dd899..dbacb73 100644 >--- a/source3/lib/system.c >+++ b/source3/lib/system.c >@@ -621,16 +621,20 @@ int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf, > /******************************************************************* > An posix_fallocate() wrapper that will deal with 64 bit filesizes. > ********************************************************************/ >-#if (defined(HAVE_POSIX_FALLOCATE64) || defined(HAVE_POSIX_FALLOCATE)) && !defined(HAVE_BROKEN_POSIX_FALLOCATE) > int sys_posix_fallocate(int fd, SMB_OFF_T offset, SMB_OFF_T len) > { >+#if (defined(HAVE_POSIX_FALLOCATE64) || defined(HAVE_POSIX_FALLOCATE)) && !defined(HAVE_BROKEN_POSIX_FALLOCATE) > #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_POSIX_FALLOCATE64) > return posix_fallocate64(fd, offset, len); > #else > return posix_fallocate(fd, offset, len); > #endif >-} >+#else >+ /* No posix_fallocate System Call */ >+ errno = ENOSYS; >+ return -1; > #endif >+} > > /******************************************************************* > An ftruncate() wrapper that will deal with 64 bit filesizes. >diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c >index 3691fb0..2826652 100644 >--- a/source3/modules/vfs_default.c >+++ b/source3/modules/vfs_default.c >@@ -997,10 +997,14 @@ static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_O > SMB_STRUCT_STAT st; > char c = 0; > SMB_OFF_T currpos; >+ enum smb_strict_allocate_options sa_options = lp_strict_allocate(SNUM(fsp->conn)); > > START_PROFILE(syscall_ftruncate); > >- if (lp_strict_allocate(SNUM(fsp->conn))) { >+ /* Only use allocation truncate if strict allocate >+ * is set "on", not off or partial. >+ */ >+ if (sa_options == STRICT_ALLOCATE_ON) { > result = strict_allocate_ftruncate(handle, fsp, len); > END_PROFILE(syscall_ftruncate); > return result; >@@ -1028,7 +1032,7 @@ static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_O > size in which case the ftruncate above should have > succeeded or shorter, in which case seek to len - 1 and > write 1 byte of zero */ >- if (SMB_VFS_FSTAT(fsp, &st) == -1) { >+ if (SMB_VFS_FSTAT(fsp, &st) == -1) { > goto done; > } > >@@ -1066,6 +1070,100 @@ static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_O > return result; > } > >+#define SPARSE_BUF_WRITE_SIZE (32*1024) >+static char *sparse_buf = NULL; >+ >+static int vfswrap_fallocate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T offset, SMB_OFF_T len) >+{ >+ int result = -1; >+ SMB_STRUCT_STAT st; >+ char c = 0; >+ SMB_OFF_T currpos; >+ SMB_OFF_T total, pwrite_ret; >+ >+ START_PROFILE(syscall_fallocate); >+ >+ result = sys_posix_fallocate(fsp->fh->fd, offset, len); >+ if (result == 0) >+ goto done; >+ >+ /* double check for invalid parameters */ >+ if (len <= 0 || offset < 0) { >+ result = 0; >+ goto done; >+ } >+ >+ if (SMB_VFS_FSTAT(fsp, &st) == -1) { >+ goto done; >+ } >+ >+#ifdef S_ISFIFO >+ if (S_ISFIFO(st.st_ex_mode)) { >+ result = 0; >+ goto done; >+ } >+#endif >+ >+ /* be cautious! if file already larger: NOP */ >+ if (st.st_ex_size >= offset + len) { >+ result = 0; >+ goto done; >+ } >+ >+ if (!sparse_buf) { >+ sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE); >+ if (!sparse_buf) { >+ errno = ENOMEM; >+ result = -1; >+ goto done; >+ } >+ } >+ >+ /* check if offset is within the current file */ >+ if(st.st_ex_size > offset) { >+ /* already checked, len could not be negative */ >+ len -= (st.st_ex_size - offset) - 1; >+ /* position one byte behind eof */ >+ offset = st.st_ex_size + 1; >+ } >+ >+ currpos = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR); >+ if (currpos == -1) { >+ goto done; >+ } >+ >+ total = 0; >+ >+ while (total < len) { >+ size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total)); >+ >+ pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total); >+ if (pwrite_ret == -1) { >+ DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file " >+ "%s failed with error %s\n", >+ fsp_str_dbg(fsp), strerror(errno))); >+ result = -1; >+ goto done; >+ } >+ if (pwrite_ret == 0) { >+ result = 0; >+ goto done; >+ } >+ >+ total += pwrite_ret; >+ } >+ >+ /* Seek to where we were */ >+ if (SMB_VFS_LSEEK(fsp, currpos, SEEK_SET) != currpos) >+ goto done; >+ result = 0; >+ >+ done: >+ >+ END_PROFILE(syscall_ftruncate); >+ return result; >+} >+ > static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type) > { > bool result; >@@ -1736,6 +1834,7 @@ static struct vfs_fn_pointers vfs_default_fns = { > .getwd = vfswrap_getwd, > .ntimes = vfswrap_ntimes, > .ftruncate = vfswrap_ftruncate, >+ .fallocate = vfswrap_fallocate, > .lock = vfswrap_lock, > .kernel_flock = vfswrap_kernel_flock, > .linux_setlease = vfswrap_linux_setlease, >diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c >index 19ac7ad..10f9713 100644 >--- a/source3/modules/vfs_full_audit.c >+++ b/source3/modules/vfs_full_audit.c >@@ -123,6 +123,7 @@ typedef enum _vfs_op_type { > SMB_VFS_OP_GETWD, > SMB_VFS_OP_NTIMES, > SMB_VFS_OP_FTRUNCATE, >+ SMB_VFS_OP_FALLOCATE, > SMB_VFS_OP_LOCK, > SMB_VFS_OP_KERNEL_FLOCK, > SMB_VFS_OP_LINUX_SETLEASE, >@@ -261,6 +262,7 @@ static struct { > { SMB_VFS_OP_GETWD, "getwd" }, > { SMB_VFS_OP_NTIMES, "ntimes" }, > { SMB_VFS_OP_FTRUNCATE, "ftruncate" }, >+ { SMB_VFS_OP_FALLOCATE, "fallocate" }, > { SMB_VFS_OP_LOCK, "lock" }, > { SMB_VFS_OP_KERNEL_FLOCK, "kernel_flock" }, > { SMB_VFS_OP_LINUX_SETLEASE, "linux_setlease" }, >@@ -1231,6 +1233,19 @@ static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp > return result; > } > >+static int smb_full_audit_fallocate(vfs_handle_struct *handle, files_struct *fsp, >+ SMB_OFF_T offset, SMB_OFF_T len) >+{ >+ int result; >+ >+ result = SMB_VFS_NEXT_FALLOCATE(handle, fsp, offset, len); >+ >+ do_log(SMB_VFS_OP_FTRUNCATE, (result >= 0), handle, >+ "%s", fsp_str_do_log(fsp)); >+ >+ return result; >+} >+ > static bool smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp, > int op, SMB_OFF_T offset, SMB_OFF_T count, int type) > { >@@ -2227,6 +2242,7 @@ static struct vfs_fn_pointers vfs_full_audit_fns = { > .getwd = smb_full_audit_getwd, > .ntimes = smb_full_audit_ntimes, > .ftruncate = smb_full_audit_ftruncate, >+ .fallocate = smb_full_audit_fallocate, > .lock = smb_full_audit_lock, > .kernel_flock = smb_full_audit_kernel_flock, > .linux_setlease = smb_full_audit_linux_setlease, >diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c >index 0499d65..33b0afb 100644 >--- a/source3/param/loadparm.c >+++ b/source3/param/loadparm.c >@@ -464,7 +464,7 @@ struct service { > bool bWidelinks; > bool bSymlinks; > bool bSyncAlways; >- bool bStrictAllocate; >+ int iStrictAllocate; > bool bStrictSync; > char magic_char; > struct bitmap *copymap; >@@ -608,7 +608,7 @@ static struct service sDefault = { > True, /* bWidelinks */ > True, /* bSymlinks */ > False, /* bSyncAlways */ >- False, /* bStrictAllocate */ >+ STRICT_ALLOCATE_OFF, /* iStrictAllocate */ > False, /* bStrictSync */ > '~', /* magic char */ > NULL, /* copymap */ >@@ -892,6 +892,21 @@ static const struct enum_list enum_kerberos_method[] = { > {-1, NULL} > }; > >+static const struct enum_list enum_strict_allocate[] = { >+ {STRICT_ALLOCATE_OFF, "No"}, >+ {STRICT_ALLOCATE_OFF, "False"}, >+ {STRICT_ALLOCATE_OFF, "0"}, >+ {STRICT_ALLOCATE_OFF, "Off"}, >+ {STRICT_ALLOCATE_OFF, "disabled"}, >+ {STRICT_ALLOCATE_ON, "Yes"}, >+ {STRICT_ALLOCATE_ON, "True"}, >+ {STRICT_ALLOCATE_ON, "1"}, >+ {STRICT_ALLOCATE_ON, "On"}, >+ {STRICT_ALLOCATE_ON, "enabled"}, >+ {STRICT_ALLOCATE_PARTIAL, "partial"}, >+ {-1, NULL} >+}; >+ > /* Note: We do not initialise the defaults union - it is not allowed in ANSI C > * > * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit >@@ -2444,11 +2459,11 @@ static struct parm_struct parm_table[] = { > }, > { > .label = "strict allocate", >- .type = P_BOOL, >+ .type = P_ENUM, > .p_class = P_LOCAL, >- .ptr = &sDefault.bStrictAllocate, >+ .ptr = &sDefault.iStrictAllocate, > .special = NULL, >- .enum_list = NULL, >+ .enum_list = enum_strict_allocate, > .flags = FLAG_ADVANCED | FLAG_SHARE, > }, > { >@@ -5637,7 +5652,7 @@ FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames) > FN_LOCAL_BOOL(lp_widelinks, bWidelinks) > FN_LOCAL_BOOL(lp_symlinks, bSymlinks) > FN_LOCAL_BOOL(lp_syncalways, bSyncAlways) >-FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate) >+FN_LOCAL_INTEGER(lp_strict_allocate, iStrictAllocate) > FN_LOCAL_BOOL(lp_strict_sync, bStrictSync) > FN_LOCAL_BOOL(lp_map_system, bMap_system) > FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly) >diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c >index 751fed1..b2a73b6 100644 >--- a/source3/smbd/aio.c >+++ b/source3/smbd/aio.c >@@ -1,3 +1,4 @@ >+ > /* > Unix SMB/Netbios implementation. > Version 3.0 >@@ -207,8 +208,10 @@ bool schedule_aio_write_and_X(connection_struct *conn, > { > struct aio_extra *aio_ex; > SMB_STRUCT_AIOCB *a; >+ SMB_STRUCT_STAT st; > size_t bufsize; > bool write_through = BITSETW(req->vwv+7,0); >+ bool other_aio_found; > size_t min_aio_write_size = lp_aio_write_size(SNUM(conn)); > int ret; > >@@ -229,7 +232,7 @@ bool schedule_aio_write_and_X(connection_struct *conn, > } > > /* Only do this on non-chained and non-chaining reads not using the >- * write cache. */ >+ write cache. */ > if (req_is_in_chain(req) || (lp_write_cache_size(SNUM(conn)) != 0)) { > return False; > } >@@ -247,6 +250,49 @@ bool schedule_aio_write_and_X(connection_struct *conn, > return False; > } > >+ other_aio_found = false; >+ /* Make sure there are no outstanding aio writes on same fsp */ >+ for( aio_ex = aio_list_head; aio_ex; aio_ex = aio_ex->next) { >+ if (fsp == aio_ex->fsp) { >+ /* Don't do sparse file detection if other */ >+ /* aio statements are outstanding */ >+ /* this should not happen! */ >+ other_aio_found = true; >+ break; >+ } >+ } >+ >+ if (!other_aio_found) { >+ ret = SMB_VFS_FSTAT(fsp, &st); >+ if (ret == -1) { >+ /* This should not happen, fall back to synchronous */ >+ return False; >+ } >+ >+ if (startpos > st.st_ex_size) { >+ /* Writing beyond end of file >+ potentially creating a gap */ >+ >+ enum smb_strict_allocate_options sa_options = >+ lp_strict_allocate(SNUM(fsp->conn)); >+ >+ /* let a synchronous write handle filling >+ the sparse file */ >+ if (sa_options == STRICT_ALLOCATE_ON) >+ return False; >+ >+ /* If strict allocate is set to "partial", >+ ignore all allocate requests over the >+ STRICT_ALLOCATE_PARTIAL_LIMIT. */ >+ >+ if ((sa_options == STRICT_ALLOCATE_PARTIAL) && >+ (startpos - st.st_ex_size < >+ STRICT_ALLOCATE_PARTIAL_LIMIT)) { >+ return False; >+ } >+ } >+ } >+ > bufsize = smb_size + 6*2; > > if (!(aio_ex = create_aio_extra(fsp, bufsize))) { >diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c >index 1c27fef..3f6dfbe 100644 >--- a/source3/smbd/fileio.c >+++ b/source3/smbd/fileio.c >@@ -126,9 +126,10 @@ static ssize_t real_write_file(struct smb_request *req, > if (pos == -1) { > ret = vfs_write_data(req, fsp, data, n); > } else { >+ enum smb_strict_allocate_options sa_options = lp_strict_allocate(SNUM(fsp->conn)); > fsp->fh->pos = pos; >- if (pos && lp_strict_allocate(SNUM(fsp->conn))) { >- if (vfs_fill_sparse(fsp, pos) == -1) { >+ if (pos && (sa_options != STRICT_ALLOCATE_OFF)) { >+ if (vfs_fill_sparse(fsp, pos, sa_options) == -1) { > return -1; > } > } >diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c >index 68fa795..bd792ad 100644 >--- a/source3/smbd/globals.c >+++ b/source3/smbd/globals.c >@@ -121,7 +121,6 @@ struct conn_ctx conn_ctx_stack[MAX_SEC_CTX_DEPTH]; > int conn_ctx_stack_ndx = 0; > > struct vfs_init_function_entry *backends = NULL; >-char *sparse_buf = NULL; > char *LastDir = NULL; > > /* Current number of oplocks we have outstanding. */ >diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h >index 0db61f8..5de1fcc 100644 >--- a/source3/smbd/globals.h >+++ b/source3/smbd/globals.h >@@ -130,7 +130,6 @@ extern int conn_ctx_stack_ndx; > > struct vfs_init_function_entry; > extern struct vfs_init_function_entry *backends; >-extern char *sparse_buf; > extern char *LastDir; > > /* Current number of oplocks we have outstanding. */ >diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c >index 2ce61ee..3c9454a 100644 >--- a/source3/smbd/vfs.c >+++ b/source3/smbd/vfs.c >@@ -503,8 +503,9 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len) > contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW); > contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW); > >- if (!lp_strict_allocate(SNUM(fsp->conn))) >+ if (lp_strict_allocate(SNUM(fsp->conn)) == STRICT_ALLOCATE_OFF) { > return 0; >+ } > > len -= st.st_ex_size; > len /= 1024; /* Len is now number of 1k blocks needed. */ >@@ -562,9 +563,8 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len) > Returns 0 on success, -1 on failure. > ****************************************************************************/ > >-#define SPARSE_BUF_WRITE_SIZE (32*1024) > >-int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) >+int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len, enum smb_strict_allocate_options sa_options) > { > int ret; > SMB_STRUCT_STAT st; >@@ -582,6 +582,14 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) > return 0; > } > >+ /* If strict allocate is set to "partial", ignore all allocate >+ * requests over the STRICT_ALLOCATE_PARTIAL_LIMIT. */ >+ >+ if ((sa_options == STRICT_ALLOCATE_PARTIAL) && >+ (len - st.st_ex_size > STRICT_ALLOCATE_PARTIAL_LIMIT)) { >+ return 0; >+ } >+ > DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to " > "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp), > (double)st.st_ex_size, (double)len, >@@ -591,37 +599,7 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) > > flush_write_cache(fsp, SIZECHANGE_FLUSH); > >- if (!sparse_buf) { >- sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE); >- if (!sparse_buf) { >- errno = ENOMEM; >- ret = -1; >- goto out; >- } >- } >- >- offset = st.st_ex_size; >- num_to_write = len - st.st_ex_size; >- total = 0; >- >- while (total < num_to_write) { >- size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (num_to_write - total)); >- >- pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total); >- if (pwrite_ret == -1) { >- DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file " >- "%s failed with error %s\n", >- fsp_str_dbg(fsp), strerror(errno))); >- ret = -1; >- goto out; >- } >- if (pwrite_ret == 0) { >- ret = 0; >- goto out; >- } >- >- total += pwrite_ret; >- } >+ SMB_VFS_FALLOCATE( fsp, st.st_ex_size, len); > > set_filelen_write_cache(fsp, len); > >@@ -1438,6 +1416,14 @@ int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle, > return handle->fns->ftruncate(handle, fsp, offset); > } > >+int smb_vfs_call_fallocate(struct vfs_handle_struct *handle, >+ struct files_struct *fsp, SMB_OFF_T offset, >+ SMB_OFF_T len) >+{ >+ VFS_FIND(fallocate); >+ return handle->fns->fallocate(handle, fsp, offset, len); >+} >+ > int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle, > struct files_struct *fsp, uint32 share_mode, > uint32_t access_mask) >-- >1.6.0.2 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 6942
:
5027
|
5028
|
5032
|
5033
|
5065
|
5066
|
5312
|
5313
|
5314
|
5315
|
5317
|
5359
|
5360