diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-01-22 11:55:56 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-01-22 11:55:56 -0500 |
| commit | c8fefb1bb4b38607d305c7e9ef55f146c9c628cb (patch) | |
| tree | cb61e947055b5332b3c1124dcce888a039444b05 | |
| parent | a99d726bd0574991245fe7d38e8b11c41089eee4 (diff) | |
| parent | bd62b23cbcc691cc8faa6f4028783f60957b6508 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6:
NTFS: Forgot to bump version number in makefile to 2.1.28...
NTFS: 2.1.28 - Fix deadlock reported by Sergey Vlasov due to ntfs_put_inode().
| -rw-r--r-- | Documentation/filesystems/ntfs.txt | 2 | ||||
| -rw-r--r-- | fs/ntfs/ChangeLog | 7 | ||||
| -rw-r--r-- | fs/ntfs/Makefile | 2 | ||||
| -rw-r--r-- | fs/ntfs/dir.c | 45 | ||||
| -rw-r--r-- | fs/ntfs/inode.c | 69 | ||||
| -rw-r--r-- | fs/ntfs/inode.h | 6 | ||||
| -rw-r--r-- | fs/ntfs/super.c | 7 |
7 files changed, 53 insertions, 85 deletions
diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt index 13ba649bda75..81779068b09b 100644 --- a/Documentation/filesystems/ntfs.txt +++ b/Documentation/filesystems/ntfs.txt | |||
| @@ -457,6 +457,8 @@ ChangeLog | |||
| 457 | 457 | ||
| 458 | Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. | 458 | Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. |
| 459 | 459 | ||
| 460 | 2.1.28: | ||
| 461 | - Fix a deadlock. | ||
| 460 | 2.1.27: | 462 | 2.1.27: |
| 461 | - Implement page migration support so the kernel can move memory used | 463 | - Implement page migration support so the kernel can move memory used |
| 462 | by NTFS files and directories around for management purposes. | 464 | by NTFS files and directories around for management purposes. |
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 35cc4b1d60f7..af4ef808fa94 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog | |||
| @@ -17,6 +17,13 @@ ToDo/Notes: | |||
| 17 | happen is unclear however so it is worth waiting until someone hits | 17 | happen is unclear however so it is worth waiting until someone hits |
| 18 | the problem. | 18 | the problem. |
| 19 | 19 | ||
| 20 | 2.1.28 - Fix a deadlock. | ||
| 21 | |||
| 22 | - Fix deadlock in fs/ntfs/inode.c::ntfs_put_inode(). Thanks to Sergey | ||
| 23 | Vlasov for the report and detailed analysis of the deadlock. The fix | ||
| 24 | involved getting rid of ntfs_put_inode() altogether and hence NTFS no | ||
| 25 | longer has a ->put_inode super operation. | ||
| 26 | |||
| 20 | 2.1.27 - Various bug fixes and cleanups. | 27 | 2.1.27 - Various bug fixes and cleanups. |
| 21 | 28 | ||
| 22 | - Fix two compiler warnings on Alpha. Thanks to Andrew Morton for | 29 | - Fix two compiler warnings on Alpha. Thanks to Andrew Morton for |
diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile index e27b4eacffbf..825508385565 100644 --- a/fs/ntfs/Makefile +++ b/fs/ntfs/Makefile | |||
| @@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \ | |||
| 6 | index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ | 6 | index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ |
| 7 | unistr.o upcase.o | 7 | unistr.o upcase.o |
| 8 | 8 | ||
| 9 | EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.27\" | 9 | EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.28\" |
| 10 | 10 | ||
| 11 | ifeq ($(CONFIG_NTFS_DEBUG),y) | 11 | ifeq ($(CONFIG_NTFS_DEBUG),y) |
| 12 | EXTRA_CFLAGS += -DDEBUG | 12 | EXTRA_CFLAGS += -DDEBUG |
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c index 8296c29ae3b8..74f99a6a369b 100644 --- a/fs/ntfs/dir.c +++ b/fs/ntfs/dir.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /** | 1 | /** |
| 2 | * dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project. | 2 | * dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project. |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2001-2005 Anton Altaparmakov | 4 | * Copyright (c) 2001-2007 Anton Altaparmakov |
| 5 | * Copyright (c) 2002 Richard Russon | 5 | * Copyright (c) 2002 Richard Russon |
| 6 | * | 6 | * |
| 7 | * This program/include file is free software; you can redistribute it and/or | 7 | * This program/include file is free software; you can redistribute it and/or |
| @@ -1249,16 +1249,12 @@ skip_index_root: | |||
| 1249 | /* Get the offset into the index allocation attribute. */ | 1249 | /* Get the offset into the index allocation attribute. */ |
| 1250 | ia_pos = (s64)fpos - vol->mft_record_size; | 1250 | ia_pos = (s64)fpos - vol->mft_record_size; |
| 1251 | ia_mapping = vdir->i_mapping; | 1251 | ia_mapping = vdir->i_mapping; |
| 1252 | bmp_vi = ndir->itype.index.bmp_ino; | 1252 | ntfs_debug("Inode 0x%lx, getting index bitmap.", vdir->i_ino); |
| 1253 | if (unlikely(!bmp_vi)) { | 1253 | bmp_vi = ntfs_attr_iget(vdir, AT_BITMAP, I30, 4); |
| 1254 | ntfs_debug("Inode 0x%lx, regetting index bitmap.", vdir->i_ino); | 1254 | if (IS_ERR(bmp_vi)) { |
| 1255 | bmp_vi = ntfs_attr_iget(vdir, AT_BITMAP, I30, 4); | 1255 | ntfs_error(sb, "Failed to get bitmap attribute."); |
| 1256 | if (IS_ERR(bmp_vi)) { | 1256 | err = PTR_ERR(bmp_vi); |
| 1257 | ntfs_error(sb, "Failed to get bitmap attribute."); | 1257 | goto err_out; |
| 1258 | err = PTR_ERR(bmp_vi); | ||
| 1259 | goto err_out; | ||
| 1260 | } | ||
| 1261 | ndir->itype.index.bmp_ino = bmp_vi; | ||
| 1262 | } | 1258 | } |
| 1263 | bmp_mapping = bmp_vi->i_mapping; | 1259 | bmp_mapping = bmp_vi->i_mapping; |
| 1264 | /* Get the starting bitmap bit position and sanity check it. */ | 1260 | /* Get the starting bitmap bit position and sanity check it. */ |
| @@ -1266,7 +1262,7 @@ skip_index_root: | |||
| 1266 | if (unlikely(bmp_pos >> 3 >= i_size_read(bmp_vi))) { | 1262 | if (unlikely(bmp_pos >> 3 >= i_size_read(bmp_vi))) { |
| 1267 | ntfs_error(sb, "Current index allocation position exceeds " | 1263 | ntfs_error(sb, "Current index allocation position exceeds " |
| 1268 | "index bitmap size."); | 1264 | "index bitmap size."); |
| 1269 | goto err_out; | 1265 | goto iput_err_out; |
| 1270 | } | 1266 | } |
| 1271 | /* Get the starting bit position in the current bitmap page. */ | 1267 | /* Get the starting bit position in the current bitmap page. */ |
| 1272 | cur_bmp_pos = bmp_pos & ((PAGE_CACHE_SIZE * 8) - 1); | 1268 | cur_bmp_pos = bmp_pos & ((PAGE_CACHE_SIZE * 8) - 1); |
| @@ -1282,7 +1278,7 @@ get_next_bmp_page: | |||
| 1282 | ntfs_error(sb, "Reading index bitmap failed."); | 1278 | ntfs_error(sb, "Reading index bitmap failed."); |
| 1283 | err = PTR_ERR(bmp_page); | 1279 | err = PTR_ERR(bmp_page); |
| 1284 | bmp_page = NULL; | 1280 | bmp_page = NULL; |
| 1285 | goto err_out; | 1281 | goto iput_err_out; |
| 1286 | } | 1282 | } |
| 1287 | bmp = (u8*)page_address(bmp_page); | 1283 | bmp = (u8*)page_address(bmp_page); |
| 1288 | /* Find next index block in use. */ | 1284 | /* Find next index block in use. */ |
| @@ -1429,6 +1425,7 @@ find_next_index_buffer: | |||
| 1429 | /* @ia_page is already unlocked in this case. */ | 1425 | /* @ia_page is already unlocked in this case. */ |
| 1430 | ntfs_unmap_page(ia_page); | 1426 | ntfs_unmap_page(ia_page); |
| 1431 | ntfs_unmap_page(bmp_page); | 1427 | ntfs_unmap_page(bmp_page); |
| 1428 | iput(bmp_vi); | ||
| 1432 | goto abort; | 1429 | goto abort; |
| 1433 | } | 1430 | } |
| 1434 | } | 1431 | } |
| @@ -1439,6 +1436,7 @@ unm_EOD: | |||
| 1439 | ntfs_unmap_page(ia_page); | 1436 | ntfs_unmap_page(ia_page); |
| 1440 | } | 1437 | } |
| 1441 | ntfs_unmap_page(bmp_page); | 1438 | ntfs_unmap_page(bmp_page); |
| 1439 | iput(bmp_vi); | ||
| 1442 | EOD: | 1440 | EOD: |
| 1443 | /* We are finished, set fpos to EOD. */ | 1441 | /* We are finished, set fpos to EOD. */ |
| 1444 | fpos = i_size + vol->mft_record_size; | 1442 | fpos = i_size + vol->mft_record_size; |
| @@ -1455,8 +1453,11 @@ done: | |||
| 1455 | filp->f_pos = fpos; | 1453 | filp->f_pos = fpos; |
| 1456 | return 0; | 1454 | return 0; |
| 1457 | err_out: | 1455 | err_out: |
| 1458 | if (bmp_page) | 1456 | if (bmp_page) { |
| 1459 | ntfs_unmap_page(bmp_page); | 1457 | ntfs_unmap_page(bmp_page); |
| 1458 | iput_err_out: | ||
| 1459 | iput(bmp_vi); | ||
| 1460 | } | ||
| 1460 | if (ia_page) { | 1461 | if (ia_page) { |
| 1461 | unlock_page(ia_page); | 1462 | unlock_page(ia_page); |
| 1462 | ntfs_unmap_page(ia_page); | 1463 | ntfs_unmap_page(ia_page); |
| @@ -1529,14 +1530,22 @@ static int ntfs_dir_open(struct inode *vi, struct file *filp) | |||
| 1529 | static int ntfs_dir_fsync(struct file *filp, struct dentry *dentry, | 1530 | static int ntfs_dir_fsync(struct file *filp, struct dentry *dentry, |
| 1530 | int datasync) | 1531 | int datasync) |
| 1531 | { | 1532 | { |
| 1532 | struct inode *vi = dentry->d_inode; | 1533 | struct inode *bmp_vi, *vi = dentry->d_inode; |
| 1533 | ntfs_inode *ni = NTFS_I(vi); | ||
| 1534 | int err, ret; | 1534 | int err, ret; |
| 1535 | ntfs_attr na; | ||
| 1535 | 1536 | ||
| 1536 | ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); | 1537 | ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); |
| 1537 | BUG_ON(!S_ISDIR(vi->i_mode)); | 1538 | BUG_ON(!S_ISDIR(vi->i_mode)); |
| 1538 | if (NInoIndexAllocPresent(ni) && ni->itype.index.bmp_ino) | 1539 | /* If the bitmap attribute inode is in memory sync it, too. */ |
| 1539 | write_inode_now(ni->itype.index.bmp_ino, !datasync); | 1540 | na.mft_no = vi->i_ino; |
| 1541 | na.type = AT_BITMAP; | ||
| 1542 | na.name = I30; | ||
| 1543 | na.name_len = 4; | ||
| 1544 | bmp_vi = ilookup5(vi->i_sb, vi->i_ino, (test_t)ntfs_test_inode, &na); | ||
| 1545 | if (bmp_vi) { | ||
| 1546 | write_inode_now(bmp_vi, !datasync); | ||
| 1547 | iput(bmp_vi); | ||
| 1548 | } | ||
| 1540 | ret = ntfs_write_inode(vi, 1); | 1549 | ret = ntfs_write_inode(vi, 1); |
| 1541 | write_inode_now(vi, !datasync); | 1550 | write_inode_now(vi, !datasync); |
| 1542 | err = sync_blockdev(vi->i_sb->s_bdev); | 1551 | err = sync_blockdev(vi->i_sb->s_bdev); |
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 247989891b4b..f8bf8da67ee8 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /** | 1 | /** |
| 2 | * inode.c - NTFS kernel inode handling. Part of the Linux-NTFS project. | 2 | * inode.c - NTFS kernel inode handling. Part of the Linux-NTFS project. |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2001-2006 Anton Altaparmakov | 4 | * Copyright (c) 2001-2007 Anton Altaparmakov |
| 5 | * | 5 | * |
| 6 | * This program/include file is free software; you can redistribute it and/or | 6 | * This program/include file is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License as published | 7 | * modify it under the terms of the GNU General Public License as published |
| @@ -95,7 +95,7 @@ int ntfs_test_inode(struct inode *vi, ntfs_attr *na) | |||
| 95 | * If initializing the normal file/directory inode, set @na->type to AT_UNUSED. | 95 | * If initializing the normal file/directory inode, set @na->type to AT_UNUSED. |
| 96 | * In that case, @na->name and @na->name_len should be set to NULL and 0, | 96 | * In that case, @na->name and @na->name_len should be set to NULL and 0, |
| 97 | * respectively. Although that is not strictly necessary as | 97 | * respectively. Although that is not strictly necessary as |
| 98 | * ntfs_read_inode_locked() will fill them in later. | 98 | * ntfs_read_locked_inode() will fill them in later. |
| 99 | * | 99 | * |
| 100 | * Return 0 on success and -errno on error. | 100 | * Return 0 on success and -errno on error. |
| 101 | * | 101 | * |
| @@ -171,8 +171,8 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, | |||
| 171 | struct inode *ntfs_iget(struct super_block *sb, unsigned long mft_no) | 171 | struct inode *ntfs_iget(struct super_block *sb, unsigned long mft_no) |
| 172 | { | 172 | { |
| 173 | struct inode *vi; | 173 | struct inode *vi; |
| 174 | ntfs_attr na; | ||
| 175 | int err; | 174 | int err; |
| 175 | ntfs_attr na; | ||
| 176 | 176 | ||
| 177 | na.mft_no = mft_no; | 177 | na.mft_no = mft_no; |
| 178 | na.type = AT_UNUSED; | 178 | na.type = AT_UNUSED; |
| @@ -229,8 +229,8 @@ struct inode *ntfs_attr_iget(struct inode *base_vi, ATTR_TYPE type, | |||
| 229 | ntfschar *name, u32 name_len) | 229 | ntfschar *name, u32 name_len) |
| 230 | { | 230 | { |
| 231 | struct inode *vi; | 231 | struct inode *vi; |
| 232 | ntfs_attr na; | ||
| 233 | int err; | 232 | int err; |
| 233 | ntfs_attr na; | ||
| 234 | 234 | ||
| 235 | /* Make sure no one calls ntfs_attr_iget() for indices. */ | 235 | /* Make sure no one calls ntfs_attr_iget() for indices. */ |
| 236 | BUG_ON(type == AT_INDEX_ALLOCATION); | 236 | BUG_ON(type == AT_INDEX_ALLOCATION); |
| @@ -287,8 +287,8 @@ struct inode *ntfs_index_iget(struct inode *base_vi, ntfschar *name, | |||
| 287 | u32 name_len) | 287 | u32 name_len) |
| 288 | { | 288 | { |
| 289 | struct inode *vi; | 289 | struct inode *vi; |
| 290 | ntfs_attr na; | ||
| 291 | int err; | 290 | int err; |
| 291 | ntfs_attr na; | ||
| 292 | 292 | ||
| 293 | na.mft_no = base_vi->i_ino; | 293 | na.mft_no = base_vi->i_ino; |
| 294 | na.type = AT_INDEX_ALLOCATION; | 294 | na.type = AT_INDEX_ALLOCATION; |
| @@ -402,7 +402,6 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni) | |||
| 402 | ntfs_init_runlist(&ni->attr_list_rl); | 402 | ntfs_init_runlist(&ni->attr_list_rl); |
| 403 | lockdep_set_class(&ni->attr_list_rl.lock, | 403 | lockdep_set_class(&ni->attr_list_rl.lock, |
| 404 | &attr_list_rl_lock_class); | 404 | &attr_list_rl_lock_class); |
| 405 | ni->itype.index.bmp_ino = NULL; | ||
| 406 | ni->itype.index.block_size = 0; | 405 | ni->itype.index.block_size = 0; |
| 407 | ni->itype.index.vcn_size = 0; | 406 | ni->itype.index.vcn_size = 0; |
| 408 | ni->itype.index.collation_rule = 0; | 407 | ni->itype.index.collation_rule = 0; |
| @@ -546,6 +545,7 @@ static int ntfs_read_locked_inode(struct inode *vi) | |||
| 546 | { | 545 | { |
| 547 | ntfs_volume *vol = NTFS_SB(vi->i_sb); | 546 | ntfs_volume *vol = NTFS_SB(vi->i_sb); |
| 548 | ntfs_inode *ni; | 547 | ntfs_inode *ni; |
| 548 | struct inode *bvi; | ||
| 549 | MFT_RECORD *m; | 549 | MFT_RECORD *m; |
| 550 | ATTR_RECORD *a; | 550 | ATTR_RECORD *a; |
| 551 | STANDARD_INFORMATION *si; | 551 | STANDARD_INFORMATION *si; |
| @@ -780,7 +780,6 @@ skip_attr_list_load: | |||
| 780 | */ | 780 | */ |
| 781 | if (S_ISDIR(vi->i_mode)) { | 781 | if (S_ISDIR(vi->i_mode)) { |
| 782 | loff_t bvi_size; | 782 | loff_t bvi_size; |
| 783 | struct inode *bvi; | ||
| 784 | ntfs_inode *bni; | 783 | ntfs_inode *bni; |
| 785 | INDEX_ROOT *ir; | 784 | INDEX_ROOT *ir; |
| 786 | u8 *ir_end, *index_end; | 785 | u8 *ir_end, *index_end; |
| @@ -985,13 +984,12 @@ skip_attr_list_load: | |||
| 985 | err = PTR_ERR(bvi); | 984 | err = PTR_ERR(bvi); |
| 986 | goto unm_err_out; | 985 | goto unm_err_out; |
| 987 | } | 986 | } |
| 988 | ni->itype.index.bmp_ino = bvi; | ||
| 989 | bni = NTFS_I(bvi); | 987 | bni = NTFS_I(bvi); |
| 990 | if (NInoCompressed(bni) || NInoEncrypted(bni) || | 988 | if (NInoCompressed(bni) || NInoEncrypted(bni) || |
| 991 | NInoSparse(bni)) { | 989 | NInoSparse(bni)) { |
| 992 | ntfs_error(vi->i_sb, "$BITMAP attribute is compressed " | 990 | ntfs_error(vi->i_sb, "$BITMAP attribute is compressed " |
| 993 | "and/or encrypted and/or sparse."); | 991 | "and/or encrypted and/or sparse."); |
| 994 | goto unm_err_out; | 992 | goto iput_unm_err_out; |
| 995 | } | 993 | } |
| 996 | /* Consistency check bitmap size vs. index allocation size. */ | 994 | /* Consistency check bitmap size vs. index allocation size. */ |
| 997 | bvi_size = i_size_read(bvi); | 995 | bvi_size = i_size_read(bvi); |
| @@ -1000,8 +998,10 @@ skip_attr_list_load: | |||
| 1000 | ntfs_error(vi->i_sb, "Index bitmap too small (0x%llx) " | 998 | ntfs_error(vi->i_sb, "Index bitmap too small (0x%llx) " |
| 1001 | "for index allocation (0x%llx).", | 999 | "for index allocation (0x%llx).", |
| 1002 | bvi_size << 3, vi->i_size); | 1000 | bvi_size << 3, vi->i_size); |
| 1003 | goto unm_err_out; | 1001 | goto iput_unm_err_out; |
| 1004 | } | 1002 | } |
| 1003 | /* No longer need the bitmap attribute inode. */ | ||
| 1004 | iput(bvi); | ||
| 1005 | skip_large_dir_stuff: | 1005 | skip_large_dir_stuff: |
| 1006 | /* Setup the operations for this inode. */ | 1006 | /* Setup the operations for this inode. */ |
| 1007 | vi->i_op = &ntfs_dir_inode_ops; | 1007 | vi->i_op = &ntfs_dir_inode_ops; |
| @@ -1176,7 +1176,8 @@ no_data_attr_special_case: | |||
| 1176 | vi->i_blocks = ni->allocated_size >> 9; | 1176 | vi->i_blocks = ni->allocated_size >> 9; |
| 1177 | ntfs_debug("Done."); | 1177 | ntfs_debug("Done."); |
| 1178 | return 0; | 1178 | return 0; |
| 1179 | 1179 | iput_unm_err_out: | |
| 1180 | iput(bvi); | ||
| 1180 | unm_err_out: | 1181 | unm_err_out: |
| 1181 | if (!err) | 1182 | if (!err) |
| 1182 | err = -EIO; | 1183 | err = -EIO; |
| @@ -1697,7 +1698,7 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi) | |||
| 1697 | vi->i_size); | 1698 | vi->i_size); |
| 1698 | goto iput_unm_err_out; | 1699 | goto iput_unm_err_out; |
| 1699 | } | 1700 | } |
| 1700 | ni->itype.index.bmp_ino = bvi; | 1701 | iput(bvi); |
| 1701 | skip_large_index_stuff: | 1702 | skip_large_index_stuff: |
| 1702 | /* Setup the operations for this index inode. */ | 1703 | /* Setup the operations for this index inode. */ |
| 1703 | vi->i_op = NULL; | 1704 | vi->i_op = NULL; |
| @@ -1714,7 +1715,6 @@ skip_large_index_stuff: | |||
| 1714 | 1715 | ||
| 1715 | ntfs_debug("Done."); | 1716 | ntfs_debug("Done."); |
| 1716 | return 0; | 1717 | return 0; |
| 1717 | |||
| 1718 | iput_unm_err_out: | 1718 | iput_unm_err_out: |
| 1719 | iput(bvi); | 1719 | iput(bvi); |
| 1720 | unm_err_out: | 1720 | unm_err_out: |
| @@ -2191,37 +2191,6 @@ err_out: | |||
| 2191 | return -1; | 2191 | return -1; |
| 2192 | } | 2192 | } |
| 2193 | 2193 | ||
| 2194 | /** | ||
| 2195 | * ntfs_put_inode - handler for when the inode reference count is decremented | ||
| 2196 | * @vi: vfs inode | ||
| 2197 | * | ||
| 2198 | * The VFS calls ntfs_put_inode() every time the inode reference count (i_count) | ||
| 2199 | * is about to be decremented (but before the decrement itself. | ||
| 2200 | * | ||
| 2201 | * If the inode @vi is a directory with two references, one of which is being | ||
| 2202 | * dropped, we need to put the attribute inode for the directory index bitmap, | ||
| 2203 | * if it is present, otherwise the directory inode would remain pinned for | ||
| 2204 | * ever. | ||
| 2205 | */ | ||
| 2206 | void ntfs_put_inode(struct inode *vi) | ||
| 2207 | { | ||
| 2208 | if (S_ISDIR(vi->i_mode) && atomic_read(&vi->i_count) == 2) { | ||
| 2209 | ntfs_inode *ni = NTFS_I(vi); | ||
| 2210 | if (NInoIndexAllocPresent(ni)) { | ||
| 2211 | struct inode *bvi = NULL; | ||
| 2212 | mutex_lock(&vi->i_mutex); | ||
| 2213 | if (atomic_read(&vi->i_count) == 2) { | ||
| 2214 | bvi = ni->itype.index.bmp_ino; | ||
| 2215 | if (bvi) | ||
| 2216 | ni->itype.index.bmp_ino = NULL; | ||
| 2217 | } | ||
| 2218 | mutex_unlock(&vi->i_mutex); | ||
| 2219 | if (bvi) | ||
| 2220 | iput(bvi); | ||
| 2221 | } | ||
| 2222 | } | ||
| 2223 | } | ||
| 2224 | |||
| 2225 | static void __ntfs_clear_inode(ntfs_inode *ni) | 2194 | static void __ntfs_clear_inode(ntfs_inode *ni) |
| 2226 | { | 2195 | { |
| 2227 | /* Free all alocated memory. */ | 2196 | /* Free all alocated memory. */ |
| @@ -2287,18 +2256,6 @@ void ntfs_clear_big_inode(struct inode *vi) | |||
| 2287 | { | 2256 | { |
| 2288 | ntfs_inode *ni = NTFS_I(vi); | 2257 | ntfs_inode *ni = NTFS_I(vi); |
| 2289 | 2258 | ||
| 2290 | /* | ||
| 2291 | * If the inode @vi is an index inode we need to put the attribute | ||
| 2292 | * inode for the index bitmap, if it is present, otherwise the index | ||
| 2293 | * inode would disappear and the attribute inode for the index bitmap | ||
| 2294 | * would no longer be referenced from anywhere and thus it would remain | ||
| 2295 | * pinned for ever. | ||
| 2296 | */ | ||
| 2297 | if (NInoAttr(ni) && (ni->type == AT_INDEX_ALLOCATION) && | ||
| 2298 | NInoIndexAllocPresent(ni) && ni->itype.index.bmp_ino) { | ||
| 2299 | iput(ni->itype.index.bmp_ino); | ||
| 2300 | ni->itype.index.bmp_ino = NULL; | ||
| 2301 | } | ||
| 2302 | #ifdef NTFS_RW | 2259 | #ifdef NTFS_RW |
| 2303 | if (NInoDirty(ni)) { | 2260 | if (NInoDirty(ni)) { |
| 2304 | bool was_bad = (is_bad_inode(vi)); | 2261 | bool was_bad = (is_bad_inode(vi)); |
diff --git a/fs/ntfs/inode.h b/fs/ntfs/inode.h index f088291e017c..117eaf8032a3 100644 --- a/fs/ntfs/inode.h +++ b/fs/ntfs/inode.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * inode.h - Defines for inode structures NTFS Linux kernel driver. Part of | 2 | * inode.h - Defines for inode structures NTFS Linux kernel driver. Part of |
| 3 | * the Linux-NTFS project. | 3 | * the Linux-NTFS project. |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2001-2005 Anton Altaparmakov | 5 | * Copyright (c) 2001-2007 Anton Altaparmakov |
| 6 | * Copyright (c) 2002 Richard Russon | 6 | * Copyright (c) 2002 Richard Russon |
| 7 | * | 7 | * |
| 8 | * This program/include file is free software; you can redistribute it and/or | 8 | * This program/include file is free software; you can redistribute it and/or |
| @@ -101,8 +101,6 @@ struct _ntfs_inode { | |||
| 101 | runlist attr_list_rl; /* Run list for the attribute list value. */ | 101 | runlist attr_list_rl; /* Run list for the attribute list value. */ |
| 102 | union { | 102 | union { |
| 103 | struct { /* It is a directory, $MFT, or an index inode. */ | 103 | struct { /* It is a directory, $MFT, or an index inode. */ |
| 104 | struct inode *bmp_ino; /* Attribute inode for the | ||
| 105 | index $BITMAP. */ | ||
| 106 | u32 block_size; /* Size of an index block. */ | 104 | u32 block_size; /* Size of an index block. */ |
| 107 | u32 vcn_size; /* Size of a vcn in this | 105 | u32 vcn_size; /* Size of a vcn in this |
| 108 | index. */ | 106 | index. */ |
| @@ -300,8 +298,6 @@ extern void ntfs_clear_extent_inode(ntfs_inode *ni); | |||
| 300 | 298 | ||
| 301 | extern int ntfs_read_inode_mount(struct inode *vi); | 299 | extern int ntfs_read_inode_mount(struct inode *vi); |
| 302 | 300 | ||
| 303 | extern void ntfs_put_inode(struct inode *vi); | ||
| 304 | |||
| 305 | extern int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt); | 301 | extern int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt); |
| 306 | 302 | ||
| 307 | #ifdef NTFS_RW | 303 | #ifdef NTFS_RW |
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 03a391ac7145..babf94d90def 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project. | 2 | * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project. |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2001-2006 Anton Altaparmakov | 4 | * Copyright (c) 2001-2007 Anton Altaparmakov |
| 5 | * Copyright (c) 2001,2002 Richard Russon | 5 | * Copyright (c) 2001,2002 Richard Russon |
| 6 | * | 6 | * |
| 7 | * This program/include file is free software; you can redistribute it and/or | 7 | * This program/include file is free software; you can redistribute it and/or |
| @@ -2702,9 +2702,6 @@ static int ntfs_statfs(struct dentry *dentry, struct kstatfs *sfs) | |||
| 2702 | static struct super_operations ntfs_sops = { | 2702 | static struct super_operations ntfs_sops = { |
| 2703 | .alloc_inode = ntfs_alloc_big_inode, /* VFS: Allocate new inode. */ | 2703 | .alloc_inode = ntfs_alloc_big_inode, /* VFS: Allocate new inode. */ |
| 2704 | .destroy_inode = ntfs_destroy_big_inode, /* VFS: Deallocate inode. */ | 2704 | .destroy_inode = ntfs_destroy_big_inode, /* VFS: Deallocate inode. */ |
| 2705 | .put_inode = ntfs_put_inode, /* VFS: Called just before | ||
| 2706 | the inode reference count | ||
| 2707 | is decreased. */ | ||
| 2708 | #ifdef NTFS_RW | 2705 | #ifdef NTFS_RW |
| 2709 | //.dirty_inode = NULL, /* VFS: Called from | 2706 | //.dirty_inode = NULL, /* VFS: Called from |
| 2710 | // __mark_inode_dirty(). */ | 2707 | // __mark_inode_dirty(). */ |
| @@ -3261,7 +3258,7 @@ static void __exit exit_ntfs_fs(void) | |||
| 3261 | } | 3258 | } |
| 3262 | 3259 | ||
| 3263 | MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>"); | 3260 | MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>"); |
| 3264 | MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2006 Anton Altaparmakov"); | 3261 | MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2007 Anton Altaparmakov"); |
| 3265 | MODULE_VERSION(NTFS_VERSION); | 3262 | MODULE_VERSION(NTFS_VERSION); |
| 3266 | MODULE_LICENSE("GPL"); | 3263 | MODULE_LICENSE("GPL"); |
| 3267 | #ifdef DEBUG | 3264 | #ifdef DEBUG |
