diff options
author | Andrew Tridgell <tridge@samba.org> | 2001-07-05 10:33:10 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2001-07-05 10:33:10 +0000 |
commit | c9291d02c1628abd89c4e0c18cb592037cc24cb2 (patch) | |
tree | a7901e565ef4ab281b2244bf58244efd2c41e3ac | |
parent | 005582d1b54e095cadd9fbb50c475a203d831dac (diff) | |
download | samba-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.c | 59 |
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) |