Lines Matching refs:opinfo
35 struct oplock_info *opinfo; in alloc_opinfo() local
37 opinfo = kzalloc(sizeof(struct oplock_info), KSMBD_DEFAULT_GFP); in alloc_opinfo()
38 if (!opinfo) in alloc_opinfo()
41 opinfo->sess = sess; in alloc_opinfo()
42 opinfo->conn = conn; in alloc_opinfo()
43 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in alloc_opinfo()
44 opinfo->op_state = OPLOCK_STATE_NONE; in alloc_opinfo()
45 opinfo->pending_break = 0; in alloc_opinfo()
46 opinfo->fid = id; in alloc_opinfo()
47 opinfo->Tid = Tid; in alloc_opinfo()
48 INIT_LIST_HEAD(&opinfo->op_entry); in alloc_opinfo()
49 init_waitqueue_head(&opinfo->oplock_q); in alloc_opinfo()
50 init_waitqueue_head(&opinfo->oplock_brk); in alloc_opinfo()
51 atomic_set(&opinfo->refcount, 1); in alloc_opinfo()
52 atomic_set(&opinfo->breaking_cnt, 0); in alloc_opinfo()
53 atomic_inc(&opinfo->conn->refcnt); in alloc_opinfo()
55 return opinfo; in alloc_opinfo()
58 static void lease_add_list(struct oplock_info *opinfo) in lease_add_list() argument
60 struct lease_table *lb = opinfo->o_lease->l_lb; in lease_add_list()
63 list_add_rcu(&opinfo->lease_entry, &lb->lease_list); in lease_add_list()
67 static void lease_del_list(struct oplock_info *opinfo) in lease_del_list() argument
69 struct lease_table *lb = opinfo->o_lease->l_lb; in lease_del_list()
75 if (list_empty(&opinfo->lease_entry)) { in lease_del_list()
80 list_del_init(&opinfo->lease_entry); in lease_del_list()
81 opinfo->o_lease->l_lb = NULL; in lease_del_list()
92 static int alloc_lease(struct oplock_info *opinfo, struct lease_ctx_info *lctx) in alloc_lease() argument
109 INIT_LIST_HEAD(&opinfo->lease_entry); in alloc_lease()
110 opinfo->o_lease = lease; in alloc_lease()
115 static void free_lease(struct oplock_info *opinfo) in free_lease() argument
119 lease = opinfo->o_lease; in free_lease()
123 static void free_opinfo(struct oplock_info *opinfo) in free_opinfo() argument
125 if (opinfo->is_lease) in free_opinfo()
126 free_lease(opinfo); in free_opinfo()
127 if (opinfo->conn && atomic_dec_and_test(&opinfo->conn->refcnt)) in free_opinfo()
128 kfree(opinfo->conn); in free_opinfo()
129 kfree(opinfo); in free_opinfo()
134 struct oplock_info *opinfo; in opinfo_get() local
137 opinfo = rcu_dereference(fp->f_opinfo); in opinfo_get()
138 if (opinfo && !atomic_inc_not_zero(&opinfo->refcount)) in opinfo_get()
139 opinfo = NULL; in opinfo_get()
142 return opinfo; in opinfo_get()
147 struct oplock_info *opinfo; in opinfo_get_list() local
150 opinfo = list_first_entry_or_null(&ci->m_op_list, struct oplock_info, in opinfo_get_list()
152 if (opinfo) { in opinfo_get_list()
153 if (opinfo->conn == NULL || in opinfo_get_list()
154 !atomic_inc_not_zero(&opinfo->refcount)) in opinfo_get_list()
155 opinfo = NULL; in opinfo_get_list()
157 if (ksmbd_conn_releasing(opinfo->conn)) { in opinfo_get_list()
158 atomic_dec(&opinfo->refcount); in opinfo_get_list()
159 opinfo = NULL; in opinfo_get_list()
165 return opinfo; in opinfo_get_list()
168 void opinfo_put(struct oplock_info *opinfo) in opinfo_put() argument
170 if (!opinfo) in opinfo_put()
173 if (!atomic_dec_and_test(&opinfo->refcount)) in opinfo_put()
176 free_opinfo(opinfo); in opinfo_put()
179 static void opinfo_add(struct oplock_info *opinfo) in opinfo_add() argument
181 struct ksmbd_inode *ci = opinfo->o_fp->f_ci; in opinfo_add()
184 list_add(&opinfo->op_entry, &ci->m_op_list); in opinfo_add()
188 static void opinfo_del(struct oplock_info *opinfo) in opinfo_del() argument
190 struct ksmbd_inode *ci = opinfo->o_fp->f_ci; in opinfo_del()
192 if (opinfo->is_lease) { in opinfo_del()
194 lease_del_list(opinfo); in opinfo_del()
198 list_del(&opinfo->op_entry); in opinfo_del()
232 int opinfo_write_to_read(struct oplock_info *opinfo) in opinfo_write_to_read() argument
234 struct lease *lease = opinfo->o_lease; in opinfo_write_to_read()
236 if (!(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH || in opinfo_write_to_read()
237 opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) { in opinfo_write_to_read()
238 pr_err("bad oplock(0x%x)\n", opinfo->level); in opinfo_write_to_read()
239 if (opinfo->is_lease) in opinfo_write_to_read()
243 opinfo->level = SMB2_OPLOCK_LEVEL_II; in opinfo_write_to_read()
245 if (opinfo->is_lease) in opinfo_write_to_read()
256 int opinfo_read_handle_to_read(struct oplock_info *opinfo) in opinfo_read_handle_to_read() argument
258 struct lease *lease = opinfo->o_lease; in opinfo_read_handle_to_read()
261 opinfo->level = SMB2_OPLOCK_LEVEL_II; in opinfo_read_handle_to_read()
271 int opinfo_write_to_none(struct oplock_info *opinfo) in opinfo_write_to_none() argument
273 struct lease *lease = opinfo->o_lease; in opinfo_write_to_none()
275 if (!(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH || in opinfo_write_to_none()
276 opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) { in opinfo_write_to_none()
277 pr_err("bad oplock(0x%x)\n", opinfo->level); in opinfo_write_to_none()
278 if (opinfo->is_lease) in opinfo_write_to_none()
282 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in opinfo_write_to_none()
283 if (opinfo->is_lease) in opinfo_write_to_none()
294 int opinfo_read_to_none(struct oplock_info *opinfo) in opinfo_read_to_none() argument
296 struct lease *lease = opinfo->o_lease; in opinfo_read_to_none()
298 if (opinfo->level != SMB2_OPLOCK_LEVEL_II) { in opinfo_read_to_none()
299 pr_err("bad oplock(0x%x)\n", opinfo->level); in opinfo_read_to_none()
300 if (opinfo->is_lease) in opinfo_read_to_none()
304 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in opinfo_read_to_none()
305 if (opinfo->is_lease) in opinfo_read_to_none()
316 int lease_read_to_write(struct oplock_info *opinfo) in lease_read_to_write() argument
318 struct lease *lease = opinfo->o_lease; in lease_read_to_write()
328 opinfo->level = SMB2_OPLOCK_LEVEL_BATCH; in lease_read_to_write()
330 opinfo->level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; in lease_read_to_write()
341 static int lease_none_upgrade(struct oplock_info *opinfo, __le32 new_state) in lease_none_upgrade() argument
343 struct lease *lease = opinfo->o_lease; in lease_none_upgrade()
354 opinfo->level = SMB2_OPLOCK_LEVEL_BATCH; in lease_none_upgrade()
356 opinfo->level = SMB2_OPLOCK_LEVEL_II; in lease_none_upgrade()
358 opinfo->level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; in lease_none_upgrade()
360 opinfo->level = SMB2_OPLOCK_LEVEL_II; in lease_none_upgrade()
371 struct oplock_info *opinfo; in close_id_del_oplock() local
376 opinfo = opinfo_get(fp); in close_id_del_oplock()
377 if (!opinfo) in close_id_del_oplock()
380 opinfo_del(opinfo); in close_id_del_oplock()
383 if (opinfo->op_state == OPLOCK_ACK_WAIT) { in close_id_del_oplock()
384 opinfo->op_state = OPLOCK_CLOSING; in close_id_del_oplock()
385 wake_up_interruptible_all(&opinfo->oplock_q); in close_id_del_oplock()
386 if (opinfo->is_lease) { in close_id_del_oplock()
387 atomic_set(&opinfo->breaking_cnt, 0); in close_id_del_oplock()
388 wake_up_interruptible_all(&opinfo->oplock_brk); in close_id_del_oplock()
393 atomic_dec(&opinfo->refcount); in close_id_del_oplock()
394 opinfo_put(opinfo); in close_id_del_oplock()
463 static inline int compare_guid_key(struct oplock_info *opinfo, in compare_guid_key() argument
468 guid2 = opinfo->conn->ClientGUID; in compare_guid_key()
469 key2 = opinfo->o_lease->lease_key; in compare_guid_key()
492 struct oplock_info *opinfo; in same_client_has_lease() local
503 list_for_each_entry(opinfo, &ci->m_op_list, op_entry) { in same_client_has_lease()
504 if (!opinfo->is_lease || !opinfo->conn) in same_client_has_lease()
506 lease = opinfo->o_lease; in same_client_has_lease()
508 ret = compare_guid_key(opinfo, client_guid, lctx->lease_key); in same_client_has_lease()
510 m_opinfo = opinfo; in same_client_has_lease()
512 if (atomic_read(&opinfo->breaking_cnt)) in same_client_has_lease()
524 lease_read_to_write(opinfo); in same_client_has_lease()
540 lease_none_upgrade(opinfo, lctx->req_state); in same_client_has_lease()
549 static void wait_for_break_ack(struct oplock_info *opinfo) in wait_for_break_ack() argument
553 rc = wait_event_interruptible_timeout(opinfo->oplock_q, in wait_for_break_ack()
554 opinfo->op_state == OPLOCK_STATE_NONE || in wait_for_break_ack()
555 opinfo->op_state == OPLOCK_CLOSING, in wait_for_break_ack()
560 if (opinfo->is_lease) in wait_for_break_ack()
561 opinfo->o_lease->state = SMB2_LEASE_NONE_LE; in wait_for_break_ack()
562 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in wait_for_break_ack()
563 opinfo->op_state = OPLOCK_STATE_NONE; in wait_for_break_ack()
567 static void wake_up_oplock_break(struct oplock_info *opinfo) in wake_up_oplock_break() argument
569 clear_bit_unlock(0, &opinfo->pending_break); in wake_up_oplock_break()
572 wake_up_bit(&opinfo->pending_break, 0); in wake_up_oplock_break()
575 static int oplock_break_pending(struct oplock_info *opinfo, int req_op_level) in oplock_break_pending() argument
577 while (test_and_set_bit(0, &opinfo->pending_break)) { in oplock_break_pending()
578 wait_on_bit(&opinfo->pending_break, 0, TASK_UNINTERRUPTIBLE); in oplock_break_pending()
581 opinfo->open_trunc = 0; in oplock_break_pending()
583 if (opinfo->op_state == OPLOCK_CLOSING) in oplock_break_pending()
585 else if (opinfo->level <= req_op_level) { in oplock_break_pending()
586 if (opinfo->is_lease == false) in oplock_break_pending()
589 if (opinfo->o_lease->state != in oplock_break_pending()
596 if (opinfo->level <= req_op_level) { in oplock_break_pending()
597 if (opinfo->is_lease == false) { in oplock_break_pending()
598 wake_up_oplock_break(opinfo); in oplock_break_pending()
601 if (opinfo->o_lease->state != in oplock_break_pending()
604 wake_up_oplock_break(opinfo); in oplock_break_pending()
691 static int smb2_oplock_break_noti(struct oplock_info *opinfo) in smb2_oplock_break_noti() argument
693 struct ksmbd_conn *conn = opinfo->conn; in smb2_oplock_break_noti()
707 br_info->level = opinfo->level; in smb2_oplock_break_noti()
708 br_info->fid = opinfo->fid; in smb2_oplock_break_noti()
709 br_info->open_trunc = opinfo->open_trunc; in smb2_oplock_break_noti()
713 work->sess = opinfo->sess; in smb2_oplock_break_noti()
716 if (opinfo->op_state == OPLOCK_ACK_WAIT) { in smb2_oplock_break_noti()
720 wait_for_break_ack(opinfo); in smb2_oplock_break_noti()
723 if (opinfo->level == SMB2_OPLOCK_LEVEL_II) in smb2_oplock_break_noti()
724 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in smb2_oplock_break_noti()
795 static int smb2_lease_break_noti(struct oplock_info *opinfo) in smb2_lease_break_noti() argument
797 struct ksmbd_conn *conn = opinfo->conn; in smb2_lease_break_noti()
800 struct lease *lease = opinfo->o_lease; in smb2_lease_break_noti()
822 work->sess = opinfo->sess; in smb2_lease_break_noti()
825 if (opinfo->op_state == OPLOCK_ACK_WAIT) { in smb2_lease_break_noti()
828 wait_for_break_ack(opinfo); in smb2_lease_break_noti()
831 if (opinfo->o_lease->new_state == SMB2_LEASE_NONE_LE) { in smb2_lease_break_noti()
832 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in smb2_lease_break_noti()
833 opinfo->o_lease->state = SMB2_LEASE_NONE_LE; in smb2_lease_break_noti()
839 static void wait_lease_breaking(struct oplock_info *opinfo) in wait_lease_breaking() argument
841 if (!opinfo->is_lease) in wait_lease_breaking()
844 wake_up_interruptible_all(&opinfo->oplock_brk); in wait_lease_breaking()
845 if (atomic_read(&opinfo->breaking_cnt)) { in wait_lease_breaking()
848 ret = wait_event_interruptible_timeout(opinfo->oplock_brk, in wait_lease_breaking()
849 atomic_read(&opinfo->breaking_cnt) == 0, in wait_lease_breaking()
852 atomic_set(&opinfo->breaking_cnt, 0); in wait_lease_breaking()
938 struct oplock_info *opinfo; in destroy_lease_table() local
952 list_for_each_entry_rcu(opinfo, &lb->lease_list, in destroy_lease_table()
955 lease_del_list(opinfo); in destroy_lease_table()
968 struct oplock_info *opinfo; in find_same_lease_key() local
992 list_for_each_entry_rcu(opinfo, &lb->lease_list, lease_entry) { in find_same_lease_key()
993 if (!atomic_inc_not_zero(&opinfo->refcount)) in find_same_lease_key()
996 if (opinfo->o_fp->f_ci == ci) in find_same_lease_key()
998 err = compare_guid_key(opinfo, sess->ClientGUID, in find_same_lease_key()
1004 opinfo_put(opinfo); in find_same_lease_key()
1008 opinfo_put(opinfo); in find_same_lease_key()
1033 static int add_lease_global_list(struct oplock_info *opinfo) in add_lease_global_list() argument
1039 if (!memcmp(lb->client_guid, opinfo->conn->ClientGUID, in add_lease_global_list()
1041 opinfo->o_lease->l_lb = lb; in add_lease_global_list()
1042 lease_add_list(opinfo); in add_lease_global_list()
1053 memcpy(lb->client_guid, opinfo->conn->ClientGUID, in add_lease_global_list()
1057 opinfo->o_lease->l_lb = lb; in add_lease_global_list()
1058 lease_add_list(opinfo); in add_lease_global_list()
1063 static void set_oplock_level(struct oplock_info *opinfo, int level, in set_oplock_level() argument
1069 grant_write_oplock(opinfo, level, lctx); in set_oplock_level()
1072 grant_read_oplock(opinfo, lctx); in set_oplock_level()
1075 grant_none_oplock(opinfo, lctx); in set_oplock_level()
1083 struct oplock_info *opinfo; in smb_send_parent_lease_break_noti() local
1094 list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) { in smb_send_parent_lease_break_noti()
1095 if (opinfo->conn == NULL || !opinfo->is_lease) in smb_send_parent_lease_break_noti()
1098 if (opinfo->o_lease->state != SMB2_OPLOCK_LEVEL_NONE && in smb_send_parent_lease_break_noti()
1100 !compare_guid_key(opinfo, fp->conn->ClientGUID, in smb_send_parent_lease_break_noti()
1102 if (!atomic_inc_not_zero(&opinfo->refcount)) in smb_send_parent_lease_break_noti()
1105 if (ksmbd_conn_releasing(opinfo->conn)) { in smb_send_parent_lease_break_noti()
1106 opinfo_put(opinfo); in smb_send_parent_lease_break_noti()
1110 oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE, NULL); in smb_send_parent_lease_break_noti()
1111 opinfo_put(opinfo); in smb_send_parent_lease_break_noti()
1121 struct oplock_info *opinfo; in smb_lazy_parent_lease_break_close() local
1125 opinfo = rcu_dereference(fp->f_opinfo); in smb_lazy_parent_lease_break_close()
1128 if (!opinfo || !opinfo->is_lease || opinfo->o_lease->version != 2) in smb_lazy_parent_lease_break_close()
1136 list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) { in smb_lazy_parent_lease_break_close()
1137 if (opinfo->conn == NULL || !opinfo->is_lease) in smb_lazy_parent_lease_break_close()
1140 if (opinfo->o_lease->state != SMB2_OPLOCK_LEVEL_NONE) { in smb_lazy_parent_lease_break_close()
1141 if (!atomic_inc_not_zero(&opinfo->refcount)) in smb_lazy_parent_lease_break_close()
1144 if (ksmbd_conn_releasing(opinfo->conn)) { in smb_lazy_parent_lease_break_close()
1145 opinfo_put(opinfo); in smb_lazy_parent_lease_break_close()
1149 oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE, NULL); in smb_lazy_parent_lease_break_close()
1150 opinfo_put(opinfo); in smb_lazy_parent_lease_break_close()
1176 struct oplock_info *opinfo = NULL, *prev_opinfo = NULL; in smb_grant_oplock() local
1189 opinfo = alloc_opinfo(work, pid, tid); in smb_grant_oplock()
1190 if (!opinfo) in smb_grant_oplock()
1194 err = alloc_lease(opinfo, lctx); in smb_grant_oplock()
1197 opinfo->is_lease = 1; in smb_grant_oplock()
1219 copy_lease(m_opinfo, opinfo); in smb_grant_oplock()
1221 opinfo->o_lease->flags = in smb_grant_oplock()
1277 set_oplock_level(opinfo, req_op_level, lctx); in smb_grant_oplock()
1280 rcu_assign_pointer(fp->f_opinfo, opinfo); in smb_grant_oplock()
1281 opinfo->o_fp = fp; in smb_grant_oplock()
1284 opinfo_add(opinfo); in smb_grant_oplock()
1285 if (opinfo->is_lease) { in smb_grant_oplock()
1286 err = add_lease_global_list(opinfo); in smb_grant_oplock()
1293 free_opinfo(opinfo); in smb_grant_oplock()
1763 struct oplock_info *opinfo = NULL, *ret_op = NULL; in lookup_lease_in_table() local
1779 list_for_each_entry_rcu(opinfo, <->lease_list, lease_entry) { in lookup_lease_in_table()
1780 if (!atomic_inc_not_zero(&opinfo->refcount)) in lookup_lease_in_table()
1783 if (!opinfo->op_state || opinfo->op_state == OPLOCK_CLOSING) in lookup_lease_in_table()
1785 if (!(opinfo->o_lease->state & in lookup_lease_in_table()
1789 ret = compare_guid_key(opinfo, conn->ClientGUID, in lookup_lease_in_table()
1793 ret_op = opinfo; in lookup_lease_in_table()
1797 opinfo_put(opinfo); in lookup_lease_in_table()
1813 struct oplock_info *opinfo = opinfo_get(fp); in smb2_check_durable_oplock() local
1816 if (!opinfo) in smb2_check_durable_oplock()
1819 if (opinfo->is_lease == false) { in smb2_check_durable_oplock()
1826 if (opinfo->level != SMB2_OPLOCK_LEVEL_BATCH) { in smb2_check_durable_oplock()
1847 if (memcmp(opinfo->o_lease->lease_key, lctx->lease_key, in smb2_check_durable_oplock()
1855 if (!(opinfo->o_lease->state & SMB2_LEASE_HANDLE_CACHING_LE)) { in smb2_check_durable_oplock()
1861 if (opinfo->o_lease->version != lctx->version) { in smb2_check_durable_oplock()
1871 opinfo_put(opinfo); in smb2_check_durable_oplock()