Ignore:
Timestamp:
May 27, 2009, 9:09:42 AM (16 years ago)
Author:
Herwig Bauernfeind
Message:

Update 3.2 branch to 3.2.8

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/samba-3.2.x/source/smbd/open.c

    r228 r232  
    668668
    669669/*
    670  * 1) No files open at all or internal open: Grant whatever the client wants.
    671  *
    672  * 2) Exclusive (or batch) oplock around: If the requested access is a delete
    673  *    request, break if the oplock around is a batch oplock. If it's another
    674  *    requested access type, break.
    675  *
    676  * 3) Only level2 around: Grant level2 and do nothing else.
     670 * Send a break message to the oplock holder and delay the open for
     671 * our client.
    677672 */
    678673
    679 static bool delay_for_oplocks(struct share_mode_lock *lck,
    680                               files_struct *fsp,
    681                               uint16 mid,
    682                               int pass_number,
    683                               int oplock_request)
     674static NTSTATUS send_break_message(files_struct *fsp,
     675                                        struct share_mode_entry *exclusive,
     676                                        uint16 mid,
     677                                        int oplock_request)
    684678{
    685         int i;
    686         struct share_mode_entry *exclusive = NULL;
    687         bool valid_entry = False;
    688         bool delay_it = False;
    689         bool have_level2 = False;
    690679        NTSTATUS status;
    691680        char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
    692 
    693         if (oplock_request & INTERNAL_OPEN_ONLY) {
    694                 fsp->oplock_type = NO_OPLOCK;
    695         }
    696 
    697         if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
    698                 return False;
    699         }
    700 
    701         for (i=0; i<lck->num_share_modes; i++) {
    702 
    703                 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
    704                         continue;
    705                 }
    706 
    707                 /* At least one entry is not an invalid or deferred entry. */
    708                 valid_entry = True;
    709 
    710                 if (pass_number == 1) {
    711                         if (BATCH_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
    712                                 SMB_ASSERT(exclusive == NULL);                 
    713                                 exclusive = &lck->share_modes[i];
    714                         }
    715                 } else {
    716                         if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
    717                                 SMB_ASSERT(exclusive == NULL);                 
    718                                 exclusive = &lck->share_modes[i];
    719                         }
    720                 }
    721 
    722                 if (lck->share_modes[i].op_type == LEVEL_II_OPLOCK) {
    723                         SMB_ASSERT(exclusive == NULL);                 
    724                         have_level2 = True;
    725                 }
    726         }
    727 
    728         if (!valid_entry) {
    729                 /* All entries are placeholders or deferred.
    730                  * Directly grant whatever the client wants. */
    731                 if (fsp->oplock_type == NO_OPLOCK) {
    732                         /* Store a level2 oplock, but don't tell the client */
    733                         fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
    734                 }
    735                 return False;
    736         }
    737 
    738         if (exclusive != NULL) { /* Found an exclusive oplock */
    739                 SMB_ASSERT(!have_level2);
    740                 delay_it = is_delete_request(fsp) ?
    741                         BATCH_OPLOCK_TYPE(exclusive->op_type) : True;
    742         }
    743 
    744         if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
    745                 /* We can at most grant level2 as there are other
    746                  * level2 or NO_OPLOCK entries. */
    747                 fsp->oplock_type = LEVEL_II_OPLOCK;
    748         }
    749 
    750         if ((fsp->oplock_type == NO_OPLOCK) && have_level2) {
    751                 /* Store a level2 oplock, but don't tell the client */
    752                 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
    753         }
    754 
    755         if (!delay_it) {
    756                 return False;
    757         }
    758 
    759         /*
    760          * Send a break message to the oplock holder and delay the open for
    761          * our client.
    762          */
    763681
    764682        DEBUG(10, ("Sending break request to PID %s\n",
     
    785703        }
    786704
    787         return True;
     705        return status;
     706}
     707
     708/*
     709 * 1) No files open at all or internal open: Grant whatever the client wants.
     710 *
     711 * 2) Exclusive (or batch) oplock around: If the requested access is a delete
     712 *    request, break if the oplock around is a batch oplock. If it's another
     713 *    requested access type, break.
     714 *
     715 * 3) Only level2 around: Grant level2 and do nothing else.
     716 */
     717
     718static bool delay_for_oplocks(struct share_mode_lock *lck,
     719                              files_struct *fsp,
     720                              uint16 mid,
     721                              int pass_number,
     722                              int oplock_request)
     723{
     724        extern uint32 global_client_caps;
     725        int i;
     726        struct share_mode_entry *exclusive = NULL;
     727        bool valid_entry = false;
     728        bool have_level2 = false;
     729        bool have_a_none_oplock = false;
     730        bool allow_level2 = (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
     731                            lp_level2_oplocks(SNUM(fsp->conn));
     732
     733        if (oplock_request & INTERNAL_OPEN_ONLY) {
     734                fsp->oplock_type = NO_OPLOCK;
     735        }
     736
     737        if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
     738                return false;
     739        }
     740
     741        for (i=0; i<lck->num_share_modes; i++) {
     742
     743                if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
     744                        continue;
     745                }
     746
     747                /* At least one entry is not an invalid or deferred entry. */
     748                valid_entry = true;
     749
     750                if (pass_number == 1) {
     751                        if (BATCH_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
     752                                SMB_ASSERT(exclusive == NULL);
     753                                exclusive = &lck->share_modes[i];
     754                        }
     755                } else {
     756                        if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
     757                                SMB_ASSERT(exclusive == NULL);
     758                                exclusive = &lck->share_modes[i];
     759                        }
     760                }
     761
     762                if (LEVEL_II_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
     763                        SMB_ASSERT(exclusive == NULL);
     764                        have_level2 = true;
     765                }
     766
     767                if (lck->share_modes[i].op_type == NO_OPLOCK) {
     768                        have_a_none_oplock = true;
     769                }
     770        }
     771
     772        if (exclusive != NULL) { /* Found an exclusive oplock */
     773                bool delay_it = is_delete_request(fsp) ?
     774                                BATCH_OPLOCK_TYPE(exclusive->op_type) : true;
     775                SMB_ASSERT(!have_level2);
     776                if (delay_it) {
     777                        send_break_message(fsp, exclusive, mid, oplock_request);
     778                        return true;
     779                }
     780        }
     781
     782        /*
     783         * Match what was requested (fsp->oplock_type) with
     784         * what was found in the existing share modes.
     785         */
     786
     787        if (!valid_entry) {
     788                /* All entries are placeholders or deferred.
     789                 * Directly grant whatever the client wants. */
     790                if (fsp->oplock_type == NO_OPLOCK) {
     791                        /* Store a level2 oplock, but don't tell the client */
     792                        fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
     793                }
     794        } else if (have_a_none_oplock) {
     795                fsp->oplock_type = NO_OPLOCK;
     796        } else if (have_level2) {
     797                if (fsp->oplock_type == NO_OPLOCK ||
     798                                fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) {
     799                        /* Store a level2 oplock, but don't tell the client */
     800                        fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
     801                } else {
     802                        fsp->oplock_type = LEVEL_II_OPLOCK;
     803                }
     804        } else {
     805                /* This case can never happen. */
     806                SMB_ASSERT(1);
     807        }
     808
     809        /*
     810         * Don't grant level2 to clients that don't want them
     811         * or if we've turned them off.
     812         */
     813        if (fsp->oplock_type == LEVEL_II_OPLOCK && !allow_level2) {
     814                fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
     815        }
     816
     817        DEBUG(10,("delay_for_oplocks: oplock type 0x%x on file %s\n",
     818                fsp->oplock_type, fsp->fsp_name));
     819
     820        /* No delay. */
     821        return false;
    788822}
    789823
     
    9731007        uint32 share_mode;
    9741008        uint32 create_disposition;
    975         uint32 create_options = 0;
     1009        uint32 create_options = FILE_NON_DIRECTORY_FILE;
    9761010
    9771011        DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
     
    11891223                DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n", fname));
    11901224
    1191                 return print_fsp_open(conn, fname, fsp);
     1225                return print_fsp_open(conn, fname, fsp, psbuf);
    11921226        }
    11931227
     
    18261860         */
    18271861
    1828         if ((fsp->oplock_type != NO_OPLOCK) &&
    1829             (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
    1830                 if (!set_file_oplock(fsp, fsp->oplock_type)) {
    1831                         /* Could not get the kernel oplock */
    1832                         fsp->oplock_type = NO_OPLOCK;
    1833                 }
     1862        if (!set_file_oplock(fsp, fsp->oplock_type)) {
     1863                /* Could not get the kernel oplock */
     1864                fsp->oplock_type = NO_OPLOCK;
    18341865        }
    18351866
     
    18381869        }
    18391870
    1840         set_share_mode(lck, fsp, current_user.ut.uid, 0, fsp->oplock_type, new_file_created);
     1871        set_share_mode(lck, fsp, current_user.ut.uid, 0,
     1872                       fsp->oplock_type);
    18411873
    18421874        /* Handle strange delete on close create semantics. */
    1843         if ((create_options & FILE_DELETE_ON_CLOSE)
    1844             && (((conn->fs_capabilities & FILE_NAMED_STREAMS)
    1845                         && is_ntfs_stream_name(fname))
    1846                 || can_set_initial_delete_on_close(lck))) {
     1875        if (create_options & FILE_DELETE_ON_CLOSE) {
     1876
    18471877                status = can_set_delete_on_close(fsp, True, new_dos_attributes);
    18481878
     
    22862316        }
    22872317
    2288         set_share_mode(lck, fsp, current_user.ut.uid, 0, NO_OPLOCK, True);
     2318        set_share_mode(lck, fsp, current_user.ut.uid, 0, NO_OPLOCK);
    22892319
    22902320        /* For directories the delete on close bit at open time seems
Note: See TracChangeset for help on using the changeset viewer.