-
Notifications
You must be signed in to change notification settings - Fork 7
fuse: Allow stale time info for permission getattr #150
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
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 |
|---|---|---|
|
|
@@ -1244,6 +1244,62 @@ static int fuse_do_statx(struct inode *inode, struct file *file, | |
| return 0; | ||
| } | ||
|
|
||
| /* | ||
| * This is used by permission checking to get attributes without requiring | ||
| * accurate time information. This allows the FUSE server to acquire a weaker | ||
| * lock mode and reduce lock contention. | ||
| */ | ||
| static int fuse_perm_do_statx(struct inode *inode, struct file *file) | ||
| { | ||
| int err; | ||
| struct fuse_attr attr; | ||
| struct fuse_statx *sx; | ||
| struct fuse_statx_in inarg; | ||
| struct fuse_statx_out outarg; | ||
| struct fuse_mount *fm = get_fuse_mount(inode); | ||
| u64 attr_version = fuse_get_attr_version(fm->fc); | ||
| FUSE_ARGS(args); | ||
|
|
||
| memset(&inarg, 0, sizeof(inarg)); | ||
| memset(&outarg, 0, sizeof(outarg)); | ||
| /* Directories have separate file-handle space */ | ||
| if (file && S_ISREG(inode->i_mode)) { | ||
| struct fuse_file *ff = file->private_data; | ||
|
|
||
| inarg.getattr_flags |= FUSE_GETATTR_FH; | ||
| inarg.fh = ff->fh; | ||
| } | ||
|
|
||
| inarg.sx_flags = 0; | ||
| inarg.sx_mask = STATX_BASIC_STATS & ~(STATX_ATIME | STATX_MTIME | STATX_CTIME); | ||
| args.opcode = FUSE_STATX; | ||
| args.nodeid = get_node_id(inode); | ||
| args.in_numargs = 1; | ||
| args.in_args[0].size = sizeof(inarg); | ||
| args.in_args[0].value = &inarg; | ||
| args.out_numargs = 1; | ||
| args.out_args[0].size = sizeof(outarg); | ||
| args.out_args[0].value = &outarg; | ||
| err = fuse_simple_request(fm, &args); | ||
| if (err) | ||
| return err; | ||
|
|
||
| sx = &outarg.stat; | ||
| if (((sx->mask & STATX_SIZE) && !fuse_valid_size(sx->size)) || | ||
| ((sx->mask & STATX_TYPE) && (!fuse_valid_type(sx->mode) || | ||
| inode_wrong_type(inode, sx->mode)))) { | ||
| fuse_make_bad(inode); | ||
| return -EIO; | ||
| } | ||
|
|
||
| fuse_statx_to_attr(&outarg.stat, &attr); | ||
| fuse_change_attributes(inode, &attr, &outarg.stat, | ||
| ATTR_TIMEOUT(&outarg), attr_version); | ||
| fuse_invalidate_attr_mask(inode, STATX_ATIME|STATX_MTIME|STATX_CTIME); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| static int fuse_do_getattr(struct inode *inode, struct kstat *stat, | ||
| struct file *file) | ||
| { | ||
|
|
@@ -1484,7 +1540,7 @@ static int fuse_perm_getattr(struct inode *inode, int mask) | |
| return -ECHILD; | ||
|
|
||
| forget_all_cached_acls(inode); | ||
| return fuse_do_getattr(inode, NULL, NULL); | ||
| return fuse_perm_do_statx(inode, NULL); | ||
|
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 think that can be much simpler, look at the caller of
How about this Sorry, only noticed past midnight when I was just on my way to bed - the above is not even compilation tested. Basically this passes in the request mask to fuse_statx_to_attr() and uses that function in fuse_perm_getattr() via fuse_update_get_attr().
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. With "much simpler" I actually mean "without code dup".
Collaborator
Author
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. Yes, but that may cause problem when we cherry-pick upstream kernel changes later.
Collaborator
Author
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 mean my change intentionally does not modify the existing kernel routine signature.
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. Obviously we need to send my suggestion upstream.
Collaborator
Author
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. @bsbernd The suggested code fails to improve performance; fuse_do_statx() does not invoke redfs_change_attributes() for the requested mask STATX_MODE | STATX_UID | STATX_GID. |
||
| } | ||
|
|
||
| /* | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.