+bool update_num_read_oplocks(files_struct *fsp, struct share_mode_lock *lck)
+{
+ struct share_mode_data *d = lck->data;
+ struct byte_range_lock *br_lck;
+ uint32_t num_read_oplocks = 0;
+ uint32_t i;
+
+ if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
+ /*
+ * If we're the only one, we don't need a brlock entry
+ */
+ SMB_ASSERT(d->num_share_modes == 1);
+ SMB_ASSERT(EXCLUSIVE_OPLOCK_TYPE(d->share_modes[0].op_type));
+ return true;
+ }
+
+ for (i=0; i<d->num_share_modes; i++) {
+ struct share_mode_entry *e = &d->share_modes[i];
+
+ if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
+ num_read_oplocks += 1;
+ continue;
+ }
+
+ if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
+ num_read_oplocks += 1;
+ continue;
+ }
+ }
+
+ br_lck = brl_get_locks_readonly(fsp);
+ if (br_lck == NULL) {
+ return false;
+ }
+ if (brl_num_read_oplocks(br_lck) == num_read_oplocks) {
+ return true;
+ }
+
+ br_lck = brl_get_locks(talloc_tos(), fsp);
+ if (br_lck == NULL) {
+ return false;
+ }
+ brl_set_num_read_oplocks(br_lck, num_read_oplocks);
+ TALLOC_FREE(br_lck);
+ return true;
+}
+