18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * fs/hmdfs/inode_share.h 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include "hmdfs_share.h" 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_cistatic inline bool hmdfs_is_dst_path(struct path *src, struct path *dst) 118c2ecf20Sopenharmony_ci{ 128c2ecf20Sopenharmony_ci return (src->dentry == dst->dentry) && (src->mnt == dst->mnt); 138c2ecf20Sopenharmony_ci} 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_cistatic inline bool is_dst_device(char *src_cid, char *dst_cid) 168c2ecf20Sopenharmony_ci{ 178c2ecf20Sopenharmony_ci return strncmp(src_cid, dst_cid, HMDFS_CID_SIZE) == 0; 188c2ecf20Sopenharmony_ci} 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cibool hmdfs_is_share_file(struct file *file) 218c2ecf20Sopenharmony_ci{ 228c2ecf20Sopenharmony_ci struct file *cur_file = file; 238c2ecf20Sopenharmony_ci struct hmdfs_dentry_info *gdi; 248c2ecf20Sopenharmony_ci struct hmdfs_file_info *gfi; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci while (cur_file->f_inode->i_sb->s_magic == HMDFS_SUPER_MAGIC) { 278c2ecf20Sopenharmony_ci gdi = hmdfs_d(cur_file->f_path.dentry); 288c2ecf20Sopenharmony_ci gfi = hmdfs_f(cur_file); 298c2ecf20Sopenharmony_ci if (hm_isshare(gdi->file_type)) 308c2ecf20Sopenharmony_ci return true; 318c2ecf20Sopenharmony_ci if (gfi->lower_file) 328c2ecf20Sopenharmony_ci cur_file = gfi->lower_file; 338c2ecf20Sopenharmony_ci else 348c2ecf20Sopenharmony_ci break; 358c2ecf20Sopenharmony_ci } 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci return false; 388c2ecf20Sopenharmony_ci} 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistatic void remove_and_release_share_item(struct hmdfs_share_item *item) 418c2ecf20Sopenharmony_ci{ 428c2ecf20Sopenharmony_ci list_del(&item->list); 438c2ecf20Sopenharmony_ci item->hst->item_cnt--; 448c2ecf20Sopenharmony_ci fput(item->file); 458c2ecf20Sopenharmony_ci kfree(item->relative_path.name); 468c2ecf20Sopenharmony_ci kfree(item); 478c2ecf20Sopenharmony_ci} 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic inline bool is_share_item_timeout(struct hmdfs_share_item *item) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci return !item->opened && item->timeout; 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistruct hmdfs_share_item *hmdfs_lookup_share_item(struct hmdfs_share_table *st, 558c2ecf20Sopenharmony_ci struct qstr *cur_relative_path) 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci struct hmdfs_share_item *item, *tmp; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci list_for_each_entry_safe(item, tmp, &st->item_list_head, list) { 608c2ecf20Sopenharmony_ci if (is_share_item_timeout(item)){ 618c2ecf20Sopenharmony_ci remove_and_release_share_item(item); 628c2ecf20Sopenharmony_ci } else { 638c2ecf20Sopenharmony_ci if (qstr_eq(&item->relative_path, cur_relative_path)) 648c2ecf20Sopenharmony_ci return item; 658c2ecf20Sopenharmony_ci } 668c2ecf20Sopenharmony_ci } 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci return NULL; 698c2ecf20Sopenharmony_ci} 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistatic void share_item_timeout_work(struct work_struct *work) { 728c2ecf20Sopenharmony_ci struct hmdfs_share_item *item = 738c2ecf20Sopenharmony_ci container_of(work, struct hmdfs_share_item, d_work.work); 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci item->timeout = true; 768c2ecf20Sopenharmony_ci} 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ciint insert_share_item(struct hmdfs_share_table *st, struct qstr *relative_path, 798c2ecf20Sopenharmony_ci struct file *file, char *cid) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci struct hmdfs_share_item *new_item = NULL; 828c2ecf20Sopenharmony_ci char *path_name; 838c2ecf20Sopenharmony_ci int err = 0; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci if (st->item_cnt >= st->max_cnt) { 868c2ecf20Sopenharmony_ci int ret = hmdfs_clear_first_item(st); 878c2ecf20Sopenharmony_ci if (unlikely(ret)) { 888c2ecf20Sopenharmony_ci err = -EMFILE; 898c2ecf20Sopenharmony_ci goto err_out; 908c2ecf20Sopenharmony_ci } 918c2ecf20Sopenharmony_ci } 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci path_name = kzalloc(PATH_MAX, GFP_KERNEL); 948c2ecf20Sopenharmony_ci if (unlikely(!path_name)) { 958c2ecf20Sopenharmony_ci err = -EMFILE; 968c2ecf20Sopenharmony_ci goto err_out; 978c2ecf20Sopenharmony_ci } 988c2ecf20Sopenharmony_ci strcpy(path_name, relative_path->name); 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci new_item = kmalloc(sizeof(*new_item), GFP_KERNEL); 1018c2ecf20Sopenharmony_ci if (unlikely(!new_item)) { 1028c2ecf20Sopenharmony_ci err = -ENOMEM; 1038c2ecf20Sopenharmony_ci kfree(path_name); 1048c2ecf20Sopenharmony_ci goto err_out; 1058c2ecf20Sopenharmony_ci } 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci new_item->file = file; 1088c2ecf20Sopenharmony_ci get_file(file); 1098c2ecf20Sopenharmony_ci new_item->relative_path.name = path_name; 1108c2ecf20Sopenharmony_ci new_item->relative_path.len = relative_path->len; 1118c2ecf20Sopenharmony_ci memcpy(new_item->cid, cid, HMDFS_CID_SIZE); 1128c2ecf20Sopenharmony_ci new_item->opened = false; 1138c2ecf20Sopenharmony_ci new_item->timeout = false; 1148c2ecf20Sopenharmony_ci list_add_tail(&new_item->list, &st->item_list_head); 1158c2ecf20Sopenharmony_ci new_item->hst = st; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci INIT_DELAYED_WORK(&new_item->d_work, share_item_timeout_work); 1188c2ecf20Sopenharmony_ci queue_delayed_work(new_item->hst->share_item_timeout_wq, 1198c2ecf20Sopenharmony_ci &new_item->d_work, HZ * HMDFS_SHARE_ITEM_TIMEOUT_S); 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci st->item_cnt++; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_cierr_out: 1248c2ecf20Sopenharmony_ci return err; 1258c2ecf20Sopenharmony_ci} 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_civoid update_share_item(struct hmdfs_share_item *item, struct file *file, 1288c2ecf20Sopenharmony_ci char *cid) 1298c2ecf20Sopenharmony_ci{ 1308c2ecf20Sopenharmony_ci /* if not the same file, we need to update struct file */ 1318c2ecf20Sopenharmony_ci if (!hmdfs_is_dst_path(&file->f_path, &item->file->f_path)) { 1328c2ecf20Sopenharmony_ci fput(item->file); 1338c2ecf20Sopenharmony_ci get_file(file); 1348c2ecf20Sopenharmony_ci item->file = file; 1358c2ecf20Sopenharmony_ci } 1368c2ecf20Sopenharmony_ci memcpy(item->cid, cid, HMDFS_CID_SIZE); 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci if (!cancel_delayed_work_sync(&item->d_work)) 1398c2ecf20Sopenharmony_ci item->timeout = false; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci queue_delayed_work(item->hst->share_item_timeout_wq, &item->d_work, 1428c2ecf20Sopenharmony_ci HZ * HMDFS_SHARE_ITEM_TIMEOUT_S); 1438c2ecf20Sopenharmony_ci} 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_cibool in_share_dir(struct dentry *child_dentry) 1468c2ecf20Sopenharmony_ci{ 1478c2ecf20Sopenharmony_ci struct dentry *parent_dentry = dget_parent(child_dentry); 1488c2ecf20Sopenharmony_ci bool ret = false; 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci if (!strncmp(parent_dentry->d_name.name, SHARE_RESERVED_DIR, 1518c2ecf20Sopenharmony_ci strlen(SHARE_RESERVED_DIR))) 1528c2ecf20Sopenharmony_ci ret = true; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci dput(parent_dentry); 1558c2ecf20Sopenharmony_ci return ret; 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ciinline bool is_share_dir(struct inode *inode, const char *name) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci return (S_ISDIR(inode->i_mode) && 1618c2ecf20Sopenharmony_ci !strncmp(name, SHARE_RESERVED_DIR, sizeof(SHARE_RESERVED_DIR))); 1628c2ecf20Sopenharmony_ci} 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ciint get_path_from_share_table(struct hmdfs_sb_info *sbi, 1658c2ecf20Sopenharmony_ci struct dentry *cur_dentry, 1668c2ecf20Sopenharmony_ci struct path *src_path) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci struct hmdfs_share_item *item; 1698c2ecf20Sopenharmony_ci const char *path_name; 1708c2ecf20Sopenharmony_ci struct qstr relative_path; 1718c2ecf20Sopenharmony_ci int err = 0; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci path_name = hmdfs_get_dentry_relative_path(cur_dentry); 1748c2ecf20Sopenharmony_ci if (unlikely(!path_name)) { 1758c2ecf20Sopenharmony_ci err = -ENOMEM; 1768c2ecf20Sopenharmony_ci goto err_out; 1778c2ecf20Sopenharmony_ci } 1788c2ecf20Sopenharmony_ci relative_path.name = path_name; 1798c2ecf20Sopenharmony_ci relative_path.len = strlen(path_name); 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci spin_lock(&sbi->share_table.item_list_lock); 1828c2ecf20Sopenharmony_ci item = hmdfs_lookup_share_item(&sbi->share_table, &relative_path); 1838c2ecf20Sopenharmony_ci if (!item) { 1848c2ecf20Sopenharmony_ci err = -ENOENT; 1858c2ecf20Sopenharmony_ci goto unlock; 1868c2ecf20Sopenharmony_ci } 1878c2ecf20Sopenharmony_ci path_get(&item->file->f_path); 1888c2ecf20Sopenharmony_ci *src_path = item->file->f_path; 1898c2ecf20Sopenharmony_ciunlock: 1908c2ecf20Sopenharmony_ci spin_unlock(&sbi->share_table.item_list_lock); 1918c2ecf20Sopenharmony_ci kfree(path_name); 1928c2ecf20Sopenharmony_cierr_out: 1938c2ecf20Sopenharmony_ci return err; 1948c2ecf20Sopenharmony_ci} 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_civoid hmdfs_clear_share_item_offline(struct hmdfs_peer *conn) 1978c2ecf20Sopenharmony_ci{ 1988c2ecf20Sopenharmony_ci struct hmdfs_sb_info *sbi = conn->sbi; 1998c2ecf20Sopenharmony_ci struct hmdfs_share_item *item, *tmp; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci spin_lock(&sbi->share_table.item_list_lock); 2028c2ecf20Sopenharmony_ci list_for_each_entry_safe(item, tmp, &sbi->share_table.item_list_head, 2038c2ecf20Sopenharmony_ci list) { 2048c2ecf20Sopenharmony_ci if (is_dst_device(item->cid, conn->cid)) { 2058c2ecf20Sopenharmony_ci /* release the item that was not closed properly */ 2068c2ecf20Sopenharmony_ci if (item->opened) 2078c2ecf20Sopenharmony_ci remove_and_release_share_item(item); 2088c2ecf20Sopenharmony_ci } 2098c2ecf20Sopenharmony_ci } 2108c2ecf20Sopenharmony_ci spin_unlock(&sbi->share_table.item_list_lock); 2118c2ecf20Sopenharmony_ci} 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_civoid reset_item_opened_status(struct hmdfs_sb_info *sbi, const char *filename) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci struct qstr candidate = QSTR_INIT(filename, strlen(filename)); 2168c2ecf20Sopenharmony_ci struct hmdfs_share_item *item = NULL; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci spin_lock(&sbi->share_table.item_list_lock); 2198c2ecf20Sopenharmony_ci item = hmdfs_lookup_share_item(&sbi->share_table, &candidate); 2208c2ecf20Sopenharmony_ci if (item) { 2218c2ecf20Sopenharmony_ci item->opened = false; 2228c2ecf20Sopenharmony_ci queue_delayed_work(item->hst->share_item_timeout_wq, 2238c2ecf20Sopenharmony_ci &item->d_work, HZ * HMDFS_SHARE_ITEM_TIMEOUT_S); 2248c2ecf20Sopenharmony_ci } 2258c2ecf20Sopenharmony_ci spin_unlock(&sbi->share_table.item_list_lock); 2268c2ecf20Sopenharmony_ci} 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_civoid hmdfs_close_share_item(struct hmdfs_sb_info *sbi, struct file *file, 2298c2ecf20Sopenharmony_ci char *cid) 2308c2ecf20Sopenharmony_ci{ 2318c2ecf20Sopenharmony_ci struct qstr relativepath; 2328c2ecf20Sopenharmony_ci const char *path_name; 2338c2ecf20Sopenharmony_ci struct hmdfs_share_item *item = NULL; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci path_name = hmdfs_get_dentry_relative_path(file->f_path.dentry); 2368c2ecf20Sopenharmony_ci if (unlikely(!path_name)) { 2378c2ecf20Sopenharmony_ci hmdfs_err("get dentry relative path error"); 2388c2ecf20Sopenharmony_ci return; 2398c2ecf20Sopenharmony_ci } 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci relativepath.name = path_name; 2428c2ecf20Sopenharmony_ci relativepath.len = strlen(path_name); 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci spin_lock(&sbi->share_table.item_list_lock); 2458c2ecf20Sopenharmony_ci item = hmdfs_lookup_share_item(&sbi->share_table, &relativepath); 2468c2ecf20Sopenharmony_ci if (unlikely(!item)) { 2478c2ecf20Sopenharmony_ci hmdfs_err("cannot get share item %s", relativepath.name); 2488c2ecf20Sopenharmony_ci goto unlock; 2498c2ecf20Sopenharmony_ci } 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci /* 2528c2ecf20Sopenharmony_ci * If the item is shared to all device, we should close the item directly. 2538c2ecf20Sopenharmony_ci */ 2548c2ecf20Sopenharmony_ci if (!strcmp(item->cid, SHARE_ALL_DEVICE)) { 2558c2ecf20Sopenharmony_ci goto close; 2568c2ecf20Sopenharmony_ci } 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci if (unlikely(!is_dst_device(item->cid, cid))) { 2598c2ecf20Sopenharmony_ci hmdfs_err("item not right, dst cid is: %s", item->cid); 2608c2ecf20Sopenharmony_ci goto unlock; 2618c2ecf20Sopenharmony_ci } 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci /* 2648c2ecf20Sopenharmony_ci * After remote close, we should reset the opened status and restart 2658c2ecf20Sopenharmony_ci * delayed timeout work. 2668c2ecf20Sopenharmony_ci */ 2678c2ecf20Sopenharmony_ciclose: 2688c2ecf20Sopenharmony_ci item->opened = false; 2698c2ecf20Sopenharmony_ci queue_delayed_work(item->hst->share_item_timeout_wq, &item->d_work, 2708c2ecf20Sopenharmony_ci HZ * HMDFS_SHARE_ITEM_TIMEOUT_S); 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ciunlock: 2738c2ecf20Sopenharmony_ci spin_unlock(&sbi->share_table.item_list_lock); 2748c2ecf20Sopenharmony_ci kfree(path_name); 2758c2ecf20Sopenharmony_ci} 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ciint hmdfs_check_share_access_permission(struct hmdfs_sb_info *sbi, 2788c2ecf20Sopenharmony_ci const char *filename, 2798c2ecf20Sopenharmony_ci char *cid) 2808c2ecf20Sopenharmony_ci{ 2818c2ecf20Sopenharmony_ci struct qstr candidate = QSTR_INIT(filename, strlen(filename)); 2828c2ecf20Sopenharmony_ci struct hmdfs_share_item *item = NULL; 2838c2ecf20Sopenharmony_ci int ret = -ENOENT; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci spin_lock(&sbi->share_table.item_list_lock); 2868c2ecf20Sopenharmony_ci item = hmdfs_lookup_share_item(&sbi->share_table, &candidate); 2878c2ecf20Sopenharmony_ci /* 2888c2ecf20Sopenharmony_ci * When cid matches, we set the item status opened and canel 2898c2ecf20Sopenharmony_ci * its delayed work to ensure that the open process can get 2908c2ecf20Sopenharmony_ci * the correct path 2918c2ecf20Sopenharmony_ci */ 2928c2ecf20Sopenharmony_ci if (item && (is_dst_device(item->cid, cid) || !strcmp(item->cid, SHARE_ALL_DEVICE))) { 2938c2ecf20Sopenharmony_ci item->opened = true; 2948c2ecf20Sopenharmony_ci if (!cancel_delayed_work_sync(&item->d_work)) { 2958c2ecf20Sopenharmony_ci item->timeout = false; 2968c2ecf20Sopenharmony_ci } 2978c2ecf20Sopenharmony_ci ret = 0; 2988c2ecf20Sopenharmony_ci } 2998c2ecf20Sopenharmony_ci spin_unlock(&sbi->share_table.item_list_lock); 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci return ret; 3028c2ecf20Sopenharmony_ci} 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ciint hmdfs_init_share_table(struct hmdfs_sb_info *sbi) 3068c2ecf20Sopenharmony_ci{ 3078c2ecf20Sopenharmony_ci spin_lock_init(&sbi->share_table.item_list_lock); 3088c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&sbi->share_table.item_list_head); 3098c2ecf20Sopenharmony_ci sbi->share_table.item_cnt = 0; 3108c2ecf20Sopenharmony_ci sbi->share_table.max_cnt = HMDFS_SHARE_ITEMS_MAX; 3118c2ecf20Sopenharmony_ci sbi->share_table.share_item_timeout_wq = 3128c2ecf20Sopenharmony_ci create_singlethread_workqueue("share_item_timeout_wq"); 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci if (!sbi->share_table.share_item_timeout_wq) 3158c2ecf20Sopenharmony_ci return -ENOMEM; 3168c2ecf20Sopenharmony_ci return 0; 3178c2ecf20Sopenharmony_ci} 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_civoid hmdfs_clear_share_table(struct hmdfs_sb_info *sbi) 3208c2ecf20Sopenharmony_ci{ 3218c2ecf20Sopenharmony_ci struct hmdfs_share_table *st = &sbi->share_table; 3228c2ecf20Sopenharmony_ci struct hmdfs_share_item *item, *tmp; 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci spin_lock(&sbi->share_table.item_list_lock); 3258c2ecf20Sopenharmony_ci list_for_each_entry_safe(item, tmp, &sbi->share_table.item_list_head, 3268c2ecf20Sopenharmony_ci list) { 3278c2ecf20Sopenharmony_ci flush_delayed_work(&item->d_work); 3288c2ecf20Sopenharmony_ci remove_and_release_share_item(item); 3298c2ecf20Sopenharmony_ci } 3308c2ecf20Sopenharmony_ci spin_unlock(&sbi->share_table.item_list_lock); 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci if (st->share_item_timeout_wq != NULL) 3338c2ecf20Sopenharmony_ci destroy_workqueue(st->share_item_timeout_wq); 3348c2ecf20Sopenharmony_ci} 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ciint hmdfs_clear_first_item(struct hmdfs_share_table *st) 3378c2ecf20Sopenharmony_ci{ 3388c2ecf20Sopenharmony_ci int ret = -EMFILE; 3398c2ecf20Sopenharmony_ci struct hmdfs_share_item *item, *tmp; 3408c2ecf20Sopenharmony_ci list_for_each_entry_safe(item, tmp, &st->item_list_head, list) { 3418c2ecf20Sopenharmony_ci if (!item->timeout) { 3428c2ecf20Sopenharmony_ci cancel_delayed_work_sync(&item->d_work); 3438c2ecf20Sopenharmony_ci } 3448c2ecf20Sopenharmony_ci remove_and_release_share_item(item); 3458c2ecf20Sopenharmony_ci ret = 0; 3468c2ecf20Sopenharmony_ci break; 3478c2ecf20Sopenharmony_ci } 3488c2ecf20Sopenharmony_ci return ret; 3498c2ecf20Sopenharmony_ci} 350