Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/smbd/files.c

    r414 r745  
    33   Files[] structure handling
    44   Copyright (C) Andrew Tridgell 1998
    5    
     5
    66   This program is free software; you can redistribute it and/or modify
    77   it under the terms of the GNU General Public License as published by
    88   the Free Software Foundation; either version 3 of the License, or
    99   (at your option) any later version.
    10    
     10
    1111   This program is distributed in the hope that it will be useful,
    1212   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1313   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1414   GNU General Public License for more details.
    15    
     15
    1616   You should have received a copy of the GNU General Public License
    1717   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    1919
    2020#include "includes.h"
     21#include "smbd/smbd.h"
    2122#include "smbd/globals.h"
     23#include "libcli/security/security.h"
     24#include "util_tdb.h"
    2225
    2326#define VALID_FNUM(fnum)   (((fnum) >= 0) && ((fnum) < real_max_open_files))
     
    2932****************************************************************************/
    3033
    31 static unsigned long get_gen_count(void)
    32 {
    33         if ((++file_gen_counter) == 0)
    34                 return ++file_gen_counter;
    35         return file_gen_counter;
     34static unsigned long get_gen_count(struct smbd_server_connection *sconn)
     35{
     36        sconn->file_gen_counter += 1;
     37        if (sconn->file_gen_counter == 0) {
     38                sconn->file_gen_counter += 1;
     39        }
     40        return sconn->file_gen_counter;
    3641}
    3742
     
    4348                  files_struct **result)
    4449{
     50        struct smbd_server_connection *sconn = conn->sconn;
    4551        int i;
    4652        files_struct *fsp;
     
    5258           increases the chance that the errant client will get an error rather
    5359           than causing corruption */
    54         if (first_file == 0) {
    55                 first_file = (sys_getpid() ^ (int)time(NULL)) % real_max_open_files;
     60        if (sconn->first_file == 0) {
     61                sconn->first_file = (sys_getpid() ^ (int)time(NULL));
     62                sconn->first_file %= sconn->real_max_open_files;
    5663        }
    5764
    5865        /* TODO: Port the id-tree implementation from Samba4 */
    5966
    60         i = bitmap_find(file_bmap, first_file);
     67        i = bitmap_find(sconn->file_bmap, sconn->first_file);
    6168        if (i == -1) {
    6269                DEBUG(0,("ERROR! Out of file structures\n"));
     
    6976        /*
    7077         * Make a child of the connection_struct as an fsp can't exist
    71          * indepenedent of a connection.
     78         * independent of a connection.
    7279         */
    7380        fsp = talloc_zero(conn, struct files_struct);
     
    9198
    9299        fsp->conn = conn;
    93         fsp->fh->gen_id = get_gen_count();
     100        fsp->fh->gen_id = get_gen_count(sconn);
    94101        GetTimeOfDay(&fsp->open_time);
    95102
    96         first_file = (i+1) % real_max_open_files;
    97 
    98         bitmap_set(file_bmap, i);
    99         files_used++;
     103        sconn->first_file = (i+1) % (sconn->real_max_open_files);
     104
     105        bitmap_set(sconn->file_bmap, i);
     106        sconn->files_used += 1;
    100107
    101108        fsp->fnum = i + FILE_HANDLE_OFFSET;
     
    114121        }
    115122
    116         DLIST_ADD(Files, fsp);
     123        DLIST_ADD(sconn->files, fsp);
    117124
    118125        DEBUG(5,("allocated file structure %d, fnum = %d (%d used)\n",
    119                  i, fsp->fnum, files_used));
     126                 i, fsp->fnum, sconn->files_used));
    120127
    121128        if (req != NULL) {
     
    128135          a cache hit to the *end* of the list. */
    129136
    130         ZERO_STRUCT(fsp_fi_cache);
     137        ZERO_STRUCT(sconn->fsp_fi_cache);
    131138
    132139        conn->num_files_open++;
     
    143150{
    144151        files_struct *fsp, *next;
    145        
    146         for (fsp=Files;fsp;fsp=next) {
     152
     153        for (fsp=conn->sconn->files; fsp; fsp=next) {
    147154                next = fsp->next;
    148155                if (fsp->conn == conn) {
     
    156163****************************************************************************/
    157164
    158 void file_close_pid(uint16 smbpid, int vuid)
     165void file_close_pid(struct smbd_server_connection *sconn, uint16 smbpid,
     166                    int vuid)
    159167{
    160168        files_struct *fsp, *next;
    161        
    162         for (fsp=Files;fsp;fsp=next) {
     169
     170        for (fsp=sconn->files;fsp;fsp=next) {
    163171                next = fsp->next;
    164172                if ((fsp->file_pid == smbpid) && (fsp->vuid == vuid)) {
     
    172180****************************************************************************/
    173181
    174 void file_init(void)
     182bool file_init(struct smbd_server_connection *sconn)
    175183{
    176184        int request_max_open_files = lp_max_open_files();
     
    184192        real_lim = set_maxfiles(request_max_open_files + MAX_OPEN_FUDGEFACTOR);
    185193
    186         real_max_open_files = real_lim - MAX_OPEN_FUDGEFACTOR;
    187 
    188         if (real_max_open_files + FILE_HANDLE_OFFSET + MAX_OPEN_PIPES > 65536)
    189                 real_max_open_files = 65536 - FILE_HANDLE_OFFSET - MAX_OPEN_PIPES;
    190 
    191         if(real_max_open_files != request_max_open_files) {
    192                 DEBUG(1,("file_init: Information only: requested %d \
    193 open files, %d are available.\n", request_max_open_files, real_max_open_files));
    194         }
    195 
    196         SMB_ASSERT(real_max_open_files > 100);
    197 
    198         file_bmap = bitmap_allocate(real_max_open_files);
    199        
    200         if (!file_bmap) {
    201                 exit_server("out of memory in file_init");
    202         }
     194        sconn->real_max_open_files = real_lim - MAX_OPEN_FUDGEFACTOR;
     195
     196        if (sconn->real_max_open_files + FILE_HANDLE_OFFSET + MAX_OPEN_PIPES
     197            > 65536)
     198                sconn->real_max_open_files =
     199                        65536 - FILE_HANDLE_OFFSET - MAX_OPEN_PIPES;
     200
     201        if(sconn->real_max_open_files != request_max_open_files) {
     202                DEBUG(1, ("file_init: Information only: requested %d "
     203                          "open files, %d are available.\n",
     204                          request_max_open_files, sconn->real_max_open_files));
     205        }
     206
     207        SMB_ASSERT(sconn->real_max_open_files > 100);
     208
     209        sconn->file_bmap = bitmap_talloc(sconn, sconn->real_max_open_files);
     210
     211        if (!sconn->file_bmap) {
     212                return false;
     213        }
     214        return true;
    203215}
    204216
     
    207219****************************************************************************/
    208220
    209 void file_close_user(int vuid)
     221void file_close_user(struct smbd_server_connection *sconn, int vuid)
    210222{
    211223        files_struct *fsp, *next;
    212224
    213         for (fsp=Files;fsp;fsp=next) {
     225        for (fsp=sconn->files; fsp; fsp=next) {
    214226                next=fsp->next;
    215227                if (fsp->vuid == vuid) {
     
    223235 */
    224236
    225 struct files_struct *file_walk_table(
     237struct files_struct *files_forall(
     238        struct smbd_server_connection *sconn,
    226239        struct files_struct *(*fn)(struct files_struct *fsp,
    227240                                   void *private_data),
     
    230243        struct files_struct *fsp, *next;
    231244
    232         for (fsp = Files; fsp; fsp = next) {
     245        for (fsp = sconn->files; fsp; fsp = next) {
    233246                struct files_struct *ret;
    234247                next = fsp->next;
     
    242255
    243256/****************************************************************************
    244  Debug to enumerate all open files in the smbd.
    245 ****************************************************************************/
    246 
    247 void file_dump_open_table(void)
     257 Find a fsp given a file descriptor.
     258****************************************************************************/
     259
     260files_struct *file_find_fd(struct smbd_server_connection *sconn, int fd)
    248261{
    249262        int count=0;
    250263        files_struct *fsp;
    251264
    252         for (fsp=Files;fsp;fsp=fsp->next,count++) {
    253                 DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, gen = %lu, "
    254                           "fileid=%s\n", count, fsp->fnum, fsp_str_dbg(fsp),
    255                           fsp->fh->fd, (unsigned long)fsp->fh->gen_id,
    256                           file_id_string_tos(&fsp->file_id)));
    257         }
    258 }
    259 
    260 /****************************************************************************
    261  Find a fsp given a file descriptor.
    262 ****************************************************************************/
    263 
    264 files_struct *file_find_fd(int fd)
    265 {
    266         int count=0;
    267         files_struct *fsp;
    268 
    269         for (fsp=Files;fsp;fsp=fsp->next,count++) {
     265        for (fsp=sconn->files; fsp; fsp=fsp->next,count++) {
    270266                if (fsp->fh->fd == fd) {
    271267                        if (count > 10) {
    272                                 DLIST_PROMOTE(Files, fsp);
     268                                DLIST_PROMOTE(sconn->files, fsp);
    273269                        }
    274270                        return fsp;
     
    283279****************************************************************************/
    284280
    285 files_struct *file_find_dif(struct file_id id, unsigned long gen_id)
     281files_struct *file_find_dif(struct smbd_server_connection *sconn,
     282                            struct file_id id, unsigned long gen_id)
    286283{
    287284        int count=0;
    288285        files_struct *fsp;
    289286
    290         for (fsp=Files;fsp;fsp=fsp->next,count++) {
     287        for (fsp=sconn->files; fsp; fsp=fsp->next,count++) {
    291288                /* We can have a fsp->fh->fd == -1 here as it could be a stat open. */
    292289                if (file_id_equal(&fsp->file_id, &id) &&
    293290                    fsp->fh->gen_id == gen_id ) {
    294291                        if (count > 10) {
    295                                 DLIST_PROMOTE(Files, fsp);
     292                                DLIST_PROMOTE(sconn->files, fsp);
    296293                        }
    297294                        /* Paranoia check. */
     
    316313
    317314/****************************************************************************
    318  Check if an fsp still exists.
    319 ****************************************************************************/
    320 
    321 files_struct *file_find_fsp(files_struct *orig_fsp)
    322 {
    323         files_struct *fsp;
    324 
    325         for (fsp=Files;fsp;fsp=fsp->next) {
    326                 if (fsp == orig_fsp)
    327                         return fsp;
    328         }
    329 
    330         return NULL;
    331 }
    332 
    333 /****************************************************************************
    334315 Find the first fsp given a device and inode.
    335316 We use a singleton cache here to speed up searching from getfilepathinfo
     
    337318****************************************************************************/
    338319
    339 files_struct *file_find_di_first(struct file_id id)
    340 {
    341         files_struct *fsp;
    342 
    343         if (file_id_equal(&fsp_fi_cache.id, &id)) {
     320files_struct *file_find_di_first(struct smbd_server_connection *sconn,
     321                                 struct file_id id)
     322{
     323        files_struct *fsp;
     324
     325        if (file_id_equal(&sconn->fsp_fi_cache.id, &id)) {
    344326                /* Positive or negative cache hit. */
    345                 return fsp_fi_cache.fsp;
    346         }
    347 
    348         fsp_fi_cache.id = id;
    349 
    350         for (fsp=Files;fsp;fsp=fsp->next) {
     327                return sconn->fsp_fi_cache.fsp;
     328        }
     329
     330        sconn->fsp_fi_cache.id = id;
     331
     332        for (fsp=sconn->files;fsp;fsp=fsp->next) {
    351333                if (file_id_equal(&fsp->file_id, &id)) {
    352334                        /* Setup positive cache. */
    353                         fsp_fi_cache.fsp = fsp;
     335                        sconn->fsp_fi_cache.fsp = fsp;
    354336                        return fsp;
    355337                }
     
    357339
    358340        /* Setup negative cache. */
    359         fsp_fi_cache.fsp = NULL;
     341        sconn->fsp_fi_cache.fsp = NULL;
    360342        return NULL;
    361343}
     
    379361
    380362/****************************************************************************
    381  Find a fsp that is open for printing.
    382 ****************************************************************************/
    383 
    384 files_struct *file_find_print(void)
    385 {
    386         files_struct *fsp;
    387 
    388         for (fsp=Files;fsp;fsp=fsp->next) {
    389                 if (fsp->print_file) {
    390                         return fsp;
    391                 }
    392         }
    393 
    394         return NULL;
    395 }
    396 
    397 /****************************************************************************
    398363 Find any fsp open with a pathname below that of an already open path.
    399364****************************************************************************/
     
    415380        dlen = strlen(d_fullname);
    416381
    417         for (fsp=Files;fsp;fsp=fsp->next) {
     382        for (fsp=dir_fsp->conn->sconn->files; fsp; fsp=fsp->next) {
    418383                char *d1_fullname;
    419384
     
    452417        files_struct *fsp, *next;
    453418
    454         for (fsp=Files;fsp;fsp=next) {
     419        for (fsp=conn->sconn->files; fsp; fsp=next) {
    455420                next=fsp->next;
    456421                if ((conn == fsp->conn) && (fsp->fh->fd != -1)) {
     
    466431void file_free(struct smb_request *req, files_struct *fsp)
    467432{
    468         DLIST_REMOVE(Files, fsp);
     433        struct smbd_server_connection *sconn = fsp->conn->sconn;
     434
     435        DLIST_REMOVE(sconn->files, fsp);
    469436
    470437        TALLOC_FREE(fsp->fake_file_handle);
     
    491458        TALLOC_FREE(fsp->update_write_time_event);
    492459
    493         bitmap_clear(file_bmap, fsp->fnum - FILE_HANDLE_OFFSET);
    494         files_used--;
     460        bitmap_clear(sconn->file_bmap, fsp->fnum - FILE_HANDLE_OFFSET);
     461        sconn->files_used--;
    495462
    496463        DEBUG(5,("freed files structure %d (%d used)\n",
    497                  fsp->fnum, files_used));
     464                 fsp->fnum, sconn->files_used));
    498465
    499466        fsp->conn->num_files_open--;
     
    503470        }
    504471
     472        /*
     473         * Clear all possible chained fsp
     474         * pointers in the SMB2 request queue.
     475         */
     476        if (req != NULL && req->smb2req) {
     477                remove_smb2_chained_fsp(fsp);
     478        }
     479
    505480        /* Closing a file can invalidate the positive cache. */
    506         if (fsp == fsp_fi_cache.fsp) {
    507                 ZERO_STRUCT(fsp_fi_cache);
     481        if (fsp == sconn->fsp_fi_cache.fsp) {
     482                ZERO_STRUCT(sconn->fsp_fi_cache);
    508483        }
    509484
     
    525500****************************************************************************/
    526501
    527 files_struct *file_fnum(uint16 fnum)
     502static struct files_struct *file_fnum(struct smbd_server_connection *sconn,
     503                                      uint16 fnum)
    528504{
    529505        files_struct *fsp;
    530506        int count=0;
    531507
    532         for (fsp=Files;fsp;fsp=fsp->next, count++) {
     508        for (fsp=sconn->files; fsp; fsp=fsp->next, count++) {
    533509                if (fsp->fnum == fnum) {
    534510                        if (count > 10) {
    535                                 DLIST_PROMOTE(Files, fsp);
     511                                DLIST_PROMOTE(sconn->files, fsp);
    536512                        }
    537513                        return fsp;
     
    542518
    543519/****************************************************************************
    544  Get an fsp from a packet given the offset of a 16 bit fnum.
     520 Get an fsp from a packet given a 16 bit fnum.
    545521****************************************************************************/
    546522
     
    549525        files_struct *fsp;
    550526
    551         if ((req != NULL) && (req->chain_fsp != NULL)) {
     527        if (req == NULL) {
     528                /*
     529                 * We should never get here. req==NULL could in theory
     530                 * only happen from internal opens with a non-zero
     531                 * root_dir_fid. Internal opens just don't do that, at
     532                 * least they are not supposed to do so. And if they
     533                 * start to do so, they better fake up a smb_request
     534                 * from which we get the right smbd_server_conn. While
     535                 * this should never happen, let's return NULL here.
     536                 */
     537                return NULL;
     538        }
     539
     540        if (req->chain_fsp != NULL) {
    552541                return req->chain_fsp;
    553542        }
    554543
    555         fsp = file_fnum(fid);
    556         if ((fsp != NULL) && (req != NULL)) {
     544        fsp = file_fnum(req->sconn, fid);
     545        if (fsp != NULL) {
    557546                req->chain_fsp = fsp;
    558547        }
     
    589578                to->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ? True : False;
    590579        }
    591         to->print_file = from->print_file;
    592580        to->modified = from->modified;
    593581        to->is_directory = from->is_directory;
    594582        to->aio_write_behind = from->aio_write_behind;
     583
     584        if (from->print_file) {
     585                to->print_file = talloc(to, struct print_file_data);
     586                if (!to->print_file) return NT_STATUS_NO_MEMORY;
     587                to->print_file->rap_jobid = from->print_file->rap_jobid;
     588        } else {
     589                to->print_file = NULL;
     590        }
     591
    595592        return fsp_set_smb_fname(to, from->fsp_name);
     593}
     594
     595/**
     596 * Return a jenkins hash of a pathname on a connection.
     597 */
     598
     599NTSTATUS file_name_hash(connection_struct *conn,
     600                        const char *name, uint32_t *p_name_hash)
     601{
     602        TDB_DATA key;
     603        char *fullpath = NULL;
     604
     605        /* Set the hash of the full pathname. */
     606        fullpath = talloc_asprintf(talloc_tos(),
     607                        "%s/%s",
     608                        conn->connectpath,
     609                        name);
     610        if (!fullpath) {
     611                return NT_STATUS_NO_MEMORY;
     612        }
     613        key = string_term_tdb_data(fullpath);
     614        *p_name_hash = tdb_jenkins_hash(&key);
     615
     616        DEBUG(10,("file_name_hash: %s hash 0x%x\n",
     617                fullpath,
     618                (unsigned int)*p_name_hash ));
     619
     620        TALLOC_FREE(fullpath);
     621        return NT_STATUS_OK;
    596622}
    597623
     
    613639        fsp->fsp_name = smb_fname_new;
    614640
    615         return NT_STATUS_OK;
    616 }
     641        return file_name_hash(fsp->conn,
     642                        smb_fname_str_dbg(fsp->fsp_name),
     643                        &fsp->name_hash);
     644}
Note: See TracChangeset for help on using the changeset viewer.