Lines Matching refs:opinfo

34 	struct oplock_info *opinfo;  in alloc_opinfo()  local
36 opinfo = kzalloc(sizeof(struct oplock_info), GFP_KERNEL); in alloc_opinfo()
37 if (!opinfo) in alloc_opinfo()
40 opinfo->sess = sess; in alloc_opinfo()
41 opinfo->conn = sess->conn; in alloc_opinfo()
42 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in alloc_opinfo()
43 opinfo->op_state = OPLOCK_STATE_NONE; in alloc_opinfo()
44 opinfo->pending_break = 0; in alloc_opinfo()
45 opinfo->fid = id; in alloc_opinfo()
46 opinfo->Tid = Tid; in alloc_opinfo()
47 INIT_LIST_HEAD(&opinfo->op_entry); in alloc_opinfo()
48 INIT_LIST_HEAD(&opinfo->interim_list); 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()
54 return opinfo; in alloc_opinfo()
57 static void lease_add_list(struct oplock_info *opinfo) in lease_add_list() argument
59 struct lease_table *lb = opinfo->o_lease->l_lb; in lease_add_list()
62 list_add_rcu(&opinfo->lease_entry, &lb->lease_list); in lease_add_list()
66 static void lease_del_list(struct oplock_info *opinfo) in lease_del_list() argument
68 struct lease_table *lb = opinfo->o_lease->l_lb; in lease_del_list()
74 if (list_empty(&opinfo->lease_entry)) { in lease_del_list()
79 list_del_init(&opinfo->lease_entry); in lease_del_list()
80 opinfo->o_lease->l_lb = NULL; in lease_del_list()
91 static int alloc_lease(struct oplock_info *opinfo, struct lease_ctx_info *lctx) in alloc_lease() argument
107 INIT_LIST_HEAD(&opinfo->lease_entry); in alloc_lease()
108 opinfo->o_lease = lease; in alloc_lease()
113 static void free_lease(struct oplock_info *opinfo) in free_lease() argument
117 lease = opinfo->o_lease; in free_lease()
121 static void free_opinfo(struct oplock_info *opinfo) in free_opinfo() argument
123 if (opinfo->is_lease) in free_opinfo()
124 free_lease(opinfo); in free_opinfo()
125 kfree(opinfo); in free_opinfo()
130 struct oplock_info *opinfo; in opinfo_free_rcu() local
132 opinfo = container_of(rcu_head, struct oplock_info, rcu_head); in opinfo_free_rcu()
133 free_opinfo(opinfo); in opinfo_free_rcu()
138 struct oplock_info *opinfo; in opinfo_get() local
141 opinfo = rcu_dereference(fp->f_opinfo); in opinfo_get()
142 if (opinfo && !atomic_inc_not_zero(&opinfo->refcount)) in opinfo_get()
143 opinfo = NULL; in opinfo_get()
146 return opinfo; in opinfo_get()
151 struct oplock_info *opinfo; in opinfo_get_list() local
157 opinfo = list_first_or_null_rcu(&ci->m_op_list, struct oplock_info, in opinfo_get_list()
159 if (opinfo && !atomic_inc_not_zero(&opinfo->refcount)) in opinfo_get_list()
160 opinfo = NULL; in opinfo_get_list()
163 return opinfo; in opinfo_get_list()
166 void opinfo_put(struct oplock_info *opinfo) in opinfo_put() argument
168 if (!atomic_dec_and_test(&opinfo->refcount)) in opinfo_put()
171 call_rcu(&opinfo->rcu_head, opinfo_free_rcu); in opinfo_put()
174 static void opinfo_add(struct oplock_info *opinfo) in opinfo_add() argument
176 struct ksmbd_inode *ci = opinfo->o_fp->f_ci; in opinfo_add()
179 list_add_rcu(&opinfo->op_entry, &ci->m_op_list); in opinfo_add()
183 static void opinfo_del(struct oplock_info *opinfo) in opinfo_del() argument
185 struct ksmbd_inode *ci = opinfo->o_fp->f_ci; in opinfo_del()
187 if (opinfo->is_lease) { in opinfo_del()
189 lease_del_list(opinfo); in opinfo_del()
193 list_del_rcu(&opinfo->op_entry); in opinfo_del()
227 int opinfo_write_to_read(struct oplock_info *opinfo) in opinfo_write_to_read() argument
229 struct lease *lease = opinfo->o_lease; in opinfo_write_to_read()
231 if (!(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH || in opinfo_write_to_read()
232 opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) { in opinfo_write_to_read()
233 pr_err("bad oplock(0x%x)\n", opinfo->level); in opinfo_write_to_read()
234 if (opinfo->is_lease) in opinfo_write_to_read()
238 opinfo->level = SMB2_OPLOCK_LEVEL_II; in opinfo_write_to_read()
240 if (opinfo->is_lease) in opinfo_write_to_read()
251 int opinfo_read_handle_to_read(struct oplock_info *opinfo) in opinfo_read_handle_to_read() argument
253 struct lease *lease = opinfo->o_lease; in opinfo_read_handle_to_read()
256 opinfo->level = SMB2_OPLOCK_LEVEL_II; in opinfo_read_handle_to_read()
266 int opinfo_write_to_none(struct oplock_info *opinfo) in opinfo_write_to_none() argument
268 struct lease *lease = opinfo->o_lease; in opinfo_write_to_none()
270 if (!(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH || in opinfo_write_to_none()
271 opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) { in opinfo_write_to_none()
272 pr_err("bad oplock(0x%x)\n", opinfo->level); in opinfo_write_to_none()
273 if (opinfo->is_lease) in opinfo_write_to_none()
277 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in opinfo_write_to_none()
278 if (opinfo->is_lease) in opinfo_write_to_none()
289 int opinfo_read_to_none(struct oplock_info *opinfo) in opinfo_read_to_none() argument
291 struct lease *lease = opinfo->o_lease; in opinfo_read_to_none()
293 if (opinfo->level != SMB2_OPLOCK_LEVEL_II) { in opinfo_read_to_none()
294 pr_err("bad oplock(0x%x)\n", opinfo->level); in opinfo_read_to_none()
295 if (opinfo->is_lease) in opinfo_read_to_none()
299 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in opinfo_read_to_none()
300 if (opinfo->is_lease) in opinfo_read_to_none()
311 int lease_read_to_write(struct oplock_info *opinfo) in lease_read_to_write() argument
313 struct lease *lease = opinfo->o_lease; in lease_read_to_write()
323 opinfo->level = SMB2_OPLOCK_LEVEL_BATCH; in lease_read_to_write()
325 opinfo->level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; in lease_read_to_write()
336 static int lease_none_upgrade(struct oplock_info *opinfo, __le32 new_state) in lease_none_upgrade() argument
338 struct lease *lease = opinfo->o_lease; in lease_none_upgrade()
349 opinfo->level = SMB2_OPLOCK_LEVEL_BATCH; in lease_none_upgrade()
351 opinfo->level = SMB2_OPLOCK_LEVEL_II; in lease_none_upgrade()
353 opinfo->level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; in lease_none_upgrade()
355 opinfo->level = SMB2_OPLOCK_LEVEL_II; in lease_none_upgrade()
366 struct oplock_info *opinfo; in close_id_del_oplock() local
371 opinfo = opinfo_get(fp); in close_id_del_oplock()
372 if (!opinfo) in close_id_del_oplock()
375 opinfo_del(opinfo); in close_id_del_oplock()
378 if (opinfo->op_state == OPLOCK_ACK_WAIT) { in close_id_del_oplock()
379 opinfo->op_state = OPLOCK_CLOSING; in close_id_del_oplock()
380 wake_up_interruptible_all(&opinfo->oplock_q); in close_id_del_oplock()
381 if (opinfo->is_lease) { in close_id_del_oplock()
382 atomic_set(&opinfo->breaking_cnt, 0); in close_id_del_oplock()
383 wake_up_interruptible_all(&opinfo->oplock_brk); in close_id_del_oplock()
388 atomic_dec(&opinfo->refcount); in close_id_del_oplock()
389 opinfo_put(opinfo); in close_id_del_oplock()
458 static inline int compare_guid_key(struct oplock_info *opinfo, in compare_guid_key() argument
463 guid2 = opinfo->conn->ClientGUID; in compare_guid_key()
464 key2 = opinfo->o_lease->lease_key; in compare_guid_key()
487 struct oplock_info *opinfo; in same_client_has_lease() local
498 list_for_each_entry(opinfo, &ci->m_op_list, op_entry) { in same_client_has_lease()
499 if (!opinfo->is_lease) in same_client_has_lease()
502 lease = opinfo->o_lease; in same_client_has_lease()
504 ret = compare_guid_key(opinfo, client_guid, lctx->lease_key); in same_client_has_lease()
506 m_opinfo = opinfo; in same_client_has_lease()
508 if (atomic_read(&opinfo->breaking_cnt)) { in same_client_has_lease()
521 lease_read_to_write(opinfo); in same_client_has_lease()
533 lease_none_upgrade(opinfo, lctx->req_state); in same_client_has_lease()
542 static void wait_for_break_ack(struct oplock_info *opinfo) in wait_for_break_ack() argument
546 rc = wait_event_interruptible_timeout(opinfo->oplock_q, in wait_for_break_ack()
547 opinfo->op_state == OPLOCK_STATE_NONE || in wait_for_break_ack()
548 opinfo->op_state == OPLOCK_CLOSING, in wait_for_break_ack()
553 if (opinfo->is_lease) in wait_for_break_ack()
554 opinfo->o_lease->state = SMB2_LEASE_NONE_LE; in wait_for_break_ack()
555 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in wait_for_break_ack()
556 opinfo->op_state = OPLOCK_STATE_NONE; in wait_for_break_ack()
560 static void wake_up_oplock_break(struct oplock_info *opinfo) in wake_up_oplock_break() argument
562 clear_bit_unlock(0, &opinfo->pending_break); in wake_up_oplock_break()
565 wake_up_bit(&opinfo->pending_break, 0); in wake_up_oplock_break()
568 static int oplock_break_pending(struct oplock_info *opinfo, int req_op_level) in oplock_break_pending() argument
570 while (test_and_set_bit(0, &opinfo->pending_break)) { in oplock_break_pending()
571 wait_on_bit(&opinfo->pending_break, 0, TASK_UNINTERRUPTIBLE); in oplock_break_pending()
574 opinfo->open_trunc = 0; in oplock_break_pending()
576 if (opinfo->op_state == OPLOCK_CLOSING) in oplock_break_pending()
578 else if (!opinfo->is_lease && opinfo->level <= req_op_level) in oplock_break_pending()
582 if (!opinfo->is_lease && opinfo->level <= req_op_level) { in oplock_break_pending()
583 wake_up_oplock_break(opinfo); in oplock_break_pending()
681 static int smb2_oplock_break_noti(struct oplock_info *opinfo) in smb2_oplock_break_noti() argument
683 struct ksmbd_conn *conn = opinfo->conn; in smb2_oplock_break_noti()
697 br_info->level = opinfo->level; in smb2_oplock_break_noti()
698 br_info->fid = opinfo->fid; in smb2_oplock_break_noti()
699 br_info->open_trunc = opinfo->open_trunc; in smb2_oplock_break_noti()
703 work->sess = opinfo->sess; in smb2_oplock_break_noti()
706 if (opinfo->op_state == OPLOCK_ACK_WAIT) { in smb2_oplock_break_noti()
710 wait_for_break_ack(opinfo); in smb2_oplock_break_noti()
713 if (opinfo->level == SMB2_OPLOCK_LEVEL_II) in smb2_oplock_break_noti()
714 opinfo->level = SMB2_OPLOCK_LEVEL_NONE; in smb2_oplock_break_noti()
785 static int smb2_lease_break_noti(struct oplock_info *opinfo) in smb2_lease_break_noti() argument
787 struct ksmbd_conn *conn = opinfo->conn; in smb2_lease_break_noti()
791 struct lease *lease = opinfo->o_lease; in smb2_lease_break_noti()
813 work->sess = opinfo->sess; in smb2_lease_break_noti()
816 if (opinfo->op_state == OPLOCK_ACK_WAIT) { in smb2_lease_break_noti()
817 list_for_each_safe(tmp, t, &opinfo->interim_list) { 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()
931 struct oplock_info *opinfo; in destroy_lease_table() local
945 list_for_each_entry_rcu(opinfo, &lb->lease_list, in destroy_lease_table()
948 lease_del_list(opinfo); in destroy_lease_table()
961 struct oplock_info *opinfo; in find_same_lease_key() local
985 list_for_each_entry_rcu(opinfo, &lb->lease_list, lease_entry) { in find_same_lease_key()
986 if (!atomic_inc_not_zero(&opinfo->refcount)) in find_same_lease_key()
989 if (opinfo->o_fp->f_ci == ci) in find_same_lease_key()
991 err = compare_guid_key(opinfo, sess->conn->ClientGUID, in find_same_lease_key()
997 opinfo_put(opinfo); in find_same_lease_key()
1001 opinfo_put(opinfo); in find_same_lease_key()
1024 static int add_lease_global_list(struct oplock_info *opinfo) in add_lease_global_list() argument
1030 if (!memcmp(lb->client_guid, opinfo->conn->ClientGUID, in add_lease_global_list()
1032 opinfo->o_lease->l_lb = lb; in add_lease_global_list()
1033 lease_add_list(opinfo); in add_lease_global_list()
1044 memcpy(lb->client_guid, opinfo->conn->ClientGUID, in add_lease_global_list()
1048 opinfo->o_lease->l_lb = lb; in add_lease_global_list()
1049 lease_add_list(opinfo); in add_lease_global_list()
1054 static void set_oplock_level(struct oplock_info *opinfo, int level, in set_oplock_level() argument
1060 grant_write_oplock(opinfo, level, lctx); in set_oplock_level()
1063 grant_read_oplock(opinfo, lctx); in set_oplock_level()
1066 grant_none_oplock(opinfo, lctx); in set_oplock_level()
1089 struct oplock_info *opinfo = NULL, *prev_opinfo = NULL; in smb_grant_oplock() local
1098 opinfo = alloc_opinfo(work, pid, tid); in smb_grant_oplock()
1099 if (!opinfo) in smb_grant_oplock()
1103 err = alloc_lease(opinfo, lctx); in smb_grant_oplock()
1106 opinfo->is_lease = 1; in smb_grant_oplock()
1128 copy_lease(m_opinfo, opinfo); in smb_grant_oplock()
1130 opinfo->o_lease->flags = in smb_grant_oplock()
1185 set_oplock_level(opinfo, req_op_level, lctx); in smb_grant_oplock()
1188 rcu_assign_pointer(fp->f_opinfo, opinfo); in smb_grant_oplock()
1189 opinfo->o_fp = fp; in smb_grant_oplock()
1192 opinfo_add(opinfo); in smb_grant_oplock()
1193 if (opinfo->is_lease) { in smb_grant_oplock()
1194 err = add_lease_global_list(opinfo); in smb_grant_oplock()
1201 free_opinfo(opinfo); in smb_grant_oplock()
1660 struct oplock_info *opinfo = NULL, *ret_op = NULL; in lookup_lease_in_table() local
1676 list_for_each_entry_rcu(opinfo, &lt->lease_list, lease_entry) { in lookup_lease_in_table()
1677 if (!atomic_inc_not_zero(&opinfo->refcount)) in lookup_lease_in_table()
1680 if (!opinfo->op_state || opinfo->op_state == OPLOCK_CLOSING) in lookup_lease_in_table()
1682 if (!(opinfo->o_lease->state & in lookup_lease_in_table()
1686 ret = compare_guid_key(opinfo, conn->ClientGUID, in lookup_lease_in_table()
1690 ret_op = opinfo; in lookup_lease_in_table()
1694 opinfo_put(opinfo); in lookup_lease_in_table()
1707 struct oplock_info *opinfo = opinfo_get(fp); in smb2_check_durable_oplock() local
1710 if (opinfo && opinfo->is_lease) { in smb2_check_durable_oplock()
1716 if (memcmp(opinfo->o_lease->lease_key, lctx->lease_key, in smb2_check_durable_oplock()
1729 if (opinfo) in smb2_check_durable_oplock()
1730 opinfo_put(opinfo); in smb2_check_durable_oplock()