From 8f62c4026588319090229e31a34f56dee009db2d Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Thu, 14 Oct 2004 19:09:31 +0100 Subject: [PATCH] NTFS: - Fix two race conditions in fs/ntfs/inode.c::ntfs_put_inode(). - Fix race condition in fs/ntfs/inode.c::ntfs_put_inode() by moving the index inode bitmap inode release code from there to fs/ntfs/inode.c::ntfs_clear_big_inode(). (Thanks to Christoph Hellwig for spotting this.) - Fix race condition in fs/ntfs/inode.c::ntfs_put_inode() by taking the inode semaphore around the code thst sets ni->itype.index.bmp_ino to NULL and reorganize the code to optimize it a bit. (Thanks to Christoph Hellwig for spotting this.) Signed-off-by: Anton Altaparmakov --- fs/ntfs/ChangeLog | 8 ++++++++ fs/ntfs/inode.c | 49 +++++++++++++++++++++++------------------------ 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 6217c5b7c2c45..a1c774578090c 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -110,6 +110,14 @@ ToDo/Notes: - Fix callers of fs/ntfs/aops.c::mark_ntfs_record_dirty() to call it with the ntfs inode which contains the page rather than the ntfs inode the mft record of which is in the page. + - Fix race condition in fs/ntfs/inode.c::ntfs_put_inode() by moving the + index inode bitmap inode release code from there to + fs/ntfs/inode.c::ntfs_clear_big_inode(). (Thanks to Christoph + Hellwig for spotting this.) + - Fix race condition in fs/ntfs/inode.c::ntfs_put_inode() by taking the + inode semaphore around the code thst sets ni->itype.index.bmp_ino to + NULL and reorganize the code to optimize it a bit. (Thanks to + Christoph Hellwig for spotting this.) 2.1.20 - Fix two stupid bugs introduced in 2.1.18 release. diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 11032d239103e..3f1a444384474 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -2095,37 +2095,24 @@ err_out: * dropped, we need to put the attribute inode for the directory index bitmap, * if it is present, otherwise the directory inode would remain pinned for * ever. - * - * If the inode @vi is an index inode with only one reference which is being - * dropped, we need to put the attribute inode for the index bitmap, if it is - * present, otherwise the index inode would disappear and the attribute inode - * for the index bitmap would no longer be referenced from anywhere and thus it - * would remain pinned for ever. */ void ntfs_put_inode(struct inode *vi) { - ntfs_inode *ni; - - if (S_ISDIR(vi->i_mode)) { - if (atomic_read(&vi->i_count) == 2) { - ni = NTFS_I(vi); - if (NInoIndexAllocPresent(ni) && - ni->itype.index.bmp_ino) { - iput(ni->itype.index.bmp_ino); - ni->itype.index.bmp_ino = NULL; + if (S_ISDIR(vi->i_mode) && atomic_read(&vi->i_count) == 2) { + ntfs_inode *ni = NTFS_I(vi); + if (NInoIndexAllocPresent(ni)) { + struct inode *bvi = NULL; + down(&vi->i_sem); + if (atomic_read(&vi->i_count) == 2) { + bvi = ni->itype.index.bmp_ino; + if (bvi) + ni->itype.index.bmp_ino = NULL; } + up(&vi->i_sem); + if (bvi) + iput(bvi); } - return; - } - if (atomic_read(&vi->i_count) != 1) - return; - ni = NTFS_I(vi); - if (NInoAttr(ni) && (ni->type == AT_INDEX_ALLOCATION) && - NInoIndexAllocPresent(ni) && ni->itype.index.bmp_ino) { - iput(ni->itype.index.bmp_ino); - ni->itype.index.bmp_ino = NULL; } - return; } void __ntfs_clear_inode(ntfs_inode *ni) @@ -2193,6 +2180,18 @@ void ntfs_clear_big_inode(struct inode *vi) { ntfs_inode *ni = NTFS_I(vi); + /* + * If the inode @vi is an index inode we need to put the attribute + * inode for the index bitmap, if it is present, otherwise the index + * inode would disappear and the attribute inode for the index bitmap + * would no longer be referenced from anywhere and thus it would remain + * pinned for ever. + */ + if (NInoAttr(ni) && (ni->type == AT_INDEX_ALLOCATION) && + NInoIndexAllocPresent(ni) && ni->itype.index.bmp_ino) { + iput(ni->itype.index.bmp_ino); + ni->itype.index.bmp_ino = NULL; + } #ifdef NTFS_RW if (NInoDirty(ni)) { BOOL was_bad = (is_bad_inode(vi)); -- 2.53.0