Commit 8f62c402 authored by Anton Altaparmakov's avatar Anton Altaparmakov Committed by Richard Russon

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: default avatarAnton Altaparmakov <aia21@cantab.net>
parent d7ca9266
...@@ -110,6 +110,14 @@ ToDo/Notes: ...@@ -110,6 +110,14 @@ ToDo/Notes:
- Fix callers of fs/ntfs/aops.c::mark_ntfs_record_dirty() to call it - 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 with the ntfs inode which contains the page rather than the ntfs
inode the mft record of which is in the page. 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. 2.1.20 - Fix two stupid bugs introduced in 2.1.18 release.
......
...@@ -2095,37 +2095,24 @@ int ntfs_read_inode_mount(struct inode *vi) ...@@ -2095,37 +2095,24 @@ int ntfs_read_inode_mount(struct inode *vi)
* dropped, we need to put the attribute inode for the directory index bitmap, * 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 * if it is present, otherwise the directory inode would remain pinned for
* ever. * 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) void ntfs_put_inode(struct inode *vi)
{ {
ntfs_inode *ni; if (S_ISDIR(vi->i_mode) && atomic_read(&vi->i_count) == 2) {
ntfs_inode *ni = NTFS_I(vi);
if (S_ISDIR(vi->i_mode)) { if (NInoIndexAllocPresent(ni)) {
if (atomic_read(&vi->i_count) == 2) { struct inode *bvi = NULL;
ni = NTFS_I(vi); down(&vi->i_sem);
if (NInoIndexAllocPresent(ni) && if (atomic_read(&vi->i_count) == 2) {
ni->itype.index.bmp_ino) { bvi = ni->itype.index.bmp_ino;
iput(ni->itype.index.bmp_ino); if (bvi)
ni->itype.index.bmp_ino = NULL; 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) void __ntfs_clear_inode(ntfs_inode *ni)
...@@ -2193,6 +2180,18 @@ void ntfs_clear_big_inode(struct inode *vi) ...@@ -2193,6 +2180,18 @@ void ntfs_clear_big_inode(struct inode *vi)
{ {
ntfs_inode *ni = NTFS_I(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 #ifdef NTFS_RW
if (NInoDirty(ni)) { if (NInoDirty(ni)) {
BOOL was_bad = (is_bad_inode(vi)); BOOL was_bad = (is_bad_inode(vi));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment