Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1611832 > unrolled thread
| Started by | Jan Kara <jack@suse.cz> |
|---|---|
| First post | 2017-03-29 13:20 +0200 |
| Last post | 2017-04-05 03:30 +0200 |
| Articles | 20 on this page of 22 — 6 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization Jan Kara <jack@suse.cz> - 2017-03-29 13:20 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization Jeff Layton <jlayton@redhat.com> - 2017-03-29 20:00 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization Dave Chinner <david@fromorbit.com> - 2017-03-30 01:50 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization Jeff Layton <jlayton@redhat.com> - 2017-03-30 13:30 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization "J. Bruce Fields" <bfields@fieldses.org> - 2017-04-04 20:40 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization Jan Kara <jack@suse.cz> - 2017-03-30 08:50 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization Jeff Layton <jlayton@redhat.com> - 2017-03-30 13:20 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization "J. Bruce Fields" <bfields@fieldses.org> - 2017-03-30 18:20 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization Jeff Layton <jlayton@redhat.com> - 2017-03-30 20:40 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization Boaz Harrosh <openosd@gmail.com> - 2017-03-30 23:20 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization "J. Bruce Fields" <bfields@fieldses.org> - 2017-04-04 20:40 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization NeilBrown <neil@brown.name> - 2017-04-05 03:50 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization Jan Kara <jack@suse.cz> - 2017-04-05 10:10 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization "J. Bruce Fields" <bfields@fieldses.org> - 2017-04-05 20:20 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization NeilBrown <neil@brown.name> - 2017-04-06 03:20 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization Jan Kara <jack@suse.cz> - 2017-04-06 09:30 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization "J. Bruce Fields" <bfields@fieldses.org> - 2017-04-05 19:50 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization Dave Chinner <david@fromorbit.com> - 2017-04-02 01:10 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization Jan Kara <jack@suse.cz> - 2017-04-03 16:10 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization Dave Chinner <david@fromorbit.com> - 2017-04-04 14:40 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization "J. Bruce Fields" <bfields@fieldses.org> - 2017-04-04 20:00 +0200
Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization NeilBrown <neil@brown.name> - 2017-04-05 03:30 +0200
Page 1 of 2 [1] 2 Next page →
| From | Jan Kara <jack@suse.cz> |
|---|---|
| Date | 2017-03-29 13:20 +0200 |
| Subject | Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization |
| Message-ID | <tqjNT-63S-7@gated-at.bofh.it> |
On Tue 21-03-17 14:46:53, Jeff Layton wrote: > On Tue, 2017-03-21 at 14:30 -0400, J. Bruce Fields wrote: > > On Tue, Mar 21, 2017 at 01:23:24PM -0400, Jeff Layton wrote: > > > On Tue, 2017-03-21 at 12:30 -0400, J. Bruce Fields wrote: > > > > - It's durable; the above comparison still works if there were reboots > > > > between the two i_version checks. > > > > - I don't know how realistic this is--we may need to figure out > > > > if there's a weaker guarantee that's still useful. Do > > > > filesystems actually make ctime/mtime/i_version changes > > > > atomically with the changes that caused them? What if a > > > > change attribute is exposed to an NFS client but doesn't make > > > > it to disk, and then that value is reused after reboot? > > > > > > > > > > Yeah, there could be atomicity there. If we bump i_version, we'll mark > > > the inode dirty and I think that will end up with the new i_version at > > > least being journalled before __mark_inode_dirty returns. > > > > So you think the filesystem can provide the atomicity? In more detail: > > > > Sorry, I hit send too quickly. That should have read: > > "Yeah, there could be atomicity issues there." > > I think providing that level of atomicity may be difficult, though > maybe there's some way to make the querying of i_version block until > the inode update has been journalled? Just to complement what Dave said from ext4 side - similarly as with XFS ext4 doesn't guarantee atomicity unless fsync() has completed on the file. Until that you can see arbitrary combination of data & i_version after the crash. We do take care to keep data and metadata in sync only when there are security implications to that (like exposing uninitialized disk blocks) and if not, we are as lazy as we can to improve performance... Honza -- Jan Kara <jack@suse.com> SUSE Labs, CR
[toc] | [next] | [standalone]
| From | Jeff Layton <jlayton@redhat.com> |
|---|---|
| Date | 2017-03-29 20:00 +0200 |
| Subject | Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization |
| Message-ID | <tqq30-1Wd-27@gated-at.bofh.it> |
| In reply to | #1611832 |
On Wed, 2017-03-29 at 13:15 +0200, Jan Kara wrote: > On Tue 21-03-17 14:46:53, Jeff Layton wrote: > > On Tue, 2017-03-21 at 14:30 -0400, J. Bruce Fields wrote: > > > On Tue, Mar 21, 2017 at 01:23:24PM -0400, Jeff Layton wrote: > > > > On Tue, 2017-03-21 at 12:30 -0400, J. Bruce Fields wrote: > > > > > - It's durable; the above comparison still works if there were reboots > > > > > between the two i_version checks. > > > > > - I don't know how realistic this is--we may need to figure out > > > > > if there's a weaker guarantee that's still useful. Do > > > > > filesystems actually make ctime/mtime/i_version changes > > > > > atomically with the changes that caused them? What if a > > > > > change attribute is exposed to an NFS client but doesn't make > > > > > it to disk, and then that value is reused after reboot? > > > > > > > > > > > > > Yeah, there could be atomicity there. If we bump i_version, we'll mark > > > > the inode dirty and I think that will end up with the new i_version at > > > > least being journalled before __mark_inode_dirty returns. > > > > > > So you think the filesystem can provide the atomicity? In more detail: > > > > > > > Sorry, I hit send too quickly. That should have read: > > > > "Yeah, there could be atomicity issues there." > > > > I think providing that level of atomicity may be difficult, though > > maybe there's some way to make the querying of i_version block until > > the inode update has been journalled? > > Just to complement what Dave said from ext4 side - similarly as with XFS > ext4 doesn't guarantee atomicity unless fsync() has completed on the file. > Until that you can see arbitrary combination of data & i_version after the > crash. We do take care to keep data and metadata in sync only when there > are security implications to that (like exposing uninitialized disk blocks) > and if not, we are as lazy as we can to improve performance... > > Yeah, I think what we'll have to do here is ensure that those filesystems do an fsync prior to reporting the i_version getattr codepath. It's not pretty, but I don't see a real alternative. -- Jeff Layton <jlayton@redhat.com>
[toc] | [prev] | [next] | [standalone]
| From | Dave Chinner <david@fromorbit.com> |
|---|---|
| Date | 2017-03-30 01:50 +0200 |
| Message-ID | <tqvvH-5PF-7@gated-at.bofh.it> |
| In reply to | #1612216 |
On Wed, Mar 29, 2017 at 01:54:31PM -0400, Jeff Layton wrote: > On Wed, 2017-03-29 at 13:15 +0200, Jan Kara wrote: > > On Tue 21-03-17 14:46:53, Jeff Layton wrote: > > > On Tue, 2017-03-21 at 14:30 -0400, J. Bruce Fields wrote: > > > > On Tue, Mar 21, 2017 at 01:23:24PM -0400, Jeff Layton wrote: > > > > > On Tue, 2017-03-21 at 12:30 -0400, J. Bruce Fields wrote: > > > > > > - It's durable; the above comparison still works if there were reboots > > > > > > between the two i_version checks. > > > > > > - I don't know how realistic this is--we may need to figure out > > > > > > if there's a weaker guarantee that's still useful. Do > > > > > > filesystems actually make ctime/mtime/i_version changes > > > > > > atomically with the changes that caused them? What if a > > > > > > change attribute is exposed to an NFS client but doesn't make > > > > > > it to disk, and then that value is reused after reboot? > > > > > > > > > > > > > > > > Yeah, there could be atomicity there. If we bump i_version, we'll mark > > > > > the inode dirty and I think that will end up with the new i_version at > > > > > least being journalled before __mark_inode_dirty returns. > > > > > > > > So you think the filesystem can provide the atomicity? In more detail: > > > > > > > > > > Sorry, I hit send too quickly. That should have read: > > > > > > "Yeah, there could be atomicity issues there." > > > > > > I think providing that level of atomicity may be difficult, though > > > maybe there's some way to make the querying of i_version block until > > > the inode update has been journalled? > > > > Just to complement what Dave said from ext4 side - similarly as with XFS > > ext4 doesn't guarantee atomicity unless fsync() has completed on the file. > > Until that you can see arbitrary combination of data & i_version after the > > crash. We do take care to keep data and metadata in sync only when there > > are security implications to that (like exposing uninitialized disk blocks) > > and if not, we are as lazy as we can to improve performance... > > > > > > Yeah, I think what we'll have to do here is ensure that those > filesystems do an fsync prior to reporting the i_version getattr > codepath. It's not pretty, but I don't see a real alternative. I think that's even more problematic. ->getattr currently runs completely unlocked for performance reasons - it's racy w.r.t. to ongoing modifications to begin with, so /nothing/ that is returned to userspace via stat/statx can be guaranteed to be "coherent". Linus will be very unhappy if you make his git workload (which is /very/ stat heavy) run slower by adding any sort of locking in this hot path. Even if we did put an fsync() into ->getattr() (and dealt with all the locking issues that entails), by the time the statx syscall returns to userspace the i_version value may not match the data/metadata in the inode(*). IOWs, by the time i_version gets to userspace, it is out of date and any use of it for data versioning from userspace is going to be prone to race conditions. Cheers, Dave. (*) fiemap has exactly the same "stale the moment internal fs locks are released" race conditions, which is why it cannot safely be used for mapping holes when copying file data.... -- Dave Chinner david@fromorbit.com
[toc] | [prev] | [next] | [standalone]
| From | Jeff Layton <jlayton@redhat.com> |
|---|---|
| Date | 2017-03-30 13:30 +0200 |
| Subject | Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization |
| Message-ID | <tqGr8-5AE-7@gated-at.bofh.it> |
| In reply to | #1612450 |
On Thu, 2017-03-30 at 10:41 +1100, Dave Chinner wrote: > On Wed, Mar 29, 2017 at 01:54:31PM -0400, Jeff Layton wrote: > > On Wed, 2017-03-29 at 13:15 +0200, Jan Kara wrote: > > > On Tue 21-03-17 14:46:53, Jeff Layton wrote: > > > > On Tue, 2017-03-21 at 14:30 -0400, J. Bruce Fields wrote: > > > > > On Tue, Mar 21, 2017 at 01:23:24PM -0400, Jeff Layton wrote: > > > > > > On Tue, 2017-03-21 at 12:30 -0400, J. Bruce Fields wrote: > > > > > > > - It's durable; the above comparison still works if there were reboots > > > > > > > between the two i_version checks. > > > > > > > - I don't know how realistic this is--we may need to figure out > > > > > > > if there's a weaker guarantee that's still useful. Do > > > > > > > filesystems actually make ctime/mtime/i_version changes > > > > > > > atomically with the changes that caused them? What if a > > > > > > > change attribute is exposed to an NFS client but doesn't make > > > > > > > it to disk, and then that value is reused after reboot? > > > > > > > > > > > > > > > > > > > Yeah, there could be atomicity there. If we bump i_version, we'll mark > > > > > > the inode dirty and I think that will end up with the new i_version at > > > > > > least being journalled before __mark_inode_dirty returns. > > > > > > > > > > So you think the filesystem can provide the atomicity? In more detail: > > > > > > > > > > > > > Sorry, I hit send too quickly. That should have read: > > > > > > > > "Yeah, there could be atomicity issues there." > > > > > > > > I think providing that level of atomicity may be difficult, though > > > > maybe there's some way to make the querying of i_version block until > > > > the inode update has been journalled? > > > > > > Just to complement what Dave said from ext4 side - similarly as with XFS > > > ext4 doesn't guarantee atomicity unless fsync() has completed on the file. > > > Until that you can see arbitrary combination of data & i_version after the > > > crash. We do take care to keep data and metadata in sync only when there > > > are security implications to that (like exposing uninitialized disk blocks) > > > and if not, we are as lazy as we can to improve performance... > > > > > > > > > > Yeah, I think what we'll have to do here is ensure that those > > filesystems do an fsync prior to reporting the i_version getattr > > codepath. It's not pretty, but I don't see a real alternative. > > I think that's even more problematic. ->getattr currently runs > completely unlocked for performance reasons - it's racy w.r.t. to > ongoing modifications to begin with, so /nothing/ that is returned > to userspace via stat/statx can be guaranteed to be "coherent". > Linus will be very unhappy if you make his git workload (which is > /very/ stat heavy) run slower by adding any sort of locking in this > hot path. > > Even if we did put an fsync() into ->getattr() (and dealt with all > the locking issues that entails), by the time the statx syscall > returns to userspace the i_version value may not match the > data/metadata in the inode(*). IOWs, by the time i_version gets > to userspace, it is out of date and any use of it for data > versioning from userspace is going to be prone to race conditions. > > Cheers, > > Dave. > > (*) fiemap has exactly the same "stale the moment internal fs > locks are released" race conditions, which is why it cannot safely > be used for mapping holes when copying file data.... > FWIW, I'm not terribly worried about atomicity for all of the reasons you describe. My main concern is reusing an i_version value that has already been handed out when the inode is now in an entirely different state. To that end, I was only considering doing an fsync iff STATX_VERSION was requested. If it wasn't we wouldn't need to do one. A lot of ->getattr implementations already call filemap_write_and_wait, but you're correct that flushing out the metadata is different matter. It'd be nice to avoid that if we can. -- Jeff Layton <jlayton@redhat.com>
[toc] | [prev] | [next] | [standalone]
| From | "J. Bruce Fields" <bfields@fieldses.org> |
|---|---|
| Date | 2017-04-04 20:40 +0200 |
| Message-ID | <tsBwZ-ao-1@gated-at.bofh.it> |
| In reply to | #1612450 |
On Thu, Mar 30, 2017 at 10:41:37AM +1100, Dave Chinner wrote: > On Wed, Mar 29, 2017 at 01:54:31PM -0400, Jeff Layton wrote: > > On Wed, 2017-03-29 at 13:15 +0200, Jan Kara wrote: > > > On Tue 21-03-17 14:46:53, Jeff Layton wrote: > > > > On Tue, 2017-03-21 at 14:30 -0400, J. Bruce Fields wrote: > > > > > On Tue, Mar 21, 2017 at 01:23:24PM -0400, Jeff Layton wrote: > > > > > > On Tue, 2017-03-21 at 12:30 -0400, J. Bruce Fields wrote: > > > > > > > - It's durable; the above comparison still works if there were reboots > > > > > > > between the two i_version checks. > > > > > > > - I don't know how realistic this is--we may need to figure out > > > > > > > if there's a weaker guarantee that's still useful. Do > > > > > > > filesystems actually make ctime/mtime/i_version changes > > > > > > > atomically with the changes that caused them? What if a > > > > > > > change attribute is exposed to an NFS client but doesn't make > > > > > > > it to disk, and then that value is reused after reboot? > > > > > > > > > > > > > > > > > > > Yeah, there could be atomicity there. If we bump i_version, we'll mark > > > > > > the inode dirty and I think that will end up with the new i_version at > > > > > > least being journalled before __mark_inode_dirty returns. > > > > > > > > > > So you think the filesystem can provide the atomicity? In more detail: > > > > > > > > > > > > > Sorry, I hit send too quickly. That should have read: > > > > > > > > "Yeah, there could be atomicity issues there." > > > > > > > > I think providing that level of atomicity may be difficult, though > > > > maybe there's some way to make the querying of i_version block until > > > > the inode update has been journalled? > > > > > > Just to complement what Dave said from ext4 side - similarly as with XFS > > > ext4 doesn't guarantee atomicity unless fsync() has completed on the file. > > > Until that you can see arbitrary combination of data & i_version after the > > > crash. We do take care to keep data and metadata in sync only when there > > > are security implications to that (like exposing uninitialized disk blocks) > > > and if not, we are as lazy as we can to improve performance... > > > > > > > > > > Yeah, I think what we'll have to do here is ensure that those > > filesystems do an fsync prior to reporting the i_version getattr > > codepath. It's not pretty, but I don't see a real alternative. > > I think that's even more problematic. ->getattr currently runs > completely unlocked for performance reasons - it's racy w.r.t. to > ongoing modifications to begin with, so /nothing/ that is returned > to userspace via stat/statx can be guaranteed to be "coherent". > Linus will be very unhappy if you make his git workload (which is > /very/ stat heavy) run slower by adding any sort of locking in this > hot path. > > Even if we did put an fsync() into ->getattr() (and dealt with all > the locking issues that entails), by the time the statx syscall > returns to userspace the i_version value may not match the > data/metadata in the inode(*). IOWs, by the time i_version gets > to userspace, it is out of date and any use of it for data > versioning from userspace is going to be prone to race conditions. A slightly out-of-date i_version is fine, I think. It's just the reverse we want to avoid. E.g., assuming an i_version-supporting statux, if somebody could called statx then read, and got the new i_version followed by the old data, that would cause problems. --b.
[toc] | [prev] | [next] | [standalone]
| From | Jan Kara <jack@suse.cz> |
|---|---|
| Date | 2017-03-30 08:50 +0200 |
| Message-ID | <tqC49-2hn-9@gated-at.bofh.it> |
| In reply to | #1612216 |
On Wed 29-03-17 13:54:31, Jeff Layton wrote: > On Wed, 2017-03-29 at 13:15 +0200, Jan Kara wrote: > > On Tue 21-03-17 14:46:53, Jeff Layton wrote: > > > On Tue, 2017-03-21 at 14:30 -0400, J. Bruce Fields wrote: > > > > On Tue, Mar 21, 2017 at 01:23:24PM -0400, Jeff Layton wrote: > > > > > On Tue, 2017-03-21 at 12:30 -0400, J. Bruce Fields wrote: > > > > > > - It's durable; the above comparison still works if there were reboots > > > > > > between the two i_version checks. > > > > > > - I don't know how realistic this is--we may need to figure out > > > > > > if there's a weaker guarantee that's still useful. Do > > > > > > filesystems actually make ctime/mtime/i_version changes > > > > > > atomically with the changes that caused them? What if a > > > > > > change attribute is exposed to an NFS client but doesn't make > > > > > > it to disk, and then that value is reused after reboot? > > > > > > > > > > > > > > > > Yeah, there could be atomicity there. If we bump i_version, we'll mark > > > > > the inode dirty and I think that will end up with the new i_version at > > > > > least being journalled before __mark_inode_dirty returns. > > > > > > > > So you think the filesystem can provide the atomicity? In more detail: > > > > > > > > > > Sorry, I hit send too quickly. That should have read: > > > > > > "Yeah, there could be atomicity issues there." > > > > > > I think providing that level of atomicity may be difficult, though > > > maybe there's some way to make the querying of i_version block until > > > the inode update has been journalled? > > > > Just to complement what Dave said from ext4 side - similarly as with XFS > > ext4 doesn't guarantee atomicity unless fsync() has completed on the file. > > Until that you can see arbitrary combination of data & i_version after the > > crash. We do take care to keep data and metadata in sync only when there > > are security implications to that (like exposing uninitialized disk blocks) > > and if not, we are as lazy as we can to improve performance... > > > > > > Yeah, I think what we'll have to do here is ensure that those > filesystems do an fsync prior to reporting the i_version getattr > codepath. It's not pretty, but I don't see a real alternative. Hum, so are we fine if i_version just changes (increases) for all inodes after a server crash? If I understand its use right, it would mean invalidation of all client's caches but that is not such a big deal given how frequent server crashes should be, right? Because if above is acceptable we could make reported i_version to be a sum of "superblock crash counter" and "inode i_version". We increment "superblock crash counter" whenever we detect unclean filesystem shutdown. That way after a crash we are guaranteed each inode will report new i_version (the sum would probably have to look like "superblock crash counter" * 65536 + "inode i_version" so that we avoid reusing possible i_version numbers we gave away but did not write to disk but still...). Thoughts? Honza -- Jan Kara <jack@suse.com> SUSE Labs, CR
[toc] | [prev] | [next] | [standalone]
| From | Jeff Layton <jlayton@redhat.com> |
|---|---|
| Date | 2017-03-30 13:20 +0200 |
| Subject | Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization |
| Message-ID | <tqGhs-5vQ-15@gated-at.bofh.it> |
| In reply to | #1612595 |
On Thu, 2017-03-30 at 08:47 +0200, Jan Kara wrote: > On Wed 29-03-17 13:54:31, Jeff Layton wrote: > > On Wed, 2017-03-29 at 13:15 +0200, Jan Kara wrote: > > > On Tue 21-03-17 14:46:53, Jeff Layton wrote: > > > > On Tue, 2017-03-21 at 14:30 -0400, J. Bruce Fields wrote: > > > > > On Tue, Mar 21, 2017 at 01:23:24PM -0400, Jeff Layton wrote: > > > > > > On Tue, 2017-03-21 at 12:30 -0400, J. Bruce Fields wrote: > > > > > > > - It's durable; the above comparison still works if there were reboots > > > > > > > between the two i_version checks. > > > > > > > - I don't know how realistic this is--we may need to figure out > > > > > > > if there's a weaker guarantee that's still useful. Do > > > > > > > filesystems actually make ctime/mtime/i_version changes > > > > > > > atomically with the changes that caused them? What if a > > > > > > > change attribute is exposed to an NFS client but doesn't make > > > > > > > it to disk, and then that value is reused after reboot? > > > > > > > > > > > > > > > > > > > Yeah, there could be atomicity there. If we bump i_version, we'll mark > > > > > > the inode dirty and I think that will end up with the new i_version at > > > > > > least being journalled before __mark_inode_dirty returns. > > > > > > > > > > So you think the filesystem can provide the atomicity? In more detail: > > > > > > > > > > > > > Sorry, I hit send too quickly. That should have read: > > > > > > > > "Yeah, there could be atomicity issues there." > > > > > > > > I think providing that level of atomicity may be difficult, though > > > > maybe there's some way to make the querying of i_version block until > > > > the inode update has been journalled? > > > > > > Just to complement what Dave said from ext4 side - similarly as with XFS > > > ext4 doesn't guarantee atomicity unless fsync() has completed on the file. > > > Until that you can see arbitrary combination of data & i_version after the > > > crash. We do take care to keep data and metadata in sync only when there > > > are security implications to that (like exposing uninitialized disk blocks) > > > and if not, we are as lazy as we can to improve performance... > > > > > > > > > > Yeah, I think what we'll have to do here is ensure that those > > filesystems do an fsync prior to reporting the i_version getattr > > codepath. It's not pretty, but I don't see a real alternative. > > Hum, so are we fine if i_version just changes (increases) for all inodes > after a server crash? If I understand its use right, it would mean > invalidation of all client's caches but that is not such a big deal given > how frequent server crashes should be, right? > > Because if above is acceptable we could make reported i_version to be a sum > of "superblock crash counter" and "inode i_version". We increment > "superblock crash counter" whenever we detect unclean filesystem shutdown. > That way after a crash we are guaranteed each inode will report new > i_version (the sum would probably have to look like "superblock crash > counter" * 65536 + "inode i_version" so that we avoid reusing possible > i_version numbers we gave away but did not write to disk but still...). > Thoughts? > That does sound like a good idea. This is a 64 bit value, so we should be able to carve out some upper bits for a crash counter without risking wrapping. The other constraint here is that we'd like any later version of the counter to be larger than any earlier value that was handed out. I think this idea would still satisfy that. -- Jeff Layton <jlayton@redhat.com>
[toc] | [prev] | [next] | [standalone]
| From | "J. Bruce Fields" <bfields@fieldses.org> |
|---|---|
| Date | 2017-03-30 18:20 +0200 |
| Message-ID | <tqKXN-ry-21@gated-at.bofh.it> |
| In reply to | #1612968 |
On Thu, Mar 30, 2017 at 07:11:48AM -0400, Jeff Layton wrote: > On Thu, 2017-03-30 at 08:47 +0200, Jan Kara wrote: > > Hum, so are we fine if i_version just changes (increases) for all inodes > > after a server crash? If I understand its use right, it would mean > > invalidation of all client's caches but that is not such a big deal given > > how frequent server crashes should be, right? Even if it's rare, it may be really painful when all your clients are forced to throw out and repopulate their caches after a crash. But, yes, maybe we can live with it. > > Because if above is acceptable we could make reported i_version to be a sum > > of "superblock crash counter" and "inode i_version". We increment > > "superblock crash counter" whenever we detect unclean filesystem shutdown. > > That way after a crash we are guaranteed each inode will report new > > i_version (the sum would probably have to look like "superblock crash > > counter" * 65536 + "inode i_version" so that we avoid reusing possible > > i_version numbers we gave away but did not write to disk but still...). > > Thoughts? How hard is this for filesystems to support? Do they need an on-disk format change to keep track of the crash counter? Maybe not, maybe the high bits of the i_version counters are all they need. > That does sound like a good idea. This is a 64 bit value, so we should > be able to carve out some upper bits for a crash counter without risking > wrapping. > > The other constraint here is that we'd like any later version of the > counter to be larger than any earlier value that was handed out. I think > this idea would still satisfy that. I guess we just want to have some back-of-the-envelope estimates of maximum number of i_version increments possible between crashes and maximum number of crashes possible over lifetime of a filesystem, to decide how to split up the bits. I wonder if we could get away with using the new crash counter only for *new* values of the i_version? After a crash, use the on disk i_version as is, and put off using the new crash counter until the next time the file's modified. That would still eliminate the risk of accidental reuse of an old i_version value. It still leaves some cases where the client could fail to notice an update indefinitely. All these cases I think have to assume that a writer made some changes that it failed to ever sync, so as long as we care only about close-to-open semantics perhaps those cases don't matter. I wonder if repeated crashes can lead to any odd corner cases. --b.
[toc] | [prev] | [next] | [standalone]
| From | Jeff Layton <jlayton@redhat.com> |
|---|---|
| Date | 2017-03-30 20:40 +0200 |
| Subject | Re: [RFC PATCH v1 00/30] fs: inode->i_version rework and optimization |
| Message-ID | <tqN9f-246-17@gated-at.bofh.it> |
| In reply to | #1613263 |
On Thu, 2017-03-30 at 12:12 -0400, J. Bruce Fields wrote: > On Thu, Mar 30, 2017 at 07:11:48AM -0400, Jeff Layton wrote: > > On Thu, 2017-03-30 at 08:47 +0200, Jan Kara wrote: > > > Hum, so are we fine if i_version just changes (increases) for all inodes > > > after a server crash? If I understand its use right, it would mean > > > invalidation of all client's caches but that is not such a big deal given > > > how frequent server crashes should be, right? > > Even if it's rare, it may be really painful when all your clients are > forced to throw out and repopulate their caches after a crash. But, > yes, maybe we can live with it. > Yeah, assuming that normal reboots wouldn't cause this, then I don't see it as being too bad. > > > Because if above is acceptable we could make reported i_version to be a sum > > > of "superblock crash counter" and "inode i_version". We increment > > > "superblock crash counter" whenever we detect unclean filesystem shutdown. > > > That way after a crash we are guaranteed each inode will report new > > > i_version (the sum would probably have to look like "superblock crash > > > counter" * 65536 + "inode i_version" so that we avoid reusing possible > > > i_version numbers we gave away but did not write to disk but still...). > > > Thoughts? > > How hard is this for filesystems to support? Do they need an on-disk > format change to keep track of the crash counter? Maybe not, maybe the > high bits of the i_version counters are all they need. > Yeah, I imagine we'd need a on-disk change for this unless there's something already present that we could use in place of a crash counter. > > That does sound like a good idea. This is a 64 bit value, so we should > > be able to carve out some upper bits for a crash counter without risking > > wrapping. > > > > The other constraint here is that we'd like any later version of the > > counter to be larger than any earlier value that was handed out. I think > > this idea would still satisfy that. > > I guess we just want to have some back-of-the-envelope estimates of > maximum number of i_version increments possible between crashes and > maximum number of crashes possible over lifetime of a filesystem, to > decide how to split up the bits. > > I wonder if we could get away with using the new crash counter only for > *new* values of the i_version? After a crash, use the on disk i_version > as is, and put off using the new crash counter until the next time the > file's modified. > That sounds difficult to get right. Suppose I have an inode that has not been updated in a long time. Someone writes to it and then queries the i_version. How do I know whether there were crashes since the last time I updated it? Or am I misunderstanding what you're proposing here? > That would still eliminate the risk of accidental reuse of an old > i_version value. It still leaves some cases where the client could fail > to notice an update indefinitely. All these cases I think have to > assume that a writer made some changes that it failed to ever sync, so > as long as we care only about close-to-open semantics perhaps those > cases don't matter. > > I wonder if repeated crashes can lead to any odd corner cases. > -- Jeff Layton <jlayton@redhat.com>
[toc] | [prev] | [next] | [standalone]
| From | Boaz Harrosh <openosd@gmail.com> |
|---|---|
| Date | 2017-03-30 23:20 +0200 |
| Message-ID | <tqPE6-3Oq-13@gated-at.bofh.it> |
| In reply to | #1613356 |
On 03/30/2017 09:35 PM, Jeff Layton wrote: <> > Yeah, I imagine we'd need a on-disk change for this unless there's > something already present that we could use in place of a crash counter. > Perhaps we can use s_mtime and/or s_wtime in some way, I'm not sure what is a parallel for that in xfs. s_mtime - time-of-last mount s_wtime - time-of-last mount, umount, freez, unfreez, remount, ... Of course you'll need a per FS vector to access that. But this will need some math foo to get the bits compacted correctly just a thought. Thanks Boaz
[toc] | [prev] | [next] | [standalone]
| From | "J. Bruce Fields" <bfields@fieldses.org> |
|---|---|
| Date | 2017-04-04 20:40 +0200 |
| Message-ID | <tsBx1-ao-37@gated-at.bofh.it> |
| In reply to | #1613356 |
On Thu, Mar 30, 2017 at 02:35:32PM -0400, Jeff Layton wrote: > On Thu, 2017-03-30 at 12:12 -0400, J. Bruce Fields wrote: > > On Thu, Mar 30, 2017 at 07:11:48AM -0400, Jeff Layton wrote: > > > On Thu, 2017-03-30 at 08:47 +0200, Jan Kara wrote: > > > > Because if above is acceptable we could make reported i_version to be a sum > > > > of "superblock crash counter" and "inode i_version". We increment > > > > "superblock crash counter" whenever we detect unclean filesystem shutdown. > > > > That way after a crash we are guaranteed each inode will report new > > > > i_version (the sum would probably have to look like "superblock crash > > > > counter" * 65536 + "inode i_version" so that we avoid reusing possible > > > > i_version numbers we gave away but did not write to disk but still...). > > > > Thoughts? > > > > How hard is this for filesystems to support? Do they need an on-disk > > format change to keep track of the crash counter? Maybe not, maybe the > > high bits of the i_version counters are all they need. > > > > Yeah, I imagine we'd need a on-disk change for this unless there's > something already present that we could use in place of a crash counter. We could consider using the current time instead. So, put the current time (or time of last boot, or this inode's ctime, or something) in the high bits of the change attribute, and keep the low bits as a counter. Then as long as we trust our clock, we're no longer at risk of reusing an i_version value. > > I guess we just want to have some back-of-the-envelope estimates of > > maximum number of i_version increments possible between crashes and > > maximum number of crashes possible over lifetime of a filesystem, to > > decide how to split up the bits. > > > > I wonder if we could get away with using the new crash counter only for > > *new* values of the i_version? After a crash, use the on disk i_version > > as is, and put off using the new crash counter until the next time the > > file's modified. > > > > That sounds difficult to get right. Suppose I have an inode that has not > been updated in a long time. Someone writes to it and then queries the > i_version. How do I know whether there were crashes since the last time > I updated it? Or am I misunderstanding what you're proposing here? I believe Jan was suggesting that we keep the i_version as-is on disk but combine with with the crash counter when it's queried. I was suggesting instead that on write, when we bump the i_version, we replace the simple increment by something that increments *and* sticks the current crash counter (or maybe just a time) in the high bits. And that combination will be what goes in i_version and is written to disk. That guarantees that we never reuse an old value when we increment. It also avoids having to invalidate absolutely every cache, even of completely static files. Clients could still see the change attribute go backwards, though, if they query a file with dirty data and the server crashes before it writes out the new change attribute. Also, they could fail to detect data that reverted after boot if they cache data while the file's dirty on the server side, and the server crash preserves the i_version update but not the new data. Presumably both are possible already for ctime (depending on the filesystem), and I'm not convinced they're a big problem. In both cases the reading client is caching while somebody's still writing, and as long as the writer comes back and finishes its job, readers will thereafter see the right thing. So I think it's adequate for close-to-open. --b.
[toc] | [prev] | [next] | [standalone]
| From | NeilBrown <neil@brown.name> |
|---|---|
| Date | 2017-04-05 03:50 +0200 |
| Message-ID | <tsIf7-4p7-7@gated-at.bofh.it> |
| In reply to | #1616316 |
[Multipart message — attachments visible in raw view] — view raw
On Tue, Apr 04 2017, J. Bruce Fields wrote: > On Thu, Mar 30, 2017 at 02:35:32PM -0400, Jeff Layton wrote: >> On Thu, 2017-03-30 at 12:12 -0400, J. Bruce Fields wrote: >> > On Thu, Mar 30, 2017 at 07:11:48AM -0400, Jeff Layton wrote: >> > > On Thu, 2017-03-30 at 08:47 +0200, Jan Kara wrote: >> > > > Because if above is acceptable we could make reported i_version to be a sum >> > > > of "superblock crash counter" and "inode i_version". We increment >> > > > "superblock crash counter" whenever we detect unclean filesystem shutdown. >> > > > That way after a crash we are guaranteed each inode will report new >> > > > i_version (the sum would probably have to look like "superblock crash >> > > > counter" * 65536 + "inode i_version" so that we avoid reusing possible >> > > > i_version numbers we gave away but did not write to disk but still...). >> > > > Thoughts? >> > >> > How hard is this for filesystems to support? Do they need an on-disk >> > format change to keep track of the crash counter? Maybe not, maybe the >> > high bits of the i_version counters are all they need. >> > >> >> Yeah, I imagine we'd need a on-disk change for this unless there's >> something already present that we could use in place of a crash counter. > > We could consider using the current time instead. So, put the current > time (or time of last boot, or this inode's ctime, or something) in the > high bits of the change attribute, and keep the low bits as a counter. This is a very different proposal. I don't think Jan was suggesting that the i_version be split into two bit fields, one the change-counter and one the crash-counter. Rather, the crash-counter was multiplied by a large-number and added to the change-counter with the expectation that while not ever change-counter landed on disk, at least 1 in every large-number would. So after each crash we effectively add large-number to the change-counter, and can be sure that number hasn't been used already. To store the crash-counter in each inode (which does appeal) you would need to be able to remove it before adding the new crash counter, and that requires bit-fields. Maybe there are enough bits. If you want to ensure read-only files can remain cached over a crash, then you would have to mark a file in some way on stable storage *before* allowing any change. e.g. you could use the lsb. Odd i_versions might have been changed recently and crash-count*large-number needs to be added. Even i_versions have not been changed recently and nothing need be added. If you want to change a file with an even i_version, you subtract crash-count*large-number to the i_version, then set lsb. This is written to stable storage before the change. If a file has not been changed for a while, you can add crash-count*large-number and clear lsb. The lsb of the i_version would be for internal use only. It would not be visible outside the filesystem. It feels a bit clunky, but I think it would work and is the best combination of Jan's idea and your requirement. The biggest cost would be switching to 'odd' before an changes, and the unknown is when does it make sense to switch to 'even'. NeilBrown
[toc] | [prev] | [next] | [standalone]
| From | Jan Kara <jack@suse.cz> |
|---|---|
| Date | 2017-04-05 10:10 +0200 |
| Message-ID | <tsOaS-5c-25@gated-at.bofh.it> |
| In reply to | #1616497 |
On Wed 05-04-17 11:43:32, NeilBrown wrote:
> On Tue, Apr 04 2017, J. Bruce Fields wrote:
>
> > On Thu, Mar 30, 2017 at 02:35:32PM -0400, Jeff Layton wrote:
> >> On Thu, 2017-03-30 at 12:12 -0400, J. Bruce Fields wrote:
> >> > On Thu, Mar 30, 2017 at 07:11:48AM -0400, Jeff Layton wrote:
> >> > > On Thu, 2017-03-30 at 08:47 +0200, Jan Kara wrote:
> >> > > > Because if above is acceptable we could make reported i_version to be a sum
> >> > > > of "superblock crash counter" and "inode i_version". We increment
> >> > > > "superblock crash counter" whenever we detect unclean filesystem shutdown.
> >> > > > That way after a crash we are guaranteed each inode will report new
> >> > > > i_version (the sum would probably have to look like "superblock crash
> >> > > > counter" * 65536 + "inode i_version" so that we avoid reusing possible
> >> > > > i_version numbers we gave away but did not write to disk but still...).
> >> > > > Thoughts?
> >> >
> >> > How hard is this for filesystems to support? Do they need an on-disk
> >> > format change to keep track of the crash counter? Maybe not, maybe the
> >> > high bits of the i_version counters are all they need.
> >> >
> >>
> >> Yeah, I imagine we'd need a on-disk change for this unless there's
> >> something already present that we could use in place of a crash counter.
> >
> > We could consider using the current time instead. So, put the current
> > time (or time of last boot, or this inode's ctime, or something) in the
> > high bits of the change attribute, and keep the low bits as a counter.
>
> This is a very different proposal.
> I don't think Jan was suggesting that the i_version be split into two
> bit fields, one the change-counter and one the crash-counter.
> Rather, the crash-counter was multiplied by a large-number and added to
> the change-counter with the expectation that while not ever
> change-counter landed on disk, at least 1 in every large-number would.
> So after each crash we effectively add large-number to the
> change-counter, and can be sure that number hasn't been used already.
Yes, that was my thinking.
> To store the crash-counter in each inode (which does appeal) you would
> need to be able to remove it before adding the new crash counter, and
> that requires bit-fields. Maybe there are enough bits.
Furthermore you'd have a potential problem that you need to change
i_version on disk just because you are reading after a crash and such
changes tend to be problematic (think of read-only mounts and stuff like
that).
> If you want to ensure read-only files can remain cached over a crash,
> then you would have to mark a file in some way on stable storage
> *before* allowing any change.
> e.g. you could use the lsb. Odd i_versions might have been changed
> recently and crash-count*large-number needs to be added.
> Even i_versions have not been changed recently and nothing need be
> added.
>
> If you want to change a file with an even i_version, you subtract
> crash-count*large-number
> to the i_version, then set lsb. This is written to stable storage before
> the change.
>
> If a file has not been changed for a while, you can add
> crash-count*large-number
> and clear lsb.
>
> The lsb of the i_version would be for internal use only. It would not
> be visible outside the filesystem.
>
> It feels a bit clunky, but I think it would work and is the best
> combination of Jan's idea and your requirement.
> The biggest cost would be switching to 'odd' before an changes, and the
> unknown is when does it make sense to switch to 'even'.
Well, there is also a problem that you would need to somehow remember with
which 'crash count' the i_version has been previously reported as that is
not stored on disk with my scheme. So I don't think we can easily use your
scheme.
So the options we have are:
1) Keep i_version as is, make clients also check for i_ctime.
Pro: No on-disk format changes.
Cons: After a crash, i_version can go backwards (but when file changes
i_version, i_ctime pair should be still different) or not, data can be
old or not.
2) Fsync when reporting i_version.
Pro: No on-disk format changes, strong consistency of i_version and
data.
Cons: Difficult to implement for filesystems due to locking constrains.
High performance overhead or i_version reporting.
3) Some variant of crash counter.
Pro: i_version cannot go backwards.
Cons: Requires on-disk format changes. After a crash data can be old
(however i_version increased).
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
[toc] | [prev] | [next] | [standalone]
| From | "J. Bruce Fields" <bfields@fieldses.org> |
|---|---|
| Date | 2017-04-05 20:20 +0200 |
| Message-ID | <tsXHc-66T-25@gated-at.bofh.it> |
| In reply to | #1616673 |
On Wed, Apr 05, 2017 at 10:05:51AM +0200, Jan Kara wrote: > 1) Keep i_version as is, make clients also check for i_ctime. That would be a protocol revision, which we'd definitely rather avoid. But can't we accomplish the same by using something like ctime * (some constant) + i_version ? > Pro: No on-disk format changes. > Cons: After a crash, i_version can go backwards (but when file changes > i_version, i_ctime pair should be still different) or not, data can be > old or not. This is probably good enough for NFS purposes: typically on an NFS filesystem, results of a read in the face of a concurrent write open are undefined. And writers sync before close. So after a crash with a dirty inode, we're in a situation where an NFS client still needs to resend some writes, sync, and close. I'm OK with things being inconsistent during this window. I do expect things to return to normal once that client's has resent its writes--hence the worry about actually resuing old values after boot (such as if i_version regresses on boot and then increments back to the same value after further writes). Factoring in ctime fixes that. > 2) Fsync when reporting i_version. > Pro: No on-disk format changes, strong consistency of i_version and > data. > Cons: Difficult to implement for filesystems due to locking constrains. > High performance overhead or i_version reporting. Sounds painful. > 3) Some variant of crash counter. > Pro: i_version cannot go backwards. > Cons: Requires on-disk format changes. After a crash data can be old > (however i_version increased). Also, some unnecessary invalidations. Which maybe can be mostly avoided by some variation of Neil's scheme. It looks to me like option (1) is doable now and introduces no regressions compared to the current situation. (2) and (3) are more copmlicated and involve some tradeoffs. Also, we can implement (1) and switch to (2) or (3) later. We'd want to do it without reported i_versions decreasing on kernel upgrade, but there are multiple ways of handling that. (Worst case, just restrict the change to newly created filesystems.) --b.
[toc] | [prev] | [next] | [standalone]
| From | NeilBrown <neil@brown.name> |
|---|---|
| Date | 2017-04-06 03:20 +0200 |
| Message-ID | <tt4fD-1IR-3@gated-at.bofh.it> |
| In reply to | #1616673 |
[Multipart message — attachments visible in raw view] — view raw
On Wed, Apr 05 2017, Jan Kara wrote:
> On Wed 05-04-17 11:43:32, NeilBrown wrote:
>> On Tue, Apr 04 2017, J. Bruce Fields wrote:
>>
>> > On Thu, Mar 30, 2017 at 02:35:32PM -0400, Jeff Layton wrote:
>> >> On Thu, 2017-03-30 at 12:12 -0400, J. Bruce Fields wrote:
>> >> > On Thu, Mar 30, 2017 at 07:11:48AM -0400, Jeff Layton wrote:
>> >> > > On Thu, 2017-03-30 at 08:47 +0200, Jan Kara wrote:
>> >> > > > Because if above is acceptable we could make reported i_version to be a sum
>> >> > > > of "superblock crash counter" and "inode i_version". We increment
>> >> > > > "superblock crash counter" whenever we detect unclean filesystem shutdown.
>> >> > > > That way after a crash we are guaranteed each inode will report new
>> >> > > > i_version (the sum would probably have to look like "superblock crash
>> >> > > > counter" * 65536 + "inode i_version" so that we avoid reusing possible
>> >> > > > i_version numbers we gave away but did not write to disk but still...).
>> >> > > > Thoughts?
>> >> >
>> >> > How hard is this for filesystems to support? Do they need an on-disk
>> >> > format change to keep track of the crash counter? Maybe not, maybe the
>> >> > high bits of the i_version counters are all they need.
>> >> >
>> >>
>> >> Yeah, I imagine we'd need a on-disk change for this unless there's
>> >> something already present that we could use in place of a crash counter.
>> >
>> > We could consider using the current time instead. So, put the current
>> > time (or time of last boot, or this inode's ctime, or something) in the
>> > high bits of the change attribute, and keep the low bits as a counter.
>>
>> This is a very different proposal.
>> I don't think Jan was suggesting that the i_version be split into two
>> bit fields, one the change-counter and one the crash-counter.
>> Rather, the crash-counter was multiplied by a large-number and added to
>> the change-counter with the expectation that while not ever
>> change-counter landed on disk, at least 1 in every large-number would.
>> So after each crash we effectively add large-number to the
>> change-counter, and can be sure that number hasn't been used already.
>
> Yes, that was my thinking.
>
>> To store the crash-counter in each inode (which does appeal) you would
>> need to be able to remove it before adding the new crash counter, and
>> that requires bit-fields. Maybe there are enough bits.
>
> Furthermore you'd have a potential problem that you need to change
> i_version on disk just because you are reading after a crash and such
> changes tend to be problematic (think of read-only mounts and stuff like
> that).
>
>> If you want to ensure read-only files can remain cached over a crash,
>> then you would have to mark a file in some way on stable storage
>> *before* allowing any change.
>> e.g. you could use the lsb. Odd i_versions might have been changed
>> recently and crash-count*large-number needs to be added.
>> Even i_versions have not been changed recently and nothing need be
>> added.
>>
>> If you want to change a file with an even i_version, you subtract
>> crash-count*large-number
>> to the i_version, then set lsb. This is written to stable storage before
>> the change.
>>
>> If a file has not been changed for a while, you can add
>> crash-count*large-number
>> and clear lsb.
>>
>> The lsb of the i_version would be for internal use only. It would not
>> be visible outside the filesystem.
>>
>> It feels a bit clunky, but I think it would work and is the best
>> combination of Jan's idea and your requirement.
>> The biggest cost would be switching to 'odd' before an changes, and the
>> unknown is when does it make sense to switch to 'even'.
>
> Well, there is also a problem that you would need to somehow remember with
> which 'crash count' the i_version has been previously reported as that is
> not stored on disk with my scheme. So I don't think we can easily use your
> scheme.
I don't think there is a problem here.... maybe I didn't explain
properly or something.
I'm assuming there is a crash-count that is stored once per filesystem.
This might be a disk-format change, or maybe the "Last checked" time
could be used with ext4 (that is a bit horrible though).
Every on-disk i_version has a flag to choose between:
- use this number as it is, but update it on-disk before any change
- add multiple of current crash-count to this number before use.
If you crash during an update, the i_version is thus automatically
increased.
To change from the first option to the second option you subtract the
multiple of the current crash-count (which might make the stored
i_version negative), and flip the bit.
To change from the second option to the first, you add the multiple
of the current crash-count, and flip the bit.
In each case, the externally visible i_version does not change.
Nothing needs to be stored except the per-inode i_version and the per-fs
crash_count.
>
> So the options we have are:
>
> 1) Keep i_version as is, make clients also check for i_ctime.
> Pro: No on-disk format changes.
> Cons: After a crash, i_version can go backwards (but when file changes
> i_version, i_ctime pair should be still different) or not, data can be
> old or not.
I like to think of this approach as using the i_version as an extension
to the i_ctime.
i_ctime doesn't necessarily change on every file modification, either
because it is not a modification that is meant to change i_ctime, or
because i_ctime doesn't have the resolution to show a very small change
in time, or because the clock that is used to update i_ctime doesn't
have much resolution.
So when a change happens, if the stored c_time changes, set i_version to
zero, otherwise increment i_version.
Then the externally visible i-version is a combination of the stored
c_time and the stored i_version.
If you only used 1-second ctime resolution for versioning purposes, you
could provide a 64bit i_version as 34 bits of ctime and 30 bits of
changes-in-one-second.
It is important that the resolution of ctime used is less that the
fastest possible restart after a crash.
I don't think that i_version going backwards should be a problem, as
long as an old version means exactly the same old data. Presumably
journalling would ensure that the data and ctime/version are updated
atomically.
>
> 2) Fsync when reporting i_version.
> Pro: No on-disk format changes, strong consistency of i_version and
> data.
> Cons: Difficult to implement for filesystems due to locking constrains.
> High performance overhead or i_version reporting.
This reminds me of the old ext3 fsync-when-renaming a file. People
might depend on it for all the wrong reasons, and other people might
studiously avoid it due to the performance implications.
>
> 3) Some variant of crash counter.
> Pro: i_version cannot go backwards.
> Cons: Requires on-disk format changes. After a crash data can be old
> (however i_version increased).
If it is essential for i_version to always go forward, then I think this
is the best approach.
If an i_version reset can be tolerated, then I think a
time-plus-version-count approach is likely to be best.
Thanks,
NeilBrown
>
> Honza
> --
> Jan Kara <jack@suse.com>
> SUSE Labs, CR
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
[toc] | [prev] | [next] | [standalone]
| From | Jan Kara <jack@suse.cz> |
|---|---|
| Date | 2017-04-06 09:30 +0200 |
| Message-ID | <tta1H-5sD-1@gated-at.bofh.it> |
| In reply to | #1617454 |
On Thu 06-04-17 11:12:02, NeilBrown wrote: > On Wed, Apr 05 2017, Jan Kara wrote: > >> If you want to ensure read-only files can remain cached over a crash, > >> then you would have to mark a file in some way on stable storage > >> *before* allowing any change. > >> e.g. you could use the lsb. Odd i_versions might have been changed > >> recently and crash-count*large-number needs to be added. > >> Even i_versions have not been changed recently and nothing need be > >> added. > >> > >> If you want to change a file with an even i_version, you subtract > >> crash-count*large-number > >> to the i_version, then set lsb. This is written to stable storage before > >> the change. > >> > >> If a file has not been changed for a while, you can add > >> crash-count*large-number > >> and clear lsb. > >> > >> The lsb of the i_version would be for internal use only. It would not > >> be visible outside the filesystem. > >> > >> It feels a bit clunky, but I think it would work and is the best > >> combination of Jan's idea and your requirement. > >> The biggest cost would be switching to 'odd' before an changes, and the > >> unknown is when does it make sense to switch to 'even'. > > > > Well, there is also a problem that you would need to somehow remember with > > which 'crash count' the i_version has been previously reported as that is > > not stored on disk with my scheme. So I don't think we can easily use your > > scheme. > > I don't think there is a problem here.... maybe I didn't explain > properly or something. > > I'm assuming there is a crash-count that is stored once per filesystem. > This might be a disk-format change, or maybe the "Last checked" time > could be used with ext4 (that is a bit horrible though). > > Every on-disk i_version has a flag to choose between: > - use this number as it is, but update it on-disk before any change > - add multiple of current crash-count to this number before use. > If you crash during an update, the i_version is thus automatically > increased. > > To change from the first option to the second option you subtract the > multiple of the current crash-count (which might make the stored > i_version negative), and flip the bit. > To change from the second option to the first, you add the multiple > of the current crash-count, and flip the bit. > In each case, the externally visible i_version does not change. > Nothing needs to be stored except the per-inode i_version and the per-fs > crash_count. Right, I didn't realize you would subtract crash counter when flipping the bit and then add it back when flipping again. That would work. > > So the options we have are: > > > > 1) Keep i_version as is, make clients also check for i_ctime. > > Pro: No on-disk format changes. > > Cons: After a crash, i_version can go backwards (but when file changes > > i_version, i_ctime pair should be still different) or not, data can be > > old or not. > > I like to think of this approach as using the i_version as an extension > to the i_ctime. > i_ctime doesn't necessarily change on every file modification, either > because it is not a modification that is meant to change i_ctime, or > because i_ctime doesn't have the resolution to show a very small change > in time, or because the clock that is used to update i_ctime doesn't > have much resolution. > So when a change happens, if the stored c_time changes, set i_version to > zero, otherwise increment i_version. > Then the externally visible i-version is a combination of the stored > c_time and the stored i_version. > If you only used 1-second ctime resolution for versioning purposes, you > could provide a 64bit i_version as 34 bits of ctime and 30 bits of > changes-in-one-second. > It is important that the resolution of ctime used is less that the > fastest possible restart after a crash. > > I don't think that i_version going backwards should be a problem, as > long as an old version means exactly the same old data. Presumably > journalling would ensure that the data and ctime/version are updated > atomically. So as Dave and I wrote earlier in this thread, journalling does not ensure data vs ctime/version consistency (well, except for ext4 in data=journal mode but people rarely run that due to performance implications). So you can get old data and new version as well as new data and old version after a crash. The only thing filesystems guarantee is that you will not see uninitialized blocks and that fsync makes both data & ctime/version persistent. But as Bruce wrote for NFS open-to-close semantics this may be actually good enough. Honza -- Jan Kara <jack@suse.com> SUSE Labs, CR
[toc] | [prev] | [next] | [standalone]
| From | "J. Bruce Fields" <bfields@fieldses.org> |
|---|---|
| Date | 2017-04-05 19:50 +0200 |
| Message-ID | <tsXe9-5FW-1@gated-at.bofh.it> |
| In reply to | #1616497 |
On Wed, Apr 05, 2017 at 11:43:32AM +1000, NeilBrown wrote: > On Tue, Apr 04 2017, J. Bruce Fields wrote: > > > On Thu, Mar 30, 2017 at 02:35:32PM -0400, Jeff Layton wrote: > >> On Thu, 2017-03-30 at 12:12 -0400, J. Bruce Fields wrote: > >> > On Thu, Mar 30, 2017 at 07:11:48AM -0400, Jeff Layton wrote: > >> > > On Thu, 2017-03-30 at 08:47 +0200, Jan Kara wrote: > >> > > > Because if above is acceptable we could make reported i_version to be a sum > >> > > > of "superblock crash counter" and "inode i_version". We increment > >> > > > "superblock crash counter" whenever we detect unclean filesystem shutdown. > >> > > > That way after a crash we are guaranteed each inode will report new > >> > > > i_version (the sum would probably have to look like "superblock crash > >> > > > counter" * 65536 + "inode i_version" so that we avoid reusing possible > >> > > > i_version numbers we gave away but did not write to disk but still...). > >> > > > Thoughts? > >> > > >> > How hard is this for filesystems to support? Do they need an on-disk > >> > format change to keep track of the crash counter? Maybe not, maybe the > >> > high bits of the i_version counters are all they need. > >> > > >> > >> Yeah, I imagine we'd need a on-disk change for this unless there's > >> something already present that we could use in place of a crash counter. > > > > We could consider using the current time instead. So, put the current > > time (or time of last boot, or this inode's ctime, or something) in the > > high bits of the change attribute, and keep the low bits as a counter. > > This is a very different proposal. > I don't think Jan was suggesting that the i_version be split into two > bit fields, one the change-counter and one the crash-counter. > Rather, the crash-counter was multiplied by a large-number and added to > the change-counter with the expectation that while not ever > change-counter landed on disk, at least 1 in every large-number would. > So after each crash we effectively add large-number to the > change-counter, and can be sure that number hasn't been used already. I was sort of ignoring the distinction between concatenate(A,B) and A*m+B, but, sure, multiplying's probably better. > To store the crash-counter in each inode (which does appeal) you would > need to be able to remove it before adding the new crash counter, and > that requires bit-fields. Maybe there are enough bits. i_version and the NFSv4 change attribute are 64 bits which gives us a fair amount of flexibility. > If you want to ensure read-only files can remain cached over a crash, > then you would have to mark a file in some way on stable storage > *before* allowing any change. > e.g. you could use the lsb. Odd i_versions might have been changed > recently and crash-count*large-number needs to be added. > Even i_versions have not been changed recently and nothing need be > added. > > If you want to change a file with an even i_version, you subtract > crash-count*large-number > to the i_version, then set lsb. This is written to stable storage before > the change. > > If a file has not been changed for a while, you can add > crash-count*large-number > and clear lsb. > > The lsb of the i_version would be for internal use only. It would not > be visible outside the filesystem. > > It feels a bit clunky, but I think it would work and is the best > combination of Jan's idea and your requirement. > The biggest cost would be switching to 'odd' before an changes, and the > unknown is when does it make sense to switch to 'even'. I'm not sure how to model the costs. Something like that might work. --b.
[toc] | [prev] | [next] | [standalone]
| From | Dave Chinner <david@fromorbit.com> |
|---|---|
| Date | 2017-04-02 01:10 +0200 |
| Message-ID | <trAjE-Kq-3@gated-at.bofh.it> |
| In reply to | #1613263 |
On Thu, Mar 30, 2017 at 12:12:31PM -0400, J. Bruce Fields wrote: > On Thu, Mar 30, 2017 at 07:11:48AM -0400, Jeff Layton wrote: > > On Thu, 2017-03-30 at 08:47 +0200, Jan Kara wrote: > > > Because if above is acceptable we could make reported i_version to be a sum > > > of "superblock crash counter" and "inode i_version". We increment > > > "superblock crash counter" whenever we detect unclean filesystem shutdown. > > > That way after a crash we are guaranteed each inode will report new > > > i_version (the sum would probably have to look like "superblock crash > > > counter" * 65536 + "inode i_version" so that we avoid reusing possible > > > i_version numbers we gave away but did not write to disk but still...). > > > Thoughts? > > How hard is this for filesystems to support? Do they need an on-disk > format change to keep track of the crash counter? Yes. We'll need version counter in the superblock, and we'll need to know what the increment semantics are. The big question is how do we know there was a crash? The only thing a journalling filesystem knows at mount time is whether it is clean or requires recovery. Filesystems can require recovery for many reasons that don't involve a crash (e.g. root fs is never unmounted cleanly, so always requires recovery). Further, some filesystems may not even know there was a crash at mount time because their architecture always leaves a consistent filesystem on disk (e.g. COW filesystems).... > I wonder if repeated crashes can lead to any odd corner cases. WIthout defined, locked down behavour of the superblock counter, the almost certainly corner cases will exist... Cheers, Dave. -- Dave Chinner david@fromorbit.com
[toc] | [prev] | [next] | [standalone]
| From | Jan Kara <jack@suse.cz> |
|---|---|
| Date | 2017-04-03 16:10 +0200 |
| Message-ID | <tsaQa-7U5-29@gated-at.bofh.it> |
| In reply to | #1614614 |
On Sun 02-04-17 09:05:26, Dave Chinner wrote: > On Thu, Mar 30, 2017 at 12:12:31PM -0400, J. Bruce Fields wrote: > > On Thu, Mar 30, 2017 at 07:11:48AM -0400, Jeff Layton wrote: > > > On Thu, 2017-03-30 at 08:47 +0200, Jan Kara wrote: > > > > Because if above is acceptable we could make reported i_version to be a sum > > > > of "superblock crash counter" and "inode i_version". We increment > > > > "superblock crash counter" whenever we detect unclean filesystem shutdown. > > > > That way after a crash we are guaranteed each inode will report new > > > > i_version (the sum would probably have to look like "superblock crash > > > > counter" * 65536 + "inode i_version" so that we avoid reusing possible > > > > i_version numbers we gave away but did not write to disk but still...). > > > > Thoughts? > > > > How hard is this for filesystems to support? Do they need an on-disk > > format change to keep track of the crash counter? > > Yes. We'll need version counter in the superblock, and we'll need to > know what the increment semantics are. > > The big question is how do we know there was a crash? The only thing > a journalling filesystem knows at mount time is whether it is clean > or requires recovery. Filesystems can require recovery for many > reasons that don't involve a crash (e.g. root fs is never unmounted > cleanly, so always requires recovery). Further, some filesystems may > not even know there was a crash at mount time because their > architecture always leaves a consistent filesystem on disk (e.g. COW > filesystems).... What filesystems can or cannot easily do obviously differs. Ext4 has a recovery flag set in superblock on RW mount/remount and cleared on umount/RO remount. This flag being set on mount would imply incrementing the crash counter. It should be pretty easy for each filesystem to implement such flag and the counter but I agree it requires an on-disk format change. Honza -- Jan Kara <jack@suse.com> SUSE Labs, CR
[toc] | [prev] | [next] | [standalone]
| From | Dave Chinner <david@fromorbit.com> |
|---|---|
| Date | 2017-04-04 14:40 +0200 |
| Message-ID | <tsvUC-4Rz-25@gated-at.bofh.it> |
| In reply to | #1615226 |
On Mon, Apr 03, 2017 at 04:00:55PM +0200, Jan Kara wrote: > On Sun 02-04-17 09:05:26, Dave Chinner wrote: > > On Thu, Mar 30, 2017 at 12:12:31PM -0400, J. Bruce Fields wrote: > > > On Thu, Mar 30, 2017 at 07:11:48AM -0400, Jeff Layton wrote: > > > > On Thu, 2017-03-30 at 08:47 +0200, Jan Kara wrote: > > > > > Because if above is acceptable we could make reported i_version to be a sum > > > > > of "superblock crash counter" and "inode i_version". We increment > > > > > "superblock crash counter" whenever we detect unclean filesystem shutdown. > > > > > That way after a crash we are guaranteed each inode will report new > > > > > i_version (the sum would probably have to look like "superblock crash > > > > > counter" * 65536 + "inode i_version" so that we avoid reusing possible > > > > > i_version numbers we gave away but did not write to disk but still...). > > > > > Thoughts? > > > > > > How hard is this for filesystems to support? Do they need an on-disk > > > format change to keep track of the crash counter? > > > > Yes. We'll need version counter in the superblock, and we'll need to > > know what the increment semantics are. > > > > The big question is how do we know there was a crash? The only thing > > a journalling filesystem knows at mount time is whether it is clean > > or requires recovery. Filesystems can require recovery for many > > reasons that don't involve a crash (e.g. root fs is never unmounted > > cleanly, so always requires recovery). Further, some filesystems may > > not even know there was a crash at mount time because their > > architecture always leaves a consistent filesystem on disk (e.g. COW > > filesystems).... > > What filesystems can or cannot easily do obviously differs. Ext4 has a > recovery flag set in superblock on RW mount/remount and cleared on > umount/RO remount. Even this doesn't help. A recent bug that was reported to the XFS list - turns out that systemd can't remount-ro the root filesystem sucessfully on shutdown because there are open write fds on the root filesystem when it attempts the remount. So it just reboots without a remount-ro. This uncovered a bug in grub in that it (still!) thinks sync(1) is sufficient to get all the metadata that points to a kernel image onto disk in places it can read. XFS, like ext4, leaves it in the journal and so the system then fails to boot because systemd didn't remount-ro the root fs and hence the journal was never flushed before reboot and so grub can't find the kernel and so everything fails.... > This flag being set on mount would imply incrementing the crash > counter. It should be pretty easy for each filesystem to implement > such flag and the counter but I agree it requires an on-disk > format change. Yup, anything we want that is persistent and consistent across filesystems will need on-disk format changes. Hence we need a solid specification first, not to mention tests to validate correct behaviour across all filesystems in xfstests... Cheers, Dave. -- Dave Chinner david@fromorbit.com
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | linux.kernel
csiph-web