From 4c5c26b1ef4be862fc2037dd5fcc120cb35bacca Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Aug 1998 07:15:54 +0000 Subject: now that we have no global arrays we can start to split up the monster server.c without breaking things. this splits off netprot.c and fileio.c for negprot and read/write/seek handling respectively. (This used to be commit b3d7014643ec9f2eef6e6f598f5b9db1fe2f930d) --- source3/smbd/fileio.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 source3/smbd/fileio.c (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c new file mode 100644 index 0000000000..edf87f3e7b --- /dev/null +++ b/source3/smbd/fileio.c @@ -0,0 +1,117 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + read/write to a files_struct + Copyright (C) Andrew Tridgell 1992-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +extern int DEBUGLEVEL; + + +/**************************************************************************** +seek a file. Try to avoid the seek if possible +****************************************************************************/ +int seek_file(files_struct *fsp,uint32 pos) +{ + uint32 offset = 0; + + if (fsp->print_file && lp_postscript(fsp->conn->service)) + offset = 3; + + fsp->pos = (int)(lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET) - offset); + return(fsp->pos); +} + +/**************************************************************************** +read from a file +****************************************************************************/ +int read_file(files_struct *fsp,char *data,uint32 pos,int n) +{ + int ret=0,readret; + +#if USE_READ_PREDICTION + if (!fsp->can_write) + { + ret = read_predict(fsp->fd_ptr->fd,pos,data,NULL,n); + + data += ret; + n -= ret; + pos += ret; + } +#endif + +#if WITH_MMAP + if (fsp->mmap_ptr) + { + int num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : -1; + num = MIN(n,num); + if (num > 0) + { + memcpy(data,fsp->mmap_ptr+pos,num); + data += num; + pos += num; + n -= num; + ret += num; + } + } +#endif + + if (n <= 0) + return(ret); + + if (seek_file(fsp,pos) != pos) + { + DEBUG(3,("Failed to seek to %d\n",pos)); + return(ret); + } + + if (n > 0) { + readret = read(fsp->fd_ptr->fd,data,n); + if (readret > 0) ret += readret; + } + + return(ret); +} + + +/**************************************************************************** +write to a file +****************************************************************************/ +int write_file(files_struct *fsp,char *data,int n) +{ + + if (!fsp->can_write) { + errno = EPERM; + return(0); + } + + if (!fsp->modified) { + struct stat st; + fsp->modified = True; + if (fstat(fsp->fd_ptr->fd,&st) == 0) { + int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); + if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) { + dos_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); + } + } + } + + return(write_data(fsp->fd_ptr->fd,data,n)); +} + -- cgit From 0922615405838af7430ef39490ee578711866320 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Aug 1998 07:40:06 +0000 Subject: more splitting of server.c created dosmode.c and filename.c (This used to be commit 534a90ca44641417c21f6ed6d4b94b1de60f808d) --- source3/smbd/fileio.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index edf87f3e7b..971d309ff9 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -115,3 +115,15 @@ int write_file(files_struct *fsp,char *data,int n) return(write_data(fsp->fd_ptr->fd,data,n)); } + +/******************************************************************* +sync a file +********************************************************************/ +void sync_file(connection_struct *conn, files_struct *fsp) +{ +#ifdef HAVE_FSYNC + if(lp_strict_sync(SNUM(conn))) + fsync(fsp->fd_ptr->fd); +#endif +} + -- cgit From 18556274139cc5a00593471bd745354d98a35303 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Sep 1998 20:11:54 +0000 Subject: More abstraction of file system data types, to move to a 64 bit file interface for the NT SMB's. Created a new define, SMB_STRUCT_STAT that currently is defined to be struct stat - this wil change to a user defined type containing 64 bit info when the correct wrappers are written for 64 bit stat(), fstat() and lstat() calls. Also changed all sys_xxxx() calls that were previously just wrappers to the same call prefixed by a dos_to_unix() call into dos_xxxx() calls. This makes it explicit when a pathname translation is being done, and when it is not. Now, all sys_xxx() calls are meant to be wrappers to mask OS differences, and not silently converting filenames on the fly. Jeremy. (This used to be commit 28aa182dbffaa4ffd86047e608400de4b26e80eb) --- source3/smbd/fileio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 971d309ff9..047c84f35f 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -102,12 +102,12 @@ int write_file(files_struct *fsp,char *data,int n) } if (!fsp->modified) { - struct stat st; + SMB_STRUCT_STAT st; fsp->modified = True; if (fstat(fsp->fd_ptr->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) { - dos_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); + file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); } } } -- cgit From 7bb86c1b132bce31a006ea9768a54db7a45fe1a5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Sep 1998 18:40:31 +0000 Subject: Ok - this is the 64 bit widening check in. It changes the configure to check for stat64 and friends, and then changes much of Samba to use the data type SMB_OFF_T for file size information. stat/fstat/lstat/lseek/ftruncate have now become sys_stat etc. to hide the 64 bit calls if needed. Note that this still does not expose 64 bit functionality to the client, as the changes to the reply_xxx smb's are not yet done. This code change should make these changes possible. Still to do before full 64 bit-ness to the client: fcntl lock code. statfs code widening of dev_t and ino_t (now possible due to SMB_DEV_T and SMB_OFF_T types being in place). Let me know if wierd things happen after this check-in and I'll fix them :-). Jeremy. (This used to be commit 14500936c321d15995c963766aac67bf1f4e3824) --- source3/smbd/fileio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 047c84f35f..6d6edf9d37 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -27,14 +27,14 @@ extern int DEBUGLEVEL; /**************************************************************************** seek a file. Try to avoid the seek if possible ****************************************************************************/ -int seek_file(files_struct *fsp,uint32 pos) +SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) { - uint32 offset = 0; + SMB_OFF_T offset = 0; if (fsp->print_file && lp_postscript(fsp->conn->service)) offset = 3; - fsp->pos = (int)(lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET) - offset); + fsp->pos = (sys_lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET) - offset); return(fsp->pos); } @@ -104,7 +104,7 @@ int write_file(files_struct *fsp,char *data,int n) if (!fsp->modified) { SMB_STRUCT_STAT st; fsp->modified = True; - if (fstat(fsp->fd_ptr->fd,&st) == 0) { + if (sys_fstat(fsp->fd_ptr->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) { file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); -- cgit From 06cc91f9a631a23dcd4902d710b89e4b7584c459 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Sep 1998 01:24:30 +0000 Subject: Added ssize_t to configure code. Got 'religion' about using size_t and ssize_t for read/write stuff as part of the code to expose 64 bits to the client. This checkin does all the 'easy' stuff - such as all the read/write/lock calls - but now comes the harder parts (open & friends) and all the file enquiry functions..... Jeremy. (This used to be commit 36544fe5476f7770bd5748574fc54be7b3ee4d4a) --- source3/smbd/fileio.c | 60 +++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 6d6edf9d37..f0bb5e45ac 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -27,6 +27,7 @@ extern int DEBUGLEVEL; /**************************************************************************** seek a file. Try to avoid the seek if possible ****************************************************************************/ + SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) { SMB_OFF_T offset = 0; @@ -41,45 +42,43 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) /**************************************************************************** read from a file ****************************************************************************/ -int read_file(files_struct *fsp,char *data,uint32 pos,int n) + +ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) { - int ret=0,readret; + ssize_t ret=0,readret; #if USE_READ_PREDICTION - if (!fsp->can_write) - { - ret = read_predict(fsp->fd_ptr->fd,pos,data,NULL,n); + if (!fsp->can_write) { + ret = read_predict(fsp->fd_ptr->fd,pos,data,NULL,n); - data += ret; - n -= ret; - pos += ret; - } + data += ret; + n -= ret; + pos += ret; + } #endif #if WITH_MMAP - if (fsp->mmap_ptr) - { - int num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : -1; - num = MIN(n,num); - if (num > 0) - { - memcpy(data,fsp->mmap_ptr+pos,num); - data += num; - pos += num; - n -= num; - ret += num; - } + if (fsp->mmap_ptr) { + SMB_OFF_T num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : -1; + num = MIN(n,num); +#ifdef LARGE_SMB_OFF_T + if ((num > 0) && (num < (1<<(sizeof(size_t)*8))) { +#else /* LARGE_SMB_OFF_T */ + if (num > 0) { +#endif /* LARGE_SMB_OFF_T */ + memcpy(data,fsp->mmap_ptr+pos,num); + data += num; + pos += num; + n -= num; + ret += num; } + } #endif - if (n <= 0) + if (seek_file(fsp,pos) != pos) { + DEBUG(3,("Failed to seek to %.0f\n",(double)pos)); return(ret); - - if (seek_file(fsp,pos) != pos) - { - DEBUG(3,("Failed to seek to %d\n",pos)); - return(ret); - } + } if (n > 0) { readret = read(fsp->fd_ptr->fd,data,n); @@ -93,7 +92,8 @@ int read_file(files_struct *fsp,char *data,uint32 pos,int n) /**************************************************************************** write to a file ****************************************************************************/ -int write_file(files_struct *fsp,char *data,int n) + +ssize_t write_file(files_struct *fsp,char *data,size_t n) { if (!fsp->can_write) { @@ -119,6 +119,7 @@ int write_file(files_struct *fsp,char *data,int n) /******************************************************************* sync a file ********************************************************************/ + void sync_file(connection_struct *conn, files_struct *fsp) { #ifdef HAVE_FSYNC @@ -126,4 +127,3 @@ void sync_file(connection_struct *conn, files_struct *fsp) fsync(fsp->fd_ptr->fd); #endif } - -- cgit From 9b20e5bac2a7b83f8e3dfdf3a274a1ce12dbd92c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Sep 1998 21:42:18 +0000 Subject: Ok so with this bugfix 64 bit file access actually seems to work :-). Problems were just dumb bugs like (defining sys_lseek to return 'int' DOH !). Jeremy. (This used to be commit 54dd51176fbab18af0b21bdee71b53f8f86573a8) --- source3/smbd/fileio.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index f0bb5e45ac..d40c159798 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -36,6 +36,10 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) offset = 3; fsp->pos = (sys_lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET) - offset); + + DEBUG(10,("seek_file: requested pos = %.0f, new pos = %.0f\n", + (double)(pos+offset), (double)fsp->pos )); + return(fsp->pos); } @@ -62,7 +66,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) SMB_OFF_T num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : -1; num = MIN(n,num); #ifdef LARGE_SMB_OFF_T - if ((num > 0) && (num < (1<<(sizeof(size_t)*8))) { + if ((num > 0) && (num < (1LL<<(sizeof(size_t)*8)))) { #else /* LARGE_SMB_OFF_T */ if (num > 0) { #endif /* LARGE_SMB_OFF_T */ @@ -76,7 +80,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) #endif if (seek_file(fsp,pos) != pos) { - DEBUG(3,("Failed to seek to %.0f\n",(double)pos)); + DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos)); return(ret); } -- cgit From c7da9992cb39fc84a6a915dd2158beaf5e616617 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Sep 1998 03:00:20 +0000 Subject: gto ri of a bunch more #ifdef LARGE_SMB_OFF_T checks by introducing a SOFF_T() macro for setting an SMB_OFF_T variable also limited mmap based reads to MAX_MMAP_SIZE. We really can't mmap 2^50 bytes due to virtual address space problems. (This used to be commit 4e784b18899eddd2399a51fa7d8c219560432922) --- source3/smbd/fileio.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index d40c159798..5c4bf7dfc2 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -63,19 +63,15 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) #if WITH_MMAP if (fsp->mmap_ptr) { - SMB_OFF_T num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : -1; - num = MIN(n,num); -#ifdef LARGE_SMB_OFF_T - if ((num > 0) && (num < (1LL<<(sizeof(size_t)*8)))) { -#else /* LARGE_SMB_OFF_T */ - if (num > 0) { -#endif /* LARGE_SMB_OFF_T */ - memcpy(data,fsp->mmap_ptr+pos,num); - data += num; - pos += num; - n -= num; - ret += num; - } + SMB_OFF_T num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : -1; + num = MIN(n,num); + if (num > 0) { + memcpy(data,fsp->mmap_ptr+pos,num); + data += num; + pos += num; + n -= num; + ret += num; + } } #endif -- cgit From fc7d3e4caa7650c02ef36fff83b64b06050f66b1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Oct 1998 00:55:17 +0000 Subject: config: Fix crypt prototype on RedHat Linux. include/includes.h: Fix crypt prototype on RedHat Linux. smbd/fileio.c: Fix mmap bug found by WinCE client. smbd/ipc.c: Fix WinCE wierdness with pipes being opened as \server\pipe\lanman smbd/password.c: Fix encrypted null passwords. Jeremy. (This used to be commit 475992730c0ecbf31c09b3518df2f0354cec61da) --- source3/smbd/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 5c4bf7dfc2..ebc4544a76 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -63,7 +63,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) #if WITH_MMAP if (fsp->mmap_ptr) { - SMB_OFF_T num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : -1; + SMB_OFF_T num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : 0; num = MIN(n,num); if (num > 0) { memcpy(data,fsp->mmap_ptr+pos,num); -- cgit From b8aec499dc49b1d86d9f44296e07d40232813642 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 18 Oct 1998 22:06:35 +0000 Subject: Fixed sys_lseek and seek_file calls so all returns are *checked* :-). Jeremy. (This used to be commit b8b781191dd7d28944d87eec5fa0fbef798e289b) --- source3/smbd/fileio.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index ebc4544a76..c7ffb6412d 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -31,11 +31,20 @@ seek a file. Try to avoid the seek if possible SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) { SMB_OFF_T offset = 0; + SMB_OFF_T seek_ret; if (fsp->print_file && lp_postscript(fsp->conn->service)) offset = 3; - fsp->pos = (sys_lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET) - offset); + seek_ret = sys_lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET); + + if((seek_ret == -1) || (seek_ret != pos+offset)) { + DEBUG(0,("seek_file: sys_lseek failed. Error was %s\n", strerror(errno) )); + fsp->pos = -1; + return -1; + } + + fsp->pos = seek_ret - offset; DEBUG(10,("seek_file: requested pos = %.0f, new pos = %.0f\n", (double)(pos+offset), (double)fsp->pos )); @@ -75,7 +84,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) } #endif - if (seek_file(fsp,pos) != pos) { + if (seek_file(fsp,pos) == -1) { DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos)); return(ret); } -- cgit From 5cf21e60c8e406d390ee271b9e5945a9c229695e Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 4 Apr 1999 07:05:03 +0000 Subject: Use VFS operations for file I/O. Modified args to read_predict to pass in fsp. Renamed sync_file() function to sys_sync_file(). (This used to be commit 7ced7fd3958c76303e4b6019b5d54eda666d7b33) --- source3/smbd/fileio.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index c7ffb6412d..7ab13f33f4 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -36,7 +36,7 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) if (fsp->print_file && lp_postscript(fsp->conn->service)) offset = 3; - seek_ret = sys_lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET); + seek_ret = fsp->conn->vfs_ops.lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET); if((seek_ret == -1) || (seek_ret != pos+offset)) { DEBUG(0,("seek_file: sys_lseek failed. Error was %s\n", strerror(errno) )); @@ -62,7 +62,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) #if USE_READ_PREDICTION if (!fsp->can_write) { - ret = read_predict(fsp->fd_ptr->fd,pos,data,NULL,n); + ret = read_predict(fsp, fsp->fd_ptr->fd,pos,data,NULL,n); data += ret; n -= ret; @@ -88,9 +88,9 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos)); return(ret); } - + if (n > 0) { - readret = read(fsp->fd_ptr->fd,data,n); + readret = fsp->conn->vfs_ops.read(fsp->fd_ptr->fd,data,n); if (readret > 0) ret += readret; } @@ -104,7 +104,6 @@ write to a file ssize_t write_file(files_struct *fsp,char *data,size_t n) { - if (!fsp->can_write) { errno = EPERM; return(0); @@ -113,7 +112,7 @@ ssize_t write_file(files_struct *fsp,char *data,size_t n) if (!fsp->modified) { SMB_STRUCT_STAT st; fsp->modified = True; - if (sys_fstat(fsp->fd_ptr->fd,&st) == 0) { + if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) { file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); @@ -121,7 +120,7 @@ ssize_t write_file(files_struct *fsp,char *data,size_t n) } } - return(write_data(fsp->fd_ptr->fd,data,n)); + return(vfs_write_data(fsp,data,n)); } @@ -129,7 +128,7 @@ ssize_t write_file(files_struct *fsp,char *data,size_t n) sync a file ********************************************************************/ -void sync_file(connection_struct *conn, files_struct *fsp) +void sys_sync_file(struct connection_struct *conn, files_struct *fsp) { #ifdef HAVE_FSYNC if(lp_strict_sync(SNUM(conn))) -- cgit From 1e1a52bb5f0475327d435c06032d1e6234c28bcb Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 20 Apr 1999 03:29:05 +0000 Subject: Changed arguments to fsync() function to break dependency on connection_struct. (This used to be commit ee6f826ccc0897a4538f6f9a560127c54a4c4038) --- source3/smbd/fileio.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 7ab13f33f4..1e16627515 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -128,10 +128,9 @@ ssize_t write_file(files_struct *fsp,char *data,size_t n) sync a file ********************************************************************/ -void sys_sync_file(struct connection_struct *conn, files_struct *fsp) +void sys_sync_file(int fd) { #ifdef HAVE_FSYNC - if(lp_strict_sync(SNUM(conn))) - fsync(fsp->fd_ptr->fd); + fsync(fd); #endif } -- cgit From 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:27:58 +0000 Subject: first pass at updating head branch to be to be the same as the SAMBA_2_0 branch (This used to be commit 453a822a76780063dff23526c35408866d0c0154) --- source3/smbd/fileio.c | 567 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 545 insertions(+), 22 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 1e16627515..8b48a921fd 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -23,6 +23,7 @@ extern int DEBUGLEVEL; +static BOOL setup_write_cache(files_struct *, SMB_OFF_T); /**************************************************************************** seek a file. Try to avoid the seek if possible @@ -36,7 +37,19 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) if (fsp->print_file && lp_postscript(fsp->conn->service)) offset = 3; - seek_ret = fsp->conn->vfs_ops.lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET); + seek_ret = sys_lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET); + + /* + * We want to maintain the fiction that we can seek + * on a fifo for file system purposes. This allows + * people to set up UNIX fifo's that feed data to Windows + * applications. JRA. + */ + + if((seek_ret == -1) && (errno == ESPIPE)) { + seek_ret = pos+offset; + errno = 0; + } if((seek_ret == -1) || (seek_ret != pos+offset)) { DEBUG(0,("seek_file: sys_lseek failed. Error was %s\n", strerror(errno) )); @@ -52,6 +65,29 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) return(fsp->pos); } +/**************************************************************************** + Read from write cache if we can. +****************************************************************************/ + +static unsigned int cache_read_hits; + +BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) +{ + write_cache *wcp = fsp->wcp; + + if(!wcp) + return False; + + if(n > wcp->data_size || pos < wcp->offset || pos + n > wcp->offset + wcp->data_size) + return False; + + memcpy(data, wcp->data + (pos - wcp->offset), n); + + cache_read_hits++; + + return True; +} + /**************************************************************************** read from a file ****************************************************************************/ @@ -62,7 +98,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) #if USE_READ_PREDICTION if (!fsp->can_write) { - ret = read_predict(fsp, fsp->fd_ptr->fd,pos,data,NULL,n); + ret = read_predict(fsp->fd_ptr->fd,pos,data,NULL,n); data += ret; n -= ret; @@ -70,40 +106,64 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) } #endif -#if WITH_MMAP - if (fsp->mmap_ptr) { - SMB_OFF_T num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : 0; - num = MIN(n,num); - if (num > 0) { - memcpy(data,fsp->mmap_ptr+pos,num); - data += num; - pos += num; - n -= num; - ret += num; - } - } -#endif + /* + * Serve from write cache if we can. + */ + if(read_from_write_cache(fsp, data, pos, n)) + return n; + + flush_write_cache(fsp, READ_FLUSH); if (seek_file(fsp,pos) == -1) { DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos)); return(ret); } - + if (n > 0) { - readret = fsp->conn->vfs_ops.read(fsp->fd_ptr->fd,data,n); + readret = read(fsp->fd_ptr->fd,data,n); if (readret > 0) ret += readret; } return(ret); } +/* Write cache static counters. */ + +static unsigned int abutted_writes; +static unsigned int total_writes; +static unsigned int non_oplock_writes; +static unsigned int direct_writes; +static unsigned int init_writes; +static unsigned int flushed_writes; +static unsigned int num_perfect_writes; +static unsigned int flush_reasons[NUM_FLUSH_REASONS]; + +/* how many write cache buffers have been allocated */ +static unsigned int allocated_write_caches; +static unsigned int num_write_caches; + +/**************************************************************************** + *Really* write to a file +****************************************************************************/ + +static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_t n) +{ + if ((pos != -1) && (seek_file(fsp,pos) == -1)) + return -1; + + return write_data(fsp->fd_ptr->fd,data,n); +} /**************************************************************************** write to a file ****************************************************************************/ -ssize_t write_file(files_struct *fsp,char *data,size_t n) +ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) { + write_cache *wcp = fsp->wcp; + ssize_t total_written = 0; + int write_path = -1; + if (!fsp->can_write) { errno = EPERM; return(0); @@ -112,25 +172,488 @@ ssize_t write_file(files_struct *fsp,char *data,size_t n) if (!fsp->modified) { SMB_STRUCT_STAT st; fsp->modified = True; - if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&st) == 0) { + + if (sys_fstat(fsp->fd_ptr->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) { file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); } + + /* + * If this is the first write and we have an exclusive oplock then setup + * the write cache. + */ + + if ((fsp->oplock_type == EXCLUSIVE_OPLOCK) && !wcp) { + setup_write_cache(fsp, st.st_size); + wcp = fsp->wcp; + } } } - return(vfs_write_data(fsp,data,n)); + total_writes++; + if (!fsp->oplock_type) { + non_oplock_writes++; + } + + /* + * If this file is level II oplocked then we need + * to grab the shared memory lock and inform all + * other files with a level II lock that they need + * to flush their read caches. We keep the lock over + * the shared memory area whilst doing this. + */ + + if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) { + SMB_DEV_T dev = fsp->fd_ptr->dev; + SMB_INO_T inode = fsp->fd_ptr->inode; + share_mode_entry *share_list = NULL; + pid_t pid = getpid(); + int token = -1; + int num_share_modes = 0; + int i; + + if (lock_share_entry(fsp->conn, dev, inode, &token) == False) { + DEBUG(0,("write_file: failed to lock share mode entry for file %s.\n", fsp->fsp_name )); + } + + num_share_modes = get_share_modes(fsp->conn, token, dev, inode, &share_list); + + for(i = 0; i < num_share_modes; i++) { + share_mode_entry *share_entry = &share_list[i]; + + /* + * As there could have been multiple writes waiting at the lock_share_entry + * gate we may not be the first to enter. Hence the state of the op_types + * in the share mode entries may be partly NO_OPLOCK and partly LEVEL_II + * oplock. It will do no harm to re-send break messages to those smbd's + * that are still waiting their turn to remove their LEVEL_II state, and + * also no harm to ignore existing NO_OPLOCK states. JRA. + */ + + if (share_entry->op_type == NO_OPLOCK) + continue; + + /* Paranoia .... */ + if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) { + DEBUG(0,("write_file: PANIC. share mode entry %d is an exlusive oplock !\n", i )); + abort(); + } + + /* + * Check if this is a file we have open (including the + * file we've been called to do write_file on. If so + * then break it directly without releasing the lock. + */ + + if (pid == share_entry->pid) { + files_struct *new_fsp = file_find_dit(dev, inode, &share_entry->time); + + /* Paranoia check... */ + if(new_fsp == NULL) { + DEBUG(0,("write_file: PANIC. share mode entry %d is not a local file !\n", i )); + abort(); + } + oplock_break_level2(new_fsp, True, token); + + } else { + + /* + * This is a remote file and so we send an asynchronous + * message. + */ + + request_oplock_break(share_entry, dev, inode); + } + } + + free((char *)share_list); + unlock_share_entry(fsp->conn, dev, inode, token); + } + + /* Paranoia check... */ + if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) { + DEBUG(0,("write_file: PANIC. File %s still has a level II oplock.\n", fsp->fsp_name)); + abort(); + } + + if (total_writes % 500 == 0) { + DEBUG(3,("WRITECACHE: initwrites=%u abutted=%u flushes=%u total=%u \ +nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", + init_writes, abutted_writes, flushed_writes, total_writes, non_oplock_writes, + allocated_write_caches, + num_write_caches, direct_writes, num_perfect_writes, cache_read_hits )); + + DEBUG(3,("WRITECACHE: SEEK=%d, READ=%d, WRITE=%d, READRAW=%d, OPLOCK=%d, CLOSE=%d, SYNC=%d\n", + flush_reasons[SEEK_FLUSH], + flush_reasons[READ_FLUSH], + flush_reasons[WRITE_FLUSH], + flush_reasons[READRAW_FLUSH], + flush_reasons[OPLOCK_RELEASE_FLUSH], + flush_reasons[CLOSE_FLUSH], + flush_reasons[SYNC_FLUSH] )); + } + + if(!wcp) { + direct_writes++; + return real_write_file(fsp, data, pos, n); + } + + DEBUG(9,("write_file(fd=%d pos=%d size=%d) wofs=%d wsize=%d\n", + fsp->fd_ptr->fd, (int)pos, (int)n, (int)wcp->offset, (int)wcp->data_size)); + + /* + * If we have active cache and it isn't contiguous then we flush. + * NOTE: There is a small problem with running out of disk .... + */ + + if (wcp->data_size) { + + BOOL cache_flush_needed = False; + + if ((pos >= wcp->offset) && (pos <= wcp->offset + wcp->data_size)) { + + /* + * Start of write overlaps or abutts the existing data. + */ + + size_t data_used = MIN((wcp->alloc_size - (pos - wcp->offset)), n); + + memcpy(wcp->data + (pos - wcp->offset), data, data_used); + + /* + * Update the current buffer size with the new data. + */ + + if(pos + data_used > wcp->offset + wcp->data_size) + wcp->data_size = pos + data_used - wcp->offset; + + /* + * If we used all the data then + * return here. + */ + + if(n == data_used) + return n; + else + cache_flush_needed = True; + + /* + * Move the start of data forward by the amount used, + * cut down the amount left by the same amount. + */ + + data += data_used; + pos += data_used; + n -= data_used; + + abutted_writes++; + total_written = data_used; + + write_path = 1; + + } else if ((pos < wcp->offset) && (pos + n > wcp->offset) && + (pos + n <= wcp->offset + wcp->alloc_size)) { + + /* + * End of write overlaps the existing data. + */ + + size_t data_used = pos + n - wcp->offset; + + memcpy(wcp->data, data + n - data_used, data_used); + + /* + * Update the current buffer size with the new data. + */ + + if(pos + n > wcp->offset + wcp->data_size) + wcp->data_size = pos + n - wcp->offset; + + /* + * We don't need to move the start of data, but we + * cut down the amount left by the amount used. + */ + + n -= data_used; + + /* + * We cannot have used all the data here. + */ + + cache_flush_needed = True; + + abutted_writes++; + total_written = data_used; + + write_path = 2; + + } else if ( (pos >= wcp->file_size) && + (pos > wcp->offset + wcp->data_size) && + (pos < wcp->offset + wcp->alloc_size) ) { + + /* + * Non-contiguous write part of which fits within + * the cache buffer and is extending the file. + */ + + size_t data_used; + + if(pos + n <= wcp->offset + wcp->alloc_size) + data_used = n; + else + data_used = wcp->offset + wcp->alloc_size - pos; + + /* + * Fill in the non-continuous area with zeros. + */ + + memset(wcp->data + wcp->data_size, '\0', + pos - (wcp->offset + wcp->data_size) ); + + memcpy(wcp->data + (pos - wcp->offset), data, data_used); + + /* + * Update the current buffer size with the new data. + */ + + if(pos + data_used > wcp->offset + wcp->data_size) + wcp->data_size = pos + data_used - wcp->offset; + + /* + * Update the known file length. + */ + + wcp->file_size = wcp->offset + wcp->data_size; + +#if 0 + if (set_filelen(fsp->fd_ptr->fd, wcp->file_size) == -1) { + DEBUG(0,("write_file: error %s in setting file to length %.0f\n", + strerror(errno), (double)wcp->file_size )); + return -1; + } +#endif + + /* + * If we used all the data then + * return here. + */ + + if(n == data_used) + return n; + else + cache_flush_needed = True; + + /* + * Move the start of data forward by the amount used, + * cut down the amount left by the same amount. + */ + + data += data_used; + pos += data_used; + n -= data_used; + + abutted_writes++; + total_written = data_used; + + write_path = 3; + + } else { + + /* + * Write is bigger than buffer, or there is no overlap on the + * low or high ends. + */ + + DEBUG(9,("write_file: non cacheable write : fd = %d, pos = %.0f, len = %u, current cache pos = %.0f \ +len = %u\n",fsp->fd_ptr->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size )); + + /* + * Update the file size if needed. + */ + + if(pos + n > wcp->file_size) + wcp->file_size = pos + n; + + /* + * If write would fit in the cache, and is larger than + * the data already in the cache, flush the cache and + * preferentially copy the data new data into it. Otherwise + * just write the data directly. + */ + + if ( n <= wcp->alloc_size && n > wcp->data_size) { + cache_flush_needed = True; + } else { + direct_writes++; + return real_write_file(fsp, data, pos, n); + } + + write_path = 4; + + } + + if(wcp->data_size > wcp->file_size) + wcp->file_size = wcp->data_size; + + if (cache_flush_needed) { + flushed_writes++; + + DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \ +n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", + write_path, fsp->fd_ptr->fd, (double)wcp->file_size, (double)pos, (unsigned int)n, + (double)wcp->offset, (unsigned int)wcp->data_size )); + + flush_write_cache(fsp, WRITE_FLUSH); + } + } + + /* + * If the write request is bigger than the cache + * size, write it all out. + */ + + if (n > wcp->alloc_size ) { + if(real_write_file(fsp, data, pos, n) == -1) + return -1; + direct_writes++; + return total_written + n; + } + + /* + * If there's any data left, cache it. + */ + + if (n) { + if (wcp->data_size) { + abutted_writes++; + DEBUG(9,("abutted write (%u)\n", abutted_writes)); + } else { + init_writes++; + } + memcpy(wcp->data+wcp->data_size, data, n); + if (wcp->data_size == 0) { + wcp->offset = pos; + num_write_caches++; + } + wcp->data_size += n; + DEBUG(9,("cache return %u\n", (unsigned int)n)); + total_written += n; + return total_written; /* .... that's a write :) */ + } + + return total_written; } +/**************************************************************************** + Delete the write cache structure. +****************************************************************************/ +void delete_write_cache(files_struct *fsp) +{ + write_cache *wcp; + + if(!fsp) + return; + + if(!(wcp = fsp->wcp)) + return; + + allocated_write_caches--; + + SMB_ASSERT(wcp->data_size == 0); + + free(wcp->data); + free(wcp); + + fsp->wcp = NULL; +} + +/**************************************************************************** + Setup the write cache structure. +****************************************************************************/ + +static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) +{ + ssize_t alloc_size = lp_write_cache_size(SNUM(fsp->conn)); + write_cache *wcp; + + if (allocated_write_caches >= MAX_WRITE_CACHES) return False; + + if(alloc_size == 0 || fsp->wcp) + return False; + + if((wcp = (write_cache *)malloc(sizeof(write_cache))) == NULL) { + DEBUG(0,("setup_write_cache: malloc fail.\n")); + return False; + } + + wcp->file_size = file_size; + wcp->offset = 0; + wcp->alloc_size = alloc_size; + wcp->data_size = 0; + if((wcp->data = malloc(wcp->alloc_size)) == NULL) { + DEBUG(0,("setup_write_cache: malloc fail for buffer size %u.\n", + (unsigned int)wcp->alloc_size )); + free(wcp); + return False; + } + + fsp->wcp = wcp; + allocated_write_caches++; + + return True; +} + +/**************************************************************************** + Cope with a size change. +****************************************************************************/ + +void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size) +{ + if(fsp->wcp) { + flush_write_cache(fsp, SIZECHANGE_FLUSH); + fsp->wcp->file_size = file_size; + } +} + +/******************************************************************* + Flush a write cache struct to disk. +********************************************************************/ + +ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) +{ + write_cache *wcp = fsp->wcp; + size_t data_size; + + if(!wcp || !wcp->data_size) + return 0; + + data_size = wcp->data_size; + wcp->data_size = 0; + + num_write_caches--; + + flush_reasons[(int)reason]++; + + DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n", + fsp->fd_ptr->fd, (double)wcp->offset, (unsigned int)data_size)); + + if(data_size == wcp->alloc_size) + num_perfect_writes++; + + return real_write_file(fsp, wcp->data, wcp->offset, data_size); +} /******************************************************************* sync a file ********************************************************************/ -void sys_sync_file(int fd) +void sync_file(connection_struct *conn, files_struct *fsp) { #ifdef HAVE_FSYNC - fsync(fd); + if(lp_strict_sync(SNUM(conn)) && fsp->fd_ptr != NULL) { + flush_write_cache(fsp, SYNC_FLUSH); + fsync(fsp->fd_ptr->fd); + } #endif } -- cgit From 4e1291a83f61a72989045879763d9ef05fd38f71 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Dec 1999 09:25:59 +0000 Subject: converted all our existing shared memory code to use a tdb database instead of either sysv or mmap shared memory or lock files. this means we can now completely remove locking_shm.c locking_slow.c shmem.c shmem_sysv.c and lots of other things also got simpler locking.c got a bit larger, but is much better compartmentalised now (This used to be commit e48c2d9937eea0667b8cd3332e49c06314ef31e7) --- source3/smbd/fileio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 8b48a921fd..fa04e671f8 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -213,11 +213,11 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) int num_share_modes = 0; int i; - if (lock_share_entry(fsp->conn, dev, inode, &token) == False) { + if (lock_share_entry(fsp->conn, dev, inode) == False) { DEBUG(0,("write_file: failed to lock share mode entry for file %s.\n", fsp->fsp_name )); } - num_share_modes = get_share_modes(fsp->conn, token, dev, inode, &share_list); + num_share_modes = get_share_modes(fsp->conn, dev, inode, &share_list); for(i = 0; i < num_share_modes; i++) { share_mode_entry *share_entry = &share_list[i]; @@ -268,7 +268,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) } free((char *)share_list); - unlock_share_entry(fsp->conn, dev, inode, token); + unlock_share_entry(fsp->conn, dev, inode); } /* Paranoia check... */ -- cgit From 16bb009dbbe6302febf3848cee61e9927eeb0fb5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 3 Feb 2000 05:17:25 +0000 Subject: Mega-VFS merge. Yeah baby! Synopsis: change every disk access function to work through a vfs_ops structure contained in the connection_struct. (This used to be commit 3aad500c0fb61232ed3431ff4b743b5d18ec852f) --- source3/smbd/fileio.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index fa04e671f8..348486d430 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -37,7 +37,7 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) if (fsp->print_file && lp_postscript(fsp->conn->service)) offset = 3; - seek_ret = sys_lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET); + seek_ret = fsp->conn->vfs_ops.lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET); /* * We want to maintain the fiction that we can seek @@ -120,7 +120,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) } if (n > 0) { - readret = read(fsp->fd_ptr->fd,data,n); + readret = fsp->conn->vfs_ops.read(fsp->fd_ptr->fd,data,n); if (readret > 0) ret += readret; } @@ -173,7 +173,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) SMB_STRUCT_STAT st; fsp->modified = True; - if (sys_fstat(fsp->fd_ptr->fd,&st) == 0) { + if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) { file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); @@ -644,16 +644,17 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) return real_write_file(fsp, wcp->data, wcp->offset, data_size); } + /******************************************************************* sync a file ********************************************************************/ -void sync_file(connection_struct *conn, files_struct *fsp) +void sys_fsync_file(connection_struct *conn, files_struct *fsp) { #ifdef HAVE_FSYNC if(lp_strict_sync(SNUM(conn)) && fsp->fd_ptr != NULL) { flush_write_cache(fsp, SYNC_FLUSH); - fsync(fsp->fd_ptr->fd); + conn->vfs_ops.fsync(fsp->fd_ptr->fd); } #endif } -- cgit From 2d15c34f4fc2f3943328976361ab8c67508b6e82 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 Apr 2000 18:44:04 +0000 Subject: Change to vfs API. POSIX states fsync should return an int, not a void. Jeremy. (This used to be commit 6c442d68afae4140e28b770343a900b5ce510b4a) --- source3/smbd/fileio.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 348486d430..00a515d16d 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -651,10 +651,8 @@ sync a file void sys_fsync_file(connection_struct *conn, files_struct *fsp) { -#ifdef HAVE_FSYNC if(lp_strict_sync(SNUM(conn)) && fsp->fd_ptr != NULL) { flush_write_cache(fsp, SYNC_FLUSH); conn->vfs_ops.fsync(fsp->fd_ptr->fd); } -#endif } -- cgit From 689ec46450a3f373b583ebe98d124ab4a99ce3ef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Apr 2000 13:05:23 +0000 Subject: the bulk of the changes to get rid of fd_ptr and move print open handling to printing/printing.c most of this was just replacing things like fsp->fd_ptr->fd with fsp->fd the changes in open.c are quite dramatic. Most of it is removing all the functions that handled the fd multiplexing (This used to be commit d1827a3648009fd0a0d165055015d9aeda7a1037) --- source3/smbd/fileio.c | 44 ++++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 00a515d16d..43fd091b49 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -37,7 +37,7 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) if (fsp->print_file && lp_postscript(fsp->conn->service)) offset = 3; - seek_ret = fsp->conn->vfs_ops.lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET); + seek_ret = fsp->conn->vfs_ops.lseek(fsp->fd,pos+offset,SEEK_SET); /* * We want to maintain the fiction that we can seek @@ -96,16 +96,6 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) { ssize_t ret=0,readret; -#if USE_READ_PREDICTION - if (!fsp->can_write) { - ret = read_predict(fsp->fd_ptr->fd,pos,data,NULL,n); - - data += ret; - n -= ret; - pos += ret; - } -#endif - /* * Serve from write cache if we can. */ @@ -120,7 +110,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) } if (n > 0) { - readret = fsp->conn->vfs_ops.read(fsp->fd_ptr->fd,data,n); + readret = fsp->conn->vfs_ops.read(fsp->fd,data,n); if (readret > 0) ret += readret; } @@ -151,7 +141,7 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_ if ((pos != -1) && (seek_file(fsp,pos) == -1)) return -1; - return write_data(fsp->fd_ptr->fd,data,n); + return write_data(fsp->fd,data,n); } /**************************************************************************** @@ -173,7 +163,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) SMB_STRUCT_STAT st; fsp->modified = True; - if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&st) == 0) { + if (fsp->conn->vfs_ops.fstat(fsp->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) { file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); @@ -205,19 +195,17 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) */ if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) { - SMB_DEV_T dev = fsp->fd_ptr->dev; - SMB_INO_T inode = fsp->fd_ptr->inode; share_mode_entry *share_list = NULL; pid_t pid = getpid(); int token = -1; int num_share_modes = 0; int i; - if (lock_share_entry(fsp->conn, dev, inode) == False) { + if (lock_share_entry_fsp(fsp) == False) { DEBUG(0,("write_file: failed to lock share mode entry for file %s.\n", fsp->fsp_name )); } - num_share_modes = get_share_modes(fsp->conn, dev, inode, &share_list); + num_share_modes = get_share_modes(fsp->conn, fsp->dev, fsp->inode, &share_list); for(i = 0; i < num_share_modes; i++) { share_mode_entry *share_entry = &share_list[i]; @@ -247,7 +235,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) */ if (pid == share_entry->pid) { - files_struct *new_fsp = file_find_dit(dev, inode, &share_entry->time); + files_struct *new_fsp = file_find_dit(fsp->dev, fsp->inode, &share_entry->time); /* Paranoia check... */ if(new_fsp == NULL) { @@ -263,12 +251,12 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) * message. */ - request_oplock_break(share_entry, dev, inode); + request_oplock_break(share_entry, fsp->dev, fsp->inode); } } free((char *)share_list); - unlock_share_entry(fsp->conn, dev, inode); + unlock_share_entry_fsp(fsp); } /* Paranoia check... */ @@ -300,7 +288,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", } DEBUG(9,("write_file(fd=%d pos=%d size=%d) wofs=%d wsize=%d\n", - fsp->fd_ptr->fd, (int)pos, (int)n, (int)wcp->offset, (int)wcp->data_size)); + fsp->fd, (int)pos, (int)n, (int)wcp->offset, (int)wcp->data_size)); /* * If we have active cache and it isn't contiguous then we flush. @@ -427,7 +415,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", wcp->file_size = wcp->offset + wcp->data_size; #if 0 - if (set_filelen(fsp->fd_ptr->fd, wcp->file_size) == -1) { + if (set_filelen(fsp->fd, wcp->file_size) == -1) { DEBUG(0,("write_file: error %s in setting file to length %.0f\n", strerror(errno), (double)wcp->file_size )); return -1; @@ -466,7 +454,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", */ DEBUG(9,("write_file: non cacheable write : fd = %d, pos = %.0f, len = %u, current cache pos = %.0f \ -len = %u\n",fsp->fd_ptr->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size )); +len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size )); /* * Update the file size if needed. @@ -501,7 +489,7 @@ len = %u\n",fsp->fd_ptr->fd, (double)pos, (unsigned int)n, (double)wcp->offset, DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", - write_path, fsp->fd_ptr->fd, (double)wcp->file_size, (double)pos, (unsigned int)n, + write_path, fsp->fd, (double)wcp->file_size, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size )); flush_write_cache(fsp, WRITE_FLUSH); @@ -637,7 +625,7 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) flush_reasons[(int)reason]++; DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n", - fsp->fd_ptr->fd, (double)wcp->offset, (unsigned int)data_size)); + fsp->fd, (double)wcp->offset, (unsigned int)data_size)); if(data_size == wcp->alloc_size) num_perfect_writes++; @@ -651,8 +639,8 @@ sync a file void sys_fsync_file(connection_struct *conn, files_struct *fsp) { - if(lp_strict_sync(SNUM(conn)) && fsp->fd_ptr != NULL) { + if(lp_strict_sync(SNUM(conn)) && fsp->fd != -1) { flush_write_cache(fsp, SYNC_FLUSH); - conn->vfs_ops.fsync(fsp->fd_ptr->fd); + conn->vfs_ops.fsync(fsp->fd); } } -- cgit From 54de56a1be8ede7476c741cd1631ad1ac8107fcc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Apr 2000 06:22:31 +0000 Subject: the changes to the main smb code ------------ The following series of commits are for the new tdb based printing backend. This completely replaces our old printing backend. Major changes include: - all print ops are now done in printing/*.c rather than scattered all over the place - system job ids are decoupled from SMB job ids - the lpq parsers don't need to be nearly so smart, they only need to parse the filename, the status and system job id - we can store lots more info about a job, including the full job name - the queue cache control is much better I also added a new utility routine file_lines_load() that loads a text file and parses it into lines. This is used in out lpq parsing and I also want to use it to replace all of our fgets() based code in other places. (This used to be commit d870542c2884510bd45fd5b54ff2157434d53f4c) --- source3/smbd/fileio.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 43fd091b49..5d8c3a9710 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -96,6 +96,11 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) { ssize_t ret=0,readret; + /* you can't read from print files */ + if (fsp->print_file) { + return -1; + } + /* * Serve from write cache if we can. */ @@ -154,6 +159,10 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) ssize_t total_written = 0; int write_path = -1; + if (fsp->print_file) { + return print_job_write(fsp->print_jobid, data, n); + } + if (!fsp->can_write) { errno = EPERM; return(0); -- cgit From 6259f51dd9918eccc9697f3763d918f7c9b82b50 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 22 Apr 2000 00:33:16 +0000 Subject: This is a *big* checkin that may break some things, but implements the new open mechanism Andrew & I discussed. config.sub: configure: Included the QNX patch. include/vfs.h: smbd/vfs-wrap.c: smbd/vfs.c: Added ftruncate vfs call (needed). Note that we will also need locking calls in the vfs (to be added). lib/util_unistr.c: nmbd/nmbd_processlogon.c: Fix for NT domain logons causing nmbd to core dump. Also fix for sidsize DOS bug. locking/locking.c: Check value of ret before using it for memdup. printing/printing.c: Convert print_fsp_open to return an allocated fsp. rpc_server/srv_lsa.c: Fix for NT domain logons. I have removed all use of lp_share_modes() from the code (although I left the parameter in the table for backwards compatibility). It no longer makes sense for this to exist. smbd/close.c: Removed lp_share_modes(). smbd/fileio.c: Fixed parameters to unlock_share_entry call in panic code. smbd/files.c: Correctly set the unix_ERR_code to ERRnofids on fsp allocation fail. smbd/nttrans.c: smbd/reply.c: smbd/trans2.c: Changed all occurrences of open_file_shared/open_directory/ open_file_stat to return an fsp from the call. smbd/open.c: Changed all occurrences of open_file_shared/open_directory/ open_file_stat to return an fsp from the call. In addition I have fixed a long standing race condition in the deny mode processing w.r.t. two smbd's creating a file. Andrew, please note that your original idea of using open with O_EXCL in this case would not work (I went over the races very carefully) and so we must re-check deny modes *after* the open() call returns. This is because there is a race between the open with O_EXCL and the lock of the share mode entry. Imagine the case where the first smbd does the open with O_EXCL and a deny mode of DENY_ALL, but is pre-empted before it locks the share modes and creates the deny mode entry for DENY_ALL. A second smbd could then come in with O_RDONLY and a deny mode of DENY_NONE and the two opens would be allowed. The *only* way to fix this race is to lock the share modes after the open and then do the deny mode checks *after* this lock in the case where the file did not originally exist. This code will need extensive testing but seems to initially work. Jeremy. (This used to be commit ab0ecc39d688f16b9692fe90b991f0b89287070a) --- source3/smbd/fileio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 5d8c3a9710..8f8f17563e 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -234,6 +234,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) /* Paranoia .... */ if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) { DEBUG(0,("write_file: PANIC. share mode entry %d is an exlusive oplock !\n", i )); + unlock_share_entry(fsp->conn, fsp->dev, fsp->inode); abort(); } @@ -249,6 +250,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) /* Paranoia check... */ if(new_fsp == NULL) { DEBUG(0,("write_file: PANIC. share mode entry %d is not a local file !\n", i )); + unlock_share_entry(fsp->conn, fsp->dev, fsp->inode); abort(); } oplock_break_level2(new_fsp, True, token); -- cgit From 693ffb8466ada58ecc59fde754ba79fc6f51528d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 2 May 2000 02:23:41 +0000 Subject: Added sys_fork() and sys_getpid() functions to stop the overhead of doing a system call every time we want to just get our pid. Jeremy. (This used to be commit 148628b616b5c29ba6340d65fc3ddbcabba6e67a) --- source3/smbd/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 8f8f17563e..2d83378b3d 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -205,7 +205,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) { share_mode_entry *share_list = NULL; - pid_t pid = getpid(); + pid_t pid = sys_getpid(); int token = -1; int num_share_modes = 0; int i; -- cgit From a12b2cd9e806fefeabdbe73b46b569f5b9bc927f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 May 2000 02:39:02 +0000 Subject: Fix for read_file() returning -1. Jeremy. (This used to be commit b899943658bee90994b416aa6caff0ee7cab5f28) --- source3/smbd/fileio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 2d83378b3d..6507f56606 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -116,6 +116,8 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) if (n > 0) { readret = fsp->conn->vfs_ops.read(fsp->fd,data,n); + if (readret == -1) + return -1; if (readret > 0) ret += readret; } -- cgit From c88222da0ced7edf90b68e68ec49e0fe35a512fe Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 10 May 2000 01:31:46 +0000 Subject: Fix for misunderstanding of fsync added when vfs layer was done. Samba was doing fsync's (bleagh). Jeremy. (This used to be commit f9a52cadbf11f7afcef754a59d783964a2edb5bc) --- source3/smbd/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 6507f56606..79dcd8ab83 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -650,7 +650,7 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) sync a file ********************************************************************/ -void sys_fsync_file(connection_struct *conn, files_struct *fsp) +void sync_file(connection_struct *conn, files_struct *fsp) { if(lp_strict_sync(SNUM(conn)) && fsp->fd != -1) { flush_write_cache(fsp, SYNC_FLUSH); -- cgit From 49a0e6d5989656c1b3c9c063a20308ca4ee5d73b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 May 2000 10:41:59 +0000 Subject: more merging voodoo this adds "#define OLD_NTDOMAIN 1" in lots of places. Don't panic - this isn't permanent, it should go after another few merge steps have been done (This used to be commit 92109d7b3c06f240452d39f669ecb8c9c86ab610) --- source3/smbd/fileio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 79dcd8ab83..45ad959a3c 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -1,3 +1,4 @@ +#define OLD_NTDOMAIN 1 /* Unix SMB/Netbios implementation. Version 1.9. @@ -657,3 +658,4 @@ void sync_file(connection_struct *conn, files_struct *fsp) conn->vfs_ops.fsync(fsp->fd); } } +#undef OLD_NTDOMAIN -- cgit From ace6739f5e8b9cc3139c5ea1d42ab481856dd4c5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 Aug 2000 20:44:33 +0000 Subject: vfs write data fix. Fix for name matching in addtosmbpass Jeremy. (This used to be commit 85738b7ee1ea6d88999d6aedc51a2daf545cb8b8) --- source3/smbd/fileio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 45ad959a3c..7fbf6e2a37 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -141,7 +141,7 @@ static unsigned int allocated_write_caches; static unsigned int num_write_caches; /**************************************************************************** - *Really* write to a file + *Really* write to a file. ****************************************************************************/ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_t n) @@ -149,7 +149,7 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_ if ((pos != -1) && (seek_file(fsp,pos) == -1)) return -1; - return write_data(fsp->fd,data,n); + return vfs_write_data(fsp,data,n); } /**************************************************************************** -- cgit From 2679fa315da579fbdc7dd35d3ee1cb364b85a1d9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 2 Oct 2000 21:03:46 +0000 Subject: Memleak fix for cache code. Jeremy. (This used to be commit 1ebe54666b0fc6f224f17036063dfe0ef7ec9147) --- source3/smbd/fileio.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 7fbf6e2a37..3ebc46e86b 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -186,7 +186,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) * the write cache. */ - if ((fsp->oplock_type == EXCLUSIVE_OPLOCK) && !wcp) { + if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) { setup_write_cache(fsp, st.st_size); wcp = fsp->wcp; } @@ -569,6 +569,9 @@ void delete_write_cache(files_struct *fsp) free(wcp); fsp->wcp = NULL; + + DEBUG(10,("delete_write_cache: File %s deleted write cache\n", fsp->fsp_name )); + } /**************************************************************************** @@ -604,6 +607,9 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) fsp->wcp = wcp; allocated_write_caches++; + DEBUG(10,("setup_write_cache: File %s allocated write cache size %u\n", + fsp->fsp_name, wcp->alloc_size )); + return True; } -- cgit From bbd7f7bf0fd4f6cda41989c3371d7bf18f49a592 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 5 Oct 2000 18:50:18 +0000 Subject: Herb's fixes for profiling & compiler warnings. Jeremy. (This used to be commit 7914e9351abb5271ebb4990c3b1fe495d15a4eda) --- source3/smbd/fileio.c | 116 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 69 insertions(+), 47 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 3ebc46e86b..0c43a255dc 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -70,7 +70,6 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) Read from write cache if we can. ****************************************************************************/ -static unsigned int cache_read_hits; BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) { @@ -84,7 +83,9 @@ BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) memcpy(data, wcp->data + (pos - wcp->offset), n); - cache_read_hits++; +#ifdef WITH_PROFILE + INC_PROFILE_COUNT(writecache_read_hits); +#endif return True; } @@ -125,20 +126,8 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) return(ret); } -/* Write cache static counters. */ - -static unsigned int abutted_writes; -static unsigned int total_writes; -static unsigned int non_oplock_writes; -static unsigned int direct_writes; -static unsigned int init_writes; -static unsigned int flushed_writes; -static unsigned int num_perfect_writes; -static unsigned int flush_reasons[NUM_FLUSH_REASONS]; - /* how many write cache buffers have been allocated */ static unsigned int allocated_write_caches; -static unsigned int num_write_caches; /**************************************************************************** *Really* write to a file. @@ -193,10 +182,12 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) } } - total_writes++; +#ifdef WITH_PROFILE + INC_PROFILE_COUNT(writecache_total_writes); if (!fsp->oplock_type) { - non_oplock_writes++; + INC_PROFILE_COUNT(writecache_non_oplock_writes); } +#endif /* * If this file is level II oplocked then we need @@ -279,25 +270,35 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) abort(); } - if (total_writes % 500 == 0) { - DEBUG(3,("WRITECACHE: initwrites=%u abutted=%u flushes=%u total=%u \ +#ifdef WITH_PROFILE + if (profile_p && profile_p->writecache_total_writes % 500 == 0) { + DEBUG(3,("WRITECACHE: initwrites=%u abutted=%u total=%u \ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", - init_writes, abutted_writes, flushed_writes, total_writes, non_oplock_writes, - allocated_write_caches, - num_write_caches, direct_writes, num_perfect_writes, cache_read_hits )); - - DEBUG(3,("WRITECACHE: SEEK=%d, READ=%d, WRITE=%d, READRAW=%d, OPLOCK=%d, CLOSE=%d, SYNC=%d\n", - flush_reasons[SEEK_FLUSH], - flush_reasons[READ_FLUSH], - flush_reasons[WRITE_FLUSH], - flush_reasons[READRAW_FLUSH], - flush_reasons[OPLOCK_RELEASE_FLUSH], - flush_reasons[CLOSE_FLUSH], - flush_reasons[SYNC_FLUSH] )); + profile_p->writecache_init_writes, + profile_p->writecache_abutted_writes, + profile_p->writecache_total_writes, + profile_p->writecache_non_oplock_writes, + profile_p->writecache_allocated_write_caches, + profile_p->writecache_num_write_caches, + profile_p->writecache_direct_writes, + profile_p->writecache_num_perfect_writes, + profile_p->writecache_read_hits )); + + DEBUG(3,("WRITECACHE: Flushes SEEK=%d, READ=%d, WRITE=%d, READRAW=%d, OPLOCK=%d, CLOSE=%d, SYNC=%d\n", + profile_p->writecache_flushed_writes[SEEK_FLUSH], + profile_p->writecache_flushed_writes[READ_FLUSH], + profile_p->writecache_flushed_writes[WRITE_FLUSH], + profile_p->writecache_flushed_writes[READRAW_FLUSH], + profile_p->writecache_flushed_writes[OPLOCK_RELEASE_FLUSH], + profile_p->writecache_flushed_writes[CLOSE_FLUSH], + profile_p->writecache_flushed_writes[SYNC_FLUSH] )); } +#endif if(!wcp) { - direct_writes++; +#ifdef WITH_PROFILE + INC_PROFILE_COUNT(writecache_direct_writes); +#endif return real_write_file(fsp, data, pos, n); } @@ -349,7 +350,9 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", pos += data_used; n -= data_used; - abutted_writes++; +#ifdef WITH_PROFILE + INC_PROFILE_COUNT(writecache_abutted_writes); +#endif total_written = data_used; write_path = 1; @@ -385,7 +388,9 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", cache_flush_needed = True; - abutted_writes++; +#ifdef WITH_PROFILE + INC_PROFILE_COUNT(writecache_abutted_writes); +#endif total_written = data_used; write_path = 2; @@ -455,7 +460,9 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", pos += data_used; n -= data_used; - abutted_writes++; +#ifdef WITH_PROFILE + INC_PROFILE_COUNT(writecache_abutted_writes); +#endif total_written = data_used; write_path = 3; @@ -487,7 +494,9 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne if ( n <= wcp->alloc_size && n > wcp->data_size) { cache_flush_needed = True; } else { - direct_writes++; +#ifdef WITH_PROFILE + INC_PROFILE_COUNT(writecache_direct_writes); +#endif return real_write_file(fsp, data, pos, n); } @@ -499,8 +508,6 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne wcp->file_size = wcp->data_size; if (cache_flush_needed) { - flushed_writes++; - DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", write_path, fsp->fd, (double)wcp->file_size, (double)pos, (unsigned int)n, @@ -518,7 +525,9 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", if (n > wcp->alloc_size ) { if(real_write_file(fsp, data, pos, n) == -1) return -1; - direct_writes++; +#ifdef WITH_PROFILE + INC_PROFILE_COUNT(writecache_direct_writes); +#endif return total_written + n; } @@ -527,16 +536,19 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", */ if (n) { +#ifdef WITH_PROFILE if (wcp->data_size) { - abutted_writes++; - DEBUG(9,("abutted write (%u)\n", abutted_writes)); + INC_PROFILE_COUNT(writecache_abutted_writes); } else { - init_writes++; + INC_PROFILE_COUNT(writecache_init_writes); } +#endif memcpy(wcp->data+wcp->data_size, data, n); if (wcp->data_size == 0) { wcp->offset = pos; - num_write_caches++; +#ifdef WITH_PROFILE + INC_PROFILE_COUNT(writecache_num_write_caches); +#endif } wcp->data_size += n; DEBUG(9,("cache return %u\n", (unsigned int)n)); @@ -561,6 +573,9 @@ void delete_write_cache(files_struct *fsp) if(!(wcp = fsp->wcp)) return; +#ifdef WITH_PROFILE + DEC_PROFILE_COUNT(writecache_allocated_write_caches); +#endif allocated_write_caches--; SMB_ASSERT(wcp->data_size == 0); @@ -583,7 +598,8 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) ssize_t alloc_size = lp_write_cache_size(SNUM(fsp->conn)); write_cache *wcp; - if (allocated_write_caches >= MAX_WRITE_CACHES) return False; + if (allocated_write_caches >= MAX_WRITE_CACHES) + return False; if(alloc_size == 0 || fsp->wcp) return False; @@ -605,6 +621,9 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) } fsp->wcp = wcp; +#ifdef WITH_PROFILE + INC_PROFILE_COUNT(writecache_allocated_write_caches); +#endif allocated_write_caches++; DEBUG(10,("setup_write_cache: File %s allocated write cache size %u\n", @@ -640,15 +659,18 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) data_size = wcp->data_size; wcp->data_size = 0; - num_write_caches--; - - flush_reasons[(int)reason]++; +#ifdef WITH_PROFILE + DEC_PROFILE_COUNT(writecache_num_write_caches); + INC_PROFILE_COUNT(writecache_flushed_writes[reason]); +#endif DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned int)data_size)); +#ifdef WITH_PROFILE if(data_size == wcp->alloc_size) - num_perfect_writes++; + INC_PROFILE_COUNT(writecache_num_perfect_writes); +#endif return real_write_file(fsp, wcp->data, wcp->offset, data_size); } -- cgit From 636f146abf0a75cd3b21a57b50627ee149a635ab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Oct 2000 03:21:49 +0000 Subject: Restructuring of vfs layer to include a "this" pointer - can be an fsp or a conn struct depending on the call. We need this to have a clean NT ACL call interface. This will break any existing VFS libraries (that's why this is pre-release code). Andrew gets credit for this one :-) :-). In addition - added Herb's WITH_PROFILE changes - Herb - please examine the changes I've made to the smbd/reply.c code you added. The original code was very ugly and I have replaced it with a START_PROFILE(x)/END_PROFILE(x) pair using the preprocessor. Please check this compiles ok with the --with-profile switch. Jeremy. (This used to be commit b07611f8159b0b3f42e7e02611be9f4d56de96f5) --- source3/smbd/fileio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 0c43a255dc..b8a0585d90 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -38,7 +38,7 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) if (fsp->print_file && lp_postscript(fsp->conn->service)) offset = 3; - seek_ret = fsp->conn->vfs_ops.lseek(fsp->fd,pos+offset,SEEK_SET); + seek_ret = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,pos+offset,SEEK_SET); /* * We want to maintain the fiction that we can seek @@ -117,7 +117,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) } if (n > 0) { - readret = fsp->conn->vfs_ops.read(fsp->fd,data,n); + readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n); if (readret == -1) return -1; if (readret > 0) ret += readret; @@ -164,7 +164,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) SMB_STRUCT_STAT st; fsp->modified = True; - if (fsp->conn->vfs_ops.fstat(fsp->fd,&st) == 0) { + if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) { file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); @@ -683,7 +683,7 @@ void sync_file(connection_struct *conn, files_struct *fsp) { if(lp_strict_sync(SNUM(conn)) && fsp->fd != -1) { flush_write_cache(fsp, SYNC_FLUSH); - conn->vfs_ops.fsync(fsp->fd); + conn->vfs_ops.fsync(fsp,fsp->fd); } } #undef OLD_NTDOMAIN -- cgit From ba00796e6dd13b87b7988a98e532676d9eab702c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Oct 2000 18:13:52 +0000 Subject: Herb's warning fixes. Also the POSIX locking fix. We now use our own vfs layer to do get/set acl calls (hurrah!). Jeremy. (This used to be commit dfe77c7046cbd65ee52aea7439f21503c1eac41d) --- source3/smbd/fileio.c | 55 +++++++++++++++------------------------------------ 1 file changed, 16 insertions(+), 39 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index b8a0585d90..bb7ab46baa 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -83,9 +83,7 @@ BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) memcpy(data, wcp->data + (pos - wcp->offset), n); -#ifdef WITH_PROFILE - INC_PROFILE_COUNT(writecache_read_hits); -#endif + DO_PROFILE_INC(writecache_read_hits); return True; } @@ -183,9 +181,9 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) } #ifdef WITH_PROFILE - INC_PROFILE_COUNT(writecache_total_writes); + DO_PROFILE_INC(writecache_total_writes); if (!fsp->oplock_type) { - INC_PROFILE_COUNT(writecache_non_oplock_writes); + DO_PROFILE_INC(writecache_non_oplock_writes); } #endif @@ -296,9 +294,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", #endif if(!wcp) { -#ifdef WITH_PROFILE - INC_PROFILE_COUNT(writecache_direct_writes); -#endif + DO_PROFILE_INC(writecache_direct_writes); return real_write_file(fsp, data, pos, n); } @@ -350,9 +346,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", pos += data_used; n -= data_used; -#ifdef WITH_PROFILE - INC_PROFILE_COUNT(writecache_abutted_writes); -#endif + DO_PROFILE_INC(writecache_abutted_writes); total_written = data_used; write_path = 1; @@ -388,9 +382,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", cache_flush_needed = True; -#ifdef WITH_PROFILE - INC_PROFILE_COUNT(writecache_abutted_writes); -#endif + DO_PROFILE_INC(writecache_abutted_writes); total_written = data_used; write_path = 2; @@ -460,9 +452,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", pos += data_used; n -= data_used; -#ifdef WITH_PROFILE - INC_PROFILE_COUNT(writecache_abutted_writes); -#endif + DO_PROFILE_INC(writecache_abutted_writes); total_written = data_used; write_path = 3; @@ -494,9 +484,7 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne if ( n <= wcp->alloc_size && n > wcp->data_size) { cache_flush_needed = True; } else { -#ifdef WITH_PROFILE - INC_PROFILE_COUNT(writecache_direct_writes); -#endif + DO_PROFILE_INC(writecache_direct_writes); return real_write_file(fsp, data, pos, n); } @@ -525,9 +513,7 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", if (n > wcp->alloc_size ) { if(real_write_file(fsp, data, pos, n) == -1) return -1; -#ifdef WITH_PROFILE - INC_PROFILE_COUNT(writecache_direct_writes); -#endif + DO_PROFILE_INC(writecache_direct_writes); return total_written + n; } @@ -538,17 +524,15 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", if (n) { #ifdef WITH_PROFILE if (wcp->data_size) { - INC_PROFILE_COUNT(writecache_abutted_writes); + DO_PROFILE_INC(writecache_abutted_writes); } else { - INC_PROFILE_COUNT(writecache_init_writes); + DO_PROFILE_INC(writecache_init_writes); } #endif memcpy(wcp->data+wcp->data_size, data, n); if (wcp->data_size == 0) { wcp->offset = pos; -#ifdef WITH_PROFILE - INC_PROFILE_COUNT(writecache_num_write_caches); -#endif + DO_PROFILE_INC(writecache_num_write_caches); } wcp->data_size += n; DEBUG(9,("cache return %u\n", (unsigned int)n)); @@ -573,9 +557,7 @@ void delete_write_cache(files_struct *fsp) if(!(wcp = fsp->wcp)) return; -#ifdef WITH_PROFILE - DEC_PROFILE_COUNT(writecache_allocated_write_caches); -#endif + DO_PROFILE_DEC(writecache_allocated_write_caches); allocated_write_caches--; SMB_ASSERT(wcp->data_size == 0); @@ -621,9 +603,7 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) } fsp->wcp = wcp; -#ifdef WITH_PROFILE - INC_PROFILE_COUNT(writecache_allocated_write_caches); -#endif + DO_PROFILE_INC(writecache_allocated_write_caches); allocated_write_caches++; DEBUG(10,("setup_write_cache: File %s allocated write cache size %u\n", @@ -659,17 +639,14 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) data_size = wcp->data_size; wcp->data_size = 0; -#ifdef WITH_PROFILE - DEC_PROFILE_COUNT(writecache_num_write_caches); - INC_PROFILE_COUNT(writecache_flushed_writes[reason]); -#endif + DO_PROFILE_DEC_INC(writecache_num_write_caches,writecache_flushed_writes[reason]); DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned int)data_size)); #ifdef WITH_PROFILE if(data_size == wcp->alloc_size) - INC_PROFILE_COUNT(writecache_num_perfect_writes); + DO_PROFILE_INC(writecache_num_perfect_writes); #endif return real_write_file(fsp, wcp->data, wcp->offset, data_size); -- cgit From 6f58dd587124c8b85fc62177b26129aaea5819b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Nov 2000 00:59:18 +0000 Subject: 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) --- source3/smbd/fileio.c | 81 +-------------------------------------------------- 1 file changed, 1 insertion(+), 80 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index bb7ab46baa..35e2f1455e 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -195,78 +195,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) * the shared memory area whilst doing this. */ - if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) { - share_mode_entry *share_list = NULL; - pid_t pid = sys_getpid(); - int token = -1; - int num_share_modes = 0; - int i; - - if (lock_share_entry_fsp(fsp) == False) { - DEBUG(0,("write_file: failed to lock share mode entry for file %s.\n", fsp->fsp_name )); - } - - num_share_modes = get_share_modes(fsp->conn, fsp->dev, fsp->inode, &share_list); - - for(i = 0; i < num_share_modes; i++) { - share_mode_entry *share_entry = &share_list[i]; - - /* - * As there could have been multiple writes waiting at the lock_share_entry - * gate we may not be the first to enter. Hence the state of the op_types - * in the share mode entries may be partly NO_OPLOCK and partly LEVEL_II - * oplock. It will do no harm to re-send break messages to those smbd's - * that are still waiting their turn to remove their LEVEL_II state, and - * also no harm to ignore existing NO_OPLOCK states. JRA. - */ - - if (share_entry->op_type == NO_OPLOCK) - continue; - - /* Paranoia .... */ - if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) { - DEBUG(0,("write_file: PANIC. share mode entry %d is an exlusive oplock !\n", i )); - unlock_share_entry(fsp->conn, fsp->dev, fsp->inode); - abort(); - } - - /* - * Check if this is a file we have open (including the - * file we've been called to do write_file on. If so - * then break it directly without releasing the lock. - */ - - if (pid == share_entry->pid) { - files_struct *new_fsp = file_find_dit(fsp->dev, fsp->inode, &share_entry->time); - - /* Paranoia check... */ - if(new_fsp == NULL) { - DEBUG(0,("write_file: PANIC. share mode entry %d is not a local file !\n", i )); - unlock_share_entry(fsp->conn, fsp->dev, fsp->inode); - abort(); - } - oplock_break_level2(new_fsp, True, token); - - } else { - - /* - * This is a remote file and so we send an asynchronous - * message. - */ - - request_oplock_break(share_entry, fsp->dev, fsp->inode); - } - } - - free((char *)share_list); - unlock_share_entry_fsp(fsp); - } - - /* Paranoia check... */ - if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) { - DEBUG(0,("write_file: PANIC. File %s still has a level II oplock.\n", fsp->fsp_name)); - abort(); - } + release_level_2_oplocks_on_change(fsp); #ifdef WITH_PROFILE if (profile_p && profile_p->writecache_total_writes % 500 == 0) { @@ -425,14 +354,6 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", wcp->file_size = wcp->offset + wcp->data_size; -#if 0 - if (set_filelen(fsp->fd, wcp->file_size) == -1) { - DEBUG(0,("write_file: error %s in setting file to length %.0f\n", - strerror(errno), (double)wcp->file_size )); - return -1; - } -#endif - /* * If we used all the data then * return here. -- cgit From da3053048c3d224a20d6383ac6682d31059cd46c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 00:32:10 +0000 Subject: Merge of new 2.2 code into HEAD (Gerald I hate you :-) :-). Allows new SAMR RPC code to merge with new passdb code. Currently rpcclient doesn't compile. I'm working on it... Jeremy. (This used to be commit 0be41d5158ea4e645e93e8cd30617c038416e549) --- source3/smbd/fileio.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 35e2f1455e..c79f0aa89e 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -1,4 +1,3 @@ -#define OLD_NTDOMAIN 1 /* Unix SMB/Netbios implementation. Version 1.9. @@ -584,4 +583,3 @@ void sync_file(connection_struct *conn, files_struct *fsp) conn->vfs_ops.fsync(fsp,fsp->fd); } } -#undef OLD_NTDOMAIN -- cgit From 61b2794968faa35dc91edce17e9b91e5366c3514 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Sep 2001 11:25:41 +0000 Subject: move to SAFE_FREE() (This used to be commit a95943fde0ad89ae3f2deca2f7ba9cb5ab612b74) --- source3/smbd/fileio.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index c79f0aa89e..003bee84ed 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -482,10 +482,8 @@ void delete_write_cache(files_struct *fsp) SMB_ASSERT(wcp->data_size == 0); - free(wcp->data); - free(wcp); - - fsp->wcp = NULL; + SAFE_FREE(wcp->data); + SAFE_FREE(fsp->wcp); DEBUG(10,("delete_write_cache: File %s deleted write cache\n", fsp->fsp_name )); @@ -518,7 +516,7 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) if((wcp->data = malloc(wcp->alloc_size)) == NULL) { DEBUG(0,("setup_write_cache: malloc fail for buffer size %u.\n", (unsigned int)wcp->alloc_size )); - free(wcp); + SAFE_FREE(wcp); return False; } -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/smbd/fileio.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 003bee84ed..edf58d4a8e 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -21,8 +21,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - static BOOL setup_write_cache(files_struct *, SMB_OFF_T); /**************************************************************************** -- cgit From 391a72a95fda1a4d1841c29257b5001435c09dc1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 25 Nov 2001 08:26:37 +0000 Subject: #ifdefed DMF fix so not compiled by default. We need to look at this... Jeremy. (This used to be commit 97dca242a91c68048e510f42be53421b533183be) --- source3/smbd/fileio.c | 61 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 22 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index edf58d4a8e..38da96b741 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -91,34 +91,51 @@ read from a file ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) { - ssize_t ret=0,readret; + ssize_t ret=0,readret; - /* you can't read from print files */ - if (fsp->print_file) { - return -1; - } + /* you can't read from print files */ + if (fsp->print_file) + return -1; - /* - * Serve from write cache if we can. - */ - if(read_from_write_cache(fsp, data, pos, n)) - return n; + /* + * Serve from write cache if we can. + */ - flush_write_cache(fsp, READ_FLUSH); + if(read_from_write_cache(fsp, data, pos, n)) + return n; - if (seek_file(fsp,pos) == -1) { - DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos)); - return(ret); - } + flush_write_cache(fsp, READ_FLUSH); + + if (seek_file(fsp,pos) == -1) { + DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos)); + return(ret); + } - if (n > 0) { - readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n); - if (readret == -1) - return -1; - if (readret > 0) ret += readret; - } + if (n > 0) { +#ifdef DMF_FIX + int numretries = 3; +tryagain: + readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n); + if (readret == -1) { + if ((errno == EAGAIN) && numretries) { + DEBUG(3,("read_file EAGAIN retry in 10 seconds\n")); + (void)sleep(10); + --numretries; + goto tryagain; + } + return -1; + } +#else /* NO DMF fix. */ + readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n); + if (readret == -1) + return -1; +#endif + + if (readret > 0) + ret += readret; + } - return(ret); + return(ret); } /* how many write cache buffers have been allocated */ -- cgit From 427896866af5a0047482ce7a0e8e3b69e9063fb2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 20 Jan 2002 00:04:15 +0000 Subject: Attempt to fix bugs in write cache code (yes I know it's going away :-). Jeremy. (This used to be commit ccda82b457b11ec683f404c9059b02c1214a0fd1) --- source3/smbd/fileio.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 38da96b741..84b8e35bf0 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -419,7 +419,7 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne if ( n <= wcp->alloc_size && n > wcp->data_size) { cache_flush_needed = True; } else { - DO_PROFILE_INC(writecache_direct_writes); + DO_PROFILE_INC(writecache_direct_writes); return real_write_file(fsp, data, pos, n); } @@ -552,7 +552,13 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size) { if(fsp->wcp) { - flush_write_cache(fsp, SIZECHANGE_FLUSH); + /* The cache *must* have been flushed before we do this. */ + if (fsp->wcp->data_size != 0) { + pstring msg; + slprintf(msg, sizeof(msg)-1, "set_filelen_write_cache: size change \ +on file %s with write cache size = %u\n", fsp->fsp_name, fsp->wcp->data_size ); + smb_panic(msg); + } fsp->wcp->file_size = file_size; } } @@ -565,6 +571,7 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) { write_cache *wcp = fsp->wcp; size_t data_size; + ssize_t ret; if(!wcp || !wcp->data_size) return 0; @@ -582,7 +589,16 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) DO_PROFILE_INC(writecache_num_perfect_writes); #endif - return real_write_file(fsp, wcp->data, wcp->offset, data_size); + ret = real_write_file(fsp, wcp->data, wcp->offset, data_size); + + /* + * Ensure file size if kept up to date if write extends file. + */ + + if ((ret != -1) && (wcp->offset + ret >= wcp->file_size)) + wcp->file_size = wcp->offset + ret; + + return ret; } /******************************************************************* -- cgit From 2590721a36b2d6efd3b822312e9545548cfc96ca Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 20 Jan 2002 00:43:28 +0000 Subject: Fix file size calculations for write cache code. Jeremy. (This used to be commit 71d647b6c0db8470d6144683c41ab26a7e1ef35e) --- source3/smbd/fileio.c | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 84b8e35bf0..6e1f5cfcf6 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -270,6 +270,13 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", if(pos + data_used > wcp->offset + wcp->data_size) wcp->data_size = pos + data_used - wcp->offset; + /* + * Update the file size if changed. + */ + + if (wcp->offset + wcp->data_size > wcp->file_size) + wcp->file_size = wcp->offset + wcp->data_size; + /* * If we used all the data then * return here. @@ -312,6 +319,13 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", if(pos + n > wcp->offset + wcp->data_size) wcp->data_size = pos + n - wcp->offset; + /* + * Update the file size if changed. + */ + + if (wcp->offset + wcp->data_size > wcp->file_size) + wcp->file_size = wcp->offset + wcp->data_size; + /* * We don't need to move the start of data, but we * cut down the amount left by the amount used. @@ -363,10 +377,11 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", wcp->data_size = pos + data_used - wcp->offset; /* - * Update the known file length. + * Update the file size if changed. */ - wcp->file_size = wcp->offset + wcp->data_size; + if (wcp->offset + wcp->data_size > wcp->file_size) + wcp->file_size = wcp->offset + wcp->data_size; /* * If we used all the data then @@ -419,8 +434,16 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne if ( n <= wcp->alloc_size && n > wcp->data_size) { cache_flush_needed = True; } else { + ssize_t ret = real_write_file(fsp, data, pos, n); + DO_PROFILE_INC(writecache_direct_writes); - return real_write_file(fsp, data, pos, n); + if (ret == -1) + return ret; + + if (pos + ret > wcp->file_size) + wcp->file_size = pos + ret; + + return ret; } write_path = 4; @@ -446,8 +469,13 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", */ if (n > wcp->alloc_size ) { - if(real_write_file(fsp, data, pos, n) == -1) + ssize_t ret = real_write_file(fsp, data, pos, n); + if (ret == -1) return -1; + + if (pos + ret > wcp->file_size) + wcp->file_size = pos + n; + DO_PROFILE_INC(writecache_direct_writes); return total_written + n; } @@ -470,7 +498,15 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", DO_PROFILE_INC(writecache_num_write_caches); } wcp->data_size += n; + + /* + * Update the file size if changed. + */ + + if (wcp->offset + wcp->data_size > wcp->file_size) + wcp->file_size = wcp->offset + wcp->data_size; DEBUG(9,("cache return %u\n", (unsigned int)n)); + total_written += n; return total_written; /* .... that's a write :) */ } @@ -595,7 +631,7 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) * Ensure file size if kept up to date if write extends file. */ - if ((ret != -1) && (wcp->offset + ret >= wcp->file_size)) + if ((ret != -1) && (wcp->offset + ret > wcp->file_size)) wcp->file_size = wcp->offset + ret; return ret; -- cgit From a6541401b03e0a97dc7e265b223289cad7160b75 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 20 Jan 2002 01:01:46 +0000 Subject: Ensure identical between 2.2.3 and 3.0 - no need for difference here.. Jeremy. (This used to be commit 7c5c035e417b45acebc3580c4fdc80a7ef3306ce) --- source3/smbd/fileio.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 6e1f5cfcf6..9f7cb5f340 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -130,7 +130,6 @@ tryagain: if (readret == -1) return -1; #endif - if (readret > 0) ret += readret; } -- cgit From 2383fd87a7c05b56f98bf64fa9ef536a6217f3a5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 21 Jan 2002 23:34:13 +0000 Subject: Found and fixed the logic bug in write cache code. Amazingly helpful work from Juergen.Hasch@de.bosch.com in tracking this down. Jermy. (This used to be commit 40060fe3459cf103a143c324f99c2233a8e53825) --- source3/smbd/fileio.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 9f7cb5f340..a13d05ddc4 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -240,8 +240,8 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", return real_write_file(fsp, data, pos, n); } - DEBUG(9,("write_file(fd=%d pos=%d size=%d) wofs=%d wsize=%d\n", - fsp->fd, (int)pos, (int)n, (int)wcp->offset, (int)wcp->data_size)); + DEBUG(9,("write_file(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n", + fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size)); /* * If we have active cache and it isn't contiguous then we flush. @@ -344,12 +344,15 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", write_path = 2; } else if ( (pos >= wcp->file_size) && + (wcp->offset + wcp->data_size == wcp->file_size) && (pos > wcp->offset + wcp->data_size) && (pos < wcp->offset + wcp->alloc_size) ) { /* * Non-contiguous write part of which fits within - * the cache buffer and is extending the file. + * the cache buffer and is extending the file + * and the cache contents reflect the current + * data up to the current end of the file. */ size_t data_used; @@ -504,7 +507,8 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", if (wcp->offset + wcp->data_size > wcp->file_size) wcp->file_size = wcp->offset + wcp->data_size; - DEBUG(9,("cache return %u\n", (unsigned int)n)); + DEBUG(9,("wcp->offset = %.0f wcp->data_size = %u cache return %u\n", + (double)wcp->offset, (unsigned int)wcp->data_size, (unsigned int)n)); total_written += n; return total_written; /* .... that's a write :) */ @@ -570,6 +574,8 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) return False; } + memset(wcp->data, '\0', wcp->alloc_size ); + fsp->wcp = wcp; DO_PROFILE_INC(writecache_allocated_write_caches); allocated_write_caches++; -- cgit From 73af0a70f5c55192f48e2b0f2815ec3e0747fd90 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 22 Jan 2002 07:24:12 +0000 Subject: Ensure fsp->size is correct so readraw's return correct data. Jeremy. (This used to be commit 443d2530a7fe32392bdb8c7d38a10b7071392b13) --- source3/smbd/fileio.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index a13d05ddc4..ba60690383 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -177,6 +177,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); + fsp->size = st.st_size; if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) { file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); } @@ -237,7 +238,10 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", if(!wcp) { DO_PROFILE_INC(writecache_direct_writes); - return real_write_file(fsp, data, pos, n); + total_written = real_write_file(fsp, data, pos, n); + if ((total_written != -1) && (pos + total_written > fsp->size)) + fsp->size = pos + total_written; + return total_written; } DEBUG(9,("write_file(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n", @@ -274,7 +278,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", */ if (wcp->offset + wcp->data_size > wcp->file_size) - wcp->file_size = wcp->offset + wcp->data_size; + fsp->size = wcp->file_size = wcp->offset + wcp->data_size; /* * If we used all the data then @@ -323,7 +327,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", */ if (wcp->offset + wcp->data_size > wcp->file_size) - wcp->file_size = wcp->offset + wcp->data_size; + fsp->size = wcp->file_size = wcp->offset + wcp->data_size; /* * We don't need to move the start of data, but we @@ -383,7 +387,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", */ if (wcp->offset + wcp->data_size > wcp->file_size) - wcp->file_size = wcp->offset + wcp->data_size; + fsp->size = wcp->file_size = wcp->offset + wcp->data_size; /* * If we used all the data then @@ -424,7 +428,7 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne */ if(pos + n > wcp->file_size) - wcp->file_size = pos + n; + fsp->size = wcp->file_size = pos + n; /* * If write would fit in the cache, and is larger than @@ -443,7 +447,7 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne return ret; if (pos + ret > wcp->file_size) - wcp->file_size = pos + ret; + fsp->size = wcp->file_size = pos + ret; return ret; } @@ -453,7 +457,7 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne } if(wcp->data_size > wcp->file_size) - wcp->file_size = wcp->data_size; + fsp->size = wcp->file_size = wcp->data_size; if (cache_flush_needed) { DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \ @@ -476,7 +480,7 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", return -1; if (pos + ret > wcp->file_size) - wcp->file_size = pos + n; + fsp->size = wcp->file_size = pos + n; DO_PROFILE_INC(writecache_direct_writes); return total_written + n; @@ -506,7 +510,7 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", */ if (wcp->offset + wcp->data_size > wcp->file_size) - wcp->file_size = wcp->offset + wcp->data_size; + fsp->size = wcp->file_size = wcp->offset + wcp->data_size; DEBUG(9,("wcp->offset = %.0f wcp->data_size = %u cache return %u\n", (double)wcp->offset, (unsigned int)wcp->data_size, (unsigned int)n)); @@ -592,6 +596,7 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size) { + fsp->size = file_size; if(fsp->wcp) { /* The cache *must* have been flushed before we do this. */ if (fsp->wcp->data_size != 0) { -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/smbd/fileio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index ba60690383..2aafd14c99 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. read/write to a files_struct Copyright (C) Andrew Tridgell 1992-1998 -- cgit From 0bc19c0bdbcfac2cad9029bcf36d3d00d82a074b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Mar 2002 00:44:38 +0000 Subject: Fix lseek-on-pipe problem in VFS (where it belongs IMHO). Jeremy. (This used to be commit ebef2e7bc87fcbae794426c39044a7d23f43722d) --- source3/smbd/fileio.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 2aafd14c99..acbbb73352 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -36,19 +36,7 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) seek_ret = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,pos+offset,SEEK_SET); - /* - * We want to maintain the fiction that we can seek - * on a fifo for file system purposes. This allows - * people to set up UNIX fifo's that feed data to Windows - * applications. JRA. - */ - - if((seek_ret == -1) && (errno == ESPIPE)) { - seek_ret = pos+offset; - errno = 0; - } - - if((seek_ret == -1) || (seek_ret != pos+offset)) { + if(seek_ret == -1) { DEBUG(0,("seek_file: sys_lseek failed. Error was %s\n", strerror(errno) )); fsp->pos = -1; return -1; -- cgit From b9e91d2a8e41a43d7ebb7d7eed807a7d8de9b329 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 20 Mar 2002 00:46:53 +0000 Subject: Remove the "stat open" code - make it inline. This should fix the bugs with opening and renaming mp3 files, also the word rename problems that people have had for a while. Needs a make clean :-) make. Also added JohnR's printing fix. Jeremy. (This used to be commit 504e5ef0494c54efbd0357e334cb2aa5a9eb9c14) --- source3/smbd/fileio.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index acbbb73352..addbcb0b3c 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -645,3 +645,15 @@ void sync_file(connection_struct *conn, files_struct *fsp) conn->vfs_ops.fsync(fsp,fsp->fd); } } + +/************************************************************ + Perform a stat whether a valid fd or not. +************************************************************/ + +int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst) +{ + if (fsp->fd == -1) + return vfs_stat(fsp->conn, fsp->fsp_name, pst); + else + return vfs_fstat(fsp,fsp->fd, pst); +} -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/smbd/fileio.c | 779 +++++++++++++++++++++++++------------------------- 1 file changed, 395 insertions(+), 384 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index addbcb0b3c..710ba396d8 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -1,7 +1,9 @@ /* - Unix SMB/CIFS implementation. + Unix SMB/Netbios implementation. + Version 1.9. read/write to a files_struct Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Jeremy Allison 2000-2002. - write cache. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,31 +25,32 @@ static BOOL setup_write_cache(files_struct *, SMB_OFF_T); /**************************************************************************** -seek a file. Try to avoid the seek if possible + Seek a file. Try to avoid the seek if possible. ****************************************************************************/ -SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) +static SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) { - SMB_OFF_T offset = 0; - SMB_OFF_T seek_ret; + SMB_OFF_T offset = 0; + SMB_OFF_T seek_ret; - if (fsp->print_file && lp_postscript(fsp->conn->service)) - offset = 3; + if (fsp->print_file && lp_postscript(fsp->conn->service)) + offset = 3; - seek_ret = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,pos+offset,SEEK_SET); + seek_ret = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,pos+offset,SEEK_SET); - if(seek_ret == -1) { - DEBUG(0,("seek_file: sys_lseek failed. Error was %s\n", strerror(errno) )); - fsp->pos = -1; - return -1; - } + if(seek_ret == -1) { + DEBUG(0,("seek_file: (%s) sys_lseek failed. Error was %s\n", + fsp->fsp_name, strerror(errno) )); + fsp->pos = -1; + return -1; + } - fsp->pos = seek_ret - offset; + fsp->pos = seek_ret - offset; - DEBUG(10,("seek_file: requested pos = %.0f, new pos = %.0f\n", - (double)(pos+offset), (double)fsp->pos )); + DEBUG(10,("seek_file (%s): requested pos = %.0f, new pos = %.0f\n", + fsp->fsp_name, (double)(pos+offset), (double)fsp->pos )); - return(fsp->pos); + return(fsp->pos); } /**************************************************************************** @@ -55,25 +58,25 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) ****************************************************************************/ -BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) +static BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) { - write_cache *wcp = fsp->wcp; + write_cache *wcp = fsp->wcp; - if(!wcp) - return False; + if(!wcp) + return False; - if(n > wcp->data_size || pos < wcp->offset || pos + n > wcp->offset + wcp->data_size) - return False; + if(n > wcp->data_size || pos < wcp->offset || pos + n > wcp->offset + wcp->data_size) + return False; - memcpy(data, wcp->data + (pos - wcp->offset), n); + memcpy(data, wcp->data + (pos - wcp->offset), n); - DO_PROFILE_INC(writecache_read_hits); + DO_PROFILE_INC(writecache_read_hits); - return True; + return True; } /**************************************************************************** -read from a file + Read from a file. ****************************************************************************/ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) @@ -121,6 +124,9 @@ tryagain: ret += readret; } + DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n", + fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret )); + return(ret); } @@ -133,10 +139,17 @@ static unsigned int allocated_write_caches; static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_t n) { - if ((pos != -1) && (seek_file(fsp,pos) == -1)) - return -1; + ssize_t ret; + + if ((pos != -1) && (seek_file(fsp,pos) == -1)) + return -1; + + ret = vfs_write_data(fsp,data,n); + + DEBUG(10,("real_write_file (%s): pos = %.0f, size = %lu, returned %ld\n", + fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret )); - return vfs_write_data(fsp,data,n); + return ret; } /**************************************************************************** @@ -145,367 +158,365 @@ write to a file ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) { - write_cache *wcp = fsp->wcp; - ssize_t total_written = 0; - int write_path = -1; - - if (fsp->print_file) { - return print_job_write(fsp->print_jobid, data, n); - } - - if (!fsp->can_write) { - errno = EPERM; - return(0); - } - - if (!fsp->modified) { - SMB_STRUCT_STAT st; - fsp->modified = True; - - if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&st) == 0) { - int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); - fsp->size = st.st_size; - if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) { - file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); - } - - /* - * If this is the first write and we have an exclusive oplock then setup - * the write cache. - */ - - if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) { - setup_write_cache(fsp, st.st_size); - wcp = fsp->wcp; - } - } - } + write_cache *wcp = fsp->wcp; + ssize_t total_written = 0; + int write_path = -1; + + if (fsp->print_file) + return print_job_write(fsp->print_jobid, data, n); + + if (!fsp->can_write) { + errno = EPERM; + return(0); + } + + if (!fsp->modified) { + SMB_STRUCT_STAT st; + fsp->modified = True; + + if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&st) == 0) { + int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); + fsp->size = st.st_size; + if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) + file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); + + /* + * If this is the first write and we have an exclusive oplock then setup + * the write cache. + */ + + if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) { + setup_write_cache(fsp, st.st_size); + wcp = fsp->wcp; + } + } + } #ifdef WITH_PROFILE - DO_PROFILE_INC(writecache_total_writes); - if (!fsp->oplock_type) { - DO_PROFILE_INC(writecache_non_oplock_writes); - } + DO_PROFILE_INC(writecache_total_writes); + if (!fsp->oplock_type) { + DO_PROFILE_INC(writecache_non_oplock_writes); + } #endif - /* - * If this file is level II oplocked then we need - * to grab the shared memory lock and inform all - * other files with a level II lock that they need - * to flush their read caches. We keep the lock over - * the shared memory area whilst doing this. - */ + /* + * If this file is level II oplocked then we need + * to grab the shared memory lock and inform all + * other files with a level II lock that they need + * to flush their read caches. We keep the lock over + * the shared memory area whilst doing this. + */ - release_level_2_oplocks_on_change(fsp); + release_level_2_oplocks_on_change(fsp); #ifdef WITH_PROFILE - if (profile_p && profile_p->writecache_total_writes % 500 == 0) { - DEBUG(3,("WRITECACHE: initwrites=%u abutted=%u total=%u \ + if (profile_p && profile_p->writecache_total_writes % 500 == 0) { + DEBUG(3,("WRITECACHE: initwrites=%u abutted=%u total=%u \ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", - profile_p->writecache_init_writes, - profile_p->writecache_abutted_writes, - profile_p->writecache_total_writes, - profile_p->writecache_non_oplock_writes, - profile_p->writecache_allocated_write_caches, - profile_p->writecache_num_write_caches, - profile_p->writecache_direct_writes, - profile_p->writecache_num_perfect_writes, - profile_p->writecache_read_hits )); - - DEBUG(3,("WRITECACHE: Flushes SEEK=%d, READ=%d, WRITE=%d, READRAW=%d, OPLOCK=%d, CLOSE=%d, SYNC=%d\n", - profile_p->writecache_flushed_writes[SEEK_FLUSH], - profile_p->writecache_flushed_writes[READ_FLUSH], - profile_p->writecache_flushed_writes[WRITE_FLUSH], - profile_p->writecache_flushed_writes[READRAW_FLUSH], - profile_p->writecache_flushed_writes[OPLOCK_RELEASE_FLUSH], - profile_p->writecache_flushed_writes[CLOSE_FLUSH], - profile_p->writecache_flushed_writes[SYNC_FLUSH] )); - } + profile_p->writecache_init_writes, + profile_p->writecache_abutted_writes, + profile_p->writecache_total_writes, + profile_p->writecache_non_oplock_writes, + profile_p->writecache_allocated_write_caches, + profile_p->writecache_num_write_caches, + profile_p->writecache_direct_writes, + profile_p->writecache_num_perfect_writes, + profile_p->writecache_read_hits )); + + DEBUG(3,("WRITECACHE: Flushes SEEK=%d, READ=%d, WRITE=%d, READRAW=%d, OPLOCK=%d, CLOSE=%d, SYNC=%d\n", + profile_p->writecache_flushed_writes[SEEK_FLUSH], + profile_p->writecache_flushed_writes[READ_FLUSH], + profile_p->writecache_flushed_writes[WRITE_FLUSH], + profile_p->writecache_flushed_writes[READRAW_FLUSH], + profile_p->writecache_flushed_writes[OPLOCK_RELEASE_FLUSH], + profile_p->writecache_flushed_writes[CLOSE_FLUSH], + profile_p->writecache_flushed_writes[SYNC_FLUSH] )); + } #endif - if(!wcp) { - DO_PROFILE_INC(writecache_direct_writes); - total_written = real_write_file(fsp, data, pos, n); - if ((total_written != -1) && (pos + total_written > fsp->size)) - fsp->size = pos + total_written; - return total_written; - } + if(!wcp) { + DO_PROFILE_INC(writecache_direct_writes); + total_written = real_write_file(fsp, data, pos, n); + if ((total_written != -1) && (pos + total_written > fsp->size)) + fsp->size = pos + total_written; + return total_written; + } - DEBUG(9,("write_file(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n", - fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size)); + DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n", + fsp->fsp_name, fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size)); - /* - * If we have active cache and it isn't contiguous then we flush. - * NOTE: There is a small problem with running out of disk .... - */ + /* + * If we have active cache and it isn't contiguous then we flush. + * NOTE: There is a small problem with running out of disk .... + */ - if (wcp->data_size) { + if (wcp->data_size) { - BOOL cache_flush_needed = False; + BOOL cache_flush_needed = False; - if ((pos >= wcp->offset) && (pos <= wcp->offset + wcp->data_size)) { + if ((pos >= wcp->offset) && (pos <= wcp->offset + wcp->data_size)) { - /* - * Start of write overlaps or abutts the existing data. - */ + /* + * Start of write overlaps or abutts the existing data. + */ - size_t data_used = MIN((wcp->alloc_size - (pos - wcp->offset)), n); + size_t data_used = MIN((wcp->alloc_size - (pos - wcp->offset)), n); - memcpy(wcp->data + (pos - wcp->offset), data, data_used); + memcpy(wcp->data + (pos - wcp->offset), data, data_used); - /* - * Update the current buffer size with the new data. - */ + /* + * Update the current buffer size with the new data. + */ - if(pos + data_used > wcp->offset + wcp->data_size) - wcp->data_size = pos + data_used - wcp->offset; + if(pos + data_used > wcp->offset + wcp->data_size) + wcp->data_size = pos + data_used - wcp->offset; - /* - * Update the file size if changed. - */ + /* + * Update the file size if changed. + */ - if (wcp->offset + wcp->data_size > wcp->file_size) - fsp->size = wcp->file_size = wcp->offset + wcp->data_size; + if (wcp->offset + wcp->data_size > wcp->file_size) + fsp->size = wcp->file_size = wcp->offset + wcp->data_size; - /* - * If we used all the data then - * return here. - */ + /* + * If we used all the data then + * return here. + */ - if(n == data_used) - return n; - else - cache_flush_needed = True; + if(n == data_used) + return n; + else + cache_flush_needed = True; - /* - * Move the start of data forward by the amount used, - * cut down the amount left by the same amount. - */ + /* + * Move the start of data forward by the amount used, + * cut down the amount left by the same amount. + */ - data += data_used; - pos += data_used; - n -= data_used; + data += data_used; + pos += data_used; + n -= data_used; - DO_PROFILE_INC(writecache_abutted_writes); - total_written = data_used; + DO_PROFILE_INC(writecache_abutted_writes); + total_written = data_used; - write_path = 1; + write_path = 1; - } else if ((pos < wcp->offset) && (pos + n > wcp->offset) && - (pos + n <= wcp->offset + wcp->alloc_size)) { + } else if ((pos < wcp->offset) && (pos + n > wcp->offset) && + (pos + n <= wcp->offset + wcp->alloc_size)) { - /* - * End of write overlaps the existing data. - */ + /* + * End of write overlaps the existing data. + */ - size_t data_used = pos + n - wcp->offset; + size_t data_used = pos + n - wcp->offset; - memcpy(wcp->data, data + n - data_used, data_used); + memcpy(wcp->data, data + n - data_used, data_used); - /* - * Update the current buffer size with the new data. - */ + /* + * Update the current buffer size with the new data. + */ - if(pos + n > wcp->offset + wcp->data_size) - wcp->data_size = pos + n - wcp->offset; + if(pos + n > wcp->offset + wcp->data_size) + wcp->data_size = pos + n - wcp->offset; - /* - * Update the file size if changed. - */ + /* + * Update the file size if changed. + */ - if (wcp->offset + wcp->data_size > wcp->file_size) - fsp->size = wcp->file_size = wcp->offset + wcp->data_size; + if (wcp->offset + wcp->data_size > wcp->file_size) + fsp->size = wcp->file_size = wcp->offset + wcp->data_size; - /* - * We don't need to move the start of data, but we - * cut down the amount left by the amount used. - */ + /* + * We don't need to move the start of data, but we + * cut down the amount left by the amount used. + */ - n -= data_used; + n -= data_used; - /* - * We cannot have used all the data here. - */ + /* + * We cannot have used all the data here. + */ - cache_flush_needed = True; + cache_flush_needed = True; - DO_PROFILE_INC(writecache_abutted_writes); - total_written = data_used; + DO_PROFILE_INC(writecache_abutted_writes); + total_written = data_used; - write_path = 2; + write_path = 2; - } else if ( (pos >= wcp->file_size) && - (wcp->offset + wcp->data_size == wcp->file_size) && - (pos > wcp->offset + wcp->data_size) && - (pos < wcp->offset + wcp->alloc_size) ) { + } else if ( (pos >= wcp->file_size) && + (wcp->offset + wcp->data_size == wcp->file_size) && + (pos > wcp->offset + wcp->data_size) && + (pos < wcp->offset + wcp->alloc_size) ) { - /* - * Non-contiguous write part of which fits within - * the cache buffer and is extending the file - * and the cache contents reflect the current - * data up to the current end of the file. - */ + /* + * Non-contiguous write part of which fits within + * the cache buffer and is extending the file + * and the cache contents reflect the current + * data up to the current end of the file. + */ - size_t data_used; + size_t data_used; - if(pos + n <= wcp->offset + wcp->alloc_size) - data_used = n; - else - data_used = wcp->offset + wcp->alloc_size - pos; + if(pos + n <= wcp->offset + wcp->alloc_size) + data_used = n; + else + data_used = wcp->offset + wcp->alloc_size - pos; - /* - * Fill in the non-continuous area with zeros. - */ + /* + * Fill in the non-continuous area with zeros. + */ - memset(wcp->data + wcp->data_size, '\0', - pos - (wcp->offset + wcp->data_size) ); + memset(wcp->data + wcp->data_size, '\0', + pos - (wcp->offset + wcp->data_size) ); - memcpy(wcp->data + (pos - wcp->offset), data, data_used); + memcpy(wcp->data + (pos - wcp->offset), data, data_used); - /* - * Update the current buffer size with the new data. - */ + /* + * Update the current buffer size with the new data. + */ - if(pos + data_used > wcp->offset + wcp->data_size) - wcp->data_size = pos + data_used - wcp->offset; + if(pos + data_used > wcp->offset + wcp->data_size) + wcp->data_size = pos + data_used - wcp->offset; - /* - * Update the file size if changed. - */ + /* + * Update the file size if changed. + */ - if (wcp->offset + wcp->data_size > wcp->file_size) - fsp->size = wcp->file_size = wcp->offset + wcp->data_size; + if (wcp->offset + wcp->data_size > wcp->file_size) + fsp->size = wcp->file_size = wcp->offset + wcp->data_size; - /* - * If we used all the data then - * return here. - */ + /* + * If we used all the data then + * return here. + */ - if(n == data_used) - return n; - else - cache_flush_needed = True; + if(n == data_used) + return n; + else + cache_flush_needed = True; - /* - * Move the start of data forward by the amount used, - * cut down the amount left by the same amount. - */ + /* + * Move the start of data forward by the amount used, + * cut down the amount left by the same amount. + */ - data += data_used; - pos += data_used; - n -= data_used; + data += data_used; + pos += data_used; + n -= data_used; - DO_PROFILE_INC(writecache_abutted_writes); - total_written = data_used; + DO_PROFILE_INC(writecache_abutted_writes); + total_written = data_used; - write_path = 3; + write_path = 3; - } else { + } else { - /* - * Write is bigger than buffer, or there is no overlap on the - * low or high ends. - */ + /* + * Write is bigger than buffer, or there is no overlap on the + * low or high ends. + */ - DEBUG(9,("write_file: non cacheable write : fd = %d, pos = %.0f, len = %u, current cache pos = %.0f \ + DEBUG(9,("write_file: non cacheable write : fd = %d, pos = %.0f, len = %u, current cache pos = %.0f \ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size )); - /* - * Update the file size if needed. - */ + /* + * Update the file size if needed. + */ - if(pos + n > wcp->file_size) - fsp->size = wcp->file_size = pos + n; + if(pos + n > wcp->file_size) + fsp->size = wcp->file_size = pos + n; - /* - * If write would fit in the cache, and is larger than - * the data already in the cache, flush the cache and - * preferentially copy the data new data into it. Otherwise - * just write the data directly. - */ + /* + * If write would fit in the cache, and is larger than + * the data already in the cache, flush the cache and + * preferentially copy the data new data into it. Otherwise + * just write the data directly. + */ - if ( n <= wcp->alloc_size && n > wcp->data_size) { - cache_flush_needed = True; - } else { - ssize_t ret = real_write_file(fsp, data, pos, n); + if ( n <= wcp->alloc_size && n > wcp->data_size) { + cache_flush_needed = True; + } else { + ssize_t ret = real_write_file(fsp, data, pos, n); - DO_PROFILE_INC(writecache_direct_writes); - if (ret == -1) - return ret; + DO_PROFILE_INC(writecache_direct_writes); + if (ret == -1) + return ret; - if (pos + ret > wcp->file_size) - fsp->size = wcp->file_size = pos + ret; + if (pos + ret > wcp->file_size) + fsp->size = wcp->file_size = pos + ret; - return ret; - } + return ret; + } - write_path = 4; + write_path = 4; - } + } - if(wcp->data_size > wcp->file_size) - fsp->size = wcp->file_size = wcp->data_size; + if(wcp->data_size > wcp->file_size) + fsp->size = wcp->file_size = wcp->data_size; - if (cache_flush_needed) { - DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \ + if (cache_flush_needed) { + DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", - write_path, fsp->fd, (double)wcp->file_size, (double)pos, (unsigned int)n, - (double)wcp->offset, (unsigned int)wcp->data_size )); + write_path, fsp->fd, (double)wcp->file_size, (double)pos, (unsigned int)n, + (double)wcp->offset, (unsigned int)wcp->data_size )); - flush_write_cache(fsp, WRITE_FLUSH); - } - } + flush_write_cache(fsp, WRITE_FLUSH); + } + } - /* - * If the write request is bigger than the cache - * size, write it all out. - */ + /* + * If the write request is bigger than the cache + * size, write it all out. + */ - if (n > wcp->alloc_size ) { - ssize_t ret = real_write_file(fsp, data, pos, n); - if (ret == -1) - return -1; + if (n > wcp->alloc_size ) { + ssize_t ret = real_write_file(fsp, data, pos, n); + if (ret == -1) + return -1; - if (pos + ret > wcp->file_size) - fsp->size = wcp->file_size = pos + n; + if (pos + ret > wcp->file_size) + fsp->size = wcp->file_size = pos + n; - DO_PROFILE_INC(writecache_direct_writes); - return total_written + n; - } + DO_PROFILE_INC(writecache_direct_writes); + return total_written + n; + } - /* - * If there's any data left, cache it. - */ + /* + * If there's any data left, cache it. + */ - if (n) { + if (n) { #ifdef WITH_PROFILE - if (wcp->data_size) { - DO_PROFILE_INC(writecache_abutted_writes); - } else { - DO_PROFILE_INC(writecache_init_writes); - } + if (wcp->data_size) { + DO_PROFILE_INC(writecache_abutted_writes); + } else { + DO_PROFILE_INC(writecache_init_writes); + } #endif - memcpy(wcp->data+wcp->data_size, data, n); - if (wcp->data_size == 0) { - wcp->offset = pos; - DO_PROFILE_INC(writecache_num_write_caches); - } - wcp->data_size += n; - - /* - * Update the file size if changed. - */ - - if (wcp->offset + wcp->data_size > wcp->file_size) - fsp->size = wcp->file_size = wcp->offset + wcp->data_size; - DEBUG(9,("wcp->offset = %.0f wcp->data_size = %u cache return %u\n", - (double)wcp->offset, (unsigned int)wcp->data_size, (unsigned int)n)); - - total_written += n; - return total_written; /* .... that's a write :) */ - } + memcpy(wcp->data+wcp->data_size, data, n); + if (wcp->data_size == 0) { + wcp->offset = pos; + DO_PROFILE_INC(writecache_num_write_caches); + } + wcp->data_size += n; + + /* + * Update the file size if changed. + */ + + if (wcp->offset + wcp->data_size > wcp->file_size) + fsp->size = wcp->file_size = wcp->offset + wcp->data_size; + DEBUG(9,("wcp->offset = %.0f wcp->data_size = %u cache return %u\n", + (double)wcp->offset, (unsigned int)wcp->data_size, (unsigned int)n)); + + total_written += n; + return total_written; /* .... that's a write :) */ + } - return total_written; + return total_written; } /**************************************************************************** @@ -514,24 +525,23 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", void delete_write_cache(files_struct *fsp) { - write_cache *wcp; - - if(!fsp) - return; + write_cache *wcp; - if(!(wcp = fsp->wcp)) - return; + if(!fsp) + return; - DO_PROFILE_DEC(writecache_allocated_write_caches); - allocated_write_caches--; + if(!(wcp = fsp->wcp)) + return; - SMB_ASSERT(wcp->data_size == 0); + DO_PROFILE_DEC(writecache_allocated_write_caches); + allocated_write_caches--; - SAFE_FREE(wcp->data); - SAFE_FREE(fsp->wcp); + SMB_ASSERT(wcp->data_size == 0); - DEBUG(10,("delete_write_cache: File %s deleted write cache\n", fsp->fsp_name )); + SAFE_FREE(wcp->data); + SAFE_FREE(fsp->wcp); + DEBUG(10,("delete_write_cache: File %s deleted write cache\n", fsp->fsp_name )); } /**************************************************************************** @@ -540,41 +550,41 @@ void delete_write_cache(files_struct *fsp) static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) { - ssize_t alloc_size = lp_write_cache_size(SNUM(fsp->conn)); - write_cache *wcp; - - if (allocated_write_caches >= MAX_WRITE_CACHES) - return False; - - if(alloc_size == 0 || fsp->wcp) - return False; - - if((wcp = (write_cache *)malloc(sizeof(write_cache))) == NULL) { - DEBUG(0,("setup_write_cache: malloc fail.\n")); - return False; - } - - wcp->file_size = file_size; - wcp->offset = 0; - wcp->alloc_size = alloc_size; - wcp->data_size = 0; - if((wcp->data = malloc(wcp->alloc_size)) == NULL) { - DEBUG(0,("setup_write_cache: malloc fail for buffer size %u.\n", - (unsigned int)wcp->alloc_size )); - SAFE_FREE(wcp); - return False; - } - - memset(wcp->data, '\0', wcp->alloc_size ); - - fsp->wcp = wcp; - DO_PROFILE_INC(writecache_allocated_write_caches); - allocated_write_caches++; - - DEBUG(10,("setup_write_cache: File %s allocated write cache size %u\n", + ssize_t alloc_size = lp_write_cache_size(SNUM(fsp->conn)); + write_cache *wcp; + + if (allocated_write_caches >= MAX_WRITE_CACHES) + return False; + + if(alloc_size == 0 || fsp->wcp) + return False; + + if((wcp = (write_cache *)malloc(sizeof(write_cache))) == NULL) { + DEBUG(0,("setup_write_cache: malloc fail.\n")); + return False; + } + + wcp->file_size = file_size; + wcp->offset = 0; + wcp->alloc_size = alloc_size; + wcp->data_size = 0; + if((wcp->data = malloc(wcp->alloc_size)) == NULL) { + DEBUG(0,("setup_write_cache: malloc fail for buffer size %u.\n", + (unsigned int)wcp->alloc_size )); + SAFE_FREE(wcp); + return False; + } + + memset(wcp->data, '\0', wcp->alloc_size ); + + fsp->wcp = wcp; + DO_PROFILE_INC(writecache_allocated_write_caches); + allocated_write_caches++; + + DEBUG(10,("setup_write_cache: File %s allocated write cache size %u\n", fsp->fsp_name, wcp->alloc_size )); - return True; + return True; } /**************************************************************************** @@ -583,17 +593,17 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size) { - fsp->size = file_size; - if(fsp->wcp) { - /* The cache *must* have been flushed before we do this. */ - if (fsp->wcp->data_size != 0) { - pstring msg; - slprintf(msg, sizeof(msg)-1, "set_filelen_write_cache: size change \ + fsp->size = file_size; + if(fsp->wcp) { + /* The cache *must* have been flushed before we do this. */ + if (fsp->wcp->data_size != 0) { + pstring msg; + slprintf(msg, sizeof(msg)-1, "set_filelen_write_cache: size change \ on file %s with write cache size = %u\n", fsp->fsp_name, fsp->wcp->data_size ); - smb_panic(msg); - } - fsp->wcp->file_size = file_size; - } + smb_panic(msg); + } + fsp->wcp->file_size = file_size; + } } /******************************************************************* @@ -602,36 +612,36 @@ on file %s with write cache size = %u\n", fsp->fsp_name, fsp->wcp->data_size ); ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) { - write_cache *wcp = fsp->wcp; - size_t data_size; - ssize_t ret; + write_cache *wcp = fsp->wcp; + size_t data_size; + ssize_t ret; - if(!wcp || !wcp->data_size) - return 0; + if(!wcp || !wcp->data_size) + return 0; - data_size = wcp->data_size; - wcp->data_size = 0; + data_size = wcp->data_size; + wcp->data_size = 0; - DO_PROFILE_DEC_INC(writecache_num_write_caches,writecache_flushed_writes[reason]); + DO_PROFILE_DEC_INC(writecache_num_write_caches,writecache_flushed_writes[reason]); - DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n", - fsp->fd, (double)wcp->offset, (unsigned int)data_size)); + DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n", + fsp->fd, (double)wcp->offset, (unsigned int)data_size)); #ifdef WITH_PROFILE - if(data_size == wcp->alloc_size) - DO_PROFILE_INC(writecache_num_perfect_writes); + if(data_size == wcp->alloc_size) + DO_PROFILE_INC(writecache_num_perfect_writes); #endif - ret = real_write_file(fsp, wcp->data, wcp->offset, data_size); + ret = real_write_file(fsp, wcp->data, wcp->offset, data_size); - /* - * Ensure file size if kept up to date if write extends file. - */ + /* + * Ensure file size if kept up to date if write extends file. + */ - if ((ret != -1) && (wcp->offset + ret > wcp->file_size)) - wcp->file_size = wcp->offset + ret; + if ((ret != -1) && (wcp->offset + ret > wcp->file_size)) + wcp->file_size = wcp->offset + ret; - return ret; + return ret; } /******************************************************************* @@ -640,12 +650,13 @@ sync a file void sync_file(connection_struct *conn, files_struct *fsp) { - if(lp_strict_sync(SNUM(conn)) && fsp->fd != -1) { - flush_write_cache(fsp, SYNC_FLUSH); - conn->vfs_ops.fsync(fsp,fsp->fd); - } + if(lp_strict_sync(SNUM(conn)) && fsp->fd != -1) { + flush_write_cache(fsp, SYNC_FLUSH); + conn->vfs_ops.fsync(fsp,fsp->fd); + } } + /************************************************************ Perform a stat whether a valid fd or not. ************************************************************/ -- cgit From 127e77e6e334fdc33086bffcbe00d340c0ba0097 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 15:27:10 +0000 Subject: Sync 3.0 branch with head (This used to be commit 42615b945e2e48e53a21ea47f2e45407913a6a1e) --- source3/smbd/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 710ba396d8..89f05092b4 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -163,7 +163,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) int write_path = -1; if (fsp->print_file) - return print_job_write(fsp->print_jobid, data, n); + return print_job_write(SNUM(fsp->conn), fsp->print_jobid, data, n); if (!fsp->can_write) { errno = EPERM; -- cgit From a4f7b7bec191c1603f004a14d5b8b49e99305f48 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Oct 2002 18:10:59 +0000 Subject: Write cache bugfix from Rasmus Borup Hansen, system adm. Email: rbh@math.ku.dk Jeremy. (This used to be commit d40a14dbb0ec233f7a2190df1845b039072c4b84) --- source3/smbd/fileio.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 89f05092b4..a29336d3a2 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -440,6 +440,19 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne } else { ssize_t ret = real_write_file(fsp, data, pos, n); + /* + * If the write overlaps the entire cache, then + * discard the current contents of the cache. + * Fix from Rasmus Borup Hansen rbh@math.ku.dk. + */ + + if ((pos <= wcp->offset) && + (pos + n >= wcp->offset + wcp->data_size) ) { + DEBUG(9,("write_file: discarding overwritten write \ +cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned int)wcp->data_size )); + wcp->data_size = 0; + } + DO_PROFILE_INC(writecache_direct_writes); if (ret == -1) return ret; -- cgit From 474340e4403648812e7d8eb9eeb4c4111afbf725 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Oct 2002 19:05:36 +0000 Subject: Added ASCII art to make this clearer. Jeremy. (This used to be commit 31c0dd7e213509c3bed1061f140f2ea9c6e95a9d) --- source3/smbd/fileio.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index a29336d3a2..d5df9826df 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -256,6 +256,18 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", if ((pos >= wcp->offset) && (pos <= wcp->offset + wcp->data_size)) { + /* ASCII art.... JRA. + + +--------------+----- + | Cached data | Rest of allocated cache buffer.... + +--------------+----- + + +-------------------+ + | Data to write | + +-------------------+ + + */ + /* * Start of write overlaps or abutts the existing data. */ @@ -305,6 +317,18 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", } else if ((pos < wcp->offset) && (pos + n > wcp->offset) && (pos + n <= wcp->offset + wcp->alloc_size)) { + /* ASCII art.... JRA. + + +---------------+ + | Cache buffer | + +---------------+ + + +-------------------+ + | Data to write | + +-------------------+ + + */ + /* * End of write overlaps the existing data. */ @@ -350,6 +374,20 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", (pos > wcp->offset + wcp->data_size) && (pos < wcp->offset + wcp->alloc_size) ) { + /* ASCII art.... JRA. + + End of file ---->| + + +---------------+---------------+ + | Cached data | Cache buffer | + +---------------+---------------+ + + +-------------------+ + | Data to write | + +-------------------+ + + */ + /* * Non-contiguous write part of which fits within * the cache buffer and is extending the file @@ -413,7 +451,41 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", } else { - /* + /* ASCII art..... JRA. + + Case 1). + + +---------------+---------------+ + | Cached data | Cache buffer | + +---------------+---------------+ + + +-------------------+ + | Data to write | + +-------------------+ + + Case 2). + + +---------------+---------------+ + | Cached data | Cache buffer | + +---------------+---------------+ + + +-------------------+ + | Data to write | + +-------------------+ + + Case 3). + + +---------------+---------------+ + | Cached data | Cache buffer | + +---------------+---------------+ + + +-----------------------------------------------------+ + | Data to write | + +-----------------------------------------------------+ + + */ + + /* * Write is bigger than buffer, or there is no overlap on the * low or high ends. */ -- cgit From 6ce3e3b10c30946ebe6ce25b5be0ca03e9d5617f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 21 Oct 2002 20:11:12 +0000 Subject: removed the following parameters * postscript * printer driver * printer driver location * printer driver file also removed the get_a_printer_driver_9x_compatible() function (This used to be commit 743f2b8025effe57d8f075ff14a9357123c507a8) --- source3/smbd/fileio.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index d5df9826df..6bae1df996 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -30,13 +30,9 @@ static BOOL setup_write_cache(files_struct *, SMB_OFF_T); static SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) { - SMB_OFF_T offset = 0; SMB_OFF_T seek_ret; - if (fsp->print_file && lp_postscript(fsp->conn->service)) - offset = 3; - - seek_ret = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,pos+offset,SEEK_SET); + seek_ret = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,pos,SEEK_SET); if(seek_ret == -1) { DEBUG(0,("seek_file: (%s) sys_lseek failed. Error was %s\n", @@ -45,10 +41,10 @@ static SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) return -1; } - fsp->pos = seek_ret - offset; + fsp->pos = seek_ret; DEBUG(10,("seek_file (%s): requested pos = %.0f, new pos = %.0f\n", - fsp->fsp_name, (double)(pos+offset), (double)fsp->pos )); + fsp->fsp_name, (double)pos, (double)fsp->pos )); return(fsp->pos); } -- cgit From ce4628c199f8e8ac84aa7f2afe2de1d9d23e6fab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 4 Dec 2002 03:12:09 +0000 Subject: Fix for 64 bit issues with oplocks and allocation size. Jeremy. (This used to be commit 379e719e983fb71f94cd2b691f8b194c109496c3) --- source3/smbd/fileio.c | 56 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 20 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 6bae1df996..9e37b951e5 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -172,7 +172,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); - fsp->size = st.st_size; + fsp->size = (SMB_BIG_UINT)st.st_size; if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); @@ -233,8 +233,8 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", if(!wcp) { DO_PROFILE_INC(writecache_direct_writes); total_written = real_write_file(fsp, data, pos, n); - if ((total_written != -1) && (pos + total_written > fsp->size)) - fsp->size = pos + total_written; + if ((total_written != -1) && (pos + total_written > (SMB_OFF_T)fsp->size)) + fsp->size = (SMB_BIG_UINT)(pos + total_written); return total_written; } @@ -283,8 +283,10 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", * Update the file size if changed. */ - if (wcp->offset + wcp->data_size > wcp->file_size) - fsp->size = wcp->file_size = wcp->offset + wcp->data_size; + if (wcp->offset + wcp->data_size > wcp->file_size) { + wcp->file_size = wcp->offset + wcp->data_size; + fsp->size = (SMB_BIG_UINT)wcp->file_size; + } /* * If we used all the data then @@ -344,8 +346,10 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", * Update the file size if changed. */ - if (wcp->offset + wcp->data_size > wcp->file_size) - fsp->size = wcp->file_size = wcp->offset + wcp->data_size; + if (wcp->offset + wcp->data_size > wcp->file_size) { + wcp->file_size = wcp->offset + wcp->data_size; + fsp->size = (SMB_BIG_UINT)wcp->file_size; + } /* * We don't need to move the start of data, but we @@ -418,8 +422,10 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", * Update the file size if changed. */ - if (wcp->offset + wcp->data_size > wcp->file_size) - fsp->size = wcp->file_size = wcp->offset + wcp->data_size; + if (wcp->offset + wcp->data_size > wcp->file_size) { + wcp->file_size = wcp->offset + wcp->data_size; + fsp->size = (SMB_BIG_UINT)wcp->file_size; + } /* * If we used all the data then @@ -493,8 +499,10 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne * Update the file size if needed. */ - if(pos + n > wcp->file_size) - fsp->size = wcp->file_size = pos + n; + if(pos + n > wcp->file_size) { + wcp->file_size = pos + n; + fsp->size = (SMB_BIG_UINT)wcp->file_size; + } /* * If write would fit in the cache, and is larger than @@ -525,8 +533,10 @@ cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned in if (ret == -1) return ret; - if (pos + ret > wcp->file_size) - fsp->size = wcp->file_size = pos + ret; + if (pos + ret > wcp->file_size) { + wcp->file_size = pos + ret; + fsp->size = (SMB_BIG_UINT)wcp->file_size; + } return ret; } @@ -535,8 +545,10 @@ cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned in } - if(wcp->data_size > wcp->file_size) - fsp->size = wcp->file_size = wcp->data_size; + if(wcp->data_size > wcp->file_size) { + wcp->file_size = wcp->data_size; + fsp->size = (SMB_BIG_UINT)wcp->file_size; + } if (cache_flush_needed) { DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \ @@ -558,8 +570,10 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", if (ret == -1) return -1; - if (pos + ret > wcp->file_size) - fsp->size = wcp->file_size = pos + n; + if (pos + ret > wcp->file_size) { + wcp->file_size = pos + n; + fsp->size = (SMB_BIG_UINT)wcp->file_size; + } DO_PROFILE_INC(writecache_direct_writes); return total_written + n; @@ -588,8 +602,10 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", * Update the file size if changed. */ - if (wcp->offset + wcp->data_size > wcp->file_size) - fsp->size = wcp->file_size = wcp->offset + wcp->data_size; + if (wcp->offset + wcp->data_size > wcp->file_size) { + wcp->file_size = wcp->offset + wcp->data_size; + fsp->size = (SMB_BIG_UINT)wcp->file_size; + } DEBUG(9,("wcp->offset = %.0f wcp->data_size = %u cache return %u\n", (double)wcp->offset, (unsigned int)wcp->data_size, (unsigned int)n)); @@ -674,7 +690,7 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size) { - fsp->size = file_size; + fsp->size = (SMB_BIG_UINT)file_size; if(fsp->wcp) { /* The cache *must* have been flushed before we do this. */ if (fsp->wcp->data_size != 0) { -- cgit From 00a20ce45f11e62470e60a8d5fcacc6b0b1f90a2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 5 Dec 2002 04:00:16 +0000 Subject: The element in fsp->print_job should be a RAP jobid, not a uint32 RPC jobid. This was causing Win9x client "set name" calls to fail. Still need one cleanup fix to finish. Jeremy. (This used to be commit 6c23d2030ab8dddff4c849903c529f0012b94027) --- source3/smbd/fileio.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 9e37b951e5..b612b1a451 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -158,8 +158,19 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) ssize_t total_written = 0; int write_path = -1; - if (fsp->print_file) - return print_job_write(SNUM(fsp->conn), fsp->print_jobid, data, n); + if (fsp->print_file) { + int snum; + uint32 jobid; + + if (!rap_to_pjobid(fsp->rap_print_jobid, &snum, &jobid)) { + DEBUG(3,("write_file: Unable to map RAP jobid %u to jobid.\n", + (unsigned int)fsp->rap_print_jobid )); + errno = EBADF; + return -1; + } + + return print_job_write(SNUM(fsp->conn), jobid, data, n); + } if (!fsp->can_write) { errno = EPERM; -- cgit From e7c8c15888454043c73967635deb4d3419a489e9 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Sun, 11 May 2003 23:34:18 +0000 Subject: Fix VFS layer: 1. Finally work with cascaded modules with private data storage per module 2. Convert VFS API to macro calls to simplify cascading 3. Add quota support to VFS layer (prepare to NT quota support) Patch by Stefan (metze) Metzemacher, with review of Jelmer and me Tested in past few weeks. Documentation to new VFS API for third-party developers to follow (This used to be commit 91984ef5caa2d13c5d52e1f535bd3bbbae1ec978) --- source3/smbd/fileio.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index b612b1a451..5021f54fb4 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -32,7 +32,7 @@ static SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) { SMB_OFF_T seek_ret; - seek_ret = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,pos,SEEK_SET); + seek_ret = VFS_LSEEK(fsp,fsp->fd,pos,SEEK_SET); if(seek_ret == -1) { DEBUG(0,("seek_file: (%s) sys_lseek failed. Error was %s\n", @@ -101,7 +101,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) #ifdef DMF_FIX int numretries = 3; tryagain: - readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n); + readret = VFS_READ(fsp,fsp->fd,data,n); if (readret == -1) { if ((errno == EAGAIN) && numretries) { DEBUG(3,("read_file EAGAIN retry in 10 seconds\n")); @@ -112,7 +112,7 @@ tryagain: return -1; } #else /* NO DMF fix. */ - readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n); + readret = VFS_READ(fsp,fsp->fd,data,n); if (readret == -1) return -1; #endif @@ -181,7 +181,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) SMB_STRUCT_STAT st; fsp->modified = True; - if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&st) == 0) { + if (VFS_FSTAT(fsp,fsp->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); fsp->size = (SMB_BIG_UINT)st.st_size; if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) @@ -760,7 +760,7 @@ void sync_file(connection_struct *conn, files_struct *fsp) { if(lp_strict_sync(SNUM(conn)) && fsp->fd != -1) { flush_write_cache(fsp, SYNC_FLUSH); - conn->vfs_ops.fsync(fsp,fsp->fd); + VFS_FSYNC(fsp,fsp->fd); } } @@ -772,7 +772,7 @@ void sync_file(connection_struct *conn, files_struct *fsp) int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst) { if (fsp->fd == -1) - return vfs_stat(fsp->conn, fsp->fsp_name, pst); + return VFS_STAT(fsp->conn, fsp->fsp_name, pst); else - return vfs_fstat(fsp,fsp->fd, pst); + return VFS_FSTAT(fsp,fsp->fd, pst); } -- cgit From bc2a3748e9caa8f60f7c2387e7eecd7fb3fae899 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 14 May 2003 10:59:01 +0000 Subject: Prefix VFS API macros with SMB_ for consistency and to avoid problems with VFS_ macros at system side. We currently have one clash with AIX and its VFS_LOCK. Compiled and tested -- no new functionality or code, just plain rename of macros for yet-unreleased VFS API version. Needs to be done before a24 is out (This used to be commit c2689ed118b490e49497a76ed6a2251262018769) --- source3/smbd/fileio.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 5021f54fb4..6be5f6af7d 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -32,7 +32,7 @@ static SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) { SMB_OFF_T seek_ret; - seek_ret = VFS_LSEEK(fsp,fsp->fd,pos,SEEK_SET); + seek_ret = SMB_VFS_LSEEK(fsp,fsp->fd,pos,SEEK_SET); if(seek_ret == -1) { DEBUG(0,("seek_file: (%s) sys_lseek failed. Error was %s\n", @@ -101,7 +101,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) #ifdef DMF_FIX int numretries = 3; tryagain: - readret = VFS_READ(fsp,fsp->fd,data,n); + readret = SMB_VFS_READ(fsp,fsp->fd,data,n); if (readret == -1) { if ((errno == EAGAIN) && numretries) { DEBUG(3,("read_file EAGAIN retry in 10 seconds\n")); @@ -112,7 +112,7 @@ tryagain: return -1; } #else /* NO DMF fix. */ - readret = VFS_READ(fsp,fsp->fd,data,n); + readret = SMB_VFS_READ(fsp,fsp->fd,data,n); if (readret == -1) return -1; #endif @@ -181,7 +181,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) SMB_STRUCT_STAT st; fsp->modified = True; - if (VFS_FSTAT(fsp,fsp->fd,&st) == 0) { + if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); fsp->size = (SMB_BIG_UINT)st.st_size; if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) @@ -760,7 +760,7 @@ void sync_file(connection_struct *conn, files_struct *fsp) { if(lp_strict_sync(SNUM(conn)) && fsp->fd != -1) { flush_write_cache(fsp, SYNC_FLUSH); - VFS_FSYNC(fsp,fsp->fd); + SMB_VFS_FSYNC(fsp,fsp->fd); } } @@ -772,7 +772,7 @@ void sync_file(connection_struct *conn, files_struct *fsp) int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst) { if (fsp->fd == -1) - return VFS_STAT(fsp->conn, fsp->fsp_name, pst); + return SMB_VFS_STAT(fsp->conn, fsp->fsp_name, pst); else - return VFS_FSTAT(fsp,fsp->fd, pst); + return SMB_VFS_FSTAT(fsp,fsp->fd, pst); } -- cgit From 4e8b36a5749f4801022617b8fec1fe5d48529fef Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 14 Aug 2003 21:16:06 +0000 Subject: Fix SMBseek and get/set position information SMBs. Works against Samba4 tester. You will need a make clean; make all after this ! Jeremy. (This used to be commit 10d90171ed58bee3e5ab6476341059b585034134) --- source3/smbd/fileio.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 6be5f6af7d..6cf7014846 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -87,8 +87,11 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) * Serve from write cache if we can. */ - if(read_from_write_cache(fsp, data, pos, n)) + if(read_from_write_cache(fsp, data, pos, n)) { + fsp->pos = pos + n; + fsp->position_information = fsp->pos; return n; + } flush_write_cache(fsp, READ_FLUSH); @@ -123,6 +126,9 @@ tryagain: DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n", fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret )); + fsp->pos += ret; + fsp->position_information = fsp->pos; + return(ret); } @@ -145,6 +151,16 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_ DEBUG(10,("real_write_file (%s): pos = %.0f, size = %lu, returned %ld\n", fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret )); + if (ret != -1) { + fsp->pos += ret; + +/* Yes - this is correct - writes don't update this. JRA. */ +/* Found by Samba4 tests. */ +#if 0 + fsp->position_information = fsp->pos; +#endif + } + return ret; } @@ -244,7 +260,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", if(!wcp) { DO_PROFILE_INC(writecache_direct_writes); total_written = real_write_file(fsp, data, pos, n); - if ((total_written != -1) && (pos + total_written > (SMB_OFF_T)fsp->size)) + if ((total_written != -1) && (pos + total_written > (SMB_OFF_T)fsp->size)) fsp->size = (SMB_BIG_UINT)(pos + total_written); return total_written; } @@ -252,6 +268,8 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n", fsp->fsp_name, fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size)); + fsp->pos = pos + n; + /* * If we have active cache and it isn't contiguous then we flush. * NOTE: There is a small problem with running out of disk .... -- cgit From c8e84154af5027f1c20329597851d451764f4869 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 2 Nov 2003 17:10:12 +0000 Subject: Printf fixes for 64-bit size_t. (This used to be commit 8e2c543ebf65e24e73433f69b1c281e1558e9080) --- source3/smbd/fileio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 6cf7014846..84339c3a6f 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -707,8 +707,8 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) DO_PROFILE_INC(writecache_allocated_write_caches); allocated_write_caches++; - DEBUG(10,("setup_write_cache: File %s allocated write cache size %u\n", - fsp->fsp_name, wcp->alloc_size )); + DEBUG(10,("setup_write_cache: File %s allocated write cache size %lu\n", + fsp->fsp_name, (unsigned long)wcp->alloc_size )); return True; } @@ -725,7 +725,7 @@ void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size) if (fsp->wcp->data_size != 0) { pstring msg; slprintf(msg, sizeof(msg)-1, "set_filelen_write_cache: size change \ -on file %s with write cache size = %u\n", fsp->fsp_name, fsp->wcp->data_size ); +on file %s with write cache size = %lu\n", fsp->fsp_name, (unsigned long)fsp->wcp->data_size ); smb_panic(msg); } fsp->wcp->file_size = file_size; -- cgit From 0d44747df99f2168a063feedad5039f222746f61 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Jan 2004 01:22:14 +0000 Subject: Patch based on work from James Peach to convert over to using pread/pwrite. Modified a little to ensure fsp->pos is correct. Fix for #889. Jeremy. (This used to be commit 019aaaf0df091c3f67048f591e70d4353a02bb9b) --- source3/smbd/fileio.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 84339c3a6f..f395954d05 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -95,16 +95,14 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) flush_write_cache(fsp, READ_FLUSH); - if (seek_file(fsp,pos) == -1) { - DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos)); - return(ret); - } - + fsp->pos = pos; + if (n > 0) { #ifdef DMF_FIX int numretries = 3; tryagain: - readret = SMB_VFS_READ(fsp,fsp->fd,data,n); + readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos); + if (readret == -1) { if ((errno == EAGAIN) && numretries) { DEBUG(3,("read_file EAGAIN retry in 10 seconds\n")); @@ -115,7 +113,8 @@ tryagain: return -1; } #else /* NO DMF fix. */ - readret = SMB_VFS_READ(fsp,fsp->fd,data,n); + readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos); + if (readret == -1) return -1; #endif @@ -143,10 +142,12 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_ { ssize_t ret; - if ((pos != -1) && (seek_file(fsp,pos) == -1)) - return -1; - - ret = vfs_write_data(fsp,data,n); + if (pos == -1) + ret = vfs_write_data(fsp, data, n); + else { + fsp->pos = pos; + ret = vfs_pwrite_data(fsp, data, n, pos); + } DEBUG(10,("real_write_file (%s): pos = %.0f, size = %lu, returned %ld\n", fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret )); -- cgit From d86628d0628a064f58e3ce9fbaf55ad9d5a92540 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 6 Jan 2004 19:57:14 +0000 Subject: remove unused seek_file(); don't hardcode '\' when printing the auth-user (This used to be commit fac5e05ca1b56cb6e3ab6537d0848fa373c00831) --- source3/smbd/fileio.c | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index f395954d05..3462a3b9fa 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -24,31 +24,6 @@ static BOOL setup_write_cache(files_struct *, SMB_OFF_T); -/**************************************************************************** - Seek a file. Try to avoid the seek if possible. -****************************************************************************/ - -static SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos) -{ - SMB_OFF_T seek_ret; - - seek_ret = SMB_VFS_LSEEK(fsp,fsp->fd,pos,SEEK_SET); - - if(seek_ret == -1) { - DEBUG(0,("seek_file: (%s) sys_lseek failed. Error was %s\n", - fsp->fsp_name, strerror(errno) )); - fsp->pos = -1; - return -1; - } - - fsp->pos = seek_ret; - - DEBUG(10,("seek_file (%s): requested pos = %.0f, new pos = %.0f\n", - fsp->fsp_name, (double)pos, (double)fsp->pos )); - - return(fsp->pos); -} - /**************************************************************************** Read from write cache if we can. ****************************************************************************/ -- cgit From 722aa118c66b020c2b9f2b595e1af50429f13986 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Apr 2004 18:46:19 +0000 Subject: Added per-share parameter "store dos attributes". When set, will store dos attributes in an EA. Based on an original patch from tridge, but modified somewhat to cover all cases. Jeremy. (This used to be commit ed653cd468213e0be901bc654aa3748ce5837947) --- source3/smbd/fileio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 3462a3b9fa..c2fb6e3456 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -176,8 +176,9 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); fsp->size = (SMB_BIG_UINT)st.st_size; - if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) - file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); + if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) { + file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); + } /* * If this is the first write and we have an exclusive oplock then setup -- cgit From 293136c04b7eb5293ef18273e13fca00c85bb5f0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 19 Oct 2004 17:05:01 +0000 Subject: r3067: patch based on volker's initial work in trunk that fixes the queu update problem when using the background daemon (This used to be commit de7af09e727e744aa27af85ef7c0f73ed5c1550a) --- source3/smbd/fileio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index c2fb6e3456..b9fe1ad1cf 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -151,10 +151,10 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) int write_path = -1; if (fsp->print_file) { - int snum; + fstring sharename; uint32 jobid; - if (!rap_to_pjobid(fsp->rap_print_jobid, &snum, &jobid)) { + if (!rap_to_pjobid(fsp->rap_print_jobid, sharename, &jobid)) { DEBUG(3,("write_file: Unable to map RAP jobid %u to jobid.\n", (unsigned int)fsp->rap_print_jobid )); errno = EBADF; -- cgit From 9038a56f82e1352c9d7956af08b70a0b8d3cc773 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 20 Nov 2004 21:24:52 +0000 Subject: r3895: Fix for bug #2045. May also fix other timestamp bugs with Excel (Volker please test). Setting a last write timestamp from Windows overrides any subsequent write timestamp changes and must be immediately seen by and findfirst/findnexts. This is a racy solution, but should work most of the time. This may also fix #1061, not sure. Jeremy. (This used to be commit 47bab92c0b062f3fefbb4fd4a09852e1c829a7f9) --- source3/smbd/fileio.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index b9fe1ad1cf..dde254644f 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -130,6 +130,20 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_ if (ret != -1) { fsp->pos += ret; + /* + * It turns out that setting the last write time from a Windows + * client stops any subsequent writes from updating the write time. + * Doing this after the write gives a race condition here where + * a stat may see the changed write time before we reset it here, + * but it's cheaper than having to store the write time in shared + * memory and look it up using dev/inode across all running smbd's. + * The 99% solution will hopefully be good enough in this case. JRA. + */ + + if (fsp->pending_modtime) { + set_filetime(fsp->conn, fsp->fsp_name, fsp->pending_modtime); + } + /* Yes - this is correct - writes don't update this. JRA. */ /* Found by Samba4 tests. */ #if 0 -- cgit From 46f546571bc2429c4ee6ef86866520c4b5d4bcc7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Nov 2004 00:22:04 +0000 Subject: r4007: Fix bug #2088 - ensure inherit permissions is only applied on a new file, not an existing one. Jeremy. (This used to be commit fbbdb72cf1adfe567112556626f26b031747f440) --- source3/smbd/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index dde254644f..060fbb124d 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -191,7 +191,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); fsp->size = (SMB_BIG_UINT)st.st_size; if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) { - file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); + file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st, False); } /* -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/smbd/fileio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 060fbb124d..a21bd69a36 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -676,7 +676,7 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) if(alloc_size == 0 || fsp->wcp) return False; - if((wcp = (write_cache *)malloc(sizeof(write_cache))) == NULL) { + if((wcp = SMB_MALLOC_P(write_cache)) == NULL) { DEBUG(0,("setup_write_cache: malloc fail.\n")); return False; } @@ -685,7 +685,7 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) wcp->offset = 0; wcp->alloc_size = alloc_size; wcp->data_size = 0; - if((wcp->data = malloc(wcp->alloc_size)) == NULL) { + if((wcp->data = SMB_MALLOC(wcp->alloc_size)) == NULL) { DEBUG(0,("setup_write_cache: malloc fail for buffer size %u.\n", (unsigned int)wcp->alloc_size )); SAFE_FREE(wcp); -- cgit From 95e68fa7f8c109204b3ddaeb530e192c71b40e58 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 10 Mar 2005 21:43:58 +0000 Subject: r5731: Get delayed write semantics closer to W2K3. We need to store 2 times. This may fix bug #2382. Jeremy. (This used to be commit a27c351e6beafc6609790a9bb9a3d0a1331e8f35) --- source3/smbd/fileio.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index a21bd69a36..3048c27fa2 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -142,6 +142,12 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_ if (fsp->pending_modtime) { set_filetime(fsp->conn, fsp->fsp_name, fsp->pending_modtime); + + /* If we didn't get the "set modtime" call ourselves, we must + store the last write time to restore on close. JRA. */ + if (!fsp->pending_modtime_owner) { + fsp->last_write_time = time(NULL); + } } /* Yes - this is correct - writes don't update this. JRA. */ -- cgit From 08355754151b2d02b2102bc76e94b63ffffdf408 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 8 May 2005 23:16:28 +0000 Subject: r6673: Fix the write cache based on some VERY good detective work from Ingo Kilian . You must do a make clean after updating this. Jeremy. (This used to be commit 3b2cd19fcb8ce38578b122fd6ae722b73081dcda) --- source3/smbd/fileio.c | 139 +++++++++++++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 59 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 3048c27fa2..dbf1e5a789 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -28,16 +28,17 @@ static BOOL setup_write_cache(files_struct *, SMB_OFF_T); Read from write cache if we can. ****************************************************************************/ - static BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) { write_cache *wcp = fsp->wcp; - if(!wcp) + if(!wcp) { return False; + } - if(n > wcp->data_size || pos < wcp->offset || pos + n > wcp->offset + wcp->data_size) + if( n > wcp->data_size || pos < wcp->offset || pos + n > wcp->offset + wcp->data_size) { return False; + } memcpy(data, wcp->data + (pos - wcp->offset), n); @@ -55,8 +56,9 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) ssize_t ret=0,readret; /* you can't read from print files */ - if (fsp->print_file) + if (fsp->print_file) { return -1; + } /* * Serve from write cache if we can. @@ -90,11 +92,13 @@ tryagain: #else /* NO DMF fix. */ readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos); - if (readret == -1) + if (readret == -1) { return -1; + } #endif - if (readret > 0) + if (readret > 0) { ret += readret; + } } DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n", @@ -117,9 +121,9 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_ { ssize_t ret; - if (pos == -1) + if (pos == -1) { ret = vfs_write_data(fsp, data, n); - else { + } else { fsp->pos = pos; ret = vfs_pwrite_data(fsp, data, n, pos); } @@ -161,7 +165,26 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_ } /**************************************************************************** -write to a file + File size cache change. + Updates size on disk but doesn't flush the cache. +****************************************************************************/ + +static int wcp_file_size_change(files_struct *fsp) +{ + int ret; + write_cache *wcp = fsp->wcp; + + wcp->file_size = wcp->offset + wcp->data_size; + ret = SMB_VFS_FTRUNCATE(fsp, fsp->fd, wcp->file_size); + if (ret == -1) { + DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f error %s\n", + fsp->fsp_name, (double)wcp->file_size, strerror(errno) )); + } + return ret; +} + +/**************************************************************************** + Write to a file. ****************************************************************************/ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) @@ -195,7 +218,6 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); - fsp->size = (SMB_BIG_UINT)st.st_size; if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) { file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st, False); } @@ -257,8 +279,6 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", if(!wcp) { DO_PROFILE_INC(writecache_direct_writes); total_written = real_write_file(fsp, data, pos, n); - if ((total_written != -1) && (pos + total_written > (SMB_OFF_T)fsp->size)) - fsp->size = (SMB_BIG_UINT)(pos + total_written); return total_written; } @@ -273,7 +293,6 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", */ if (wcp->data_size) { - BOOL cache_flush_needed = False; if ((pos >= wcp->offset) && (pos <= wcp->offset + wcp->data_size)) { @@ -302,16 +321,18 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", * Update the current buffer size with the new data. */ - if(pos + data_used > wcp->offset + wcp->data_size) + if(pos + data_used > wcp->offset + wcp->data_size) { wcp->data_size = pos + data_used - wcp->offset; + } /* * Update the file size if changed. */ if (wcp->offset + wcp->data_size > wcp->file_size) { - wcp->file_size = wcp->offset + wcp->data_size; - fsp->size = (SMB_BIG_UINT)wcp->file_size; + if (wcp_file_size_change(fsp) == -1) { + return -1; + } } /* @@ -319,11 +340,11 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", * return here. */ - if(n == data_used) + if(n == data_used) { return n; - else + } else { cache_flush_needed = True; - + } /* * Move the start of data forward by the amount used, * cut down the amount left by the same amount. @@ -365,16 +386,18 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", * Update the current buffer size with the new data. */ - if(pos + n > wcp->offset + wcp->data_size) + if(pos + n > wcp->offset + wcp->data_size) { wcp->data_size = pos + n - wcp->offset; + } /* * Update the file size if changed. */ if (wcp->offset + wcp->data_size > wcp->file_size) { - wcp->file_size = wcp->offset + wcp->data_size; - fsp->size = (SMB_BIG_UINT)wcp->file_size; + if (wcp_file_size_change(fsp) == -1) { + return -1; + } } /* @@ -423,10 +446,11 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", size_t data_used; - if(pos + n <= wcp->offset + wcp->alloc_size) + if(pos + n <= wcp->offset + wcp->alloc_size) { data_used = n; - else + } else { data_used = wcp->offset + wcp->alloc_size - pos; + } /* * Fill in the non-continuous area with zeros. @@ -441,16 +465,18 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", * Update the current buffer size with the new data. */ - if(pos + data_used > wcp->offset + wcp->data_size) + if(pos + data_used > wcp->offset + wcp->data_size) { wcp->data_size = pos + data_used - wcp->offset; + } /* * Update the file size if changed. */ if (wcp->offset + wcp->data_size > wcp->file_size) { - wcp->file_size = wcp->offset + wcp->data_size; - fsp->size = (SMB_BIG_UINT)wcp->file_size; + if (wcp_file_size_change(fsp) == -1) { + return -1; + } } /* @@ -458,10 +484,11 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", * return here. */ - if(n == data_used) + if(n == data_used) { return n; - else + } else { cache_flush_needed = True; + } /* * Move the start of data forward by the amount used, @@ -521,15 +548,6 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", DEBUG(9,("write_file: non cacheable write : fd = %d, pos = %.0f, len = %u, current cache pos = %.0f \ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size )); - /* - * Update the file size if needed. - */ - - if(pos + n > wcp->file_size) { - wcp->file_size = pos + n; - fsp->size = (SMB_BIG_UINT)wcp->file_size; - } - /* * If write would fit in the cache, and is larger than * the data already in the cache, flush the cache and @@ -556,12 +574,12 @@ cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned in } DO_PROFILE_INC(writecache_direct_writes); - if (ret == -1) + if (ret == -1) { return ret; + } if (pos + ret > wcp->file_size) { wcp->file_size = pos + ret; - fsp->size = (SMB_BIG_UINT)wcp->file_size; } return ret; @@ -571,11 +589,6 @@ cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned in } - if(wcp->data_size > wcp->file_size) { - wcp->file_size = wcp->data_size; - fsp->size = (SMB_BIG_UINT)wcp->file_size; - } - if (cache_flush_needed) { DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", @@ -593,12 +606,12 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", if (n > wcp->alloc_size ) { ssize_t ret = real_write_file(fsp, data, pos, n); - if (ret == -1) + if (ret == -1) { return -1; + } if (pos + ret > wcp->file_size) { wcp->file_size = pos + n; - fsp->size = (SMB_BIG_UINT)wcp->file_size; } DO_PROFILE_INC(writecache_direct_writes); @@ -629,8 +642,9 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", */ if (wcp->offset + wcp->data_size > wcp->file_size) { - wcp->file_size = wcp->offset + wcp->data_size; - fsp->size = (SMB_BIG_UINT)wcp->file_size; + if (wcp_file_size_change(fsp) == -1) { + return -1; + } } DEBUG(9,("wcp->offset = %.0f wcp->data_size = %u cache return %u\n", (double)wcp->offset, (unsigned int)wcp->data_size, (unsigned int)n)); @@ -650,11 +664,13 @@ void delete_write_cache(files_struct *fsp) { write_cache *wcp; - if(!fsp) + if(!fsp) { return; + } - if(!(wcp = fsp->wcp)) + if(!(wcp = fsp->wcp)) { return; + } DO_PROFILE_DEC(writecache_allocated_write_caches); allocated_write_caches--; @@ -676,11 +692,13 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) ssize_t alloc_size = lp_write_cache_size(SNUM(fsp->conn)); write_cache *wcp; - if (allocated_write_caches >= MAX_WRITE_CACHES) + if (allocated_write_caches >= MAX_WRITE_CACHES) { return False; + } - if(alloc_size == 0 || fsp->wcp) + if(alloc_size == 0 || fsp->wcp) { return False; + } if((wcp = SMB_MALLOC_P(write_cache)) == NULL) { DEBUG(0,("setup_write_cache: malloc fail.\n")); @@ -716,7 +734,6 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size) { - fsp->size = (SMB_BIG_UINT)file_size; if(fsp->wcp) { /* The cache *must* have been flushed before we do this. */ if (fsp->wcp->data_size != 0) { @@ -739,8 +756,9 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) size_t data_size; ssize_t ret; - if(!wcp || !wcp->data_size) + if(!wcp || !wcp->data_size) { return 0; + } data_size = wcp->data_size; wcp->data_size = 0; @@ -751,8 +769,9 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) fsp->fd, (double)wcp->offset, (unsigned int)data_size)); #ifdef WITH_PROFILE - if(data_size == wcp->alloc_size) + if(data_size == wcp->alloc_size) { DO_PROFILE_INC(writecache_num_perfect_writes); + } #endif ret = real_write_file(fsp, wcp->data, wcp->offset, data_size); @@ -761,8 +780,9 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) * Ensure file size if kept up to date if write extends file. */ - if ((ret != -1) && (wcp->offset + ret > wcp->file_size)) + if ((ret != -1) && (wcp->offset + ret > wcp->file_size)) { wcp->file_size = wcp->offset + ret; + } return ret; } @@ -786,8 +806,9 @@ void sync_file(connection_struct *conn, files_struct *fsp) int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst) { - if (fsp->fd == -1) + if (fsp->fd == -1) { return SMB_VFS_STAT(fsp->conn, fsp->fsp_name, pst); - else + } else { return SMB_VFS_FSTAT(fsp,fsp->fd, pst); + } } -- cgit From 8a1756006a1abf8ceb22fff889c94b3d28d19c20 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 17 May 2005 01:04:51 +0000 Subject: 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 used to be commit 858824f37be443320487a8e28ec8fa172cdf5a18) --- source3/smbd/fileio.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index dbf1e5a789..977988fde4 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -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); } -- cgit From fe0ce8dd8e18de6110404661f26db7a66ebac5ad Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 18 May 2005 18:02:15 +0000 Subject: r6890: Refactor printing interface to take offset into job. Fixes bug where large print jobs can have out-of-order offsets. Bug found by Arcady Chernyak Jeremy. (This used to be commit 482f7e0e3706098b71aa0b31a134994acb1e9fcf) --- source3/smbd/fileio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 977988fde4..9b39bf8fe1 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -117,7 +117,7 @@ static unsigned int allocated_write_caches; *Really* write to a file. ****************************************************************************/ -static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_t n) +static ssize_t real_write_file(files_struct *fsp,const char *data, SMB_OFF_T pos, size_t n) { ssize_t ret; @@ -192,7 +192,7 @@ static int wcp_file_size_change(files_struct *fsp) Write to a file. ****************************************************************************/ -ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) +ssize_t write_file(files_struct *fsp, const char *data, SMB_OFF_T pos, size_t n) { write_cache *wcp = fsp->wcp; ssize_t total_written = 0; @@ -209,7 +209,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) return -1; } - return print_job_write(SNUM(fsp->conn), jobid, data, n); + return print_job_write(SNUM(fsp->conn), jobid, data, pos, n); } if (!fsp->can_write) { -- cgit From 0ef417d9583154a261ae8c4b01f23c29a9110ca1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 May 2005 04:55:18 +0000 Subject: r6949: Back-port Volker's cache fix, plus my change. Jeremy. (This used to be commit 27d43f6d36b3f6abc368ec6a00ef9803cb27c324) --- source3/smbd/fileio.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 9b39bf8fe1..69b8b57642 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -509,6 +509,44 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", write_path = 3; + } else if ( (pos >= wcp->file_size) && + (n == 1) && + (pos < wcp->offset + 2*wcp->alloc_size) && + (wcp->file_size == wcp->offset + wcp->data_size)) { + + /* + +---------------+ + | Cached data | + +---------------+ + + +--------+ + | 1 Byte | + +--------+ + + MS-Office seems to do this a lot to determine if there's enough + space on the filesystem to write a new file. + */ + + SMB_BIG_UINT new_start = wcp->offset + wcp->data_size; + + flush_write_cache(fsp, WRITE_FLUSH); + wcp->offset = new_start; + wcp->data_size = pos - new_start + 1; + memset(wcp->data, '\0', wcp->data_size); + memcpy(wcp->data + wcp->data_size-1, data, 1); + + /* + * Update the file size if changed. + */ + + if (wcp->offset + wcp->data_size > wcp->file_size) { + if (wcp_file_size_change(fsp) == -1) { + return -1; + } + } + + return n; + } else { /* ASCII art..... JRA. -- cgit From 19ca97a70f6b7b41d251eaa76e4d3c980c6eedff Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 24 Jun 2005 20:25:18 +0000 Subject: r7882: Looks like a large patch - but what it actually does is make Samba safe for using our headers and linking with C++ modules. Stops us from using C++ reserved keywords in our code. Jeremy (This used to be commit 9506b8e145982b1160a2f0aee5c9b7a54980940a) --- source3/smbd/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 69b8b57642..ba0766c298 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -752,7 +752,7 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) wcp->offset = 0; wcp->alloc_size = alloc_size; wcp->data_size = 0; - if((wcp->data = SMB_MALLOC(wcp->alloc_size)) == NULL) { + if((wcp->data = (char *)SMB_MALLOC(wcp->alloc_size)) == NULL) { DEBUG(0,("setup_write_cache: malloc fail for buffer size %u.\n", (unsigned int)wcp->alloc_size )); SAFE_FREE(wcp); -- cgit From af8a691db11a5072865f8b03fd1cbd3aab5cb6d7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Jul 2005 04:51:27 +0000 Subject: r8219: Merge the new open code from HEAD to 3.0. Haven't yet run the torture tests on this as it's very late NY time (just wanted to get this work into the tree). I'll test this over the weekend.... Jerry - in looking at the difference between the two trees there seem to be some printing/ntprinting.c and registry changes we might want to examine to try keep in sync. Jeremy. (This used to be commit c7fe18761e2c753afbffd3a78abff46472a9b8eb) --- source3/smbd/fileio.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index ba0766c298..76189d114b 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -65,20 +65,20 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) */ if(read_from_write_cache(fsp, data, pos, n)) { - fsp->pos = pos + n; - fsp->position_information = fsp->pos; + fsp->fh->pos = pos + n; + fsp->fh->position_information = fsp->fh->pos; return n; } flush_write_cache(fsp, READ_FLUSH); - fsp->pos = pos; + fsp->fh->pos = pos; if (n > 0) { #ifdef DMF_FIX int numretries = 3; tryagain: - readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos); + readret = SMB_VFS_PREAD(fsp,fsp->fh->fd,data,n,pos); if (readret == -1) { if ((errno == EAGAIN) && numretries) { @@ -90,7 +90,7 @@ tryagain: return -1; } #else /* NO DMF fix. */ - readret = SMB_VFS_PREAD(fsp,fsp->fd,data,n,pos); + readret = SMB_VFS_PREAD(fsp,fsp->fh->fd,data,n,pos); if (readret == -1) { return -1; @@ -104,8 +104,8 @@ tryagain: DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n", fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret )); - fsp->pos += ret; - fsp->position_information = fsp->pos; + fsp->fh->pos += ret; + fsp->fh->position_information = fsp->fh->pos; return(ret); } @@ -124,7 +124,7 @@ static ssize_t real_write_file(files_struct *fsp,const char *data, SMB_OFF_T pos if (pos == -1) { ret = vfs_write_data(fsp, data, n); } else { - fsp->pos = pos; + fsp->fh->pos = pos; if (pos && lp_strict_allocate(SNUM(fsp->conn))) { if (vfs_fill_sparse(fsp, pos) == -1) { return -1; @@ -137,7 +137,7 @@ static ssize_t real_write_file(files_struct *fsp,const char *data, SMB_OFF_T pos fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret )); if (ret != -1) { - fsp->pos += ret; + fsp->fh->pos += ret; /* * It turns out that setting the last write time from a Windows @@ -180,7 +180,7 @@ static int wcp_file_size_change(files_struct *fsp) write_cache *wcp = fsp->wcp; wcp->file_size = wcp->offset + wcp->data_size; - ret = SMB_VFS_FTRUNCATE(fsp, fsp->fd, wcp->file_size); + ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, wcp->file_size); if (ret == -1) { DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f error %s\n", fsp->fsp_name, (double)wcp->file_size, strerror(errno) )); @@ -221,7 +221,7 @@ ssize_t write_file(files_struct *fsp, const char *data, SMB_OFF_T pos, size_t n) SMB_STRUCT_STAT st; fsp->modified = True; - if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0) { + if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) { file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st, False); @@ -288,9 +288,9 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", } DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n", - fsp->fsp_name, fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size)); + fsp->fsp_name, fsp->fh->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size)); - fsp->pos = pos + n; + fsp->fh->pos = pos + n; /* * If we have active cache and it isn't contiguous then we flush. @@ -589,7 +589,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", */ DEBUG(9,("write_file: non cacheable write : fd = %d, pos = %.0f, len = %u, current cache pos = %.0f \ -len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size )); +len = %u\n",fsp->fh->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size )); /* * If write would fit in the cache, and is larger than @@ -612,7 +612,7 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne if ((pos <= wcp->offset) && (pos + n >= wcp->offset + wcp->data_size) ) { DEBUG(9,("write_file: discarding overwritten write \ -cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned int)wcp->data_size )); +cache: fd = %d, off=%.0f, size=%u\n", fsp->fh->fd, (double)wcp->offset, (unsigned int)wcp->data_size )); wcp->data_size = 0; } @@ -635,7 +635,7 @@ cache: fd = %d, off=%.0f, size=%u\n", fsp->fd, (double)wcp->offset, (unsigned in if (cache_flush_needed) { DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", - write_path, fsp->fd, (double)wcp->file_size, (double)pos, (unsigned int)n, + write_path, fsp->fh->fd, (double)wcp->file_size, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size )); flush_write_cache(fsp, WRITE_FLUSH); @@ -809,7 +809,7 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) DO_PROFILE_DEC_INC(writecache_num_write_caches,writecache_flushed_writes[reason]); DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n", - fsp->fd, (double)wcp->offset, (unsigned int)data_size)); + fsp->fh->fd, (double)wcp->offset, (unsigned int)data_size)); #ifdef WITH_PROFILE if(data_size == wcp->alloc_size) { @@ -836,9 +836,9 @@ sync a file void sync_file(connection_struct *conn, files_struct *fsp) { - if(lp_strict_sync(SNUM(conn)) && fsp->fd != -1) { + if(lp_strict_sync(SNUM(conn)) && fsp->fh->fd != -1) { flush_write_cache(fsp, SYNC_FLUSH); - SMB_VFS_FSYNC(fsp,fsp->fd); + SMB_VFS_FSYNC(fsp,fsp->fh->fd); } } @@ -849,9 +849,9 @@ void sync_file(connection_struct *conn, files_struct *fsp) int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst) { - if (fsp->fd == -1) { + if (fsp->fh->fd == -1) { return SMB_VFS_STAT(fsp->conn, fsp->fsp_name, pst); } else { - return SMB_VFS_FSTAT(fsp,fsp->fd, pst); + return SMB_VFS_FSTAT(fsp,fsp->fh->fd, pst); } } -- cgit From 93954d6390370331731bda5fcf251dc0a796c744 Mon Sep 17 00:00:00 2001 From: James Peach Date: Sat, 3 Sep 2005 07:19:28 +0000 Subject: r9985: Move the all the strict sync logic into file_sync(). (This used to be commit cc680bbe22b8bfc5a1900f11c2cbaeca3a9f9922) --- source3/smbd/fileio.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 76189d114b..375bfbe7cf 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -834,15 +834,18 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) sync a file ********************************************************************/ -void sync_file(connection_struct *conn, files_struct *fsp) +void sync_file(connection_struct *conn, files_struct *fsp, BOOL write_through) { - if(lp_strict_sync(SNUM(conn)) && fsp->fh->fd != -1) { + if (fsp->fh->fd == -1) + return; + + if (lp_strict_sync(SNUM(conn)) && + (lp_syncalways(SNUM(conn)) || write_through)) { flush_write_cache(fsp, SYNC_FLUSH); SMB_VFS_FSYNC(fsp,fsp->fh->fd); } } - /************************************************************ Perform a stat whether a valid fd or not. ************************************************************/ -- cgit From 120422f7233446e8ca366ee7c4593cdbead79508 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Jul 2006 00:16:45 +0000 Subject: r17220: If we're going to fail a write with an errno, make sure we return -1. Jeremy. (This used to be commit 89b83237b03066785ca4bf3b9d120519bddeffad) --- source3/smbd/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 375bfbe7cf..e0945be889 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -214,7 +214,7 @@ ssize_t write_file(files_struct *fsp, const char *data, SMB_OFF_T pos, size_t n) if (!fsp->can_write) { errno = EPERM; - return(0); + return -1; } if (!fsp->modified) { -- cgit From 4952fe368a40b239140b3035db6075427d237bb9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 5 Mar 2007 23:40:03 +0000 Subject: r21714: Change the VFS interface to use struct timespec for utimes - change the call to ntimes. This preserves nsec timestamps we get from stat (if the system supports it) and only maps back down to usec or sec resolution on time set. Looks bigger than it is as I had to move lots of internal code from using time_t and struct utimebuf to struct timespec. Jeremy. (This used to be commit 8f3d530c5a748ea90f42ed8fbe68ae92178d4875) --- source3/smbd/fileio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index e0945be889..65238c0e9e 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -149,13 +149,13 @@ static ssize_t real_write_file(files_struct *fsp,const char *data, SMB_OFF_T pos * The 99% solution will hopefully be good enough in this case. JRA. */ - if (fsp->pending_modtime) { + if (!null_timespec(fsp->pending_modtime)) { set_filetime(fsp->conn, fsp->fsp_name, fsp->pending_modtime); /* If we didn't get the "set modtime" call ourselves, we must store the last write time to restore on close. JRA. */ if (!fsp->pending_modtime_owner) { - fsp->last_write_time = time(NULL); + fsp->last_write_time = timespec_current(); } } -- cgit From cc35d1300d487c65f1dc8a275140701ba276adaf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 15 Jun 2007 19:24:04 +0000 Subject: r23508: Fix sync_file() to return NTSTATUS and return this on failure in the write path. Jeremy. (This used to be commit cd3f7dbee809fb40194af0e7509142166e02b252) --- source3/smbd/fileio.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 65238c0e9e..1227d12b08 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -834,16 +834,23 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) sync a file ********************************************************************/ -void sync_file(connection_struct *conn, files_struct *fsp, BOOL write_through) +NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, BOOL write_through) { if (fsp->fh->fd == -1) - return; + return NT_STATUS_INVALID_HANDLE; if (lp_strict_sync(SNUM(conn)) && (lp_syncalways(SNUM(conn)) || write_through)) { - flush_write_cache(fsp, SYNC_FLUSH); - SMB_VFS_FSYNC(fsp,fsp->fh->fd); + int ret = flush_write_cache(fsp, SYNC_FLUSH); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + ret = SMB_VFS_FSYNC(fsp,fsp->fh->fd); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } } + return NT_STATUS_OK; } /************************************************************ -- cgit From f850ba5787b893fcf0e25cfa52affb93eb0c5afc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 9 Jul 2007 16:27:13 +0000 Subject: r23773: One pstring a day... (This used to be commit 0c3016d32b5277b901788b13aa7d3f4b647728f2) --- source3/smbd/fileio.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 1227d12b08..946d57da7e 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -780,9 +780,11 @@ void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size) if(fsp->wcp) { /* The cache *must* have been flushed before we do this. */ if (fsp->wcp->data_size != 0) { - pstring msg; - slprintf(msg, sizeof(msg)-1, "set_filelen_write_cache: size change \ -on file %s with write cache size = %lu\n", fsp->fsp_name, (unsigned long)fsp->wcp->data_size ); + char *msg; + asprintf(&msg, "set_filelen_write_cache: size change " + "on file %s with write cache size = %lu\n", + fsp->fsp_name, + (unsigned long)fsp->wcp->data_size); smb_panic(msg); } fsp->wcp->file_size = file_size; -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/smbd/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 946d57da7e..df9f4a8c3b 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/smbd/fileio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index df9f4a8c3b..e797dbda14 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From 01ee1c7909bc6840ada40421b9ca1c3b4cbf99ae Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 3 Aug 2007 16:51:43 +0000 Subject: r24164: Fix for write cache corruption bug reported by Jean-Francois Panisset . Awaiting confirmation from reporter. Jeremy. (This used to be commit 7bd65060bd965bd17a5d79639cf561b8b578cb36) --- source3/smbd/fileio.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index e797dbda14..76b29ec998 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -508,15 +508,20 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", write_path = 3; - } else if ( (pos >= wcp->file_size) && + } else if ( (pos >= wcp->file_size) && (n == 1) && - (pos < wcp->offset + 2*wcp->alloc_size) && - (wcp->file_size == wcp->offset + wcp->data_size)) { + (wcp->file_size == wcp->offset + wcp->data_size) && + (pos < wcp->file_size + wcp->alloc_size)) { /* - +---------------+ - | Cached data | - +---------------+ + + End of file ---->| + + +---------------+---------------+ + | Cached data | Cache buffer | + +---------------+---------------+ + + |<------- allocated size ---------------->| +--------+ | 1 Byte | @@ -524,13 +529,18 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", MS-Office seems to do this a lot to determine if there's enough space on the filesystem to write a new file. - */ - SMB_BIG_UINT new_start = wcp->offset + wcp->data_size; + Change to : + + End of file ---->| + +-----------------------+--------+ + | Zeroed Cached data | 1 Byte | + +-----------------------+--------+ + */ flush_write_cache(fsp, WRITE_FLUSH); - wcp->offset = new_start; - wcp->data_size = pos - new_start + 1; + wcp->offset = wcp->file_size; + wcp->data_size = pos - wcp->file_size + 1; memset(wcp->data, '\0', wcp->data_size); memcpy(wcp->data + wcp->data_size-1, data, 1); -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/smbd/fileio.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 76b29ec998..14056ddc80 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -21,13 +21,13 @@ #include "includes.h" -static BOOL setup_write_cache(files_struct *, SMB_OFF_T); +static bool setup_write_cache(files_struct *, SMB_OFF_T); /**************************************************************************** Read from write cache if we can. ****************************************************************************/ -static BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) +static bool read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) { write_cache *wcp = fsp->wcp; @@ -297,7 +297,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", */ if (wcp->data_size) { - BOOL cache_flush_needed = False; + bool cache_flush_needed = False; if ((pos >= wcp->offset) && (pos <= wcp->offset + wcp->data_size)) { @@ -739,7 +739,7 @@ void delete_write_cache(files_struct *fsp) Setup the write cache structure. ****************************************************************************/ -static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) +static bool setup_write_cache(files_struct *fsp, SMB_OFF_T file_size) { ssize_t alloc_size = lp_write_cache_size(SNUM(fsp->conn)); write_cache *wcp; @@ -845,7 +845,7 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) sync a file ********************************************************************/ -NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, BOOL write_through) +NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_through) { if (fsp->fh->fd == -1) return NT_STATUS_INVALID_HANDLE; -- cgit From c3250149e12338fac5093991b385ad2807c92d1f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Oct 2007 16:22:24 -0700 Subject: Add new parameter, "min receivefile size" (by default set to zero). If non-zero, writeX calls greater than this value will be left in the socket buffer for later handling with recvfile (or userspace equivalent). Definition of recvfile for your system is left as an exercise for the reader (I'm working on getting splice working :-). Jeremy. (This used to be commit 11c03b75ddbcb6e36b231bb40a1773d1c550621c) --- source3/smbd/fileio.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 14056ddc80..9e296f2204 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -116,12 +116,16 @@ static unsigned int allocated_write_caches; *Really* write to a file. ****************************************************************************/ -static ssize_t real_write_file(files_struct *fsp,const char *data, SMB_OFF_T pos, size_t n) +static ssize_t real_write_file(struct smb_request *req, + files_struct *fsp, + const char *data, + SMB_OFF_T pos, + size_t n) { ssize_t ret; if (pos == -1) { - ret = vfs_write_data(fsp, data, n); + ret = vfs_write_data(req, fsp, data, n); } else { fsp->fh->pos = pos; if (pos && lp_strict_allocate(SNUM(fsp->conn))) { @@ -129,7 +133,7 @@ static ssize_t real_write_file(files_struct *fsp,const char *data, SMB_OFF_T pos return -1; } } - ret = vfs_pwrite_data(fsp, data, n, pos); + ret = vfs_pwrite_data(req, fsp, data, n, pos); } DEBUG(10,("real_write_file (%s): pos = %.0f, size = %lu, returned %ld\n", @@ -191,11 +195,15 @@ static int wcp_file_size_change(files_struct *fsp) Write to a file. ****************************************************************************/ -ssize_t write_file(files_struct *fsp, const char *data, SMB_OFF_T pos, size_t n) +ssize_t write_file(struct smb_request *req, + files_struct *fsp, + const char *data, + SMB_OFF_T pos, + size_t n) { write_cache *wcp = fsp->wcp; ssize_t total_written = 0; - int write_path = -1; + int write_path = -1; if (fsp->print_file) { fstring sharename; @@ -234,8 +242,8 @@ ssize_t write_file(files_struct *fsp, const char *data, SMB_OFF_T pos, size_t n) if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) { setup_write_cache(fsp, st.st_size); wcp = fsp->wcp; - } - } + } + } } #ifdef WITH_PROFILE @@ -280,9 +288,18 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", } #endif + if (wcp && req->unread_bytes) { + /* If we're using receivefile don't + * deal with a write cache. + */ + flush_write_cache(fsp, WRITE_FLUSH); + delete_write_cache(fsp); + wcp = NULL; + } + if(!wcp) { DO_PROFILE_INC(writecache_direct_writes); - total_written = real_write_file(fsp, data, pos, n); + total_written = real_write_file(req, fsp, data, pos, n); return total_written; } @@ -291,7 +308,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n", fsp->fh->pos = pos + n; - /* + /* * If we have active cache and it isn't contiguous then we flush. * NOTE: There is a small problem with running out of disk .... */ @@ -610,7 +627,7 @@ len = %u\n",fsp->fh->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (uns if ( n <= wcp->alloc_size && n > wcp->data_size) { cache_flush_needed = True; } else { - ssize_t ret = real_write_file(fsp, data, pos, n); + ssize_t ret = real_write_file(NULL,fsp, data, pos, n); /* * If the write overlaps the entire cache, then @@ -657,7 +674,7 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n", */ if (n > wcp->alloc_size ) { - ssize_t ret = real_write_file(fsp, data, pos, n); + ssize_t ret = real_write_file(NULL,fsp, data, pos, n); if (ret == -1) { return -1; } @@ -828,7 +845,7 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) } #endif - ret = real_write_file(fsp, wcp->data, wcp->offset, data_size); + ret = real_write_file(NULL, fsp, wcp->data, wcp->offset, data_size); /* * Ensure file size if kept up to date if write extends file. -- cgit From 8f1f2f04c796a8659d93bafadefca4a98fee00f0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 31 Oct 2007 15:45:45 -0700 Subject: Fix some cases where file_set_dosmode was being passed False instead of NULL. Fix more of the notifications to be correct for Samba4 RAW-NOTIFY torture (we had missed one when calling set_ea_dos_attribute(). Jeremy. (This used to be commit 39d265375cf55eedddef2c4faa65398df73d5ed2) --- source3/smbd/fileio.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 9e296f2204..74f2c6774f 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -230,8 +230,13 @@ ssize_t write_file(struct smb_request *req, if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); - if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) { - file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st, False); + if ((lp_store_dos_attributes(SNUM(fsp->conn)) || + MAP_ARCHIVE(fsp->conn)) && + !IS_DOS_ARCHIVE(dosmode)) { + file_set_dosmode(fsp->conn,fsp->fsp_name, + dosmode | aARCH,&st, + NULL, + false); } /* -- cgit From 0bb1a6ec2d963c2001230142692de8335c540434 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 31 Oct 2007 16:32:48 -0700 Subject: Note when we're setting change time, not write time, and send message accordingly. Apart from not supporting create time we now pass the S4 RAW-NOTIFY torture. Jeremy. (This used to be commit 8a77f520fa03afa60eac2aaeab4babe7dd8db4f0) --- source3/smbd/fileio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 74f2c6774f..8037510d80 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -153,7 +153,8 @@ static ssize_t real_write_file(struct smb_request *req, */ if (!null_timespec(fsp->pending_modtime)) { - set_filetime(fsp->conn, fsp->fsp_name, fsp->pending_modtime); + set_filetime(fsp->conn, fsp->fsp_name, + fsp->pending_modtime); /* If we didn't get the "set modtime" call ourselves, we must store the last write time to restore on close. JRA. */ -- cgit From ca275e254985727c50b1b988c958a3743a7bc8ce Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Jan 2008 00:14:19 +0100 Subject: Remove unneeded parameter fd from SMB_VFS_PREAD(). Michael (This used to be commit 73e28806ce87d829ea7c38ed3440020845bb13bf) --- source3/smbd/fileio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 8037510d80..a648326f89 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -77,7 +77,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n) #ifdef DMF_FIX int numretries = 3; tryagain: - readret = SMB_VFS_PREAD(fsp,fsp->fh->fd,data,n,pos); + readret = SMB_VFS_PREAD(fsp,data,n,pos); if (readret == -1) { if ((errno == EAGAIN) && numretries) { @@ -89,7 +89,7 @@ tryagain: return -1; } #else /* NO DMF fix. */ - readret = SMB_VFS_PREAD(fsp,fsp->fh->fd,data,n,pos); + readret = SMB_VFS_PREAD(fsp,data,n,pos); if (readret == -1) { return -1; -- cgit From 8dcce0d236b2102ca94fbcb7aa7126fe6733f2e7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Jan 2008 12:49:02 +0100 Subject: Remove redundant parameter fd from SMB_VFS_FSYNC(). Michael (This used to be commit 8f83c9a7b245dbfef28195f9a7f33047a8ba95a0) --- source3/smbd/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index a648326f89..5a4263739b 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -879,7 +879,7 @@ NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_throug if (ret == -1) { return map_nt_error_from_unix(errno); } - ret = SMB_VFS_FSYNC(fsp,fsp->fh->fd); + ret = SMB_VFS_FSYNC(fsp); if (ret == -1) { return map_nt_error_from_unix(errno); } -- cgit From 87a684f7fcfa8d9fabc42e33981299d0b33eeeb7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Jan 2008 13:21:26 +0100 Subject: Remove redundant parameter fd from SMB_VFS_FSTAT(). Michael (This used to be commit 0b86c420be94d295f6917a220b5d699f65b46711) --- source3/smbd/fileio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 5a4263739b..1258b73cad 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -229,7 +229,7 @@ ssize_t write_file(struct smb_request *req, SMB_STRUCT_STAT st; fsp->modified = True; - if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) { + if (SMB_VFS_FSTAT(fsp, &st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && @@ -896,6 +896,6 @@ int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst) if (fsp->fh->fd == -1) { return SMB_VFS_STAT(fsp->conn, fsp->fsp_name, pst); } else { - return SMB_VFS_FSTAT(fsp,fsp->fh->fd, pst); + return SMB_VFS_FSTAT(fsp, pst); } } -- cgit From b457b94bb86897b7020c6f300cd19a3d8e192610 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Jan 2008 15:55:09 +0100 Subject: Remove redundant parameter fd from SMB_VFS_FTRUNCATE(). Michael (This used to be commit 2ad66050a0452b8e7e08b1e7a01efa00c72fd451) --- source3/smbd/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 1258b73cad..8cea4989f5 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -184,7 +184,7 @@ static int wcp_file_size_change(files_struct *fsp) write_cache *wcp = fsp->wcp; wcp->file_size = wcp->offset + wcp->data_size; - ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, wcp->file_size); + ret = SMB_VFS_FTRUNCATE(fsp, wcp->file_size); if (ret == -1) { DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f error %s\n", fsp->fsp_name, (double)wcp->file_size, strerror(errno) )); -- cgit From d03453864ab1bc5fd3b4a3abaf96176a006c102b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Mar 2008 15:39:38 +0100 Subject: smbd: implement the strange write time update logic We now never call file_ntimes() directly, every update is done via smb_set_file_time(). This let samba3 pass the BASE-DELAYWRITE test. The write time is only updated 2 seconds after the first write() on any open handle to the current time (not the time of the first write). Each handle which had write requests updates the write time to the current time on close(). If the write time is set explicit via setfileinfo or setpathinfo the write time is visible directly and a following close on the same handle doesn't update the write time. metze (This used to be commit 2eab212ea2e1bfd8fa716c2c89b2c042f7ba12ea) --- source3/smbd/fileio.c | 60 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 22 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 8cea4989f5..93a303f6c8 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -142,27 +142,6 @@ static ssize_t real_write_file(struct smb_request *req, if (ret != -1) { fsp->fh->pos += ret; - /* - * It turns out that setting the last write time from a Windows - * client stops any subsequent writes from updating the write time. - * Doing this after the write gives a race condition here where - * a stat may see the changed write time before we reset it here, - * but it's cheaper than having to store the write time in shared - * memory and look it up using dev/inode across all running smbd's. - * The 99% solution will hopefully be good enough in this case. JRA. - */ - - if (!null_timespec(fsp->pending_modtime)) { - set_filetime(fsp->conn, fsp->fsp_name, - fsp->pending_modtime); - - /* If we didn't get the "set modtime" call ourselves, we must - store the last write time to restore on close. JRA. */ - if (!fsp->pending_modtime_owner) { - fsp->last_write_time = timespec_current(); - } - } - /* Yes - this is correct - writes don't update this. JRA. */ /* Found by Samba4 tests. */ #if 0 @@ -192,6 +171,41 @@ static int wcp_file_size_change(files_struct *fsp) return ret; } +static void update_write_time_handler(struct event_context *ctx, + struct timed_event *te, + const struct timeval *now, + void *private_data) +{ + files_struct *fsp = (files_struct *)private_data; + + /* Remove the timed event handler. */ + TALLOC_FREE(fsp->update_write_time_event); + DEBUG(5, ("Update write time on %s\n", fsp->fsp_name)); + + /* change the write time if not already changed by someoneelse */ + set_write_time_fsp(fsp, timespec_current(), false); +} + +void trigger_write_time_update(struct files_struct *fsp) +{ + if (fsp->write_time_forced) { + return; + } + + if (fsp->update_write_time_triggered) { + return; + } + fsp->update_write_time_triggered = true; + + /* trigger the update 2 seconds later */ + fsp->update_write_time_on_close = true; + fsp->update_write_time_event = + event_add_timed(smbd_event_context(), NULL, + timeval_current_ofs(2, 0), + "update_write_time_handler", + update_write_time_handler, fsp); +} + /**************************************************************************** Write to a file. ****************************************************************************/ @@ -230,7 +244,9 @@ ssize_t write_file(struct smb_request *req, fsp->modified = True; if (SMB_VFS_FSTAT(fsp, &st) == 0) { - int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); + int dosmode; + trigger_write_time_update(fsp); + dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) { -- cgit From 206e7eeb6fb5491155ac4b54e13b7b81ae6c29a0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 7 Apr 2008 09:27:22 +0200 Subject: smbd: make it possible to change the write time delay for testing metze (This used to be commit df8c100c2b53575a0d425a2daf52e2d59904746a) --- source3/smbd/fileio.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 93a303f6c8..64cea7f7ce 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -188,6 +188,8 @@ static void update_write_time_handler(struct event_context *ctx, void trigger_write_time_update(struct files_struct *fsp) { + int delay; + if (fsp->write_time_forced) { return; } @@ -197,11 +199,15 @@ void trigger_write_time_update(struct files_struct *fsp) } fsp->update_write_time_triggered = true; + delay = lp_parm_int(SNUM(fsp->conn), + "smbd", "writetimeupdatedelay", + WRITE_TIME_UPDATE_USEC_DELAY); + /* trigger the update 2 seconds later */ fsp->update_write_time_on_close = true; fsp->update_write_time_event = event_add_timed(smbd_event_context(), NULL, - timeval_current_ofs(2, 0), + timeval_current_ofs(0, delay), "update_write_time_handler", update_write_time_handler, fsp); } -- cgit From 405b072431db3f3f8f16e4e0d2f2b1b2f1c71286 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Sep 2008 19:00:48 -0700 Subject: Write times code update. Ok, here's the fix for the write times breakage with the new tests in S4 smbtorture. The key is keeping in the share mode struct the "old_file_time" as the real write time, set by all the write and allocation calls, and the "changed_write_time" as the "sticky" write time - set by the SET_FILE_TIME calls. We can set them independently (although I kept the optimization of not setting the "old_file_time" is a "changed_write_time" was already set, as we'll never see it. This allows us to update the write time immediately on the SMBwrite truncate case, SET_END_OF_FILE and SET_ALLOCATION_SIZE calls, whilst still have the 2 second delay on the "normal" SMBwrite, SMBwriteX calls. I think in a subsequent patch I'd like to change the name of these from "old_file_time" to "write_time" and "changed_write_time" to "sticky_write_time" to make this clearer. I think I also fixed a bug in Metze's original code in that once a write timestamp had been set from a "normal" SMBwriteX call the fsp->update_write_time_triggered variable was set and then never reset - thus meaning the write timestamp would never get updated again on subsequent SMBwriteX's. The new code checks the update_write_time_event event instead, and doesn't update is there's an event already scheduled. Metze especially, please check this over for your understanding. Jeremy. (This used to be commit 6f20585419046c4aca1f7d6c863cf79eb6ae53b0) --- source3/smbd/fileio.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 64cea7f7ce..63850f24eb 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -176,28 +176,38 @@ static void update_write_time_handler(struct event_context *ctx, const struct timeval *now, void *private_data) { - files_struct *fsp = (files_struct *)private_data; + files_struct *fsp = (files_struct *)private_data; - /* Remove the timed event handler. */ - TALLOC_FREE(fsp->update_write_time_event); - DEBUG(5, ("Update write time on %s\n", fsp->fsp_name)); + /* Remove the timed event handler. */ + TALLOC_FREE(fsp->update_write_time_event); + DEBUG(5, ("Update write time on %s\n", fsp->fsp_name)); - /* change the write time if not already changed by someoneelse */ - set_write_time_fsp(fsp, timespec_current(), false); + /* change the write time if not already changed by someone else */ + update_write_time(fsp); } +/********************************************************* + Schedule a write time update for WRITE_TIME_UPDATE_USEC_DELAY + in the future. +*********************************************************/ + void trigger_write_time_update(struct files_struct *fsp) { int delay; if (fsp->write_time_forced) { + /* No point - "sticky" write times + * in effect. + */ return; } - if (fsp->update_write_time_triggered) { + if (fsp->update_write_time_event) { + /* + * No point - an event is already scheduled. + */ return; } - fsp->update_write_time_triggered = true; delay = lp_parm_int(SNUM(fsp->conn), "smbd", "writetimeupdatedelay", @@ -212,6 +222,27 @@ void trigger_write_time_update(struct files_struct *fsp) update_write_time_handler, fsp); } +void trigger_write_time_update_immediate(struct files_struct *fsp) +{ + if (fsp->write_time_forced) { + /* + * No point - "sticky" write times + * in effect. + */ + return; + } + + if (fsp->update_write_time_event) { + /* + * No point - an event is already scheduled. + */ + return; + } + + fsp->update_write_time_on_close = true; + update_write_time(fsp); +} + /**************************************************************************** Write to a file. ****************************************************************************/ -- cgit From c9fb96146cdae56a2711e176f07620d33ea0e18c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 8 Sep 2008 15:12:24 +0200 Subject: smbd: some write time fixes - only the first non truncating write causes the write time update with 2 seconds delay. It's not enough to check for an existing update event as it will be NULL after the event was triggered. - SMBwrite truncates always update the write time unless the sticky write time is set. - SMBwrite truncates don't trigger a write time update on close. metze (This used to be commit 3d17089b6dc773303c8c553f3f6140e60e348fb7) --- source3/smbd/fileio.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 63850f24eb..095841825a 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -202,12 +202,13 @@ void trigger_write_time_update(struct files_struct *fsp) return; } - if (fsp->update_write_time_event) { + if (fsp->update_write_time_triggered) { /* * No point - an event is already scheduled. */ return; } + fsp->update_write_time_triggered = true; delay = lp_parm_int(SNUM(fsp->conn), "smbd", "writetimeupdatedelay", @@ -232,14 +233,12 @@ void trigger_write_time_update_immediate(struct files_struct *fsp) return; } - if (fsp->update_write_time_event) { - /* - * No point - an event is already scheduled. - */ - return; - } + TALLOC_FREE(fsp->update_write_time_event); + DEBUG(5, ("Update write time immediate on %s\n", fsp->fsp_name)); + + fsp->update_write_time_triggered = true; - fsp->update_write_time_on_close = true; + fsp->update_write_time_on_close = false; update_write_time(fsp); } -- cgit From c7b75de96269e55f07a3e788e5c99067e291e069 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 12 Sep 2008 15:03:05 -0700 Subject: Modify a comment to make things clearer. Jeremy. (This used to be commit 9d55ca85ffc73e3fa5fb9895fbcb1ee22f4e320d) --- source3/smbd/fileio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/smbd/fileio.c') diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 095841825a..60aeeef1e2 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -204,7 +204,9 @@ void trigger_write_time_update(struct files_struct *fsp) if (fsp->update_write_time_triggered) { /* - * No point - an event is already scheduled. + * We only update the write time + * on the first write. After that + * no other writes affect this. */ return; } -- cgit