summaryrefslogtreecommitdiff
path: root/source3/smbd/vfs-wrap.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/vfs-wrap.c')
-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)