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:
- 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.
......
......@@ -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,
* 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));
......
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