1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-25 23:21:54 +03:00

r6841: 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.
This commit is contained in:
Jeremy Allison 2005-05-17 01:04:51 +00:00 committed by Gerald (Jerry) Carter
parent ee45f4b17e
commit 858824f37b
2 changed files with 71 additions and 0 deletions

View File

@ -125,6 +125,11 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_
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);
}

View File

@ -588,6 +588,72 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
return ret;
}
/****************************************************************************
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.
****************************************************************************/