Commit cac45b062c67f86dc1d91d675128838773523243
1 parent
2e32cf5ef2
fat: rcu-delay unloading nls and freeing sbi
makes ->d_hash() and ->d_compare() safety in RCU mode independent from vfsmount_lock. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 2 changed files with 12 additions and 8 deletions Side-by-side Diff
fs/fat/fat.h
fs/fat/inode.c
... | ... | @@ -548,6 +548,16 @@ |
548 | 548 | brelse(bh); |
549 | 549 | } |
550 | 550 | |
551 | +static void delayed_free(struct rcu_head *p) | |
552 | +{ | |
553 | + struct msdos_sb_info *sbi = container_of(p, struct msdos_sb_info, rcu); | |
554 | + unload_nls(sbi->nls_disk); | |
555 | + unload_nls(sbi->nls_io); | |
556 | + if (sbi->options.iocharset != fat_default_iocharset) | |
557 | + kfree(sbi->options.iocharset); | |
558 | + kfree(sbi); | |
559 | +} | |
560 | + | |
551 | 561 | static void fat_put_super(struct super_block *sb) |
552 | 562 | { |
553 | 563 | struct msdos_sb_info *sbi = MSDOS_SB(sb); |
... | ... | @@ -557,14 +567,7 @@ |
557 | 567 | iput(sbi->fsinfo_inode); |
558 | 568 | iput(sbi->fat_inode); |
559 | 569 | |
560 | - unload_nls(sbi->nls_disk); | |
561 | - unload_nls(sbi->nls_io); | |
562 | - | |
563 | - if (sbi->options.iocharset != fat_default_iocharset) | |
564 | - kfree(sbi->options.iocharset); | |
565 | - | |
566 | - sb->s_fs_info = NULL; | |
567 | - kfree(sbi); | |
570 | + call_rcu(&sbi->rcu, delayed_free); | |
568 | 571 | } |
569 | 572 | |
570 | 573 | static struct kmem_cache *fat_inode_cachep; |