summaryrefslogtreecommitdiff
path: root/source3/smbd/vfs-wrap.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2000-11-16 00:59:18 +0000
committerJeremy Allison <jra@samba.org>2000-11-16 00:59:18 +0000
commit6f58dd587124c8b85fc62177b26129aaea5819b0 (patch)
tree40c926a6f3e5b5db7e913e13ea6571b97dacf362 /source3/smbd/vfs-wrap.c
parent14355a6434952071e862af3a1e7bcfbbf640a6a3 (diff)
downloadsamba-6f58dd587124c8b85fc62177b26129aaea5819b0.tar.gz
samba-6f58dd587124c8b85fc62177b26129aaea5819b0.tar.bz2
samba-6f58dd587124c8b85fc62177b26129aaea5819b0.zip
Ok - fixed a bug in our levelII oplock code. We need to break a level II on
a byte range lock (write lock only, but Win2k breaks on read lock also so I do the same) - if you think about why, this is obvious. Also fixed our client code to do level II oplocks, if requested, and fixed the code where we would assume the client wanted level II if it advertised itself as being level II capable - it may not want that. Jeremy. (This used to be commit 213cd0b5192307cd4b0026cae94b2f52fb1b0c02)
Diffstat (limited to 'source3/smbd/vfs-wrap.c')
-rw-r--r--source3/smbd/vfs-wrap.c68
1 files changed, 64 insertions, 4 deletions
diff --git a/source3/smbd/vfs-wrap.c b/source3/smbd/vfs-wrap.c
index 3b8d5eebcc..ff150b4e40 100644
--- a/source3/smbd/vfs-wrap.c
+++ b/source3/smbd/vfs-wrap.c
@@ -404,13 +404,73 @@ int vfswrap_utime(connection_struct *conn, char *path, struct utimbuf *times)
return result;
}
-int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T offset)
+int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
{
- int result;
-
+ int result = -1;
START_PROFILE(syscall_ftruncate);
- result = sys_ftruncate(fd, offset);
+#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) {
+ 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) {
+ goto done;
+ }
+
+#ifdef S_ISFIFO
+ if (S_ISFIFO(st.st_mode)) {
+ result = 0;
+ goto done;
+ }
+#endif
+
+ 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);
+ goto done;
+ }
+
+ if(vfs_ops->lseek(fsp, len-1, SEEK_SET) != len -1) {
+ goto done;
+ }
+
+ if(vfs_ops->write(fsp, &c, 1)!=1) {
+ goto done;
+ }
+
+ /* Seek to where we were */
+ if(vfs_ops->lseek(fsp, currpos, SEEK_SET) != currpos) {
+ goto done;
+ }
+#endif
+
+ done:
+
END_PROFILE(syscall_ftruncate);
return result;
}