static DEFINE_SPINLOCK(acct_lock);
static LIST_HEAD(acct_list);
+static LIST_HEAD(acct_close_list);
/*
* Check the amount of free space and suspend/resume accordingly.
return error;
}
+static void acct_close_mnts(struct work_struct *unused)
+{
+ struct bsd_acct_struct *acct;
+
+ spin_lock(&acct_lock);
+restart:
+ list_for_each_entry(acct, &acct_close_list, list) {
+ acct_file_reopen(acct, NULL, NULL);
+ goto restart;
+ }
+ spin_unlock(&acct_lock);
+}
+static DECLARE_WORK(acct_close_work, acct_close_mnts);
+
/**
* acct_auto_close - turn off a filesystem's accounting if it is on
* @m: vfsmount being shut down
*/
void acct_auto_close_mnt(struct vfsmount *m)
{
- struct bsd_acct_struct *acct;
+ struct bsd_acct_struct *acct, *tmp;
spin_lock(&acct_lock);
-restart:
- list_for_each_entry(acct, &acct_list, list)
+ list_for_each_entry_safe(acct, tmp, &acct_list, list) {
if (acct->file && acct->file->f_path.mnt == m) {
- acct_file_reopen(acct, NULL, NULL);
- goto restart;
+ list_move_tail(&acct->list, &acct_close_list);
+ schedule_work(&acct_close_work);
}
+ }
spin_unlock(&acct_lock);
}