Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/smbd/oplock.c

    r740 r988  
    55   Copyright (C) Jeremy Allison 1998 - 2001
    66   Copyright (C) Volker Lendecke 2005
    7    
     7
    88   This program is free software; you can redistribute it and/or modify
    99   it under the terms of the GNU General Public License as published by
    1010   the Free Software Foundation; either version 3 of the License, or
    1111   (at your option) any later version.
    12    
     12
    1313   This program is distributed in the hope that it will be useful,
    1414   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1515   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1616   GNU General Public License for more details.
    17    
     17
    1818   You should have received a copy of the GNU General Public License
    1919   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2525#include "smbd/globals.h"
    2626#include "messages.h"
    27 
    28 /****************************************************************************
    29  Get the number of current exclusive oplocks.
    30 ****************************************************************************/
    31 
    32 int32 get_number_of_exclusive_open_oplocks(void)
    33 {
    34   return exclusive_oplocks_open;
    35 }
     27#include "../librpc/gen_ndr/open_files.h"
    3628
    3729/*
     
    5648/****************************************************************************
    5749 Attempt to set an oplock on a file. Succeeds if kernel oplocks are
    58  disabled (just sets flags) and no byte-range locks in the file. Returns True
    59  if oplock set.
     50 disabled (just sets flags).
    6051****************************************************************************/
    6152
    62 bool set_file_oplock(files_struct *fsp, int oplock_type)
    63 {
     53NTSTATUS set_file_oplock(files_struct *fsp)
     54{
     55        struct smbd_server_connection *sconn = fsp->conn->sconn;
     56        struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops;
     57        bool use_kernel = lp_kernel_oplocks(SNUM(fsp->conn)) && koplocks;
     58
    6459        if (fsp->oplock_type == LEVEL_II_OPLOCK) {
    65                 if (koplocks &&
     60                if (use_kernel &&
    6661                    !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) {
    6762                        DEBUG(10, ("Refusing level2 oplock, kernel oplocks "
    6863                                   "don't support them\n"));
    69                         return false;
     64                        return NT_STATUS_NOT_SUPPORTED;
    7065                }
    7166        }
    7267
    7368        if ((fsp->oplock_type != NO_OPLOCK) &&
    74             (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) &&
    75             koplocks &&
    76             !koplocks->ops->set_oplock(koplocks, fsp, oplock_type)) {
    77                 return False;
    78         }
    79 
    80         fsp->oplock_type = oplock_type;
     69            use_kernel &&
     70            !koplocks->ops->set_oplock(koplocks, fsp, fsp->oplock_type))
     71        {
     72                return map_nt_error_from_unix(errno);
     73        }
     74
    8175        fsp->sent_oplock_break = NO_BREAK_SENT;
    82         if (oplock_type == LEVEL_II_OPLOCK) {
    83                 level_II_oplocks_open++;
     76        if (fsp->oplock_type == LEVEL_II_OPLOCK) {
     77                sconn->oplocks.level_II_open++;
    8478        } else if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
    85                 exclusive_oplocks_open++;
     79                sconn->oplocks.exclusive_open++;
    8680        }
    8781
     
    9286                 (int)fsp->open_time.tv_usec ));
    9387
    94         return True;
     88        return NT_STATUS_OK;
    9589}
    9690
     
    9993****************************************************************************/
    10094
    101 void release_file_oplock(files_struct *fsp)
    102 {
     95static void release_file_oplock(files_struct *fsp)
     96{
     97        struct smbd_server_connection *sconn = fsp->conn->sconn;
     98        struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops;
     99        bool use_kernel = lp_kernel_oplocks(SNUM(fsp->conn)) && koplocks;
     100
    103101        if ((fsp->oplock_type != NO_OPLOCK) &&
    104             (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) &&
    105             koplocks) {
     102            use_kernel) {
    106103                koplocks->ops->release_oplock(koplocks, fsp, NO_OPLOCK);
    107104        }
    108105
    109106        if (fsp->oplock_type == LEVEL_II_OPLOCK) {
    110                 level_II_oplocks_open--;
     107                sconn->oplocks.level_II_open--;
    111108        } else if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
    112                 exclusive_oplocks_open--;
    113         }
    114 
    115         SMB_ASSERT(exclusive_oplocks_open>=0);
    116         SMB_ASSERT(level_II_oplocks_open>=0);
    117 
    118         if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
    119                 /* This doesn't matter for close. */
    120                 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
    121         } else {
    122                 fsp->oplock_type = NO_OPLOCK;
    123         }
     109                sconn->oplocks.exclusive_open--;
     110        }
     111
     112        SMB_ASSERT(sconn->oplocks.exclusive_open>=0);
     113        SMB_ASSERT(sconn->oplocks.level_II_open>=0);
     114
     115        fsp->oplock_type = NO_OPLOCK;
    124116        fsp->sent_oplock_break = NO_BREAK_SENT;
    125117
    126         flush_write_cache(fsp, OPLOCK_RELEASE_FLUSH);
     118        flush_write_cache(fsp, SAMBA_OPLOCK_RELEASE_FLUSH);
    127119        delete_write_cache(fsp);
    128120
     
    136128static void downgrade_file_oplock(files_struct *fsp)
    137129{
     130        struct smbd_server_connection *sconn = fsp->conn->sconn;
     131        struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops;
     132
    138133        if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
    139134                DEBUG(0, ("trying to downgrade an already-downgraded oplock!\n"));
     
    145140        }
    146141        fsp->oplock_type = LEVEL_II_OPLOCK;
    147         exclusive_oplocks_open--;
    148         level_II_oplocks_open++;
     142        sconn->oplocks.exclusive_open--;
     143        sconn->oplocks.level_II_open++;
    149144        fsp->sent_oplock_break = NO_BREAK_SENT;
     145
     146        flush_write_cache(fsp, SAMBA_OPLOCK_RELEASE_FLUSH);
     147        delete_write_cache(fsp);
     148
     149        TALLOC_FREE(fsp->oplock_timeout);
     150}
     151
     152uint32_t map_oplock_to_lease_type(uint16_t op_type)
     153{
     154        uint32_t ret;
     155
     156        switch(op_type) {
     157        case BATCH_OPLOCK:
     158        case BATCH_OPLOCK|EXCLUSIVE_OPLOCK:
     159                ret = SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE;
     160                break;
     161        case EXCLUSIVE_OPLOCK:
     162                ret = SMB2_LEASE_READ|SMB2_LEASE_WRITE;
     163                break;
     164        case LEVEL_II_OPLOCK:
     165                ret = SMB2_LEASE_READ;
     166                break;
     167        default:
     168                ret = SMB2_LEASE_NONE;
     169                break;
     170        }
     171        return ret;
     172}
     173
     174uint32_t get_lease_type(struct share_mode_data *d, struct share_mode_entry *e)
     175{
     176        if (e->op_type == LEASE_OPLOCK) {
     177                return d->leases[e->lease_idx].current_state;
     178        }
     179        return map_oplock_to_lease_type(e->op_type);
     180}
     181
     182bool update_num_read_oplocks(files_struct *fsp, struct share_mode_lock *lck)
     183{
     184        struct share_mode_data *d = lck->data;
     185        struct byte_range_lock *br_lck;
     186        uint32_t num_read_oplocks = 0;
     187        uint32_t i;
     188
     189        if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
     190                /*
     191                 * If we're the only one, we don't need a brlock entry
     192                 */
     193                SMB_ASSERT(d->num_share_modes == 1);
     194                SMB_ASSERT(EXCLUSIVE_OPLOCK_TYPE(d->share_modes[0].op_type));
     195                return true;
     196        }
     197
     198        for (i=0; i<d->num_share_modes; i++) {
     199                struct share_mode_entry *e = &d->share_modes[i];
     200                uint32_t e_lease_type = get_lease_type(d, e);
     201
     202                if (e_lease_type & SMB2_LEASE_READ) {
     203                        num_read_oplocks += 1;
     204                }
     205        }
     206
     207        br_lck = brl_get_locks_readonly(fsp);
     208        if (br_lck == NULL) {
     209                return false;
     210        }
     211        if (brl_num_read_oplocks(br_lck) == num_read_oplocks) {
     212                return true;
     213        }
     214
     215        br_lck = brl_get_locks(talloc_tos(), fsp);
     216        if (br_lck == NULL) {
     217                return false;
     218        }
     219        brl_set_num_read_oplocks(br_lck, num_read_oplocks);
     220        TALLOC_FREE(br_lck);
     221        return true;
    150222}
    151223
     
    161233        struct share_mode_lock *lck;
    162234
     235        DEBUG(10, ("remove_oplock called for %s\n",
     236                   fsp_str_dbg(fsp)));
     237
    163238        /* Remove the oplock flag from the sharemode. */
    164         lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
    165                                   NULL);
     239        lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
    166240        if (lck == NULL) {
    167241                DEBUG(0,("remove_oplock: failed to lock share entry for "
     
    169243                return False;
    170244        }
     245
    171246        ret = remove_share_oplock(lck, fsp);
    172247        if (!ret) {
    173248                DEBUG(0,("remove_oplock: failed to remove share oplock for "
    174                          "file %s fnum %d, %s\n",
    175                          fsp_str_dbg(fsp), fsp->fnum,
     249                         "file %s, %s, %s\n",
     250                         fsp_str_dbg(fsp), fsp_fnum_dbg(fsp),
    176251                         file_id_string_tos(&fsp->file_id)));
    177252        }
    178253        release_file_oplock(fsp);
     254
     255        ret = update_num_read_oplocks(fsp, lck);
     256        if (!ret) {
     257                DEBUG(0, ("%s: update_num_read_oplocks failed for "
     258                         "file %s, %s, %s\n",
     259                          __func__, fsp_str_dbg(fsp), fsp_fnum_dbg(fsp),
     260                         file_id_string_tos(&fsp->file_id)));
     261        }
     262
    179263        TALLOC_FREE(lck);
    180264        return ret;
     
    189273        struct share_mode_lock *lck;
    190274
    191         lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
    192                                   NULL);
     275        DEBUG(10, ("downgrade_oplock called for %s\n",
     276                   fsp_str_dbg(fsp)));
     277
     278        lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
    193279        if (lck == NULL) {
    194280                DEBUG(0,("downgrade_oplock: failed to lock share entry for "
     
    199285        if (!ret) {
    200286                DEBUG(0,("downgrade_oplock: failed to downgrade share oplock "
    201                          "for file %s fnum %d, file_id %s\n",
    202                          fsp_str_dbg(fsp), fsp->fnum,
     287                         "for file %s, %s, file_id %s\n",
     288                         fsp_str_dbg(fsp), fsp_fnum_dbg(fsp),
    203289                         file_id_string_tos(&fsp->file_id)));
    204290        }
    205 
    206291        downgrade_file_oplock(fsp);
     292
     293        ret = update_num_read_oplocks(fsp, lck);
     294        if (!ret) {
     295                DEBUG(0, ("%s: update_num_read_oplocks failed for "
     296                         "file %s, %s, %s\n",
     297                          __func__, fsp_str_dbg(fsp), fsp_fnum_dbg(fsp),
     298                         file_id_string_tos(&fsp->file_id)));
     299        }
     300
    207301        TALLOC_FREE(lck);
    208302        return ret;
    209303}
    210304
    211 /*
    212  * Some kernel oplock implementations handle the notification themselves.
    213  */
    214 bool should_notify_deferred_opens()
    215 {
    216         return !(koplocks &&
    217                 (koplocks->flags & KOPLOCKS_DEFERRED_OPEN_NOTIFICATION));
     305static void lease_timeout_handler(struct tevent_context *ctx,
     306                                  struct tevent_timer *te,
     307                                  struct timeval now,
     308                                  void *private_data)
     309{
     310        struct fsp_lease *lease =
     311                talloc_get_type_abort(private_data,
     312                struct fsp_lease);
     313        struct files_struct *fsp;
     314        struct share_mode_lock *lck;
     315        uint16_t old_epoch = lease->lease.lease_epoch;
     316
     317        fsp = file_find_one_fsp_from_lease_key(lease->sconn,
     318                                               &lease->lease.lease_key);
     319        if (fsp == NULL) {
     320                /* race? */
     321                TALLOC_FREE(lease->timeout);
     322                return;
     323        }
     324
     325        lck = get_existing_share_mode_lock(
     326                        talloc_tos(), fsp->file_id);
     327        if (lck == NULL) {
     328                /* race? */
     329                TALLOC_FREE(lease->timeout);
     330                return;
     331        }
     332
     333        fsp_lease_update(lck, fsp_client_guid(fsp), lease);
     334
     335        if (lease->lease.lease_epoch != old_epoch) {
     336                /*
     337                 * If the epoch changed we need to wait for
     338                 * the next timeout to happen.
     339                 */
     340                DEBUG(10, ("lease break timeout race (epoch) for file %s - ignoring\n",
     341                           fsp_str_dbg(fsp)));
     342                TALLOC_FREE(lck);
     343                return;
     344        }
     345
     346        if (!(lease->lease.lease_flags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)) {
     347                /*
     348                 * If the epoch changed we need to wait for
     349                 * the next timeout to happen.
     350                 */
     351                DEBUG(10, ("lease break timeout race (flags) for file %s - ignoring\n",
     352                           fsp_str_dbg(fsp)));
     353                TALLOC_FREE(lck);
     354                return;
     355        }
     356
     357        DEBUG(1, ("lease break timed out for file %s -- replying anyway\n",
     358                  fsp_str_dbg(fsp)));
     359        (void)downgrade_lease(lease->sconn->client->connections,
     360                        1,
     361                        &fsp->file_id,
     362                        &lease->lease.lease_key,
     363                        SMB2_LEASE_NONE);
     364
     365        TALLOC_FREE(lck);
     366}
     367
     368bool fsp_lease_update(struct share_mode_lock *lck,
     369                      const struct GUID *client_guid,
     370                      struct fsp_lease *lease)
     371{
     372        struct share_mode_data *d = lck->data;
     373        int idx;
     374        struct share_mode_lease *l = NULL;
     375
     376        idx = find_share_mode_lease(d, client_guid, &lease->lease.lease_key);
     377        if (idx != -1) {
     378                l = &d->leases[idx];
     379        }
     380
     381        if (l == NULL) {
     382                DEBUG(1, ("%s: Could not find lease entry\n", __func__));
     383                TALLOC_FREE(lease->timeout);
     384                lease->lease.lease_state = SMB2_LEASE_NONE;
     385                lease->lease.lease_epoch += 1;
     386                lease->lease.lease_flags = 0;
     387                return false;
     388        }
     389
     390        DEBUG(10,("%s: refresh lease state\n", __func__));
     391
     392        /* Ensure we're in sync with current lease state. */
     393        if (lease->lease.lease_epoch != l->epoch) {
     394                DEBUG(10,("%s: cancel outdated timeout\n", __func__));
     395                TALLOC_FREE(lease->timeout);
     396        }
     397        lease->lease.lease_epoch = l->epoch;
     398        lease->lease.lease_state = l->current_state;
     399
     400        if (l->breaking) {
     401                lease->lease.lease_flags |= SMB2_LEASE_FLAG_BREAK_IN_PROGRESS;
     402
     403                if (lease->timeout == NULL) {
     404                        struct timeval t = timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0);
     405
     406                        DEBUG(10,("%s: setup timeout handler\n", __func__));
     407
     408                        lease->timeout = tevent_add_timer(lease->sconn->ev_ctx,
     409                                                          lease, t,
     410                                                          lease_timeout_handler,
     411                                                          lease);
     412                        if (lease->timeout == NULL) {
     413                                DEBUG(0, ("%s: Could not add lease timeout handler\n",
     414                                          __func__));
     415                        }
     416                }
     417        } else {
     418                lease->lease.lease_flags &= ~SMB2_LEASE_FLAG_BREAK_IN_PROGRESS;
     419                TALLOC_FREE(lease->timeout);
     420        }
     421
     422        return true;
     423}
     424
     425struct downgrade_lease_additional_state {
     426        struct tevent_immediate *im;
     427        struct smbXsrv_connection *xconn;
     428        uint32_t break_flags;
     429        struct smb2_lease_key lease_key;
     430        uint32_t break_from;
     431        uint32_t break_to;
     432        uint16_t new_epoch;
     433};
     434
     435static void downgrade_lease_additional_trigger(struct tevent_context *ev,
     436                                               struct tevent_immediate *im,
     437                                               void *private_data)
     438{
     439        struct downgrade_lease_additional_state *state =
     440                talloc_get_type_abort(private_data,
     441                struct downgrade_lease_additional_state);
     442        struct smbXsrv_connection *xconn = state->xconn;
     443        NTSTATUS status;
     444
     445        status = smbd_smb2_send_lease_break(xconn,
     446                                            state->new_epoch,
     447                                            state->break_flags,
     448                                            &state->lease_key,
     449                                            state->break_from,
     450                                            state->break_to);
     451        TALLOC_FREE(state);
     452        if (!NT_STATUS_IS_OK(status)) {
     453                smbd_server_connection_terminate(xconn,
     454                                                 nt_errstr(status));
     455                return;
     456        }
     457}
     458
     459struct downgrade_lease_fsps_state {
     460        struct file_id id;
     461        struct share_mode_lock *lck;
     462        const struct smb2_lease_key *key;
     463};
     464
     465static struct files_struct *downgrade_lease_fsps(struct files_struct *fsp,
     466                                                 void *private_data)
     467{
     468        struct downgrade_lease_fsps_state *state =
     469                (struct downgrade_lease_fsps_state *)private_data;
     470
     471        if (fsp->oplock_type != LEASE_OPLOCK) {
     472                return NULL;
     473        }
     474        if (!smb2_lease_key_equal(&fsp->lease->lease.lease_key, state->key)) {
     475                return NULL;
     476        }
     477        if (!file_id_equal(&fsp->file_id, &state->id)) {
     478                return NULL;
     479        }
     480
     481        fsp_lease_update(state->lck, fsp_client_guid(fsp), fsp->lease);
     482
     483        return NULL;
     484}
     485
     486NTSTATUS downgrade_lease(struct smbXsrv_connection *xconn,
     487                         uint32_t num_file_ids,
     488                         const struct file_id *ids,
     489                         const struct smb2_lease_key *key,
     490                         uint32_t lease_state)
     491{
     492        struct smbd_server_connection *sconn = xconn->client->sconn;
     493        struct share_mode_lock *lck;
     494        struct share_mode_lease *l = NULL;
     495        const struct file_id id = ids[0];
     496        uint32_t i;
     497        NTSTATUS status;
     498
     499        DEBUG(10, ("%s: Downgrading %s to %x\n", __func__,
     500                   file_id_string_tos(&id), (unsigned)lease_state));
     501
     502        lck = get_existing_share_mode_lock(talloc_tos(), id);
     503        if (lck == NULL) {
     504                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
     505        }
     506        status = downgrade_share_lease(sconn, lck, key, lease_state, &l);
     507
     508        DEBUG(10, ("%s: Downgrading %s to %x => %s\n", __func__,
     509                   file_id_string_tos(&id), (unsigned)lease_state, nt_errstr(status)));
     510
     511        if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_BREAK_IN_PROGRESS)) {
     512                struct downgrade_lease_additional_state *state;
     513
     514                state = talloc_zero(xconn,
     515                                    struct downgrade_lease_additional_state);
     516                if (state == NULL) {
     517                        TALLOC_FREE(lck);
     518                        return NT_STATUS_NO_MEMORY;
     519                }
     520
     521                state->im = tevent_create_immediate(state);
     522                if (state->im == NULL) {
     523                        TALLOC_FREE(state);
     524                        TALLOC_FREE(lck);
     525                        return NT_STATUS_NO_MEMORY;
     526                }
     527
     528                state->xconn = xconn;
     529                if (l->current_state & (~SMB2_LEASE_READ)) {
     530                        state->break_flags = SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED;
     531                }
     532                state->lease_key = l->lease_key;
     533                state->break_from = l->current_state;
     534                state->break_to = l->breaking_to_requested;
     535                if (l->lease_version > 1) {
     536                        state->new_epoch = l->epoch;
     537                }
     538
     539                if (state->break_flags == 0) {
     540                        /*
     541                         * This is an async break without
     542                         * SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED
     543                         *
     544                         * we need to store NONE state in the
     545                         * database.
     546                         */
     547                        l->current_state = 0;
     548                        l->breaking_to_requested = 0;
     549                        l->breaking_to_required = 0;
     550                        l->breaking = false;
     551
     552                        lck->data->modified = true;
     553                }
     554
     555                tevent_schedule_immediate(state->im, xconn->ev_ctx,
     556                                          downgrade_lease_additional_trigger,
     557                                          state);
     558        }
     559
     560        {
     561                struct downgrade_lease_fsps_state state = {
     562                        .id = id, .lck = lck, .key = key,
     563                };
     564
     565                files_forall(sconn, downgrade_lease_fsps, &state);
     566        }
     567
     568        TALLOC_FREE(lck);
     569        DEBUG(10, ("%s: Downgrading %s to %x => %s\n", __func__,
     570                   file_id_string_tos(&id), (unsigned)lease_state, nt_errstr(status)));
     571
     572        /*
     573         * Dynamic share case. Ensure other opens are copies.
     574         * This will only be breaking to NONE.
     575         */
     576
     577        for (i = 1; i < num_file_ids; i++) {
     578                lck = get_existing_share_mode_lock(talloc_tos(), ids[i]);
     579                if (lck == NULL) {
     580                        return NT_STATUS_OBJECT_NAME_NOT_FOUND;
     581                }
     582
     583                {
     584                        struct downgrade_lease_fsps_state state = {
     585                                .id = ids[i], .lck = lck, .key = key,
     586                        };
     587
     588                        files_forall(sconn, downgrade_lease_fsps, &state);
     589                }
     590
     591                DEBUG(10, ("%s: Downgrading %s to %x => %s\n", __func__,
     592                        file_id_string_tos(&ids[i]), (unsigned)lease_state, nt_errstr(status)));
     593
     594                TALLOC_FREE(lck);
     595        }
     596
     597        return status;
    218598}
    219599
     
    222602****************************************************************************/
    223603
    224 static char *new_break_message_smb1(TALLOC_CTX *mem_ctx,
    225                                    files_struct *fsp, int cmd)
    226 {
    227         char *result = TALLOC_ARRAY(mem_ctx, char, smb_size + 8*2 + 0);
    228 
    229         if (result == NULL) {
    230                 DEBUG(0, ("talloc failed\n"));
    231                 return NULL;
    232         }
    233 
     604#define SMB1_BREAK_MESSAGE_LENGTH (smb_size + 8*2)
     605
     606static void new_break_message_smb1(files_struct *fsp, int cmd,
     607                                   char result[SMB1_BREAK_MESSAGE_LENGTH])
     608{
    234609        memset(result,'\0',smb_size);
    235610        srv_set_message(result,8,0,true);
     
    243618        SCVAL(result,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
    244619        SCVAL(result,smb_vwv3+1,cmd);
    245         return result;
    246620}
    247621
     
    269643        files_struct *fsp = NULL;
    270644
    271         if( DEBUGLVL( 3 ) ) {
    272                 dbgtext( "initial_break_processing: called for %s/%u\n",
    273                          file_id_string_tos(&id), (int)file_id);
    274                 dbgtext( "Current oplocks_open (exclusive = %d, levelII = %d)\n",
    275                         exclusive_oplocks_open, level_II_oplocks_open );
    276         }
     645        DEBUG(3, ("initial_break_processing: called for %s/%u\n"
     646                  "Current oplocks_open (exclusive = %d, levelII = %d)\n",
     647                  file_id_string_tos(&id), (int)file_id,
     648                  sconn->oplocks.exclusive_open,
     649                  sconn->oplocks.level_II_open));
    277650
    278651        /*
     
    286659        if(fsp == NULL) {
    287660                /* The file could have been closed in the meantime - return success. */
    288                 if( DEBUGLVL( 3 ) ) {
    289                         dbgtext( "initial_break_processing: cannot find open file with " );
    290                         dbgtext( "file_id %s gen_id = %lu", file_id_string_tos(&id), file_id);
    291                         dbgtext( "allowing break to succeed.\n" );
    292                 }
     661                DEBUG(3, ("initial_break_processing: cannot find open file "
     662                          "with file_id %s gen_id = %lu, allowing break to "
     663                          "succeed.\n", file_id_string_tos(&id), file_id));
    293664                return NULL;
    294665        }
     
    305676
    306677        if(fsp->oplock_type == NO_OPLOCK) {
    307                 if( DEBUGLVL( 3 ) ) {
    308                         dbgtext( "initial_break_processing: file %s ",
    309                                  fsp_str_dbg(fsp));
    310                         dbgtext( "(file_id = %s gen_id = %lu) has no oplock.\n",
    311                                  file_id_string_tos(&id), fsp->fh->gen_id );
    312                         dbgtext( "Allowing break to succeed regardless.\n" );
    313                 }
     678                DEBUG(3, ("initial_break_processing: file %s (file_id = %s "
     679                          "gen_id = %lu) has no oplock. Allowing break to "
     680                          "succeed regardless.\n", fsp_str_dbg(fsp),
     681                          file_id_string_tos(&id), fsp->fh->gen_id));
    314682                return NULL;
    315683        }
     
    318686}
    319687
    320 static void oplock_timeout_handler(struct event_context *ctx,
    321                                    struct timed_event *te,
     688static void oplock_timeout_handler(struct tevent_context *ctx,
     689                                   struct tevent_timer *te,
    322690                                   struct timeval now,
    323691                                   void *private_data)
    324692{
    325693        files_struct *fsp = (files_struct *)private_data;
     694
     695        SMB_ASSERT(fsp->sent_oplock_break != NO_BREAK_SENT);
    326696
    327697        /* Remove the timed event handler. */
     
    330700                  fsp_str_dbg(fsp)));
    331701        remove_oplock(fsp);
    332         reply_to_oplock_break_requests(fsp);
    333702}
    334703
     
    339708static void add_oplock_timeout_handler(files_struct *fsp)
    340709{
     710        struct smbd_server_connection *sconn = fsp->conn->sconn;
     711        struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops;
     712
    341713        /*
    342714         * If kernel oplocks already notifies smbds when an oplock break times
     
    354726
    355727        fsp->oplock_timeout =
    356                 event_add_timed(smbd_event_context(), fsp,
    357                                 timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0),
    358                                 oplock_timeout_handler, fsp);
     728                tevent_add_timer(fsp->conn->sconn->ev_ctx, fsp,
     729                                 timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0),
     730                                 oplock_timeout_handler, fsp);
    359731
    360732        if (fsp->oplock_timeout == NULL) {
     
    365737static void send_break_message_smb1(files_struct *fsp, int level)
    366738{
    367         char *break_msg = new_break_message_smb1(talloc_tos(),
    368                                         fsp,
    369                                         level);
    370         if (break_msg == NULL) {
    371                 exit_server("Could not talloc break_msg\n");
    372         }
     739        struct smbXsrv_connection *xconn = NULL;
     740        char break_msg[SMB1_BREAK_MESSAGE_LENGTH];
     741
     742        /*
     743         * For SMB1 we only have one connection
     744         */
     745        xconn = fsp->conn->sconn->client->connections;
     746
     747        new_break_message_smb1(fsp, level, break_msg);
    373748
    374749        show_msg(break_msg);
    375         if (!srv_send_smb(fsp->conn->sconn,
     750        if (!srv_send_smb(xconn,
    376751                        break_msg, false, 0,
    377752                        IS_CONN_ENCRYPTED(fsp->conn),
     
    380755                        "srv_send_smb failed.");
    381756        }
    382 
    383         TALLOC_FREE(break_msg);
    384 }
    385 
    386 void break_level2_to_none_async(files_struct *fsp)
    387 {
    388         struct smbd_server_connection *sconn = fsp->conn->sconn;
    389 
    390         if (fsp->oplock_type == NO_OPLOCK) {
    391                 /* We already got a "break to none" message and we've handled
    392                  * it.  just ignore. */
    393                 DEBUG(3, ("process_oplock_async_level2_break_message: already "
    394                           "broken to none, ignoring.\n"));
    395                 return;
    396         }
    397 
    398         if (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) {
    399                 /* Don't tell the client, just downgrade. */
    400                 DEBUG(3, ("process_oplock_async_level2_break_message: "
    401                           "downgrading fake level 2 oplock.\n"));
    402                 remove_oplock(fsp);
    403                 return;
    404         }
    405 
    406         /* Ensure we're really at level2 state. */
    407         SMB_ASSERT(fsp->oplock_type == LEVEL_II_OPLOCK);
    408 
    409         DEBUG(10,("process_oplock_async_level2_break_message: sending break "
    410                   "to none message for fid %d, file %s\n", fsp->fnum,
    411                   fsp_str_dbg(fsp)));
    412 
    413         /* Now send a break to none message to our client. */
    414         if (sconn->using_smb2) {
    415                 send_break_message_smb2(fsp, OPLOCKLEVEL_NONE);
    416         } else {
    417                 send_break_message_smb1(fsp, OPLOCKLEVEL_NONE);
    418         }
    419 
    420         /* Async level2 request, don't send a reply, just remove the oplock. */
    421         remove_oplock(fsp);
    422 }
    423 
    424 /*******************************************************************
    425  This handles the case of a write triggering a break to none
    426  message on a level2 oplock.
    427  When we get this message we may be in any of three states :
    428  NO_OPLOCK, LEVEL_II, FAKE_LEVEL2. We only send a message to
    429  the client for LEVEL2.
    430 *******************************************************************/
    431 
    432 void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx,
    433                                                       void *private_data,
    434                                                       uint32_t msg_type,
    435                                                       struct server_id src,
    436                                                       DATA_BLOB *data)
    437 {
    438         struct smbd_server_connection *sconn;
    439         struct share_mode_entry msg;
    440         files_struct *fsp;
    441 
    442         if (data->data == NULL) {
    443                 DEBUG(0, ("Got NULL buffer\n"));
    444                 return;
    445         }
    446 
    447         sconn = msg_ctx_to_sconn(msg_ctx);
    448         if (sconn == NULL) {
    449                 DEBUG(1, ("could not find sconn\n"));
    450                 return;
    451         }
    452 
    453         if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) {
    454                 DEBUG(0, ("Got invalid msg len %d\n", (int)data->length));
    455                 return;
    456         }
    457 
    458         /* De-linearize incoming message. */
    459         message_to_share_mode_entry(&msg, (char *)data->data);
    460 
    461         DEBUG(10, ("Got oplock async level 2 break message from pid %s: "
    462                    "%s/%lu\n", procid_str(talloc_tos(), &src),
    463                    file_id_string_tos(&msg.id), msg.share_file_id));
    464 
    465         fsp = initial_break_processing(sconn, msg.id, msg.share_file_id);
    466 
    467         if (fsp == NULL) {
    468                 /* We hit a race here. Break messages are sent, and before we
    469                  * get to process this message, we have closed the file.
    470                  * No need to reply as this is an async message. */
    471                 DEBUG(3, ("process_oplock_async_level2_break_message: Did not find fsp, ignoring\n"));
    472                 return;
    473         }
    474 
    475         break_level2_to_none_async(fsp);
    476757}
    477758
     
    486767                                         DATA_BLOB *data)
    487768{
    488         struct smbd_server_connection *sconn;
    489769        struct share_mode_entry msg;
    490770        files_struct *fsp;
    491         bool break_to_level2 = False;
     771        bool use_kernel;
     772        struct smbd_server_connection *sconn =
     773                talloc_get_type_abort(private_data,
     774                struct smbd_server_connection);
     775        struct server_id self = messaging_server_id(sconn->msg_ctx);
     776        struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops;
     777        uint16_t break_from;
     778        uint16_t break_to;
     779        bool break_needed = true;
     780        struct server_id_buf tmp;
    492781
    493782        if (data->data == NULL) {
     
    496785        }
    497786
    498         sconn = msg_ctx_to_sconn(msg_ctx);
    499         if (sconn == NULL) {
    500                 DEBUG(1, ("could not find sconn\n"));
    501                 return;
    502         }
    503 
    504787        if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) {
    505788                DEBUG(0, ("Got invalid msg len %d\n", (int)data->length));
     
    509792        /* De-linearize incoming message. */
    510793        message_to_share_mode_entry(&msg, (char *)data->data);
    511 
    512         DEBUG(10, ("Got oplock break message from pid %s: %s/%lu\n",
    513                    procid_str(talloc_tos(), &src), file_id_string_tos(&msg.id),
    514                    msg.share_file_id));
     794        break_to = msg.op_type;
     795
     796        DEBUG(10, ("Got oplock break to %u message from pid %s: %s/%llu\n",
     797                   (unsigned)break_to, server_id_str_buf(src, &tmp),
     798                   file_id_string_tos(&msg.id),
     799                   (unsigned long long)msg.share_file_id));
    515800
    516801        fsp = initial_break_processing(sconn, msg.id, msg.share_file_id);
     
    518803        if (fsp == NULL) {
    519804                /* We hit a race here. Break messages are sent, and before we
    520                  * get to process this message, we have closed the file. Reply
    521                  * with 'ok, oplock broken' */
     805                 * get to process this message, we have closed the file. */
    522806                DEBUG(3, ("Did not find fsp\n"));
    523 
    524                 /* We just send the same message back. */
    525                 messaging_send_buf(msg_ctx, src, MSG_SMB_BREAK_RESPONSE,
    526                                    (uint8 *)data->data,
    527                                    MSG_SMB_SHARE_MODE_ENTRY_SIZE);
    528                 return;
    529         }
    530 
    531         if (fsp->sent_oplock_break != NO_BREAK_SENT) {
    532                 /* Remember we have to inform the requesting PID when the
    533                  * client replies */
    534                 msg.pid = src;
    535                 ADD_TO_ARRAY(NULL, struct share_mode_entry, msg,
    536                              &fsp->pending_break_messages,
    537                              &fsp->num_pending_break_messages);
    538                 return;
    539         }
    540 
    541         if (EXCLUSIVE_OPLOCK_TYPE(msg.op_type) &&
    542             !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
    543                 DEBUG(3, ("Already downgraded oplock on %s: %s\n",
     807                return;
     808        }
     809
     810        break_from = fsp_lease_type(fsp);
     811
     812        if (fsp->oplock_type != LEASE_OPLOCK) {
     813                if (fsp->sent_oplock_break != NO_BREAK_SENT) {
     814                        /*
     815                         * Nothing to do anymore
     816                         */
     817                        DEBUG(10, ("fsp->sent_oplock_break = %d\n",
     818                                   fsp->sent_oplock_break));
     819                        return;
     820                }
     821        }
     822
     823        if (!(global_client_caps & CAP_LEVEL_II_OPLOCKS)) {
     824                DEBUG(10, ("client_caps without level2 oplocks\n"));
     825                break_to &= ~SMB2_LEASE_READ;
     826        }
     827
     828        use_kernel = lp_kernel_oplocks(SNUM(fsp->conn)) && koplocks;
     829        if (use_kernel && !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) {
     830                DEBUG(10, ("Kernel oplocks don't allow level2\n"));
     831                break_to &= ~SMB2_LEASE_READ;
     832        }
     833
     834        if (!lp_level2_oplocks(SNUM(fsp->conn))) {
     835                DEBUG(10, ("no level2 oplocks by config\n"));
     836                break_to &= ~SMB2_LEASE_READ;
     837        }
     838
     839        if (fsp->oplock_type == LEASE_OPLOCK) {
     840                struct share_mode_lock *lck;
     841                int idx;
     842
     843                lck = get_existing_share_mode_lock(
     844                        talloc_tos(), fsp->file_id);
     845                if (lck == NULL) {
     846                        /*
     847                         * We hit a race here. Break messages are sent, and
     848                         * before we get to process this message, we have closed
     849                         * the file.
     850                         */
     851                        DEBUG(3, ("Did not find share_mode\n"));
     852                        return;
     853                }
     854
     855                idx = find_share_mode_lease(
     856                        lck->data,
     857                        fsp_client_guid(fsp),
     858                        &fsp->lease->lease.lease_key);
     859                if (idx != -1) {
     860                        struct share_mode_lease *l;
     861                        l = &lck->data->leases[idx];
     862
     863                        break_from = l->current_state;
     864                        break_to &= l->current_state;
     865
     866                        if (l->breaking) {
     867                                break_to &= l->breaking_to_required;
     868                                if (l->breaking_to_required != break_to) {
     869                                        /*
     870                                         * Note we don't increment the epoch
     871                                         * here, which might be a bug in
     872                                         * Windows too...
     873                                         */
     874                                        l->breaking_to_required = break_to;
     875                                        lck->data->modified = true;
     876                                }
     877                                break_needed = false;
     878                        } else if (l->current_state == break_to) {
     879                                break_needed = false;
     880                        } else if (l->current_state == SMB2_LEASE_READ) {
     881                                l->current_state = SMB2_LEASE_NONE;
     882                                /* Need to increment the epoch */
     883                                l->epoch += 1;
     884                                lck->data->modified = true;
     885                        } else {
     886                                l->breaking = true;
     887                                l->breaking_to_required = break_to;
     888                                l->breaking_to_requested = break_to;
     889                                /* Need to increment the epoch */
     890                                l->epoch += 1;
     891                                lck->data->modified = true;
     892                        }
     893
     894                        /* Ensure we're in sync with current lease state. */
     895                        fsp_lease_update(lck, fsp_client_guid(fsp), fsp->lease);
     896                }
     897
     898                TALLOC_FREE(lck);
     899        }
     900
     901        if (!break_needed) {
     902                DEBUG(10,("%s: skip break\n", __func__));
     903                return;
     904        }
     905
     906        if ((break_from == SMB2_LEASE_NONE) && !break_needed) {
     907                DEBUG(3, ("Already downgraded oplock to none on %s: %s\n",
    544908                          file_id_string_tos(&fsp->file_id),
    545909                          fsp_str_dbg(fsp)));
    546                 /* We just send the same message back. */
    547                 messaging_send_buf(msg_ctx, src, MSG_SMB_BREAK_RESPONSE,
    548                                    (uint8 *)data->data,
    549                                    MSG_SMB_SHARE_MODE_ENTRY_SIZE);
    550                 return;
    551         }
    552 
    553         if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
    554             !(msg.op_type & FORCE_OPLOCK_BREAK_TO_NONE) &&
    555             !(koplocks && !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) &&
    556             lp_level2_oplocks(SNUM(fsp->conn))) {
    557                 break_to_level2 = True;
     910                return;
     911        }
     912
     913        DEBUG(10, ("break_from=%u, break_to=%u\n",
     914                   (unsigned)break_from, (unsigned)break_to));
     915
     916        if ((break_from == break_to) && !break_needed) {
     917                DEBUG(3, ("Already downgraded oplock to %u on %s: %s\n",
     918                          (unsigned)break_to,
     919                          file_id_string_tos(&fsp->file_id),
     920                          fsp_str_dbg(fsp)));
     921                return;
    558922        }
    559923
    560924        /* Need to wait before sending a break
    561925           message if we sent ourselves this message. */
    562         if (procid_is_me(&src)) {
     926        if (serverid_equal(&self, &src)) {
    563927                wait_before_sending_break();
    564928        }
    565929
    566930        if (sconn->using_smb2) {
    567                 send_break_message_smb2(fsp, break_to_level2 ?
    568                         OPLOCKLEVEL_II : OPLOCKLEVEL_NONE);
     931                send_break_message_smb2(fsp, break_from, break_to);
    569932        } else {
    570                 send_break_message_smb1(fsp, break_to_level2 ?
    571                         OPLOCKLEVEL_II : OPLOCKLEVEL_NONE);
    572         }
    573 
    574         fsp->sent_oplock_break = break_to_level2 ? LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT;
    575 
    576         msg.pid = src;
    577         ADD_TO_ARRAY(NULL, struct share_mode_entry, msg,
    578                      &fsp->pending_break_messages,
    579                      &fsp->num_pending_break_messages);
     933                send_break_message_smb1(fsp, (break_to & SMB2_LEASE_READ) ?
     934                                        OPLOCKLEVEL_II : OPLOCKLEVEL_NONE);
     935        }
     936
     937        if ((break_from == SMB2_LEASE_READ) &&
     938            (break_to == SMB2_LEASE_NONE)) {
     939                /*
     940                 * This is an async break without a reply and thus no timeout
     941                 *
     942                 * leases are handled above.
     943                 */
     944                if (fsp->oplock_type != LEASE_OPLOCK) {
     945                        remove_oplock(fsp);
     946                }
     947                return;
     948        }
     949        if (fsp->oplock_type == LEASE_OPLOCK) {
     950                return;
     951        }
     952
     953        fsp->sent_oplock_break = (break_to & SMB2_LEASE_READ) ?
     954                LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT;
    580955
    581956        add_oplock_timeout_handler(fsp);
     
    592967                                        DATA_BLOB *data)
    593968{
    594         struct smbd_server_connection *sconn;
    595969        struct file_id id;
    596970        unsigned long file_id;
    597971        files_struct *fsp;
     972        struct smbd_server_connection *sconn =
     973                talloc_get_type_abort(private_data,
     974                struct smbd_server_connection);
     975        struct server_id_buf tmp;
    598976
    599977        if (data->data == NULL) {
     
    604982        if (data->length != MSG_SMB_KERNEL_BREAK_SIZE) {
    605983                DEBUG(0, ("Got invalid msg len %d\n", (int)data->length));
    606                 return;
    607         }
    608 
    609         sconn = msg_ctx_to_sconn(msg_ctx);
    610         if (sconn == NULL) {
    611                 DEBUG(1, ("could not find sconn\n"));
    612984                return;
    613985        }
     
    618990
    619991        DEBUG(10, ("Got kernel oplock break message from pid %s: %s/%u\n",
    620                    procid_str(talloc_tos(), &src), file_id_string_tos(&id),
     992                   server_id_str_buf(src, &tmp), file_id_string_tos(&id),
    621993                   (unsigned int)file_id));
    622994
     
    6371009
    6381010        if (sconn->using_smb2) {
    639                 send_break_message_smb2(fsp, OPLOCKLEVEL_NONE);
     1011                send_break_message_smb2(fsp, 0, OPLOCKLEVEL_NONE);
    6401012        } else {
    6411013                send_break_message_smb1(fsp, OPLOCKLEVEL_NONE);
     
    6471019}
    6481020
    649 void reply_to_oplock_break_requests(files_struct *fsp)
    650 {
    651         int i;
    652 
    653         /*
    654          * If kernel oplocks already notifies smbds when oplocks are
    655          * broken/removed, just return.
    656          */
    657         if (koplocks &&
    658             (koplocks->flags & KOPLOCKS_OPLOCK_BROKEN_NOTIFICATION)) {
    659                 return;
    660         }
    661 
    662         for (i=0; i<fsp->num_pending_break_messages; i++) {
    663                 struct share_mode_entry *e = &fsp->pending_break_messages[i];
    664                 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
    665 
    666                 share_mode_entry_to_message(msg, e);
    667 
    668                 messaging_send_buf(fsp->conn->sconn->msg_ctx, e->pid,
    669                                    MSG_SMB_BREAK_RESPONSE,
    670                                    (uint8 *)msg,
    671                                    MSG_SMB_SHARE_MODE_ENTRY_SIZE);
    672         }
    673 
    674         SAFE_FREE(fsp->pending_break_messages);
    675         fsp->num_pending_break_messages = 0;
    676         if (fsp->oplock_timeout != NULL) {
    677                 /* Remove the timed event handler. */
    678                 TALLOC_FREE(fsp->oplock_timeout);
    679                 fsp->oplock_timeout = NULL;
    680         }
    681         return;
    682 }
    683 
    684 static void process_oplock_break_response(struct messaging_context *msg_ctx,
    685                                           void *private_data,
    686                                           uint32_t msg_type,
    687                                           struct server_id src,
    688                                           DATA_BLOB *data)
    689 {
    690         struct share_mode_entry msg;
    691 
    692         if (data->data == NULL) {
    693                 DEBUG(0, ("Got NULL buffer\n"));
    694                 return;
    695         }
    696 
    697         if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) {
    698                 DEBUG(0, ("Got invalid msg len %u\n",
    699                           (unsigned int)data->length));
    700                 return;
    701         }
    702 
    703         /* De-linearize incoming message. */
    704         message_to_share_mode_entry(&msg, (char *)data->data);
    705 
    706         DEBUG(10, ("Got oplock break response from pid %s: %s/%lu mid %llu\n",
    707                    procid_str(talloc_tos(), &src), file_id_string_tos(&msg.id),
    708                    msg.share_file_id, (unsigned long long)msg.op_mid));
    709 
    710         schedule_deferred_open_message_smb(msg.op_mid);
    711 }
    712 
    713 static void process_open_retry_message(struct messaging_context *msg_ctx,
    714                                        void *private_data,
    715                                        uint32_t msg_type,
    716                                        struct server_id src,
    717                                        DATA_BLOB *data)
    718 {
    719         struct share_mode_entry msg;
    720        
    721         if (data->data == NULL) {
    722                 DEBUG(0, ("Got NULL buffer\n"));
    723                 return;
    724         }
    725 
    726         if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) {
    727                 DEBUG(0, ("Got invalid msg len %d\n", (int)data->length));
    728                 return;
    729         }
    730 
    731         /* De-linearize incoming message. */
    732         message_to_share_mode_entry(&msg, (char *)data->data);
    733 
    734         DEBUG(10, ("Got open retry msg from pid %s: %s mid %llu\n",
    735                    procid_str(talloc_tos(), &src), file_id_string_tos(&msg.id),
    736                    (unsigned long long)msg.op_mid));
    737 
    738         schedule_deferred_open_message_smb(msg.op_mid);
    739 }
     1021struct break_to_none_state {
     1022        struct smbd_server_connection *sconn;
     1023        struct file_id id;
     1024        struct smb2_lease_key lease_key;
     1025        struct GUID client_guid;
     1026};
     1027static void do_break_to_none(struct tevent_context *ctx,
     1028                             struct tevent_immediate *im,
     1029                             void *private_data);
    7401030
    7411031/****************************************************************************
     
    7481038                                              enum level2_contention_type type)
    7491039{
    750         int i;
    751         struct share_mode_lock *lck;
     1040        struct smbd_server_connection *sconn = fsp->conn->sconn;
     1041        struct tevent_immediate *im;
     1042        struct break_to_none_state *state;
     1043        struct byte_range_lock *brl;
     1044        uint32_t num_read_oplocks = 0;
    7521045
    7531046        /*
     
    7591052         */
    7601053
    761         if (!LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
    762                 return;
    763 
    764         lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
    765                                   NULL);
     1054        if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
     1055                /*
     1056                 * There can't be any level2 oplocks, we're alone.
     1057                 */
     1058                return;
     1059        }
     1060
     1061        brl = brl_get_locks_readonly(fsp);
     1062        if (brl != NULL) {
     1063                num_read_oplocks = brl_num_read_oplocks(brl);
     1064        }
     1065
     1066        DEBUG(10, ("num_read_oplocks = %"PRIu32"\n", num_read_oplocks));
     1067
     1068        if (num_read_oplocks == 0) {
     1069                DEBUG(10, ("No read oplocks around\n"));
     1070                return;
     1071        }
     1072
     1073        /*
     1074         * When we get here we might have a brlock entry locked. Also
     1075         * locking the share mode entry would violate the locking
     1076         * order. Breaking level2 oplocks to none is asynchronous
     1077         * anyway, so we postpone this into an immediate event.
     1078         */
     1079
     1080        state = talloc_zero(sconn, struct break_to_none_state);
     1081        if (state == NULL) {
     1082                DEBUG(1, ("talloc failed\n"));
     1083                return;
     1084        }
     1085        state->sconn = sconn;
     1086        state->id = fsp->file_id;
     1087
     1088        if (fsp->oplock_type == LEASE_OPLOCK) {
     1089                state->client_guid = *fsp_client_guid(fsp);
     1090                state->lease_key = fsp->lease->lease.lease_key;
     1091                DEBUG(10, ("Breaking through lease key %"PRIu64"/%"PRIu64"\n",
     1092                           state->lease_key.data[0],
     1093                           state->lease_key.data[1]));
     1094        }
     1095
     1096        im = tevent_create_immediate(state);
     1097        if (im == NULL) {
     1098                DEBUG(1, ("tevent_create_immediate failed\n"));
     1099                TALLOC_FREE(state);
     1100                return;
     1101        }
     1102        tevent_schedule_immediate(im, sconn->ev_ctx, do_break_to_none, state);
     1103}
     1104
     1105static void send_break_to_none(struct messaging_context *msg_ctx,
     1106                               const struct share_mode_entry *e)
     1107{
     1108        char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
     1109
     1110        share_mode_entry_to_message(msg, e);
     1111        /* Overload entry->op_type */
     1112        SSVAL(msg, OP_BREAK_MSG_OP_TYPE_OFFSET, NO_OPLOCK);
     1113
     1114        messaging_send_buf(msg_ctx, e->pid, MSG_SMB_BREAK_REQUEST,
     1115                           (uint8_t *)msg, sizeof(msg));
     1116}
     1117
     1118static void do_break_to_none(struct tevent_context *ctx,
     1119                             struct tevent_immediate *im,
     1120                             void *private_data)
     1121{
     1122        struct break_to_none_state *state = talloc_get_type_abort(
     1123                private_data, struct break_to_none_state);
     1124        uint32_t i;
     1125        struct share_mode_lock *lck;
     1126        struct share_mode_data *d;
     1127
     1128        lck = get_existing_share_mode_lock(talloc_tos(), state->id);
    7661129        if (lck == NULL) {
    767                 DEBUG(0,("release_level_2_oplocks_on_change: failed to lock "
    768                          "share mode entry for file %s.\n", fsp_str_dbg(fsp)));
    769                 return;
    770         }
    771 
    772         DEBUG(10,("release_level_2_oplocks_on_change: num_share_modes = %d\n",
    773                   lck->num_share_modes ));
    774 
    775         for(i = 0; i < lck->num_share_modes; i++) {
    776                 struct share_mode_entry *share_entry = &lck->share_modes[i];
    777                 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
    778 
    779                 if (!is_valid_share_mode_entry(share_entry)) {
     1130                DEBUG(1, ("%s: failed to lock share mode entry for file %s.\n",
     1131                          __func__, file_id_string_tos(&state->id)));
     1132                goto done;
     1133        }
     1134        d = lck->data;
     1135
     1136        /*
     1137         * Walk leases and oplocks separately: We have to send one break per
     1138         * lease. If we have multiple share_mode_entry having a common lease,
     1139         * we would break the lease twice if we don't walk the leases list
     1140         * separately.
     1141         */
     1142
     1143        for (i=0; i<d->num_leases; i++) {
     1144                struct share_mode_lease *l = &d->leases[i];
     1145                struct share_mode_entry *e;
     1146                uint32_t j;
     1147
     1148                if ((l->current_state & SMB2_LEASE_READ) == 0) {
     1149                        continue;
     1150                }
     1151                if (smb2_lease_equal(&state->client_guid,
     1152                                     &state->lease_key,
     1153                                     &l->client_guid,
     1154                                     &l->lease_key)) {
     1155                        DEBUG(10, ("Don't break our own lease\n"));
     1156                        continue;
     1157                }
     1158
     1159                for (j=0; j<d->num_share_modes; j++) {
     1160                        e = &d->share_modes[j];
     1161
     1162                        if (!is_valid_share_mode_entry(e)) {
     1163                                continue;
     1164                        }
     1165                        if (e->lease_idx == i) {
     1166                                break;
     1167                        }
     1168                }
     1169                if (j == d->num_share_modes) {
     1170                        DEBUG(0, ("leases[%"PRIu32"] has no share mode\n",
     1171                                  i));
     1172                        continue;
     1173                }
     1174
     1175                DEBUG(10, ("Breaking lease# %"PRIu32" with share_entry# "
     1176                           "%"PRIu32"\n", i, j));
     1177
     1178                send_break_to_none(state->sconn->msg_ctx, e);
     1179        }
     1180
     1181        for(i = 0; i < d->num_share_modes; i++) {
     1182                struct share_mode_entry *e = &d->share_modes[i];
     1183
     1184                if (!is_valid_share_mode_entry(e)) {
     1185                        continue;
     1186                }
     1187                if (e->op_type == LEASE_OPLOCK) {
     1188                        /*
     1189                         * Took care of those in the loop above
     1190                         */
    7801191                        continue;
    7811192                }
     
    7851196                 * lock_share_entry gate we may not be the first to
    7861197                 * enter. Hence the state of the op_types in the share mode
    787                  * entries may be partly NO_OPLOCK and partly LEVEL_II or FAKE_LEVEL_II
     1198                 * entries may be partly NO_OPLOCK and partly LEVEL_II
    7881199                 * oplock. It will do no harm to re-send break messages to
    7891200                 * those smbd's that are still waiting their turn to remove
     
    7921203                 */
    7931204
    794                 DEBUG(10,("release_level_2_oplocks_on_change: "
    795                           "share_entry[%i]->op_type == %d\n",
    796                           i, share_entry->op_type ));
    797 
    798                 if (share_entry->op_type == NO_OPLOCK) {
     1205                DEBUG(10, ("%s: share_entry[%i]->op_type == %d\n", __func__,
     1206                           i, e->op_type ));
     1207
     1208                if (e->op_type == NO_OPLOCK) {
    7991209                        continue;
    8001210                }
    8011211
    8021212                /* Paranoia .... */
    803                 if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) {
    804                         DEBUG(0,("release_level_2_oplocks_on_change: PANIC. "
    805                                  "share mode entry %d is an exlusive "
    806                                  "oplock !\n", i ));
     1213                if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
     1214                        DEBUG(0,("%s: PANIC. "
     1215                                 "share mode entry %d is an exclusive "
     1216                                 "oplock !\n", __func__, i ));
    8071217                        TALLOC_FREE(lck);
    8081218                        abort();
    8091219                }
    8101220
    811                 share_mode_entry_to_message(msg, share_entry);
    812 
    813                 /*
    814                  * Deal with a race condition when breaking level2
    815                  * oplocks. Don't send all the messages and release
    816                  * the lock, this allows someone else to come in and
    817                  * get a level2 lock before any of the messages are
    818                  * processed, and thus miss getting a break message.
    819                  * Ensure at least one entry (the one we're breaking)
    820                  * is processed immediately under the lock and becomes
    821                  * set as NO_OPLOCK to stop any waiter getting a level2.
    822                  * Bugid #5980.
    823                  */
    824 
    825                 if (procid_is_me(&share_entry->pid)) {
    826                         struct files_struct *cur_fsp =
    827                                 initial_break_processing(fsp->conn->sconn,
    828                                         share_entry->id,
    829                                         share_entry->share_file_id);
    830                         wait_before_sending_break();
    831                         if (cur_fsp != NULL) {
    832                                 break_level2_to_none_async(cur_fsp);
    833                         } else {
    834                                 DEBUG(3, ("release_level_2_oplocks_on_change: "
    835                                 "Did not find fsp, ignoring\n"));
    836                         }
    837                 } else {
    838                         messaging_send_buf(fsp->conn->sconn->msg_ctx,
    839                                         share_entry->pid,
    840                                         MSG_SMB_ASYNC_LEVEL2_BREAK,
    841                                         (uint8 *)msg,
    842                                         MSG_SMB_SHARE_MODE_ENTRY_SIZE);
    843                 }
     1221                send_break_to_none(state->sconn->msg_ctx, e);
    8441222        }
    8451223
     
    8481226
    8491227        TALLOC_FREE(lck);
    850 }
    851 
    852 void contend_level2_oplocks_begin(files_struct *fsp,
     1228done:
     1229        TALLOC_FREE(state);
     1230        return;
     1231}
     1232
     1233void smbd_contend_level2_oplocks_begin(files_struct *fsp,
    8531234                                  enum level2_contention_type type)
    8541235{
     1236        struct smbd_server_connection *sconn = fsp->conn->sconn;
     1237        struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops;
     1238
    8551239        if (koplocks && koplocks->ops->contend_level2_oplocks_begin) {
    8561240                koplocks->ops->contend_level2_oplocks_begin(fsp, type);
     
    8611245}
    8621246
    863 void contend_level2_oplocks_end(files_struct *fsp,
     1247void smbd_contend_level2_oplocks_end(files_struct *fsp,
    8641248                                enum level2_contention_type type)
    8651249{
     1250        struct smbd_server_connection *sconn = fsp->conn->sconn;
     1251        struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops;
     1252
    8661253        /* Only kernel oplocks implement this so far */
    8671254        if (koplocks && koplocks->ops->contend_level2_oplocks_end) {
     
    8761263void share_mode_entry_to_message(char *msg, const struct share_mode_entry *e)
    8771264{
    878         SIVAL(msg,OP_BREAK_MSG_PID_OFFSET,(uint32)e->pid.pid);
     1265        SIVAL(msg,OP_BREAK_MSG_PID_OFFSET,(uint32_t)e->pid.pid);
    8791266        SBVAL(msg,OP_BREAK_MSG_MID_OFFSET,e->op_mid);
    8801267        SSVAL(msg,OP_BREAK_MSG_OP_TYPE_OFFSET,e->op_type);
     
    8961283****************************************************************************/
    8971284
    898 void message_to_share_mode_entry(struct share_mode_entry *e, char *msg)
     1285void message_to_share_mode_entry(struct share_mode_entry *e, const char *msg)
    8991286{
    9001287        e->pid.pid = (pid_t)IVAL(msg,OP_BREAK_MSG_PID_OFFSET);
     
    9081295        pull_file_id_24(msg+OP_BREAK_MSG_DEV_OFFSET, &e->id);
    9091296        e->share_file_id = (unsigned long)IVAL(msg,OP_BREAK_MSG_FILE_ID_OFFSET);
    910         e->uid = (uint32)IVAL(msg,OP_BREAK_MSG_UID_OFFSET);
    911         e->flags = (uint16)SVAL(msg,OP_BREAK_MSG_FLAGS_OFFSET);
     1297        e->uid = (uint32_t)IVAL(msg,OP_BREAK_MSG_UID_OFFSET);
     1298        e->flags = (uint16_t)SVAL(msg,OP_BREAK_MSG_FLAGS_OFFSET);
    9121299        e->name_hash = IVAL(msg,OP_BREAK_MSG_NAME_HASH_OFFSET);
    9131300        e->pid.vnn = IVAL(msg,OP_BREAK_MSG_VNN_OFFSET);
     
    9181305****************************************************************************/
    9191306
    920 bool init_oplocks(struct messaging_context *msg_ctx)
     1307bool init_oplocks(struct smbd_server_connection *sconn)
    9211308{
    9221309        DEBUG(3,("init_oplocks: initializing messages.\n"));
    9231310
    924         messaging_register(msg_ctx, NULL, MSG_SMB_BREAK_REQUEST,
     1311        messaging_register(sconn->msg_ctx, sconn, MSG_SMB_BREAK_REQUEST,
    9251312                           process_oplock_break_message);
    926         messaging_register(msg_ctx, NULL, MSG_SMB_ASYNC_LEVEL2_BREAK,
    927                            process_oplock_async_level2_break_message);
    928         messaging_register(msg_ctx, NULL, MSG_SMB_BREAK_RESPONSE,
    929                            process_oplock_break_response);
    930         messaging_register(msg_ctx, NULL, MSG_SMB_KERNEL_BREAK,
     1313        messaging_register(sconn->msg_ctx, sconn, MSG_SMB_KERNEL_BREAK,
    9311314                           process_kernel_oplock_break);
    932         messaging_register(msg_ctx, NULL, MSG_SMB_OPEN_RETRY,
    933                            process_open_retry_message);
    934 
    935         if (lp_kernel_oplocks()) {
     1315        return true;
     1316}
     1317
     1318void init_kernel_oplocks(struct smbd_server_connection *sconn)
     1319{
     1320        struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops;
     1321
     1322        /* only initialize once */
     1323        if (koplocks == NULL) {
    9361324#if HAVE_KERNEL_OPLOCKS_IRIX
    937                 koplocks = irix_init_kernel_oplocks(NULL);
     1325                koplocks = irix_init_kernel_oplocks(sconn);
    9381326#elif HAVE_KERNEL_OPLOCKS_LINUX
    939                 koplocks = linux_init_kernel_oplocks(NULL);
    940 #elif HAVE_ONEFS
    941 #error Isilon, please check if the NULL context is okay here. Thanks!
    942                 koplocks = onefs_init_kernel_oplocks(NULL);
     1327                koplocks = linux_init_kernel_oplocks(sconn);
    9431328#endif
    944         }
    945 
    946         return True;
    947 }
     1329                sconn->oplocks.kernel_ops = koplocks;
     1330        }
     1331}
Note: See TracChangeset for help on using the changeset viewer.