Commit 17c0a5aaffa63da6b5c73a31e36616bdcd12d143
1 parent
0aec09d049
Exists in
smarc_imx_lf-5.15.y
and in
32 other branches
make acct_kill() wait for file closing.
Do actual closing of file via schedule_work(). And use __fput_sync() there. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 1 changed file with 17 additions and 3 deletions Side-by-side Diff
kernel/acct.c
... | ... | @@ -92,6 +92,8 @@ |
92 | 92 | unsigned long needcheck; |
93 | 93 | struct file *file; |
94 | 94 | struct pid_namespace *ns; |
95 | + struct work_struct work; | |
96 | + struct completion done; | |
95 | 97 | }; |
96 | 98 | |
97 | 99 | static void acct_free_rcu(struct rcu_head *head) |
98 | 100 | |
99 | 101 | |
... | ... | @@ -176,15 +178,27 @@ |
176 | 178 | return res; |
177 | 179 | } |
178 | 180 | |
181 | +static void close_work(struct work_struct *work) | |
182 | +{ | |
183 | + struct bsd_acct_struct *acct = container_of(work, struct bsd_acct_struct, work); | |
184 | + struct file *file = acct->file; | |
185 | + mnt_unpin(file->f_path.mnt); | |
186 | + if (file->f_op->flush) | |
187 | + file->f_op->flush(file, NULL); | |
188 | + __fput_sync(file); | |
189 | + complete(&acct->done); | |
190 | +} | |
191 | + | |
179 | 192 | static void acct_kill(struct bsd_acct_struct *acct, |
180 | 193 | struct bsd_acct_struct *new) |
181 | 194 | { |
182 | 195 | if (acct) { |
183 | - struct file *file = acct->file; | |
184 | 196 | struct pid_namespace *ns = acct->ns; |
185 | 197 | do_acct_process(acct); |
186 | - mnt_unpin(file->f_path.mnt); | |
187 | - filp_close(file, NULL); | |
198 | + INIT_WORK(&acct->work, close_work); | |
199 | + init_completion(&acct->done); | |
200 | + schedule_work(&acct->work); | |
201 | + wait_for_completion(&acct->done); | |
188 | 202 | spin_lock(&acct_lock); |
189 | 203 | hlist_del(&acct->m_list); |
190 | 204 | hlist_del(&acct->s_list); |