1998-08-15 11:27:34 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1998-08-15 11:27:34 +04:00
Files [ ] structure handling
Copyright ( C ) Andrew Tridgell 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 0213 9 , USA .
*/
# include "includes.h"
1998-09-30 05:49:24 +04:00
static int real_max_open_files ;
1998-08-15 11:27:34 +04:00
1998-09-30 05:49:24 +04:00
# define VALID_FNUM(fnum) (((fnum) >= 0) && ((fnum) < real_max_open_files))
1998-08-15 11:27:34 +04:00
1998-08-17 07:06:20 +04:00
# define FILE_HANDLE_OFFSET 0x1000
1998-08-16 08:08:47 +04:00
static struct bitmap * file_bmap ;
static files_struct * Files ;
1998-09-10 22:57:06 +04:00
1998-08-17 07:52:05 +04:00
/* a fsp to use when chaining */
static files_struct * chain_fsp = NULL ;
2000-04-10 17:05:23 +04:00
static int files_used ;
1998-08-15 11:27:34 +04:00
2005-03-10 04:30:14 +03:00
/* A singleton cache to speed up searching by dev/inode. */
static struct fsp_singleton_cache {
files_struct * fsp ;
SMB_DEV_T dev ;
SMB_INO_T inode ;
} fsp_fi_cache ;
1998-08-15 11:27:34 +04:00
/****************************************************************************
2001-10-21 01:59:34 +04:00
Return a unique number identifying this fsp over the life of this pid .
1998-08-15 11:27:34 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-21 01:59:34 +04:00
static unsigned long get_gen_count ( void )
{
static unsigned long file_gen_counter ;
if ( ( + + file_gen_counter ) = = 0 )
return + + file_gen_counter ;
return file_gen_counter ;
}
/****************************************************************************
Find first available file slot .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-07-11 22:01:26 +04:00
NTSTATUS file_new ( connection_struct * conn , files_struct * * result )
1998-08-15 11:27:34 +04:00
{
int i ;
static int first_file ;
2005-09-30 21:13:37 +04:00
files_struct * fsp ;
1998-08-15 11:27:34 +04:00
/* we want to give out file handles differently on each new
connection because of a common bug in MS clients where they try to
reuse a file descriptor from an earlier smb connection . This code
increases the chance that the errant client will get an error rather
than causing corruption */
if ( first_file = = 0 ) {
2000-05-02 06:23:41 +04:00
first_file = ( sys_getpid ( ) ^ ( int ) time ( NULL ) ) % real_max_open_files ;
1998-08-16 08:08:47 +04:00
}
1998-08-15 11:27:34 +04:00
2005-09-30 21:13:37 +04:00
/* TODO: Port the id-tree implementation from Samba4 */
1998-08-16 08:08:47 +04:00
i = bitmap_find ( file_bmap , first_file ) ;
if ( i = = - 1 ) {
DEBUG ( 0 , ( " ERROR! Out of file structures \n " ) ) ;
2005-09-30 21:13:37 +04:00
/* TODO: We have to unconditionally return a DOS error here,
* W2k3 even returns ERRDOS / ERRnofids for ntcreate & x with
* NTSTATUS negotiated */
2006-07-11 22:01:26 +04:00
return NT_STATUS_TOO_MANY_OPENED_FILES ;
1998-08-16 08:08:47 +04:00
}
1998-08-15 11:27:34 +04:00
2004-12-07 21:25:53 +03:00
fsp = SMB_MALLOC_P ( files_struct ) ;
2000-04-22 04:33:16 +04:00
if ( ! fsp ) {
2006-07-11 22:01:26 +04:00
return NT_STATUS_NO_MEMORY ;
2000-04-22 04:33:16 +04:00
}
1998-08-16 08:08:47 +04:00
1998-09-05 17:24:20 +04:00
ZERO_STRUCTP ( fsp ) ;
2005-07-08 08:51:27 +04:00
fsp - > fh = SMB_MALLOC_P ( struct fd_handle ) ;
if ( ! fsp - > fh ) {
SAFE_FREE ( fsp ) ;
2006-07-11 22:01:26 +04:00
return NT_STATUS_NO_MEMORY ;
2005-07-08 08:51:27 +04:00
}
ZERO_STRUCTP ( fsp - > fh ) ;
fsp - > fh - > ref_count = 1 ;
fsp - > fh - > fd = - 1 ;
2001-04-14 04:19:12 +04:00
fsp - > conn = conn ;
2006-05-18 03:15:53 +04:00
fsp - > fh - > file_id = get_gen_count ( ) ;
2001-10-21 01:59:34 +04:00
GetTimeOfDay ( & fsp - > open_time ) ;
1998-08-17 07:06:20 +04:00
1998-09-30 05:49:24 +04:00
first_file = ( i + 1 ) % real_max_open_files ;
1998-08-16 08:08:47 +04:00
bitmap_set ( file_bmap , i ) ;
files_used + + ;
1998-08-17 07:06:20 +04:00
fsp - > fnum = i + FILE_HANDLE_OFFSET ;
2002-10-23 02:17:29 +04:00
SMB_ASSERT ( fsp - > fnum < 65536 ) ;
2000-01-16 14:18:04 +03:00
string_set ( & fsp - > fsp_name , " " ) ;
1998-08-16 08:08:47 +04:00
1998-08-17 10:47:53 +04:00
DLIST_ADD ( Files , fsp ) ;
1998-08-16 08:08:47 +04:00
1998-09-10 22:57:06 +04:00
DEBUG ( 5 , ( " allocated file structure %d, fnum = %d (%d used) \n " ,
i , fsp - > fnum , files_used ) ) ;
1998-08-17 07:52:05 +04:00
chain_fsp = fsp ;
2005-03-10 04:30:14 +03:00
/* A new fsp invalidates a negative fsp_fi_cache. */
if ( fsp_fi_cache . fsp = = NULL ) {
ZERO_STRUCT ( fsp_fi_cache ) ;
}
2006-07-11 22:01:26 +04:00
* result = fsp ;
return NT_STATUS_OK ;
1998-08-15 11:27:34 +04:00
}
/****************************************************************************
2001-10-21 01:59:34 +04:00
Close all open files for a connection .
1998-08-15 11:27:34 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-21 01:59:34 +04:00
1998-08-15 11:27:34 +04:00
void file_close_conn ( connection_struct * conn )
{
1998-08-17 10:13:32 +04:00
files_struct * fsp , * next ;
1998-08-16 08:08:47 +04:00
1998-08-17 10:13:32 +04:00
for ( fsp = Files ; fsp ; fsp = next ) {
next = fsp - > next ;
2000-04-24 23:23:51 +04:00
if ( fsp - > conn = = conn ) {
2006-02-02 23:44:50 +03:00
close_file ( fsp , SHUTDOWN_CLOSE ) ;
1998-08-16 08:08:47 +04:00
}
}
1998-08-15 11:27:34 +04:00
}
2003-08-19 05:53:45 +04:00
/****************************************************************************
2006-03-16 01:52:59 +03:00
Close all open files for a pid and a vuid .
2003-08-19 05:53:45 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-03-16 01:52:59 +03:00
void file_close_pid ( uint16 smbpid , int vuid )
2003-08-19 05:53:45 +04:00
{
files_struct * fsp , * next ;
for ( fsp = Files ; fsp ; fsp = next ) {
next = fsp - > next ;
2006-03-16 01:52:59 +03:00
if ( ( fsp - > file_pid = = smbpid ) & & ( fsp - > vuid = = vuid ) ) {
2006-02-02 23:44:50 +03:00
close_file ( fsp , SHUTDOWN_CLOSE ) ;
2003-08-19 05:53:45 +04:00
}
}
}
1998-08-15 11:27:34 +04:00
/****************************************************************************
2001-10-21 01:59:34 +04:00
Initialise file structures .
1998-08-15 11:27:34 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-09-30 05:49:24 +04:00
2002-10-23 02:17:29 +04:00
# define MAX_OPEN_FUDGEFACTOR 20
1998-09-30 05:49:24 +04:00
1998-08-15 11:27:34 +04:00
void file_init ( void )
{
2001-04-13 23:33:26 +04:00
int request_max_open_files = lp_max_open_files ( ) ;
1998-10-16 10:16:10 +04:00
int real_lim ;
1998-09-30 05:49:24 +04:00
1998-10-16 10:16:10 +04:00
/*
* Set the max_open files to be the requested
* max plus a fudgefactor to allow for the extra
* fd ' s we need such as log files etc . . .
*/
real_lim = set_maxfiles ( request_max_open_files + MAX_OPEN_FUDGEFACTOR ) ;
real_max_open_files = real_lim - MAX_OPEN_FUDGEFACTOR ;
2002-10-23 02:17:29 +04:00
if ( real_max_open_files + FILE_HANDLE_OFFSET + MAX_OPEN_PIPES > 65536 )
real_max_open_files = 65536 - FILE_HANDLE_OFFSET - MAX_OPEN_PIPES ;
2001-04-13 23:33:26 +04:00
if ( real_max_open_files ! = request_max_open_files ) {
DEBUG ( 1 , ( " file_init: Information only: requested %d \
1998-10-16 10:16:10 +04:00
open files , % d are available . \ n " , request_max_open_files, real_max_open_files));
}
1998-09-30 05:49:24 +04:00
2002-10-23 02:17:29 +04:00
SMB_ASSERT ( real_max_open_files > 100 ) ;
1998-10-05 05:57:03 +04:00
file_bmap = bitmap_allocate ( real_max_open_files ) ;
1998-09-30 05:49:24 +04:00
if ( ! file_bmap ) {
exit_server ( " out of memory in file_init " ) ;
}
1998-10-05 05:57:03 +04:00
1998-10-01 07:07:09 +04:00
/*
1999-12-13 16:27:58 +03:00
* Ensure that pipe_handle_oppset is set correctly .
1998-10-01 07:07:09 +04:00
*/
set_pipe_handle_offset ( real_max_open_files ) ;
1998-08-15 11:27:34 +04:00
}
/****************************************************************************
2001-10-21 01:59:34 +04:00
Close files open by a specified vuid .
1998-08-15 11:27:34 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-21 01:59:34 +04:00
1998-08-15 11:27:34 +04:00
void file_close_user ( int vuid )
{
1998-08-17 10:13:32 +04:00
files_struct * fsp , * next ;
1998-08-16 08:08:47 +04:00
1998-08-17 10:13:32 +04:00
for ( fsp = Files ; fsp ; fsp = next ) {
next = fsp - > next ;
2000-04-24 23:23:51 +04:00
if ( fsp - > vuid = = vuid ) {
2006-02-02 23:44:50 +03:00
close_file ( fsp , SHUTDOWN_CLOSE ) ;
1998-08-15 11:27:34 +04:00
}
}
}
2005-07-10 20:40:06 +04:00
/****************************************************************************
Debug to enumerate all open files in the smbd .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-16 06:34:03 +04:00
void file_dump_open_table ( void )
{
int count = 0 ;
files_struct * fsp ;
for ( fsp = Files ; fsp ; fsp = fsp - > next , count + + ) {
DEBUG ( 10 , ( " Files[%d], fnum = %d, name %s, fd = %d, fileid = %lu, dev = %x, inode = %.0f \n " ,
2006-05-18 03:15:53 +04:00
count , fsp - > fnum , fsp - > fsp_name , fsp - > fh - > fd , ( unsigned long ) fsp - > fh - > file_id ,
2003-08-16 06:34:03 +04:00
( unsigned int ) fsp - > dev , ( double ) fsp - > inode ) ) ;
}
}
2001-10-21 01:59:34 +04:00
/****************************************************************************
Find a fsp given a file descriptor .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
files_struct * file_find_fd ( int fd )
{
int count = 0 ;
files_struct * fsp ;
for ( fsp = Files ; fsp ; fsp = fsp - > next , count + + ) {
2005-07-08 08:51:27 +04:00
if ( fsp - > fh - > fd = = fd ) {
2001-10-21 01:59:34 +04:00
if ( count > 10 ) {
DLIST_PROMOTE ( Files , fsp ) ;
}
return fsp ;
}
}
return NULL ;
}
1998-08-15 11:27:34 +04:00
/****************************************************************************
2001-10-21 01:59:34 +04:00
Find a fsp given a device , inode and file_id .
1998-08-15 11:27:34 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-09-23 05:48:45 +04:00
2001-10-21 01:59:34 +04:00
files_struct * file_find_dif ( SMB_DEV_T dev , SMB_INO_T inode , unsigned long file_id )
1998-08-15 11:27:34 +04:00
{
1998-08-17 10:47:53 +04:00
int count = 0 ;
1998-08-16 08:08:47 +04:00
files_struct * fsp ;
1998-08-17 10:47:53 +04:00
for ( fsp = Files ; fsp ; fsp = fsp - > next , count + + ) {
2005-07-08 08:51:27 +04:00
/* We can have a fsp->fh->fd == -1 here as it could be a stat open. */
2003-05-23 00:31:35 +04:00
if ( fsp - > dev = = dev & &
2000-04-10 17:05:23 +04:00
fsp - > inode = = inode & &
2006-05-18 03:15:53 +04:00
fsp - > fh - > file_id = = file_id ) {
1998-08-17 10:47:53 +04:00
if ( count > 10 ) {
DLIST_PROMOTE ( Files , fsp ) ;
}
2003-05-23 00:31:35 +04:00
/* Paranoia check. */
2005-09-30 21:13:37 +04:00
if ( ( fsp - > fh - > fd = = - 1 ) & &
( fsp - > oplock_type ! = NO_OPLOCK ) & &
( fsp - > oplock_type ! = FAKE_LEVEL_II_OPLOCK ) ) {
2003-05-23 00:31:35 +04:00
DEBUG ( 0 , ( " file_find_dif: file %s dev = %x, inode = %.0f, file_id = %u \
oplock_type = % u is a stat open with oplock type ! \ n " , fsp->fsp_name, (unsigned int)fsp->dev,
2006-05-18 03:15:53 +04:00
( double ) fsp - > inode , ( unsigned int ) fsp - > fh - > file_id ,
2003-05-23 00:31:35 +04:00
( unsigned int ) fsp - > oplock_type ) ) ;
smb_panic ( " file_find_dif \n " ) ;
}
1998-08-15 11:27:34 +04:00
return fsp ;
}
1998-08-16 08:08:47 +04:00
}
1998-08-15 11:27:34 +04:00
return NULL ;
}
2000-04-24 23:23:51 +04:00
/****************************************************************************
Check if an fsp still exists .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
files_struct * file_find_fsp ( files_struct * orig_fsp )
{
files_struct * fsp ;
2004-10-19 02:01:10 +04:00
for ( fsp = Files ; fsp ; fsp = fsp - > next ) {
if ( fsp = = orig_fsp )
return fsp ;
}
2000-04-24 23:23:51 +04:00
2004-10-19 02:01:10 +04:00
return NULL ;
2000-04-24 23:23:51 +04:00
}
1998-10-23 07:34:50 +04:00
/****************************************************************************
Find the first fsp given a device and inode .
2005-03-10 04:30:14 +03:00
We use a singleton cache here to speed up searching from getfilepathinfo
calls .
1998-10-23 07:34:50 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
files_struct * file_find_di_first ( SMB_DEV_T dev , SMB_INO_T inode )
{
2004-10-19 02:01:10 +04:00
files_struct * fsp ;
1998-10-23 07:34:50 +04:00
2005-03-10 04:30:14 +03:00
if ( fsp_fi_cache . dev = = dev & & fsp_fi_cache . inode = = inode ) {
/* Positive or negative cache hit. */
return fsp_fi_cache . fsp ;
}
fsp_fi_cache . dev = dev ;
fsp_fi_cache . inode = inode ;
2004-10-19 02:01:10 +04:00
for ( fsp = Files ; fsp ; fsp = fsp - > next ) {
2005-07-08 08:51:27 +04:00
if ( fsp - > fh - > fd ! = - 1 & &
2004-10-19 02:01:10 +04:00
fsp - > dev = = dev & &
2005-03-10 04:30:14 +03:00
fsp - > inode = = inode ) {
/* Setup positive cache. */
fsp_fi_cache . fsp = fsp ;
2004-10-19 02:01:10 +04:00
return fsp ;
2005-03-10 04:30:14 +03:00
}
2004-10-19 02:01:10 +04:00
}
1998-10-23 07:34:50 +04:00
2005-03-10 04:30:14 +03:00
/* Setup negative cache. */
fsp_fi_cache . fsp = NULL ;
2004-10-19 02:01:10 +04:00
return NULL ;
1998-10-23 07:34:50 +04:00
}
/****************************************************************************
Find the next fsp having the same device and inode .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
files_struct * file_find_di_next ( files_struct * start_fsp )
{
2004-10-19 02:01:10 +04:00
files_struct * fsp ;
1998-10-23 07:34:50 +04:00
2004-10-19 02:01:10 +04:00
for ( fsp = start_fsp - > next ; fsp ; fsp = fsp - > next ) {
2005-07-08 08:51:27 +04:00
if ( fsp - > fh - > fd ! = - 1 & &
2004-10-19 02:01:10 +04:00
fsp - > dev = = start_fsp - > dev & &
fsp - > inode = = start_fsp - > inode )
return fsp ;
}
1998-10-23 07:34:50 +04:00
2004-10-19 02:01:10 +04:00
return NULL ;
1998-10-23 07:34:50 +04:00
}
1998-08-16 08:08:47 +04:00
1998-08-15 11:27:34 +04:00
/****************************************************************************
2001-10-21 01:59:34 +04:00
Find a fsp that is open for printing .
1998-08-15 11:27:34 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-21 01:59:34 +04:00
1998-08-15 11:27:34 +04:00
files_struct * file_find_print ( void )
{
1998-08-16 08:08:47 +04:00
files_struct * fsp ;
1998-08-15 11:27:34 +04:00
1998-08-16 08:08:47 +04:00
for ( fsp = Files ; fsp ; fsp = fsp - > next ) {
2005-03-10 04:30:14 +03:00
if ( fsp - > print_file ) {
return fsp ;
}
1998-08-15 11:27:34 +04:00
}
1998-09-10 22:57:06 +04:00
1998-08-15 11:27:34 +04:00
return NULL ;
}
2005-03-10 04:30:14 +03:00
/****************************************************************************
Set a pending modtime across all files with a given dev / ino pair .
2005-03-11 00:43:58 +03:00
Record the owner of that modtime .
2005-03-10 04:30:14 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-03-06 02:40:03 +03:00
void fsp_set_pending_modtime ( files_struct * tfsp , const struct timespec mod )
2005-03-10 04:30:14 +03:00
{
files_struct * fsp ;
2007-03-06 02:40:03 +03:00
if ( null_timespec ( mod ) ) {
2005-03-10 04:30:14 +03:00
return ;
}
for ( fsp = Files ; fsp ; fsp = fsp - > next ) {
2005-07-08 08:51:27 +04:00
if ( fsp - > fh - > fd ! = - 1 & &
2005-03-10 04:30:14 +03:00
fsp - > dev = = tfsp - > dev & &
fsp - > inode = = tfsp - > inode ) {
2007-03-06 02:40:03 +03:00
fsp - > pending_modtime = mod ;
2005-03-11 00:43:58 +03:00
fsp - > pending_modtime_owner = False ;
2005-03-10 04:30:14 +03:00
}
}
2005-03-11 00:43:58 +03:00
tfsp - > pending_modtime_owner = True ;
2005-03-10 04:30:14 +03:00
}
1998-08-15 11:27:34 +04:00
/****************************************************************************
2001-10-21 01:59:34 +04:00
Sync open files on a connection .
1998-08-15 11:27:34 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-21 01:59:34 +04:00
1998-08-15 11:27:34 +04:00
void file_sync_all ( connection_struct * conn )
{
1998-08-17 10:13:32 +04:00
files_struct * fsp , * next ;
1998-08-16 08:08:47 +04:00
1998-08-17 10:13:32 +04:00
for ( fsp = Files ; fsp ; fsp = next ) {
next = fsp - > next ;
2005-07-08 08:51:27 +04:00
if ( ( conn = = fsp - > conn ) & & ( fsp - > fh - > fd ! = - 1 ) ) {
2005-09-03 11:19:28 +04:00
sync_file ( conn , fsp , True /* write through */ ) ;
1998-08-15 11:27:34 +04:00
}
}
}
1998-08-16 08:08:47 +04:00
/****************************************************************************
2001-10-21 01:59:34 +04:00
Free up a fsp .
1998-08-16 08:08:47 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-21 01:59:34 +04:00
1998-08-15 11:27:34 +04:00
void file_free ( files_struct * fsp )
{
1998-08-17 10:47:53 +04:00
DLIST_REMOVE ( Files , fsp ) ;
1998-08-16 08:08:47 +04:00
string_free ( & fsp - > fsp_name ) ;
2003-05-12 05:20:17 +04:00
if ( fsp - > fake_file_handle ) {
destroy_fake_file_handle ( & fsp - > fake_file_handle ) ;
}
2005-07-08 08:51:27 +04:00
if ( fsp - > fh - > ref_count = = 1 ) {
SAFE_FREE ( fsp - > fh ) ;
} else {
fsp - > fh - > ref_count - - ;
}
2007-01-31 17:42:56 +03:00
if ( fsp - > notify ) {
notify_remove ( fsp - > conn - > notify_ctx , fsp ) ;
TALLOC_FREE ( fsp - > notify ) ;
}
2007-01-17 19:23:45 +03:00
1998-08-17 07:06:20 +04:00
bitmap_clear ( file_bmap , fsp - > fnum - FILE_HANDLE_OFFSET ) ;
1998-08-16 08:08:47 +04:00
files_used - - ;
DEBUG ( 5 , ( " freed files structure %d (%d used) \n " ,
fsp - > fnum , files_used ) ) ;
/* this is paranoia, just in case someone tries to reuse the
information */
1998-09-05 17:24:20 +04:00
ZERO_STRUCTP ( fsp ) ;
1998-08-16 08:08:47 +04:00
2004-10-19 02:01:10 +04:00
if ( fsp = = chain_fsp ) {
chain_fsp = NULL ;
}
1998-08-17 07:52:05 +04:00
2005-03-10 04:30:14 +03:00
/* Closing a file can invalidate the positive cache. */
if ( fsp = = fsp_fi_cache . fsp ) {
ZERO_STRUCT ( fsp_fi_cache ) ;
}
2001-09-17 15:25:41 +04:00
SAFE_FREE ( fsp ) ;
1998-08-15 11:27:34 +04:00
}
1998-08-17 07:52:05 +04:00
/****************************************************************************
2006-07-11 22:01:26 +04:00
Get an fsp from a 16 bit fnum .
1998-08-17 07:52:05 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-21 01:59:34 +04:00
2006-07-11 22:01:26 +04:00
files_struct * file_fnum ( uint16 fnum )
1998-08-17 07:52:05 +04:00
{
files_struct * fsp ;
2006-07-11 22:01:26 +04:00
int count = 0 ;
1998-08-17 07:52:05 +04:00
1998-08-17 10:47:53 +04:00
for ( fsp = Files ; fsp ; fsp = fsp - > next , count + + ) {
1998-08-17 07:52:05 +04:00
if ( fsp - > fnum = = fnum ) {
1998-08-17 10:47:53 +04:00
if ( count > 10 ) {
DLIST_PROMOTE ( Files , fsp ) ;
}
1998-08-17 07:52:05 +04:00
return fsp ;
}
}
return NULL ;
}
2006-07-11 22:01:26 +04:00
/****************************************************************************
Get an fsp from a packet given the offset of a 16 bit fnum .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
files_struct * file_fsp ( char * buf , int where )
{
files_struct * fsp ;
if ( chain_fsp ) {
return chain_fsp ;
}
if ( ! buf ) {
return NULL ;
}
fsp = file_fnum ( SVAL ( buf , where ) ) ;
if ( fsp ) {
chain_fsp = fsp ;
}
return fsp ;
}
1998-08-17 07:52:05 +04:00
/****************************************************************************
2001-10-21 01:59:34 +04:00
Reset the chained fsp - done at the start of a packet reply .
1998-08-17 07:52:05 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-08-20 23:28:37 +04:00
1998-08-17 07:52:05 +04:00
void file_chain_reset ( void )
{
chain_fsp = NULL ;
}
1998-08-18 02:59:53 +04:00
2005-07-10 20:40:06 +04:00
/****************************************************************************
Duplicate the file handle part for a DOS or FCB open .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-07-11 22:01:26 +04:00
NTSTATUS dup_file_fsp ( files_struct * fsp ,
2005-07-08 08:51:27 +04:00
uint32 access_mask ,
uint32 share_access ,
2006-07-11 22:01:26 +04:00
uint32 create_options ,
files_struct * * result )
2005-07-08 08:51:27 +04:00
{
2006-07-11 22:01:26 +04:00
NTSTATUS status ;
files_struct * dup_fsp ;
2005-07-08 08:51:27 +04:00
2006-07-11 22:01:26 +04:00
status = file_new ( fsp - > conn , & dup_fsp ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2005-07-08 08:51:27 +04:00
}
SAFE_FREE ( dup_fsp - > fh ) ;
dup_fsp - > fh = fsp - > fh ;
dup_fsp - > fh - > ref_count + + ;
dup_fsp - > dev = fsp - > dev ;
dup_fsp - > inode = fsp - > inode ;
dup_fsp - > initial_allocation_size = fsp - > initial_allocation_size ;
dup_fsp - > mode = fsp - > mode ;
dup_fsp - > file_pid = fsp - > file_pid ;
dup_fsp - > vuid = fsp - > vuid ;
dup_fsp - > open_time = fsp - > open_time ;
dup_fsp - > access_mask = access_mask ;
dup_fsp - > share_access = share_access ;
dup_fsp - > pending_modtime_owner = fsp - > pending_modtime_owner ;
dup_fsp - > pending_modtime = fsp - > pending_modtime ;
dup_fsp - > last_write_time = fsp - > last_write_time ;
dup_fsp - > oplock_type = fsp - > oplock_type ;
dup_fsp - > can_lock = fsp - > can_lock ;
dup_fsp - > can_read = ( access_mask & ( FILE_READ_DATA ) ) ? True : False ;
if ( ! CAN_WRITE ( fsp - > conn ) ) {
dup_fsp - > can_write = False ;
} else {
dup_fsp - > can_write = ( access_mask & ( FILE_WRITE_DATA | FILE_APPEND_DATA ) ) ? True : False ;
}
dup_fsp - > print_file = fsp - > print_file ;
dup_fsp - > modified = fsp - > modified ;
dup_fsp - > is_directory = fsp - > is_directory ;
dup_fsp - > is_stat = fsp - > is_stat ;
string_set ( & dup_fsp - > fsp_name , fsp - > fsp_name ) ;
2006-07-11 22:01:26 +04:00
* result = dup_fsp ;
return NT_STATUS_OK ;
2005-07-08 08:51:27 +04:00
}