diff options
-rw-r--r-- | include/linux/fs.h | 7 | ||||
-rw-r--r-- | kernel/acct.c | 7 |
2 files changed, 13 insertions, 1 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h index e8cd6b83967..b5a24ba83b6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2227,6 +2227,13 @@ static inline void file_start_write(struct file *file) __sb_start_write(file_inode(file)->i_sb, SB_FREEZE_WRITE, true); } +static inline bool file_start_write_trylock(struct file *file) +{ + if (!S_ISREG(file_inode(file)->i_mode)) + return true; + return __sb_start_write(file_inode(file)->i_sb, SB_FREEZE_WRITE, false); +} + static inline void file_end_write(struct file *file) { if (!S_ISREG(file_inode(file)->i_mode)) diff --git a/kernel/acct.c b/kernel/acct.c index 85389fe2abd..8d6e145138b 100644 --- a/kernel/acct.c +++ b/kernel/acct.c @@ -540,10 +540,15 @@ static void do_acct_process(struct bsd_acct_struct *acct, ac.ac_swaps = encode_comp_t(0); /* + * Get freeze protection. If the fs is frozen, just skip the write + * as we could deadlock the system otherwise. + */ + if (!file_start_write_trylock(file)) + goto out; + /* * Kernel segment override to datasegment and write it * to the accounting file. */ - file_start_write(file); fs = get_fs(); set_fs(KERNEL_DS); /* |