utils.c (47e4937a4a7ca4184fd282791dfee76c6799966a) | utils.c (8d8a09b093d7073465c824f74caf315c073d3875) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2018 HUAWEI, Inc. 4 * http://www.huawei.com/ 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 */ 7#include "internal.h" 8#include <linux/pagevec.h> --- 32 unchanged lines hidden (view full) --- 41#define __erofs_workgroup_put(grp) atomic_dec(&(grp)->refcount) 42 43static int erofs_workgroup_get(struct erofs_workgroup *grp) 44{ 45 int o; 46 47repeat: 48 o = erofs_wait_on_workgroup_freezed(grp); | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2018 HUAWEI, Inc. 4 * http://www.huawei.com/ 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 */ 7#include "internal.h" 8#include <linux/pagevec.h> --- 32 unchanged lines hidden (view full) --- 41#define __erofs_workgroup_put(grp) atomic_dec(&(grp)->refcount) 42 43static int erofs_workgroup_get(struct erofs_workgroup *grp) 44{ 45 int o; 46 47repeat: 48 o = erofs_wait_on_workgroup_freezed(grp); |
49 if (unlikely(o <= 0)) | 49 if (o <= 0) |
50 return -1; 51 | 50 return -1; 51 |
52 if (unlikely(atomic_cmpxchg(&grp->refcount, o, o + 1) != o)) | 52 if (atomic_cmpxchg(&grp->refcount, o, o + 1) != o) |
53 goto repeat; 54 55 /* decrease refcount paired by erofs_workgroup_put */ | 53 goto repeat; 54 55 /* decrease refcount paired by erofs_workgroup_put */ |
56 if (unlikely(o == 1)) | 56 if (o == 1) |
57 atomic_long_dec(&erofs_global_shrink_cnt); 58 return 0; 59} 60 61struct erofs_workgroup *erofs_find_workgroup(struct super_block *sb, 62 pgoff_t index, bool *tag) 63{ 64 struct erofs_sb_info *sbi = EROFS_SB(sb); --- 21 unchanged lines hidden (view full) --- 86int erofs_register_workgroup(struct super_block *sb, 87 struct erofs_workgroup *grp, 88 bool tag) 89{ 90 struct erofs_sb_info *sbi; 91 int err; 92 93 /* grp shouldn't be broken or used before */ | 57 atomic_long_dec(&erofs_global_shrink_cnt); 58 return 0; 59} 60 61struct erofs_workgroup *erofs_find_workgroup(struct super_block *sb, 62 pgoff_t index, bool *tag) 63{ 64 struct erofs_sb_info *sbi = EROFS_SB(sb); --- 21 unchanged lines hidden (view full) --- 86int erofs_register_workgroup(struct super_block *sb, 87 struct erofs_workgroup *grp, 88 bool tag) 89{ 90 struct erofs_sb_info *sbi; 91 int err; 92 93 /* grp shouldn't be broken or used before */ |
94 if (unlikely(atomic_read(&grp->refcount) != 1)) { | 94 if (atomic_read(&grp->refcount) != 1) { |
95 DBG_BUGON(1); 96 return -EINVAL; 97 } 98 99 err = radix_tree_preload(GFP_NOFS); 100 if (err) 101 return err; 102 --- 5 unchanged lines hidden (view full) --- 108 /* 109 * Bump up reference count before making this workgroup 110 * visible to other users in order to avoid potential UAF 111 * without serialized by workstn_lock. 112 */ 113 __erofs_workgroup_get(grp); 114 115 err = radix_tree_insert(&sbi->workstn_tree, grp->index, grp); | 95 DBG_BUGON(1); 96 return -EINVAL; 97 } 98 99 err = radix_tree_preload(GFP_NOFS); 100 if (err) 101 return err; 102 --- 5 unchanged lines hidden (view full) --- 108 /* 109 * Bump up reference count before making this workgroup 110 * visible to other users in order to avoid potential UAF 111 * without serialized by workstn_lock. 112 */ 113 __erofs_workgroup_get(grp); 114 115 err = radix_tree_insert(&sbi->workstn_tree, grp->index, grp); |
116 if (unlikely(err)) | 116 if (err) |
117 /* 118 * it's safe to decrease since the workgroup isn't visible 119 * and refcount >= 2 (cannot be freezed). 120 */ 121 __erofs_workgroup_put(grp); 122 123 xa_unlock(&sbi->workstn_tree); 124 radix_tree_preload_end(); --- 82 unchanged lines hidden (view full) --- 207 208 first_index = grp->index + 1; 209 210 /* try to shrink each valid workgroup */ 211 if (!erofs_try_to_release_workgroup(sbi, grp, cleanup)) 212 continue; 213 214 ++freed; | 117 /* 118 * it's safe to decrease since the workgroup isn't visible 119 * and refcount >= 2 (cannot be freezed). 120 */ 121 __erofs_workgroup_put(grp); 122 123 xa_unlock(&sbi->workstn_tree); 124 radix_tree_preload_end(); --- 82 unchanged lines hidden (view full) --- 207 208 first_index = grp->index + 1; 209 210 /* try to shrink each valid workgroup */ 211 if (!erofs_try_to_release_workgroup(sbi, grp, cleanup)) 212 continue; 213 214 ++freed; |
215 if (unlikely(!--nr_shrink)) | 215 if (!--nr_shrink) |
216 break; 217 } 218 xa_unlock(&sbi->workstn_tree); 219 220 if (i && nr_shrink) 221 goto repeat; 222 return freed; 223} --- 110 unchanged lines hidden --- | 216 break; 217 } 218 xa_unlock(&sbi->workstn_tree); 219 220 if (i && nr_shrink) 221 goto repeat; 222 return freed; 223} --- 110 unchanged lines hidden --- |