-
Notifications
You must be signed in to change notification settings - Fork 7
fuse: fix race between inode creation and invalidation #80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: redfs-ubuntu-noble-6.8.0-58.60
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -231,13 +231,14 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, | |
| * if the attr_version would've been preserved. | ||
| * | ||
| * !evict_ctr -> this is create | ||
| * fi->attr_version != 0 -> this is not a new inode | ||
| * fi->attr_version > 1 -> this is not a new inode | ||
| * evict_ctr == fuse_get_evict_ctr() -> no evicts while during request | ||
| */ | ||
| if (!evict_ctr || fi->attr_version || evict_ctr == fuse_get_evict_ctr(fc)) | ||
| if (!evict_ctr || fi->attr_version > 1 || evict_ctr == fuse_get_evict_ctr(fc)) | ||
| set_mask_bits(&fi->inval_mask, STATX_BASIC_STATS, 0); | ||
|
|
||
| fi->attr_version = atomic64_inc_return(&fc->attr_version); | ||
| if (fi->attr_version != 1) /* fuse_iget() handle if attr_version == 1 */ | ||
| fi->attr_version = atomic64_inc_return(&fc->attr_version); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is if this is later on called?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's assume there is no invalidate, and just two times fuse_change_attributes_common() from two different calls. |
||
| fi->i_time = attr_valid; | ||
|
|
||
| inode->i_ino = fuse_squash_ino(attr->ino); | ||
|
|
@@ -520,6 +521,18 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid, | |
| done: | ||
| fuse_change_attributes_i(inode, attr, NULL, attr_valid, attr_version, | ||
| evict_ctr); | ||
|
|
||
| spin_lock(&fi->lock); | ||
| if (fi->attr_version == 1) /* delayed inode invalidation */ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I must be missing something, somehow I think this is always true? fuse_change_attributes_common() increases to 1? |
||
| { | ||
| spin_unlock(&fi->lock); | ||
| down_read(&fc->killsb); | ||
| fuse_reverse_inval_inode(fc, nodeid, 0, 0); | ||
| up_read(&fc->killsb); | ||
| } | ||
| else | ||
| spin_unlock(&fi->lock); | ||
|
|
||
| return inode; | ||
| } | ||
|
|
||
|
|
@@ -598,6 +611,21 @@ int fuse_reverse_inval_inode(struct fuse_conn *fc, u64 nodeid, | |
|
|
||
| fi = get_fuse_inode(inode); | ||
| spin_lock(&fi->lock); | ||
|
|
||
| if (fi->attr_version == 0) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just return -EAGAIN and let userspace handle it?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The alternative would be too add a waitq |
||
| { | ||
| /* attr_version == 0 indicate fuse_iget() is not completed yet. | ||
| Skip the inode invalidation operation here, and delay it in the | ||
| function fuse_iget(), after call to fuse_change_attributes_i(). | ||
| Initialized value of fc->attr_version is 1, so fi->attr_version | ||
| will be 0 or >= 2, we use value 1 to indicate the "delayed" | ||
| inode invalidation operation been recorded */ | ||
| fi->attr_version = 1; | ||
| spin_unlock(&fi->lock); | ||
| iput(inode); | ||
| return 0; | ||
| } | ||
|
|
||
| fi->attr_version = atomic64_inc_return(&fc->attr_version); | ||
| spin_unlock(&fi->lock); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why these changes >1, same as
>0?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah not >0