summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2001-07-05 10:33:10 +0000
committerAndrew Tridgell <tridge@samba.org>2001-07-05 10:33:10 +0000
commitc9291d02c1628abd89c4e0c18cb592037cc24cb2 (patch)
treea7901e565ef4ab281b2244bf58244efd2c41e3ac
parent005582d1b54e095cadd9fbb50c475a203d831dac (diff)
downloadsamba-c9291d02c1628abd89c4e0c18cb592037cc24cb2.tar.gz
samba-c9291d02c1628abd89c4e0c18cb592037cc24cb2.tar.bz2
samba-c9291d02c1628abd89c4e0c18cb592037cc24cb2.zip
this fixes the failure of MS office on VFAT partitions on Linux
The problem is that ftruncate can't expand on VFAT, but it can on ext2. That means our autoconf test is useless. I have recoded it to use the alternative to ftruncate when then sys_ftruncate fails. Jeremy, do you want this for 2.2.1? (This used to be commit 970236ee9926b64c0b39bd8a36b2a9317206873c)
-rw-r--r--source3/smbd/vfs-wrap.c59
1 files changed, 29 insertions, 30 deletions
diff --git a/source3/smbd/vfs-wrap.c b/source3/smbd/vfs-wrap.c
index 241216e9d7..2b465dbe15 100644
--- a/source3/smbd/vfs-wrap.c
+++ b/source3/smbd/vfs-wrap.c
@@ -479,33 +479,34 @@ int vfswrap_utime(connection_struct *conn, const char *path, struct utimbuf *tim
int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
{
int result = -1;
- START_PROFILE(syscall_ftruncate);
-
-#ifdef HAVE_FTRUNCATE_EXTEND
- result = sys_ftruncate(fd, len);
- END_PROFILE(syscall_ftruncate);
- return result;
-#else
-
- /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
- extend a file with ftruncate. Provide alternate implementation
- for this */
-
struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops;
SMB_STRUCT_STAT st;
char c = 0;
SMB_OFF_T currpos;
- currpos = vfs_ops->lseek(fsp, (SMB_OFF_T)0, SEEK_CUR);
- if(currpos == -1) {
+ START_PROFILE(syscall_ftruncate);
+
+ /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
+ sys_ftruncate if the system supports it. Then I discovered that
+ you can have some filesystems that support ftruncate
+ expansion and some that don't! On Linux fat can't do
+ ftruncate extend but ext2 can. */
+ result = sys_ftruncate(fd, len);
+ if (result == 0) goto done;
+
+ /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
+ extend a file with ftruncate. Provide alternate implementation
+ for this */
+ currpos = vfs_ops->lseek(fsp, fd, 0, SEEK_CUR);
+ if (currpos == -1) {
goto done;
}
- /* Do an fstat to see if the file is longer than
- the requested size (call ftruncate),
- or shorter, in which case seek to len - 1 and write 1
- byte of zero */
- if(vfs_ops->fstat(fsp, &st)<0) {
+ /* Do an fstat to see if the file is longer than the requested
+ 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 (vfs_ops->fstat(fsp, fd, &st) < 0) {
goto done;
}
@@ -516,35 +517,33 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
}
#endif
- if(st.st_size == len) {
+ if (st.st_size == len) {
result = 0;
goto done;
}
- if(st.st_size > len) {
- /* Yes this is *deliberately* sys_ftruncate ! JRA */
- result = sys_ftruncate(fd, len);
+ if (st.st_size > len) {
+ /* the sys_ftruncate should have worked */
goto done;
}
- if(vfs_ops->lseek(fsp, len-1, SEEK_SET) != len -1) {
+ if (vfs_ops->lseek(fsp, fd, len-1, SEEK_SET) != len -1) {
goto done;
}
- if(vfs_ops->write(fsp, &c, 1)!=1) {
+ if (vfs_ops->write(fsp, fd, &c, 1)!=1) {
goto done;
}
/* Seek to where we were */
- if(vfs_ops->lseek(fsp, currpos, SEEK_SET) != currpos) {
+ if (vfs_ops->lseek(fsp, fd, currpos, SEEK_SET) != currpos) {
goto done;
}
+ result = 0;
done:
- END_PROFILE(syscall_ftruncate);
- return result;
-#endif
-
+ END_PROFILE(syscall_ftruncate);
+ return result;
}
BOOL vfswrap_lock(files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)