Changeset 232 for branches/samba-3.2.x/source/smbd/open.c
- Timestamp:
- May 27, 2009, 9:09:42 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.2.x/source/smbd/open.c
r228 r232 668 668 669 669 /* 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. 677 672 */ 678 673 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) 674 static NTSTATUS send_break_message(files_struct *fsp, 675 struct share_mode_entry *exclusive, 676 uint16 mid, 677 int oplock_request) 684 678 { 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;690 679 NTSTATUS status; 691 680 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 other746 * 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 for761 * our client.762 */763 681 764 682 DEBUG(10, ("Sending break request to PID %s\n", … … 785 703 } 786 704 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 718 static 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; 788 822 } 789 823 … … 973 1007 uint32 share_mode; 974 1008 uint32 create_disposition; 975 uint32 create_options = 0;1009 uint32 create_options = FILE_NON_DIRECTORY_FILE; 976 1010 977 1011 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, " … … 1189 1223 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n", fname)); 1190 1224 1191 return print_fsp_open(conn, fname, fsp );1225 return print_fsp_open(conn, fname, fsp, psbuf); 1192 1226 } 1193 1227 … … 1826 1860 */ 1827 1861 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; 1834 1865 } 1835 1866 … … 1838 1869 } 1839 1870 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); 1841 1873 1842 1874 /* 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 1847 1877 status = can_set_delete_on_close(fsp, True, new_dos_attributes); 1848 1878 … … 2286 2316 } 2287 2317 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); 2289 2319 2290 2320 /* For directories the delete on close bit at open time seems
Note:
See TracChangeset
for help on using the changeset viewer.