svn commit: samba r6840 - in trunk/source/smbd: .
jra at samba.org
jra at samba.org
Tue May 17 01:04:44 GMT 2005
Author: jra
Date: 2005-05-17 01:04:44 +0000 (Tue, 17 May 2005)
New Revision: 6840
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=6840
Log:
Attempt to fix buf #2681. With "strict allocate = yes" we now zero
fill when a file is extended. Should catch disk full errors on write
from MS-Office.
Jeremy.
Modified:
trunk/source/smbd/fileio.c
trunk/source/smbd/vfs.c
Changeset:
Modified: trunk/source/smbd/fileio.c
===================================================================
--- trunk/source/smbd/fileio.c 2005-05-17 00:51:13 UTC (rev 6839)
+++ trunk/source/smbd/fileio.c 2005-05-17 01:04:44 UTC (rev 6840)
@@ -125,6 +125,11 @@
ret = vfs_write_data(fsp, data, n);
} else {
fsp->pos = pos;
+ if (pos && lp_strict_allocate(SNUM(fsp->conn))) {
+ if (vfs_fill_sparse(fsp, pos) == -1) {
+ return -1;
+ }
+ }
ret = vfs_pwrite_data(fsp, data, n, pos);
}
Modified: trunk/source/smbd/vfs.c
===================================================================
--- trunk/source/smbd/vfs.c 2005-05-17 00:51:13 UTC (rev 6839)
+++ trunk/source/smbd/vfs.c 2005-05-17 01:04:44 UTC (rev 6840)
@@ -589,6 +589,72 @@
}
/****************************************************************************
+ A vfs fill sparse call.
+ Writes zeros from the end of file to len, if len is greater than EOF.
+ Used only by strict_sync.
+ Returns 0 on success, -1 on failure.
+****************************************************************************/
+
+static char *sparse_buf;
+#define SPARSE_BUF_WRITE_SIZE (32*1024)
+
+int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
+{
+ int ret;
+ SMB_STRUCT_STAT st;
+ SMB_OFF_T offset;
+ size_t total;
+ size_t num_to_write;
+ ssize_t pwrite_ret;
+
+ release_level_2_oplocks_on_change(fsp);
+ ret = SMB_VFS_FSTAT(fsp,fsp->fd,&st);
+ if (ret == -1) {
+ return ret;
+ }
+
+ if (len <= st.st_size) {
+ return 0;
+ }
+
+ DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to len %.0f (%.0f bytes)\n",
+ fsp->fsp_name, (double)st.st_size, (double)len, (double)(len - st.st_size)));
+
+ flush_write_cache(fsp, SIZECHANGE_FLUSH);
+
+ if (!sparse_buf) {
+ sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
+ if (!sparse_buf) {
+ errno = ENOMEM;
+ return -1;
+ }
+ }
+
+ offset = st.st_size;
+ num_to_write = len - st.st_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, fsp->fd, 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->fsp_name, strerror(errno) ));
+ return -1;
+ }
+ if (pwrite_ret == 0) {
+ return 0;
+ }
+
+ total += pwrite_ret;
+ }
+
+ set_filelen_write_cache(fsp, len);
+ return 0;
+}
+
+/****************************************************************************
Transfer some data (n bytes) between two file_struct's.
****************************************************************************/
More information about the samba-cvs
mailing list