Skip to content

Commit

Permalink
fs: Fix hang with BSD accounting on frozen filesystem
Browse files Browse the repository at this point in the history
When BSD process accounting is enabled and logs information to a
filesystem which gets frozen, system easily becomes unusable because
each attempt to account process information blocks. Thus e.g. every task
gets blocked in exit.

It seems better to drop accounting information (which can already happen
when filesystem is running out of space) instead of locking system up.
So we just skip the write if the filesystem is frozen.

Reported-by: Nikola Ciprich <nikola.ciprich@linuxbox.cz>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
jankara authored and Al Viro committed May 4, 2013
1 parent 9dcc26c commit 5ae98f1
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 1 deletion.
7 changes: 7 additions & 0 deletions include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
7 changes: 6 additions & 1 deletion kernel/acct.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,11 +539,16 @@ static void do_acct_process(struct bsd_acct_struct *acct,
ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
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);
/*
Expand Down

0 comments on commit 5ae98f1

Please sign in to comment.