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
153 opinfo = list_first_entry(&ci->m_op_list, struct oplock_info, in opinfo_get_list()
155 if (opinfo) { in opinfo_get_list()
156 if (opinfo->conn == NULL || in opinfo_get_list()
157 !atomic_inc_not_zero(&opinfo->refcount)) in opinfo_get_list()
158 opinfo = NULL; in opinfo_get_list()
160 if (ksmbd_conn_releasing(opinfo->conn)) { in opinfo_get_list()
161 atomic_dec(&opinfo->refcount); in opinfo_get_list()
162 opinfo = NULL; in opinfo_get_list()
168 return opinfo; in opinfo_get_list()
171 void opinfo_put(struct oplock_info *opinfo) in opinfo_put() argument
173 if (!opinfo) in opinfo_put()
176 if (!atomic_dec_and_test(&opinfo->refcount)) in opinfo_put()
179 free_opinfo(opinfo); in opinfo_put()
182 static void opinfo_add(struct oplock_info *opinfo) in opinfo_add() argument
184 struct ksmbd_inode *ci = opinfo->o_fp->f_ci; in opinfo_add()
187 list_add(&opinfo->op_entry, &ci->m_op_list); in opinfo_add()
191 static void opinfo_del(struct oplock_info *opinfo) in opinfo_del() argument
193 struct ksmbd_inode *ci = opinfo->o_fp->f_ci; in opinfo_del()
195 if (opinfo->is_lease) { in opinfo_del()
197 lease_del_list(opinfo); in opinfo_del()
201 list_del(&opinfo->op_entry); in opinfo_del()
235 int opinfo_write_to_read(struct oplock_info *opinfo) in opinfo_write_to_read() argument
237 struct lease *lease = opinfo->o_lease; in opinfo_write_to_read()
239 if (!(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH || in opinfo_write_to_read()
240 opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) { in opinfo_write_to_read()
241 pr_err("bad oplock(0x%x)\n", opinfo->level); in opinfo_write_to_read()
242 if (opinfo->is_lease) in opinfo_write_to_read()
246 opinfo->level = SMB2_OPLOCK_LEVEL_II; in opinfo_write_to_read()
248 if (opinfo->is_lease) in opinfo_write_to_read()
259 int opinfo_read_handle_to_read(struct oplock_info *opinfo) in opinfo_read_handle_to_read() argument
261 struct lease *lease = opinfo->o_lease; in opinfo_read_handle_to_read()
264 opinfo->level = SMB2_OPLOCK_LEVEL_II; in opinfo_read_handle_to_read()
274 int opinfo_write_to_none(struct oplock_info *opinfo) in opinfo_write_to_none() argument
276 struct lease *lease = opinfo->o_lease; in opinfo_write_to_none()
278 if (!(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH || in opinfo_write_to_none()
279 opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) { in opinfo_write_to_none()
280 pr_err("bad oplock(0x%x)\n", opinfo->level); in opinfo_write_to_none()
281 if (opinfo->is_lease) in opinfo_write_to_none()
285 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in opinfo_write_to_none()
286 if (opinfo->is_lease) in opinfo_write_to_none()
297 int opinfo_read_to_none(struct oplock_info *opinfo) in opinfo_read_to_none() argument
299 struct lease *lease = opinfo->o_lease; in opinfo_read_to_none()
301 if (opinfo->level != SMB2_OPLOCK_LEVEL_II) { in opinfo_read_to_none()
302 pr_err("bad oplock(0x%x)\n", opinfo->level); in opinfo_read_to_none()
303 if (opinfo->is_lease) in opinfo_read_to_none()
307 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in opinfo_read_to_none()
308 if (opinfo->is_lease) in opinfo_read_to_none()
319 int lease_read_to_write(struct oplock_info *opinfo) in lease_read_to_write() argument
321 struct lease *lease = opinfo->o_lease; in lease_read_to_write()
331 opinfo->level = SMB2_OPLOCK_LEVEL_BATCH; in lease_read_to_write()
333 opinfo->level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; in lease_read_to_write()
344 static int lease_none_upgrade(struct oplock_info *opinfo, __le32 new_state) in lease_none_upgrade() argument
346 struct lease *lease = opinfo->o_lease; in lease_none_upgrade()
357 opinfo->level = SMB2_OPLOCK_LEVEL_BATCH; in lease_none_upgrade()
359 opinfo->level = SMB2_OPLOCK_LEVEL_II; in lease_none_upgrade()
361 opinfo->level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; in lease_none_upgrade()
363 opinfo->level = SMB2_OPLOCK_LEVEL_II; in lease_none_upgrade()
374 struct oplock_info *opinfo; in close_id_del_oplock() local
379 opinfo = opinfo_get(fp); in close_id_del_oplock()
380 if (!opinfo) in close_id_del_oplock()
383 opinfo_del(opinfo); in close_id_del_oplock()
386 if (opinfo->op_state == OPLOCK_ACK_WAIT) { in close_id_del_oplock()
387 opinfo->op_state = OPLOCK_CLOSING; in close_id_del_oplock()
388 wake_up_interruptible_all(&opinfo->oplock_q); in close_id_del_oplock()
389 if (opinfo->is_lease) { in close_id_del_oplock()
390 atomic_set(&opinfo->breaking_cnt, 0); in close_id_del_oplock()
391 wake_up_interruptible_all(&opinfo->oplock_brk); in close_id_del_oplock()
396 atomic_dec(&opinfo->refcount); in close_id_del_oplock()
397 opinfo_put(opinfo); in close_id_del_oplock()
466 static inline int compare_guid_key(struct oplock_info *opinfo, in compare_guid_key() argument
471 guid2 = opinfo->conn->ClientGUID; in compare_guid_key()
472 key2 = opinfo->o_lease->lease_key; in compare_guid_key()
495 struct oplock_info *opinfo; in same_client_has_lease() local
506 list_for_each_entry(opinfo, &ci->m_op_list, op_entry) { in same_client_has_lease()
507 if (!opinfo->is_lease || !opinfo->conn) in same_client_has_lease()
509 lease = opinfo->o_lease; in same_client_has_lease()
511 ret = compare_guid_key(opinfo, client_guid, lctx->lease_key); in same_client_has_lease()
513 m_opinfo = opinfo; in same_client_has_lease()
515 if (atomic_read(&opinfo->breaking_cnt)) in same_client_has_lease()
527 lease_read_to_write(opinfo); in same_client_has_lease()
543 lease_none_upgrade(opinfo, lctx->req_state); in same_client_has_lease()
552 static void wait_for_break_ack(struct oplock_info *opinfo) in wait_for_break_ack() argument
556 rc = wait_event_interruptible_timeout(opinfo->oplock_q, in wait_for_break_ack()
557 opinfo->op_state == OPLOCK_STATE_NONE || in wait_for_break_ack()
558 opinfo->op_state == OPLOCK_CLOSING, in wait_for_break_ack()
563 if (opinfo->is_lease) in wait_for_break_ack()
564 opinfo->o_lease->state = SMB2_LEASE_NONE_LE; in wait_for_break_ack()
565 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in wait_for_break_ack()
566 opinfo->op_state = OPLOCK_STATE_NONE; in wait_for_break_ack()
570 static void wake_up_oplock_break(struct oplock_info *opinfo) in wake_up_oplock_break() argument
572 clear_bit_unlock(0, &opinfo->pending_break); in wake_up_oplock_break()
575 wake_up_bit(&opinfo->pending_break, 0); in wake_up_oplock_break()
578 static int oplock_break_pending(struct oplock_info *opinfo, int req_op_level) in oplock_break_pending() argument
580 while (test_and_set_bit(0, &opinfo->pending_break)) { in oplock_break_pending()
581 wait_on_bit(&opinfo->pending_break, 0, TASK_UNINTERRUPTIBLE); in oplock_break_pending()
584 opinfo->open_trunc = 0; in oplock_break_pending()
586 if (opinfo->op_state == OPLOCK_CLOSING) in oplock_break_pending()
588 else if (opinfo->level <= req_op_level) { in oplock_break_pending()
589 if (opinfo->is_lease == false) in oplock_break_pending()
592 if (opinfo->o_lease->state != in oplock_break_pending()
599 if (opinfo->level <= req_op_level) { in oplock_break_pending()
600 if (opinfo->is_lease == false) { in oplock_break_pending()
601 wake_up_oplock_break(opinfo); in oplock_break_pending()
604 if (opinfo->o_lease->state != in oplock_break_pending()
607 wake_up_oplock_break(opinfo); in oplock_break_pending()
694 static int smb2_oplock_break_noti(struct oplock_info *opinfo) in smb2_oplock_break_noti() argument
696 struct ksmbd_conn *conn = opinfo->conn; in smb2_oplock_break_noti()
710 br_info->level = opinfo->level; in smb2_oplock_break_noti()
711 br_info->fid = opinfo->fid; in smb2_oplock_break_noti()
712 br_info->open_trunc = opinfo->open_trunc; in smb2_oplock_break_noti()
716 work->sess = opinfo->sess; in smb2_oplock_break_noti()
719 if (opinfo->op_state == OPLOCK_ACK_WAIT) { in smb2_oplock_break_noti()
723 wait_for_break_ack(opinfo); in smb2_oplock_break_noti()
726 if (opinfo->level == SMB2_OPLOCK_LEVEL_II) in smb2_oplock_break_noti()
727 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in smb2_oplock_break_noti()
798 static int smb2_lease_break_noti(struct oplock_info *opinfo) in smb2_lease_break_noti() argument
800 struct ksmbd_conn *conn = opinfo->conn; in smb2_lease_break_noti()
803 struct lease *lease = opinfo->o_lease; in smb2_lease_break_noti()
825 work->sess = opinfo->sess; in smb2_lease_break_noti()
828 if (opinfo->op_state == OPLOCK_ACK_WAIT) { in smb2_lease_break_noti()
831 wait_for_break_ack(opinfo); in smb2_lease_break_noti()
834 if (opinfo->o_lease->new_state == SMB2_LEASE_NONE_LE) { in smb2_lease_break_noti()
835 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in smb2_lease_break_noti()
836 opinfo->o_lease->state = SMB2_LEASE_NONE_LE; in smb2_lease_break_noti()
842 static void wait_lease_breaking(struct oplock_info *opinfo) in wait_lease_breaking() argument
844 if (!opinfo->is_lease) in wait_lease_breaking()
847 wake_up_interruptible_all(&opinfo->oplock_brk); in wait_lease_breaking()
848 if (atomic_read(&opinfo->breaking_cnt)) { in wait_lease_breaking()
851 ret = wait_event_interruptible_timeout(opinfo->oplock_brk, in wait_lease_breaking()
852 atomic_read(&opinfo->breaking_cnt) == 0, in wait_lease_breaking()
855 atomic_set(&opinfo->breaking_cnt, 0); in wait_lease_breaking()
941 struct oplock_info *opinfo; in destroy_lease_table() local
955 list_for_each_entry_rcu(opinfo, &lb->lease_list, in destroy_lease_table()
958 lease_del_list(opinfo); in destroy_lease_table()
971 struct oplock_info *opinfo; in find_same_lease_key() local
995 list_for_each_entry_rcu(opinfo, &lb->lease_list, lease_entry) { in find_same_lease_key()
996 if (!atomic_inc_not_zero(&opinfo->refcount)) in find_same_lease_key()
999 if (opinfo->o_fp->f_ci == ci) in find_same_lease_key()
1001 err = compare_guid_key(opinfo, sess->ClientGUID, in find_same_lease_key()
1007 opinfo_put(opinfo); in find_same_lease_key()
1011 opinfo_put(opinfo); in find_same_lease_key()
1036 static int add_lease_global_list(struct oplock_info *opinfo) in add_lease_global_list() argument
1042 if (!memcmp(lb->client_guid, opinfo->conn->ClientGUID, in add_lease_global_list()
1044 opinfo->o_lease->l_lb = lb; in add_lease_global_list()
1045 lease_add_list(opinfo); in add_lease_global_list()
1056 memcpy(lb->client_guid, opinfo->conn->ClientGUID, in add_lease_global_list()
1060 opinfo->o_lease->l_lb = lb; in add_lease_global_list()
1061 lease_add_list(opinfo); in add_lease_global_list()
1066 static void set_oplock_level(struct oplock_info *opinfo, int level, in set_oplock_level() argument
1072 grant_write_oplock(opinfo, level, lctx); in set_oplock_level()
1075 grant_read_oplock(opinfo, lctx); in set_oplock_level()
1078 grant_none_oplock(opinfo, lctx); in set_oplock_level()
1086 struct oplock_info *opinfo; in smb_send_parent_lease_break_noti() local
1097 list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) { in smb_send_parent_lease_break_noti()
1098 if (opinfo->conn == NULL || !opinfo->is_lease) in smb_send_parent_lease_break_noti()
1101 if (opinfo->o_lease->state != SMB2_OPLOCK_LEVEL_NONE && in smb_send_parent_lease_break_noti()
1103 !compare_guid_key(opinfo, fp->conn->ClientGUID, in smb_send_parent_lease_break_noti()
1105 if (!atomic_inc_not_zero(&opinfo->refcount)) in smb_send_parent_lease_break_noti()
1108 if (ksmbd_conn_releasing(opinfo->conn)) in smb_send_parent_lease_break_noti()
1111 oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE, NULL); in smb_send_parent_lease_break_noti()
1112 opinfo_put(opinfo); in smb_send_parent_lease_break_noti()
1122 struct oplock_info *opinfo; in smb_lazy_parent_lease_break_close() local
1126 opinfo = rcu_dereference(fp->f_opinfo); in smb_lazy_parent_lease_break_close()
1129 if (!opinfo || !opinfo->is_lease || opinfo->o_lease->version != 2) in smb_lazy_parent_lease_break_close()
1137 list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) { in smb_lazy_parent_lease_break_close()
1138 if (opinfo->conn == NULL || !opinfo->is_lease) in smb_lazy_parent_lease_break_close()
1141 if (opinfo->o_lease->state != SMB2_OPLOCK_LEVEL_NONE) { in smb_lazy_parent_lease_break_close()
1142 if (!atomic_inc_not_zero(&opinfo->refcount)) in smb_lazy_parent_lease_break_close()
1145 if (ksmbd_conn_releasing(opinfo->conn)) in smb_lazy_parent_lease_break_close()
1147 oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE, NULL); in smb_lazy_parent_lease_break_close()
1148 opinfo_put(opinfo); in smb_lazy_parent_lease_break_close()
1174 struct oplock_info *opinfo = NULL, *prev_opinfo = NULL; in smb_grant_oplock() local
1187 opinfo = alloc_opinfo(work, pid, tid); in smb_grant_oplock()
1188 if (!opinfo) in smb_grant_oplock()
1192 err = alloc_lease(opinfo, lctx); in smb_grant_oplock()
1195 opinfo->is_lease = 1; in smb_grant_oplock()
1217 copy_lease(m_opinfo, opinfo); in smb_grant_oplock()
1219 opinfo->o_lease->flags = in smb_grant_oplock()
1275 set_oplock_level(opinfo, req_op_level, lctx); in smb_grant_oplock()
1278 rcu_assign_pointer(fp->f_opinfo, opinfo); in smb_grant_oplock()
1279 opinfo->o_fp = fp; in smb_grant_oplock()
1282 opinfo_add(opinfo); in smb_grant_oplock()
1283 if (opinfo->is_lease) { in smb_grant_oplock()
1284 err = add_lease_global_list(opinfo); in smb_grant_oplock()
1291 free_opinfo(opinfo); in smb_grant_oplock()
1756 struct oplock_info *opinfo = NULL, *ret_op = NULL; in lookup_lease_in_table() local
1772 list_for_each_entry_rcu(opinfo, <->lease_list, lease_entry) { in lookup_lease_in_table()
1773 if (!atomic_inc_not_zero(&opinfo->refcount)) in lookup_lease_in_table()
1776 if (!opinfo->op_state || opinfo->op_state == OPLOCK_CLOSING) in lookup_lease_in_table()
1778 if (!(opinfo->o_lease->state & in lookup_lease_in_table()
1782 ret = compare_guid_key(opinfo, conn->ClientGUID, in lookup_lease_in_table()
1786 ret_op = opinfo; in lookup_lease_in_table()
1790 opinfo_put(opinfo); in lookup_lease_in_table()
1806 struct oplock_info *opinfo = opinfo_get(fp); in smb2_check_durable_oplock() local
1809 if (!opinfo) in smb2_check_durable_oplock()
1812 if (opinfo->is_lease == false) { in smb2_check_durable_oplock()
1819 if (opinfo->level != SMB2_OPLOCK_LEVEL_BATCH) { in smb2_check_durable_oplock()
1840 if (memcmp(opinfo->o_lease->lease_key, lctx->lease_key, in smb2_check_durable_oplock()
1848 if (!(opinfo->o_lease->state & SMB2_LEASE_HANDLE_CACHING_LE)) { in smb2_check_durable_oplock()
1854 if (opinfo->o_lease->version != lctx->version) { in smb2_check_durable_oplock()
1864 opinfo_put(opinfo); in smb2_check_durable_oplock()