svn commit: samba r6841 - in branches/SAMBA_3_0/source/smbd: .

jra at samba.org jra at samba.org
Tue May 17 01:04:56 GMT 2005


Author: jra
Date: 2005-05-17 01:04:51 +0000 (Tue, 17 May 2005)
New Revision: 6841

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=6841

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:
   branches/SAMBA_3_0/source/smbd/fileio.c
   branches/SAMBA_3_0/source/smbd/vfs.c


Changeset:
Modified: branches/SAMBA_3_0/source/smbd/fileio.c
===================================================================
--- branches/SAMBA_3_0/source/smbd/fileio.c	2005-05-17 01:04:44 UTC (rev 6840)
+++ branches/SAMBA_3_0/source/smbd/fileio.c	2005-05-17 01:04:51 UTC (rev 6841)
@@ -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: branches/SAMBA_3_0/source/smbd/vfs.c
===================================================================
--- branches/SAMBA_3_0/source/smbd/vfs.c	2005-05-17 01:04:44 UTC (rev 6840)
+++ branches/SAMBA_3_0/source/smbd/vfs.c	2005-05-17 01:04:51 UTC (rev 6841)
@@ -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