* fishy ->put_inode usage in ntfs @ 2004-10-14 11:26 Christoph Hellwig 2004-10-14 12:39 ` Anton Altaparmakov 0 siblings, 1 reply; 20+ messages in thread From: Christoph Hellwig @ 2004-10-14 11:26 UTC (permalink / raw) To: aia21; +Cc: linux-ntfs-dev, linux-fsdevel Hi Anton, the inode->i_count useage in ntfs_put_inode is possibly ract vecause we could get anoher reference while you're looking at it. For the index inode case moving this to clear_inode (which is called after we released the last reference) should be fine, but I don't understand the case for directories - why are you checking for i_count beeing 2 there and not one? ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2004-10-14 11:26 fishy ->put_inode usage in ntfs Christoph Hellwig @ 2004-10-14 12:39 ` Anton Altaparmakov 2004-10-14 12:44 ` Matthew Wilcox 2004-10-14 12:59 ` Christoph Hellwig 0 siblings, 2 replies; 20+ messages in thread From: Anton Altaparmakov @ 2004-10-14 12:39 UTC (permalink / raw) To: Christoph Hellwig; +Cc: aia21, ntfs-dev, linux-fsdevel Hi Christoph, On Thu, 2004-10-14 at 12:26, Christoph Hellwig wrote: > the inode->i_count useage in ntfs_put_inode is possibly ract vecause we > could get anoher reference while you're looking at it. Hm. For the directory inode case I don't think this is a problem because all places that use NTFS_I(vfs inode)->itype.index.bmp_ino hold i_sem of the vfs inode which guarantees that at least someone is holding a reference on the vfs inode which in turn guarantees that the i_count cannot drop to levels that would affect ntfs_put_inode(). Explanation: The person who holds i_sem also has 1 i_count and if bmp_ino is set this also has 1 i_count on its parent inode thus we now have a minimum i_count of 2. To get into ntfs_put_inode() at this point in time someone would have to do iput() and they better have 1 i_count before they do the iput() so we now have a minimum i_count of 3 and no code in ntfs_put_inode() would trigger. Only when the last external user of the inode does iput(), ntfs_put_inode() is called with i_count of 2. ntfs_put_inode() then iput()s the bmp_ino attribute inode. This in turn does iput() on the parent inode which drops i_count once more and now clear_inode() will be called by the VFS. We cannot move this code to clear_inode() as it would never get called since the i_count would never drop to 0 due to the existence of the bmp_ino attribute inode which in turn will never have its i_count drop to zero due to it being attached to the parent inode. Catch 22. If someone does get a new reference while we are running the above this is also fine as all users of NTFS_I(vfs inode)->itype.index.bmp_ino check bmp_ino for being NULL and if it is they do an ntfs_attr_iget() and attach it on NTFS_I(vfs inode)->itype.index.bmp_ino again. The reason for doing this is to not to have to ntfs_attr_iget() the bmp_ino every time we need to use it (e.g. every ->readdir() invocation). So it may look odd but it is a speedup worth doing IMO. Hm, I can now see that there is a small race window here and this is simply fixed by doing the setting to NULL of bmp_ino before doing the iput() of bmp_ino. Thanks for pointing this problem area out to! (-: > For the index inode case moving this to clear_inode (which is called > after we released the last reference) should be fine, Indeed. I will move it. Thanks! (-: > but I don't understand the case for directories - why are you checking > for i_count beeing 2 there and not one? I hope I have explained this above. If I failed please do ask again... Best regards, Anton -- Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @) Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net WWW: http://linux-ntfs.sf.net/, http://www-stu.christs.cam.ac.uk/~aia21/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2004-10-14 12:39 ` Anton Altaparmakov @ 2004-10-14 12:44 ` Matthew Wilcox 2004-10-14 13:27 ` Anton Altaparmakov 2004-10-14 14:59 ` Anton Altaparmakov 2004-10-14 12:59 ` Christoph Hellwig 1 sibling, 2 replies; 20+ messages in thread From: Matthew Wilcox @ 2004-10-14 12:44 UTC (permalink / raw) To: Anton Altaparmakov; +Cc: Christoph Hellwig, aia21, ntfs-dev, linux-fsdevel On Thu, Oct 14, 2004 at 01:39:30PM +0100, Anton Altaparmakov wrote: > Hm, I can now see that there is a small race window here and this is > simply fixed by doing the setting to NULL of bmp_ino before doing the > iput() of bmp_ino. Thanks for pointing this problem area out to! (-: If you're going to rely on ordering like this, you must at least use wmb() to ensure that neither the compiler nor the processor reorders your stores. -- "Next the statesmen will invent cheap lies, putting the blame upon the nation that is attacked, and every man will be glad of those conscience-soothing falsities, and will diligently study them, and refuse to examine any refutations of them; and thus he will by and by convince himself that the war is just, and will thank God for the better sleep he enjoys after this process of grotesque self-deception." -- Mark Twain ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2004-10-14 12:44 ` Matthew Wilcox @ 2004-10-14 13:27 ` Anton Altaparmakov 2004-10-14 14:59 ` Anton Altaparmakov 1 sibling, 0 replies; 20+ messages in thread From: Anton Altaparmakov @ 2004-10-14 13:27 UTC (permalink / raw) To: Matthew Wilcox; +Cc: Christoph Hellwig, aia21, ntfs-dev, linux-fsdevel On Thu, 2004-10-14 at 13:44, Matthew Wilcox wrote: > On Thu, Oct 14, 2004 at 01:39:30PM +0100, Anton Altaparmakov wrote: > > Hm, I can now see that there is a small race window here and this is > > simply fixed by doing the setting to NULL of bmp_ino before doing the > > iput() of bmp_ino. Thanks for pointing this problem area out to! (-: > > If you're going to rely on ordering like this, you must at least use > wmb() to ensure that neither the compiler nor the processor reorders > your stores. Thanks, will do. Best regards, Anton -- Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @) Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net WWW: http://linux-ntfs.sf.net/, http://www-stu.christs.cam.ac.uk/~aia21/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2004-10-14 12:44 ` Matthew Wilcox 2004-10-14 13:27 ` Anton Altaparmakov @ 2004-10-14 14:59 ` Anton Altaparmakov 1 sibling, 0 replies; 20+ messages in thread From: Anton Altaparmakov @ 2004-10-14 14:59 UTC (permalink / raw) To: Matthew Wilcox; +Cc: Christoph Hellwig, ntfs-dev, linux-fsdevel On Thu, 2004-10-14 at 13:44, Matthew Wilcox wrote: > On Thu, Oct 14, 2004 at 01:39:30PM +0100, Anton Altaparmakov wrote: > > Hm, I can now see that there is a small race window here and this is > > simply fixed by doing the setting to NULL of bmp_ino before doing the > > iput() of bmp_ino. Thanks for pointing this problem area out to! (-: > > If you're going to rely on ordering like this, you must at least use > wmb() to ensure that neither the compiler nor the processor reorders > your stores. Am I right that if I surround the code with down/up(i_sem) this implies a memory barrier so I do not need wmb()? The relevant code now is: 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); Best regards, Anton -- Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @) Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net WWW: http://linux-ntfs.sf.net/, http://www-stu.christs.cam.ac.uk/~aia21/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2004-10-14 12:39 ` Anton Altaparmakov 2004-10-14 12:44 ` Matthew Wilcox @ 2004-10-14 12:59 ` Christoph Hellwig 2004-10-14 13:26 ` Anton Altaparmakov 1 sibling, 1 reply; 20+ messages in thread From: Christoph Hellwig @ 2004-10-14 12:59 UTC (permalink / raw) To: Anton Altaparmakov; +Cc: Christoph Hellwig, aia21, ntfs-dev, linux-fsdevel On Thu, Oct 14, 2004 at 01:39:30PM +0100, Anton Altaparmakov wrote: > Hi Christoph, > > On Thu, 2004-10-14 at 12:26, Christoph Hellwig wrote: > > the inode->i_count useage in ntfs_put_inode is possibly ract vecause we > > could get anoher reference while you're looking at it. > > Hm. For the directory inode case I don't think this is a problem > because all places that use NTFS_I(vfs inode)->itype.index.bmp_ino hold > i_sem of the vfs inode which guarantees that at least someone is holding > a reference on the vfs inode which in turn guarantees that the i_count > cannot drop to levels that would affect ntfs_put_inode(). > > Explanation: The person who holds i_sem also has 1 i_count and if > bmp_ino is set this also has 1 i_count on its parent inode thus we now > have a minimum i_count of 2. To get into ntfs_put_inode() at this point > in time someone would have to do iput() and they better have 1 i_count > before they do the iput() so we now have a minimum i_count of 3 and no > code in ntfs_put_inode() would trigger. > > Only when the last external user of the inode does iput(), > ntfs_put_inode() is called with i_count of 2. ntfs_put_inode() then > iput()s the bmp_ino attribute inode. > > This in turn does iput() on the parent inode which drops i_count once > more and now clear_inode() will be called by the VFS. > > We cannot move this code to clear_inode() as it would never get called > since the i_count would never drop to 0 due to the existence of the > bmp_ino attribute inode which in turn will never have its i_count drop > to zero due to it being attached to the parent inode. Catch 22. > > If someone does get a new reference while we are running the above this > is also fine as all users of NTFS_I(vfs inode)->itype.index.bmp_ino > check bmp_ino for being NULL and if it is they do an ntfs_attr_iget() > and attach it on NTFS_I(vfs inode)->itype.index.bmp_ino again. > > The reason for doing this is to not to have to ntfs_attr_iget() the > bmp_ino every time we need to use it (e.g. every ->readdir() > invocation). So it may look odd but it is a speedup worth doing IMO. Have you measured the speedup? I don't like filesystem doings things like this in ->put_inode at all, and indeed the plan is to get rid of ->put_inode completely. Why do you need to hold an additional reference anyway? What's so special about the relation of these two inodes? ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2004-10-14 12:59 ` Christoph Hellwig @ 2004-10-14 13:26 ` Anton Altaparmakov 2005-02-10 10:47 ` Christoph Hellwig 0 siblings, 1 reply; 20+ messages in thread From: Anton Altaparmakov @ 2004-10-14 13:26 UTC (permalink / raw) To: Christoph Hellwig; +Cc: ntfs-dev, linux-fsdevel On Thu, 2004-10-14 at 13:59, Christoph Hellwig wrote: > On Thu, Oct 14, 2004 at 01:39:30PM +0100, Anton Altaparmakov wrote: > > Hi Christoph, > > > > On Thu, 2004-10-14 at 12:26, Christoph Hellwig wrote: > > > the inode->i_count useage in ntfs_put_inode is possibly ract vecause we > > > could get anoher reference while you're looking at it. > > > > Hm. For the directory inode case I don't think this is a problem > > because all places that use NTFS_I(vfs inode)->itype.index.bmp_ino hold > > i_sem of the vfs inode which guarantees that at least someone is holding > > a reference on the vfs inode which in turn guarantees that the i_count > > cannot drop to levels that would affect ntfs_put_inode(). > > > > Explanation: The person who holds i_sem also has 1 i_count and if > > bmp_ino is set this also has 1 i_count on its parent inode thus we now > > have a minimum i_count of 2. To get into ntfs_put_inode() at this point > > in time someone would have to do iput() and they better have 1 i_count > > before they do the iput() so we now have a minimum i_count of 3 and no > > code in ntfs_put_inode() would trigger. > > > > Only when the last external user of the inode does iput(), > > ntfs_put_inode() is called with i_count of 2. ntfs_put_inode() then > > iput()s the bmp_ino attribute inode. > > > > This in turn does iput() on the parent inode which drops i_count once > > more and now clear_inode() will be called by the VFS. > > > > We cannot move this code to clear_inode() as it would never get called > > since the i_count would never drop to 0 due to the existence of the > > bmp_ino attribute inode which in turn will never have its i_count drop > > to zero due to it being attached to the parent inode. Catch 22. > > > > If someone does get a new reference while we are running the above this > > is also fine as all users of NTFS_I(vfs inode)->itype.index.bmp_ino > > check bmp_ino for being NULL and if it is they do an ntfs_attr_iget() > > and attach it on NTFS_I(vfs inode)->itype.index.bmp_ino again. > > > > The reason for doing this is to not to have to ntfs_attr_iget() the > > bmp_ino every time we need to use it (e.g. every ->readdir() > > invocation). So it may look odd but it is a speedup worth doing IMO. > > Have you measured the speedup? No. But if ntfs_attr_iget() needs to be used every time and each time the VFS has managed to do a clear inode() then regetting the inode (not from icache) is very expensive. > I don't like filesystem doings things like this in ->put_inode at all, > and indeed the plan is to get rid of ->put_inode completely. Why do > you need to hold an additional reference anyway? What's so special > about the relation of these two inodes? The bmp_ino is a virtual inode. It doesn't exist on disk as an inode. It is an NTFS attribute of the base inode. It cannot exist without the base inode there. You could neither read from nor write to this inode without its base inode being there and you couldn't even clear_inode() this inode without the base inode being there. The reference is essential I am afraid. If ->put_inode is removed then I will have to switch to using ntfs_attr_iget() each time or I will have to attach the inode in some other much hackier way that doesn't use the i_count and uses my ntfs private counter instead. Best regards, Anton -- Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @) Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net WWW: http://linux-ntfs.sf.net/, http://www-stu.christs.cam.ac.uk/~aia21/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2004-10-14 13:26 ` Anton Altaparmakov @ 2005-02-10 10:47 ` Christoph Hellwig 2005-02-10 14:40 ` Anton Altaparmakov 0 siblings, 1 reply; 20+ messages in thread From: Christoph Hellwig @ 2005-02-10 10:47 UTC (permalink / raw) To: Anton Altaparmakov; +Cc: ntfs-dev, linux-fsdevel On Thu, Oct 14, 2004 at 02:26:45PM +0100, Anton Altaparmakov wrote: > > I don't like filesystem doings things like this in ->put_inode at all, > > and indeed the plan is to get rid of ->put_inode completely. Why do > > you need to hold an additional reference anyway? What's so special > > about the relation of these two inodes? > > The bmp_ino is a virtual inode. It doesn't exist on disk as an inode. > It is an NTFS attribute of the base inode. It cannot exist without the > base inode there. You could neither read from nor write to this inode > without its base inode being there and you couldn't even clear_inode() > this inode without the base inode being there. The reference is > essential I am afraid. > > If ->put_inode is removed then I will have to switch to using > ntfs_attr_iget() each time or I will have to attach the inode in some > other much hackier way that doesn't use the i_count and uses my ntfs > private counter instead. Coming back to this issue. Why do you need to refcount bmp_ino at all? Can someone ever grab a reference separate from it's master inode? ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2005-02-10 10:47 ` Christoph Hellwig @ 2005-02-10 14:40 ` Anton Altaparmakov 2005-02-10 14:42 ` Christoph Hellwig 0 siblings, 1 reply; 20+ messages in thread From: Anton Altaparmakov @ 2005-02-10 14:40 UTC (permalink / raw) To: Christoph Hellwig; +Cc: ntfs-dev, fsdevel On Thu, 2005-02-10 at 11:47 +0100, Christoph Hellwig wrote: > On Thu, Oct 14, 2004 at 02:26:45PM +0100, Anton Altaparmakov wrote: > > > I don't like filesystem doings things like this in ->put_inode at all, > > > and indeed the plan is to get rid of ->put_inode completely. Why do > > > you need to hold an additional reference anyway? What's so special > > > about the relation of these two inodes? > > > > The bmp_ino is a virtual inode. It doesn't exist on disk as an inode. > > It is an NTFS attribute of the base inode. It cannot exist without the > > base inode there. You could neither read from nor write to this inode > > without its base inode being there and you couldn't even clear_inode() > > this inode without the base inode being there. The reference is > > essential I am afraid. > > > > If ->put_inode is removed then I will have to switch to using > > ntfs_attr_iget() each time or I will have to attach the inode in some > > other much hackier way that doesn't use the i_count and uses my ntfs > > private counter instead. > > Coming back to this issue. Why do you need to refcount bmp_ino at all? I am not sure what you mean. The VFS layer does reference counting on inodes. I have no choice in the matter. > Can someone ever grab a reference separate from it's master inode? Again, not sure what you mean. Could you elaborate? Best regards, Anton -- Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @) Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2005-02-10 14:40 ` Anton Altaparmakov @ 2005-02-10 14:42 ` Christoph Hellwig 2005-02-10 14:48 ` Anton Altaparmakov 0 siblings, 1 reply; 20+ messages in thread From: Christoph Hellwig @ 2005-02-10 14:42 UTC (permalink / raw) To: Anton Altaparmakov; +Cc: ntfs-dev, fsdevel On Thu, Feb 10, 2005 at 02:40:39PM +0000, Anton Altaparmakov wrote: > I am not sure what you mean. The VFS layer does reference counting on > inodes. I have no choice in the matter. > > > Can someone ever grab a reference separate from it's master inode? > > Again, not sure what you mean. Could you elaborate? ntfs_read_locked_attr_inode() does igrab on the 'parent' inode currently. What do you need this for exactly - the attr inode goes away anyway when clear_inode is called on that 'parent' inode (in my scheme). ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2005-02-10 14:42 ` Christoph Hellwig @ 2005-02-10 14:48 ` Anton Altaparmakov 2005-02-10 14:50 ` Anton Altaparmakov 2005-02-10 14:50 ` Christoph Hellwig 0 siblings, 2 replies; 20+ messages in thread From: Anton Altaparmakov @ 2005-02-10 14:48 UTC (permalink / raw) To: Christoph Hellwig; +Cc: ntfs-dev, fsdevel On Thu, 2005-02-10 at 15:42 +0100, Christoph Hellwig wrote: > On Thu, Feb 10, 2005 at 02:40:39PM +0000, Anton Altaparmakov wrote: > > I am not sure what you mean. The VFS layer does reference counting on > > inodes. I have no choice in the matter. > > > > > Can someone ever grab a reference separate from it's master inode? > > > > Again, not sure what you mean. Could you elaborate? > > ntfs_read_locked_attr_inode() does igrab on the 'parent' inode > currently. What do you need this for exactly - the attr inode > goes away anyway when clear_inode is called on that 'parent' inode > (in my scheme). If the igrab() were not done, it would be possible for clear_inode to be called on the 'parent' inode whilst at the same time one or more attr inodes (belonging to this 'parent') are in use and Bad Things(TM) would happen... Best regards, Anton -- Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @) Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2005-02-10 14:48 ` Anton Altaparmakov @ 2005-02-10 14:50 ` Anton Altaparmakov 2005-02-10 14:51 ` Christoph Hellwig 2005-02-10 14:50 ` Christoph Hellwig 1 sibling, 1 reply; 20+ messages in thread From: Anton Altaparmakov @ 2005-02-10 14:50 UTC (permalink / raw) To: Christoph Hellwig; +Cc: ntfs-dev, fsdevel On Thu, 2005-02-10 at 14:48 +0000, Anton Altaparmakov wrote: > On Thu, 2005-02-10 at 15:42 +0100, Christoph Hellwig wrote: > > On Thu, Feb 10, 2005 at 02:40:39PM +0000, Anton Altaparmakov wrote: > > > I am not sure what you mean. The VFS layer does reference counting on > > > inodes. I have no choice in the matter. > > > > > > > Can someone ever grab a reference separate from it's master inode? > > > > > > Again, not sure what you mean. Could you elaborate? > > > > ntfs_read_locked_attr_inode() does igrab on the 'parent' inode > > currently. What do you need this for exactly - the attr inode > > goes away anyway when clear_inode is called on that 'parent' inode > > (in my scheme). > > If the igrab() were not done, it would be possible for clear_inode to be > called on the 'parent' inode whilst at the same time one or more attr > inodes (belonging to this 'parent') are in use and Bad Things(TM) would > happen... The igrab() effectively guarantees that iput() is called on all attr inodes before clear_inode on the 'parent' can be invoked. Best regards, Anton -- Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @) Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2005-02-10 14:50 ` Anton Altaparmakov @ 2005-02-10 14:51 ` Christoph Hellwig 0 siblings, 0 replies; 20+ messages in thread From: Christoph Hellwig @ 2005-02-10 14:51 UTC (permalink / raw) To: Anton Altaparmakov; +Cc: Christoph Hellwig, ntfs-dev, fsdevel On Thu, Feb 10, 2005 at 02:50:02PM +0000, Anton Altaparmakov wrote: > > If the igrab() were not done, it would be possible for clear_inode to be > > called on the 'parent' inode whilst at the same time one or more attr > > inodes (belonging to this 'parent') are in use and Bad Things(TM) would > > happen... > > The igrab() effectively guarantees that iput() is called on all attr > inodes before clear_inode on the 'parent' can be invoked. Yes, but why exactly is this important. It looks like you're absuing the refcount on the 'parent' inode for some shared data? ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2005-02-10 14:48 ` Anton Altaparmakov 2005-02-10 14:50 ` Anton Altaparmakov @ 2005-02-10 14:50 ` Christoph Hellwig 2005-02-10 14:59 ` Anton Altaparmakov 1 sibling, 1 reply; 20+ messages in thread From: Christoph Hellwig @ 2005-02-10 14:50 UTC (permalink / raw) To: Anton Altaparmakov; +Cc: ntfs-dev, fsdevel On Thu, Feb 10, 2005 at 02:48:26PM +0000, Anton Altaparmakov wrote: > If the igrab() were not done, it would be possible for clear_inode to be > called on the 'parent' inode whilst at the same time one or more attr > inodes (belonging to this 'parent') are in use and Bad Things(TM) would > happen... What bad thing specificly? If there's shared information we should probably refcount them separately. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2005-02-10 14:50 ` Christoph Hellwig @ 2005-02-10 14:59 ` Anton Altaparmakov 2005-02-13 16:35 ` Christoph Hellwig 0 siblings, 1 reply; 20+ messages in thread From: Anton Altaparmakov @ 2005-02-10 14:59 UTC (permalink / raw) To: Christoph Hellwig; +Cc: ntfs-dev, fsdevel On Thu, 2005-02-10 at 15:50 +0100, Christoph Hellwig wrote: > On Thu, Feb 10, 2005 at 02:48:26PM +0000, Anton Altaparmakov wrote: > > If the igrab() were not done, it would be possible for clear_inode to be > > called on the 'parent' inode whilst at the same time one or more attr > > inodes (belonging to this 'parent') are in use and Bad Things(TM) would > > happen... > > What bad thing specificly? If there's shared information we should > probably refcount them separately. Each attr inode stores a pointer to its parent inode in NTFS_I(struct inode *vi)->ext.base_ntfs_ino. This pointer would point to random memory if clear_inode is called on the parent whilst the attr inode is still in use. Best regards, Anton -- Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @) Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2005-02-10 14:59 ` Anton Altaparmakov @ 2005-02-13 16:35 ` Christoph Hellwig 2005-02-14 20:44 ` Anton Altaparmakov 0 siblings, 1 reply; 20+ messages in thread From: Christoph Hellwig @ 2005-02-13 16:35 UTC (permalink / raw) To: Anton Altaparmakov; +Cc: Christoph Hellwig, ntfs-dev, fsdevel On Thu, Feb 10, 2005 at 02:59:32PM +0000, Anton Altaparmakov wrote: > On Thu, 2005-02-10 at 15:50 +0100, Christoph Hellwig wrote: > > On Thu, Feb 10, 2005 at 02:48:26PM +0000, Anton Altaparmakov wrote: > > > If the igrab() were not done, it would be possible for clear_inode to be > > > called on the 'parent' inode whilst at the same time one or more attr > > > inodes (belonging to this 'parent') are in use and Bad Things(TM) would > > > happen... > > > > What bad thing specificly? If there's shared information we should > > probably refcount them separately. > > Each attr inode stores a pointer to its parent inode in NTFS_I(struct > inode *vi)->ext.base_ntfs_ino. This pointer would point to random > memory if clear_inode is called on the parent whilst the attr inode is > still in use. Ok. Al Viro suggested to put a spinlock around the bmp_ino pointer and then igrab the master inode when accessing it, iput it when done. Below is a rather half-backed patch to implement the suggestion. It compiles, but I'm pretty sure I introduced various bugs. Also the new spinlock isn't nice, it'd probably be better to reuse some other lock for this single field. --- 1.85/fs/ntfs/dir.c 2004-11-05 13:48:35 +01:00 +++ edited/fs/ntfs/dir.c 2005-02-13 17:34:51 +01:00 @@ -1102,7 +1102,7 @@ static int ntfs_readdir(struct file *fil { s64 ia_pos, ia_start, prev_ia_pos, bmp_pos; loff_t fpos; - struct inode *bmp_vi, *vdir = filp->f_dentry->d_inode; + struct inode *bmp_vi = NULL, *vdir = filp->f_dentry->d_inode; struct super_block *sb = vdir->i_sb; ntfs_inode *ndir = NTFS_I(vdir); ntfs_volume *vol = NTFS_SB(sb); @@ -1250,17 +1250,14 @@ skip_index_root: /* Get the offset into the index allocation attribute. */ ia_pos = (s64)fpos - vol->mft_record_size; ia_mapping = vdir->i_mapping; - bmp_vi = ndir->itype.index.bmp_ino; + + bmp_vi = ntfs_grab_bmp_inode(vdir); if (unlikely(!bmp_vi)) { - ntfs_debug("Inode 0x%lx, regetting index bitmap.", vdir->i_ino); - bmp_vi = ntfs_attr_iget(vdir, AT_BITMAP, I30, 4); - if (IS_ERR(bmp_vi)) { - ntfs_error(sb, "Failed to get bitmap attribute."); - err = PTR_ERR(bmp_vi); - goto err_out; - } - ndir->itype.index.bmp_ino = bmp_vi; + ntfs_error(sb, "Failed to get bitmap attribute."); + err = -EINVAL; + goto err_out; } + bmp_mapping = bmp_vi->i_mapping; /* Get the starting bitmap bit position and sanity check it. */ bmp_pos = ia_pos >> ndir->itype.index.block_size_bits; @@ -1445,6 +1442,8 @@ EOD: abort: kfree(name); done: + if (bmp_vi) + ntfs_ungrab_bmp_inode(vdir); #ifdef DEBUG if (!rc) ntfs_debug("EOD, fpos 0x%llx, returning 0.", fpos); @@ -1455,6 +1454,8 @@ done: filp->f_pos = fpos; return 0; err_out: + if (bmp_vi) + ntfs_ungrab_bmp_inode(vdir); if (bmp_page) ntfs_unmap_page(bmp_page); if (ia_page) { @@ -1537,8 +1538,16 @@ static int ntfs_dir_fsync(struct file *f ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); BUG_ON(!S_ISDIR(vi->i_mode)); - if (NInoIndexAllocPresent(ni) && ni->itype.index.bmp_ino) - write_inode_now(ni->itype.index.bmp_ino, !datasync); + + if (NInoIndexAllocPresent(ni)) { + struct inode *bmp_inode = ntfs_grab_bmp_inode(vi); + + if (bmp_inode) { + write_inode_now(bmp_inode, !datasync); + ntfs_ungrab_bmp_inode(vi); + } + } + ret = ntfs_write_inode(vi, 1); write_inode_now(vi, !datasync); err = sync_blockdev(vi->i_sb->s_bdev); --- 1.154/fs/ntfs/inode.c 2004-11-09 11:42:05 +01:00 +++ edited/fs/ntfs/inode.c 2005-02-13 17:40:55 +01:00 @@ -388,6 +388,7 @@ void __ntfs_init_inode(struct super_bloc ni->attr_list = NULL; ntfs_init_runlist(&ni->attr_list_rl); ni->itype.index.bmp_ino = NULL; + spin_lock_init(&ni->itype.index.bmp_ino_lock); ni->itype.index.block_size = 0; ni->itype.index.vcn_size = 0; ni->itype.index.collation_rule = 0; @@ -414,6 +415,29 @@ inline ntfs_inode *ntfs_new_extent_inode return ni; } +/* + * Grab primary inode when we're using the attr inode because they + * share state. + */ +struct inode *ntfs_grab_bmp_inode(struct inode *inode) +{ + struct inode *bmp_inode; + ntfs_inode *ni = NTFS_I(inode); + + spin_lock(&ni->itype.index.bmp_ino_lock); + bmp_inode = ni->itype.index.bmp_ino; + if (bmp_inode && !igrab(inode)) + bmp_inode = NULL; + spin_unlock(&ni->itype.index.bmp_ino_lock); + + return inode; +} + +void ntfs_ungrab_bmp_inode(struct inode *inode) +{ + iput(inode); +} + /** * ntfs_is_extended_system_file - check if a file is in the $Extend directory * @ctx: initialized attribute search context @@ -1365,7 +1389,6 @@ static int ntfs_read_locked_attr_inode(s * Make sure the base inode doesn't go away and attach it to the * attribute inode. */ - igrab(base_vi); ni->ext.base_ntfs_ino = base_ni; ni->nr_extents = -1; @@ -1651,7 +1674,6 @@ skip_large_index_stuff: * Make sure the base inode doesn't go away and attach it to the * index inode. */ - igrab(base_vi); ni->ext.base_ntfs_ino = base_ni; ni->nr_extents = -1; @@ -2102,37 +2124,6 @@ err_out: return -1; } -/** - * ntfs_put_inode - handler for when the inode reference count is decremented - * @vi: vfs inode - * - * The VFS calls ntfs_put_inode() every time the inode reference count (i_count) - * is about to be decremented (but before the decrement itself. - * - * If the inode @vi is a directory with two references, one of which is being - * 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. - */ -void ntfs_put_inode(struct inode *vi) -{ - 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); - } - } -} - static void __ntfs_clear_inode(ntfs_inode *ni) { /* Free all alocated memory. */ @@ -2198,18 +2189,6 @@ void ntfs_clear_big_inode(struct inode * { 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)); @@ -2236,15 +2215,22 @@ void ntfs_clear_big_inode(struct inode * __ntfs_clear_inode(ni); + /* Release the base inode if we are holding it. */ if (NInoAttr(ni)) { - /* Release the base inode if we are holding it. */ - if (ni->nr_extents == -1) { - iput(VFS_I(ni->ext.base_ntfs_ino)); + ntfs_inode *base_inode = ni->ext.base_ntfs_ino; + + if (S_ISDIR(VFS_I(base_inode)->i_mode)) { + spin_lock(&base_inode->itype.index.bmp_ino_lock); + base_inode->itype.index.bmp_ino = NULL; + iput(VFS_I(base_inode)); + spin_unlock(&base_inode->itype.index.bmp_ino_lock); + ni->ext.base_ntfs_ino = NULL; + } else if (ni->nr_extents == -1) { ni->nr_extents = 0; ni->ext.base_ntfs_ino = NULL; + iput(VFS_I(base_inode)); } } - return; } /** --- 1.45/fs/ntfs/inode.h 2004-10-25 11:46:30 +02:00 +++ edited/fs/ntfs/inode.h 2005-02-13 17:32:58 +01:00 @@ -101,6 +101,7 @@ struct _ntfs_inode { struct { /* It is a directory, $MFT, or an index inode. */ struct inode *bmp_ino; /* Attribute inode for the index $BITMAP. */ + spinlock_t bmp_ino_lock; u32 block_size; /* Size of an index block. */ u32 vcn_size; /* Size of a vcn in this index. */ @@ -275,6 +276,9 @@ extern struct inode *ntfs_attr_iget(stru extern struct inode *ntfs_index_iget(struct inode *base_vi, ntfschar *name, u32 name_len); +extern struct inode *ntfs_grab_bmp_inode(struct inode *inode); +extern void ntfs_ungrab_bmp_inode(struct inode *inode); + extern struct inode *ntfs_alloc_big_inode(struct super_block *sb); extern void ntfs_destroy_big_inode(struct inode *inode); extern void ntfs_clear_big_inode(struct inode *vi); @@ -295,8 +299,6 @@ extern ntfs_inode *ntfs_new_extent_inode extern void ntfs_clear_extent_inode(ntfs_inode *ni); extern int ntfs_read_inode_mount(struct inode *vi); - -extern void ntfs_put_inode(struct inode *vi); extern int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt); --- 1.184/fs/ntfs/super.c 2005-01-05 03:48:14 +01:00 +++ edited/fs/ntfs/super.c 2005-02-13 17:15:47 +01:00 @@ -2186,9 +2186,6 @@ static int ntfs_statfs(struct super_bloc static struct super_operations ntfs_sops = { .alloc_inode = ntfs_alloc_big_inode, /* VFS: Allocate new inode. */ .destroy_inode = ntfs_destroy_big_inode, /* VFS: Deallocate inode. */ - .put_inode = ntfs_put_inode, /* VFS: Called just before - the inode reference count - is decreased. */ #ifdef NTFS_RW //.dirty_inode = NULL, /* VFS: Called from // __mark_inode_dirty(). */ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2005-02-13 16:35 ` Christoph Hellwig @ 2005-02-14 20:44 ` Anton Altaparmakov 2005-03-01 23:17 ` David Woodhouse 0 siblings, 1 reply; 20+ messages in thread From: Anton Altaparmakov @ 2005-02-14 20:44 UTC (permalink / raw) To: Christoph Hellwig; +Cc: ntfs-dev, fsdevel On Sun, 13 Feb 2005, Christoph Hellwig wrote: > On Thu, Feb 10, 2005 at 02:59:32PM +0000, Anton Altaparmakov wrote: > > On Thu, 2005-02-10 at 15:50 +0100, Christoph Hellwig wrote: > > > On Thu, Feb 10, 2005 at 02:48:26PM +0000, Anton Altaparmakov wrote: > > > > If the igrab() were not done, it would be possible for clear_inode to be > > > > called on the 'parent' inode whilst at the same time one or more attr > > > > inodes (belonging to this 'parent') are in use and Bad Things(TM) would > > > > happen... > > > > > > What bad thing specificly? If there's shared information we should > > > probably refcount them separately. > > > > Each attr inode stores a pointer to its parent inode in NTFS_I(struct > > inode *vi)->ext.base_ntfs_ino. This pointer would point to random > > memory if clear_inode is called on the parent whilst the attr inode is > > still in use. > > Ok. Al Viro suggested to put a spinlock around the bmp_ino pointer and > then igrab the master inode when accessing it, iput it when done. No lock is needed. It wasn't needed in the past so why should it be needed now? > Below is a rather half-backed patch to implement the suggestion. It > compiles, but I'm pretty sure I introduced various bugs. This patch may compile but would never work. At all. A few reasons I can think of off the top of my head whilst reading the patch are inserted in it below. > Also the new spinlock isn't nice, it'd probably be better to reuse some > other lock for this single field. As I said I don't understand what you want a lock for. > --- 1.85/fs/ntfs/dir.c 2004-11-05 13:48:35 +01:00 > +++ edited/fs/ntfs/dir.c 2005-02-13 17:34:51 +01:00 > @@ -1102,7 +1102,7 @@ static int ntfs_readdir(struct file *fil > { > s64 ia_pos, ia_start, prev_ia_pos, bmp_pos; > loff_t fpos; > - struct inode *bmp_vi, *vdir = filp->f_dentry->d_inode; > + struct inode *bmp_vi = NULL, *vdir = filp->f_dentry->d_inode; > struct super_block *sb = vdir->i_sb; > ntfs_inode *ndir = NTFS_I(vdir); > ntfs_volume *vol = NTFS_SB(sb); > @@ -1250,17 +1250,14 @@ skip_index_root: > /* Get the offset into the index allocation attribute. */ > ia_pos = (s64)fpos - vol->mft_record_size; > ia_mapping = vdir->i_mapping; > - bmp_vi = ndir->itype.index.bmp_ino; > + > + bmp_vi = ntfs_grab_bmp_inode(vdir); > if (unlikely(!bmp_vi)) { > - ntfs_debug("Inode 0x%lx, regetting index bitmap.", vdir->i_ino); > - bmp_vi = ntfs_attr_iget(vdir, AT_BITMAP, I30, 4); > - if (IS_ERR(bmp_vi)) { > - ntfs_error(sb, "Failed to get bitmap attribute."); > - err = PTR_ERR(bmp_vi); > - goto err_out; > - } > - ndir->itype.index.bmp_ino = bmp_vi; > + ntfs_error(sb, "Failed to get bitmap attribute."); > + err = -EINVAL; > + goto err_out; So every time we get a concurrent clear_inode() and iget() for the same inode what happens? We get your "Failed to get bitmap attribute." every time? Or can clear_inode only be called once the inode is removed from icache? The code you are removing is getting the inode back in the case that it has disappeared (which I was able to cause really easily by applying even moderate read-access stress on a mounted volume)... > } > + > bmp_mapping = bmp_vi->i_mapping; > /* Get the starting bitmap bit position and sanity check it. */ > bmp_pos = ia_pos >> ndir->itype.index.block_size_bits; > @@ -1445,6 +1442,8 @@ EOD: > abort: > kfree(name); > done: > + if (bmp_vi) > + ntfs_ungrab_bmp_inode(vdir); > #ifdef DEBUG > if (!rc) > ntfs_debug("EOD, fpos 0x%llx, returning 0.", fpos); > @@ -1455,6 +1454,8 @@ done: > filp->f_pos = fpos; > return 0; > err_out: > + if (bmp_vi) > + ntfs_ungrab_bmp_inode(vdir); > if (bmp_page) > ntfs_unmap_page(bmp_page); > if (ia_page) { > @@ -1537,8 +1538,16 @@ static int ntfs_dir_fsync(struct file *f > > ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); > BUG_ON(!S_ISDIR(vi->i_mode)); > - if (NInoIndexAllocPresent(ni) && ni->itype.index.bmp_ino) > - write_inode_now(ni->itype.index.bmp_ino, !datasync); > + > + if (NInoIndexAllocPresent(ni)) { > + struct inode *bmp_inode = ntfs_grab_bmp_inode(vi); > + > + if (bmp_inode) { > + write_inode_now(bmp_inode, !datasync); > + ntfs_ungrab_bmp_inode(vi); > + } > + } > + > ret = ntfs_write_inode(vi, 1); > write_inode_now(vi, !datasync); > err = sync_blockdev(vi->i_sb->s_bdev); > --- 1.154/fs/ntfs/inode.c 2004-11-09 11:42:05 +01:00 > +++ edited/fs/ntfs/inode.c 2005-02-13 17:40:55 +01:00 > @@ -388,6 +388,7 @@ void __ntfs_init_inode(struct super_bloc > ni->attr_list = NULL; > ntfs_init_runlist(&ni->attr_list_rl); > ni->itype.index.bmp_ino = NULL; > + spin_lock_init(&ni->itype.index.bmp_ino_lock); > ni->itype.index.block_size = 0; > ni->itype.index.vcn_size = 0; > ni->itype.index.collation_rule = 0; > @@ -414,6 +415,29 @@ inline ntfs_inode *ntfs_new_extent_inode > return ni; > } > > +/* > + * Grab primary inode when we're using the attr inode because they > + * share state. > + */ > +struct inode *ntfs_grab_bmp_inode(struct inode *inode) > +{ > + struct inode *bmp_inode; > + ntfs_inode *ni = NTFS_I(inode); > + > + spin_lock(&ni->itype.index.bmp_ino_lock); > + bmp_inode = ni->itype.index.bmp_ino; > + if (bmp_inode && !igrab(inode)) > + bmp_inode = NULL; > + spin_unlock(&ni->itype.index.bmp_ino_lock); > + > + return inode; > +} What about when bmp_inode is NULL? Surely this function should be regetting it? (See above comment.) > + > +void ntfs_ungrab_bmp_inode(struct inode *inode) > +{ > + iput(inode); > +} > + > /** > * ntfs_is_extended_system_file - check if a file is in the $Extend directory > * @ctx: initialized attribute search context > @@ -1365,7 +1389,6 @@ static int ntfs_read_locked_attr_inode(s > * Make sure the base inode doesn't go away and attach it to the > * attribute inode. > */ > - igrab(base_vi); > ni->ext.base_ntfs_ino = base_ni; > ni->nr_extents = -1; > > @@ -1651,7 +1674,6 @@ skip_large_index_stuff: > * Make sure the base inode doesn't go away and attach it to the > * index inode. > */ > - igrab(base_vi); > ni->ext.base_ntfs_ino = base_ni; > ni->nr_extents = -1; > > @@ -2102,37 +2124,6 @@ err_out: > return -1; > } > > -/** > - * ntfs_put_inode - handler for when the inode reference count is decremented > - * @vi: vfs inode > - * > - * The VFS calls ntfs_put_inode() every time the inode reference count (i_count) > - * is about to be decremented (but before the decrement itself. > - * > - * If the inode @vi is a directory with two references, one of which is being > - * 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. > - */ > -void ntfs_put_inode(struct inode *vi) > -{ > - 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); This iput() is essential. Your patch doesn't seem to place it anywhere. This means that all the bmp_ino inodes in the mounted fs will never have their reference dropped so when you try to umount you will get "VFS: Busy inodes. Self destruct in 5 seconds."... > - } > - } > -} > - > static void __ntfs_clear_inode(ntfs_inode *ni) > { > /* Free all alocated memory. */ > @@ -2198,18 +2189,6 @@ void ntfs_clear_big_inode(struct inode * > { > 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; > - } You cannot remove this code or even move it to below the write commit and __ntfs_clear_inode call or it will break. > #ifdef NTFS_RW > if (NInoDirty(ni)) { > BOOL was_bad = (is_bad_inode(vi)); > @@ -2236,15 +2215,22 @@ void ntfs_clear_big_inode(struct inode * > > __ntfs_clear_inode(ni); > > + /* Release the base inode if we are holding it. */ > if (NInoAttr(ni)) { > - /* Release the base inode if we are holding it. */ > - if (ni->nr_extents == -1) { > - iput(VFS_I(ni->ext.base_ntfs_ino)); > + ntfs_inode *base_inode = ni->ext.base_ntfs_ino; You are not testing nr_extents and thus base_inode could be NULL or worse could be a different meaning altogether (ni->ext is a union the meaning of which is determined by nr_extents which must be checked before accessing ni->ext). > + > + if (S_ISDIR(VFS_I(base_inode)->i_mode)) { > + spin_lock(&base_inode->itype.index.bmp_ino_lock); > + base_inode->itype.index.bmp_ino = NULL; > + iput(VFS_I(base_inode)); Why are we putting the base inode here? I thought your patch removes the getting of a reference to it... > + spin_unlock(&base_inode->itype.index.bmp_ino_lock); > + ni->ext.base_ntfs_ino = NULL; > + } else if (ni->nr_extents == -1) { > ni->nr_extents = 0; > ni->ext.base_ntfs_ino = NULL; > + iput(VFS_I(base_inode)); Ditto. And when the directory is being cleared? Where is the iput() for the bmp_ino? It used to be in put_inode but you get rid of it in your patch. Why btw? It seems really silly to remove it considering it is there and it works and it is not hurting anybody... > } > } > - return; > } > > /** > --- 1.45/fs/ntfs/inode.h 2004-10-25 11:46:30 +02:00 > +++ edited/fs/ntfs/inode.h 2005-02-13 17:32:58 +01:00 > @@ -101,6 +101,7 @@ struct _ntfs_inode { > struct { /* It is a directory, $MFT, or an index inode. */ > struct inode *bmp_ino; /* Attribute inode for the > index $BITMAP. */ > + spinlock_t bmp_ino_lock; > u32 block_size; /* Size of an index block. */ > u32 vcn_size; /* Size of a vcn in this > index. */ > @@ -275,6 +276,9 @@ extern struct inode *ntfs_attr_iget(stru > extern struct inode *ntfs_index_iget(struct inode *base_vi, ntfschar *name, > u32 name_len); > > +extern struct inode *ntfs_grab_bmp_inode(struct inode *inode); > +extern void ntfs_ungrab_bmp_inode(struct inode *inode); > + > extern struct inode *ntfs_alloc_big_inode(struct super_block *sb); > extern void ntfs_destroy_big_inode(struct inode *inode); > extern void ntfs_clear_big_inode(struct inode *vi); > @@ -295,8 +299,6 @@ extern ntfs_inode *ntfs_new_extent_inode > extern void ntfs_clear_extent_inode(ntfs_inode *ni); > > extern int ntfs_read_inode_mount(struct inode *vi); > - > -extern void ntfs_put_inode(struct inode *vi); > > extern int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt); > > --- 1.184/fs/ntfs/super.c 2005-01-05 03:48:14 +01:00 > +++ edited/fs/ntfs/super.c 2005-02-13 17:15:47 +01:00 > @@ -2186,9 +2186,6 @@ static int ntfs_statfs(struct super_bloc > static struct super_operations ntfs_sops = { > .alloc_inode = ntfs_alloc_big_inode, /* VFS: Allocate new inode. */ > .destroy_inode = ntfs_destroy_big_inode, /* VFS: Deallocate inode. */ > - .put_inode = ntfs_put_inode, /* VFS: Called just before > - the inode reference count > - is decreased. */ > #ifdef NTFS_RW > //.dirty_inode = NULL, /* VFS: Called from > // __mark_inode_dirty(). */ > Best regards, Anton -- Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @) Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2005-02-14 20:44 ` Anton Altaparmakov @ 2005-03-01 23:17 ` David Woodhouse 2005-03-02 8:43 ` Anton Altaparmakov 0 siblings, 1 reply; 20+ messages in thread From: David Woodhouse @ 2005-03-01 23:17 UTC (permalink / raw) To: Anton Altaparmakov; +Cc: Christoph Hellwig, ntfs-dev, fsdevel On Mon, 2005-02-14 at 20:44 +0000, Anton Altaparmakov wrote: > So every time we get a concurrent clear_inode() and iget() for the same > inode what happens? We get your "Failed to get bitmap attribute." every > time? Or can clear_inode only be called once the inode is removed from > icache? I thought we declared that the concurrent clear_inode() and read_inode() were a VFS bug, and fixed it? It's even fixed in 2.4 now isn't it? -- dwmw2 ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2005-03-01 23:17 ` David Woodhouse @ 2005-03-02 8:43 ` Anton Altaparmakov 2005-03-02 8:53 ` David Woodhouse 0 siblings, 1 reply; 20+ messages in thread From: Anton Altaparmakov @ 2005-03-02 8:43 UTC (permalink / raw) To: David Woodhouse; +Cc: Christoph Hellwig, ntfs-dev, fsdevel On Tue, 2005-03-01 at 23:17 +0000, David Woodhouse wrote: > On Mon, 2005-02-14 at 20:44 +0000, Anton Altaparmakov wrote: > > So every time we get a concurrent clear_inode() and iget() for the same > > inode what happens? We get your "Failed to get bitmap attribute." every > > time? Or can clear_inode only be called once the inode is removed from > > icache? > > I thought we declared that the concurrent clear_inode() and read_inode() > were a VFS bug, and fixed it? It's even fixed in 2.4 now isn't it? Is it? I must have missed this discussion. )-: Best regards, Anton -- Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @) Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK Linux NTFS maintainer / IRC: #ntfs on irc.freenode.net WWW: http://linux-ntfs.sf.net/ & http://www-stu.christs.cam.ac.uk/~aia21/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: fishy ->put_inode usage in ntfs 2005-03-02 8:43 ` Anton Altaparmakov @ 2005-03-02 8:53 ` David Woodhouse 0 siblings, 0 replies; 20+ messages in thread From: David Woodhouse @ 2005-03-02 8:53 UTC (permalink / raw) To: Anton Altaparmakov; +Cc: Christoph Hellwig, ntfs-dev, fsdevel On Wed, 2005-03-02 at 08:43 +0000, Anton Altaparmakov wrote: > > I thought we declared that the concurrent clear_inode() and read_inode() > > were a VFS bug, and fixed it? It's even fixed in 2.4 now isn't it? > > Is it? I must have missed this discussion. )-: Wasn't that why we backported __wait_on_freeing_inode() to 2.4? -- dwmw2 ^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2005-03-02 8:53 UTC | newest] Thread overview: 20+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2004-10-14 11:26 fishy ->put_inode usage in ntfs Christoph Hellwig 2004-10-14 12:39 ` Anton Altaparmakov 2004-10-14 12:44 ` Matthew Wilcox 2004-10-14 13:27 ` Anton Altaparmakov 2004-10-14 14:59 ` Anton Altaparmakov 2004-10-14 12:59 ` Christoph Hellwig 2004-10-14 13:26 ` Anton Altaparmakov 2005-02-10 10:47 ` Christoph Hellwig 2005-02-10 14:40 ` Anton Altaparmakov 2005-02-10 14:42 ` Christoph Hellwig 2005-02-10 14:48 ` Anton Altaparmakov 2005-02-10 14:50 ` Anton Altaparmakov 2005-02-10 14:51 ` Christoph Hellwig 2005-02-10 14:50 ` Christoph Hellwig 2005-02-10 14:59 ` Anton Altaparmakov 2005-02-13 16:35 ` Christoph Hellwig 2005-02-14 20:44 ` Anton Altaparmakov 2005-03-01 23:17 ` David Woodhouse 2005-03-02 8:43 ` Anton Altaparmakov 2005-03-02 8:53 ` David Woodhouse
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).