fuse: Send statx with requested flags only and reduce flags for perm …#151
fuse: Send statx with requested flags only and reduce flags for perm …#151bsbernd wants to merge 2 commits into
Conversation
In preparation for allowing partial attribute updates via statx (where only a subset of STATX_BASIC_STATS may be requested and returned), modify fuse_change_attributes_common() to be more selective about what it updates. Currently, fuse_change_attributes_common() unconditionally: 1. Clears ALL of STATX_BASIC_STATS from inval_mask 2. Updates fi->i_time (extending the attribute timeout) For some fuse-servers it might be benefitial to reduce the number of queries attributes and and attribute mask is one of the features of statx. With the all or nothing handling of fuse_change_attributes_common() that statx feature is impossible to be used. This commit adds the logic to: 1. Track which attributes were actually returned (via sx->mask for statx, or assume all STATX_BASIC_STATS for getattr) 2. Only clear those specific attributes from inval_mask 3. Only update fi->i_time when it's safe: when cache_mask is empty OR when all cache_mask attributes were included in the response The condition in fuse_do_statx() still requires ALL STATX_BASIC_STATS, so this commit has no functional change. A follow up commit will relax that condition to enable partial updates. Signed-off-by: Bernd Schubert <bernd@bsbernd.com>
28ea0e0 to
787de62
Compare
| * The server may return more attributes than requested (which is fine), | ||
| * but must not return fewer. | ||
| */ | ||
| if ((sx->mask & inarg.sx_mask) != inarg.sx_mask) { |
There was a problem hiding this comment.
This is incorrect to me. The server may return a mask without STATX_BTIME even when fuse_do_statx() requests it
There was a problem hiding this comment.
Ok, we can reduce to
(inarg.sx_mask & STATX_BASIC_STATS)
``
STATX_BASIC_STATS - needs to be discussed later on with upstream
There was a problem hiding this comment.
Actually not in that function - I'm going to add a "mandatory_mask" argument.
| fi->i_time = attr_valid; | ||
| } else { | ||
| /* no writeback_cache: need all basic stats */ | ||
| if (returned_attrs == STATX_BASIC_STATS) |
There was a problem hiding this comment.
So, if I return attrs without ATIME,MTIME,CTIME, the fi->i_time will not be set?
There was a problem hiding this comment.
Yes, that is the idea - the inode does not get an updated cache timeout. The next getattr will fetch from cache what was updated or if the timeout it invalid, do a full getattr. To be discussed if the the timeout should be invalidated at all.
787de62 to
57eae77
Compare
|
LGTM, I will do a final test and report the result today. |
|
|
||
| /* FUSE only supports basic stats and possibly btime */ | ||
| request_mask &= STATX_BASIC_STATS | STATX_BTIME; | ||
| sx_mask &= STATX_BASIC_STATS | STATX_BTIME; |
There was a problem hiding this comment.
Line 1343 calls fuse_do_statx(inode, file, stat, sx_mask, mandatory_sx_mask); fuse_do_statx() requires that mandatory_sx_mask is a subset of sx_mask. But the code above handles it in the opposite way. For example, if mandatory_sx_mask contains STATX_MNT_ID, fuse_do_statx will emit a WARN.
There was a problem hiding this comment.
Ooops, sorry, I should have checked. Updated, the caller sets "request_mask & STATX_BASIC_STATS" into mandatory_sx_mask now.
…attributes For permission checks via inode_permission(), we only need mode, uid, and gid attributes. Previously, we requested all STATX_BASIC_STATS, which was inefficient. This commit enables the optimization by: 1. Requesting only STATX_MODE | STATX_UID | STATX_GID for permission checks 2. Relaxing the condition in fuse_do_statx() from requiring all basic stats to accepting any subset of basic stats 3. Adding validation that the server returns at least what was requested The preparation commit ensures partial updates work correctly by only updating returned attributes and managing timeouts appropriately. Signed-off-by: Bernd Schubert <bernd@bsbernd.com>
57eae77 to
b5fac0a
Compare
…check
One purpose of statx is to help cluster/network file systems and only request as many flags as needed. The file system is then free to add in more flags.
One use case for fuse_permission/fuse_perm_getattr and only check if mode/uid/gid have changed. Checking other stat might be an expensive operation, as time stamps and file size might need to be queries from multiple servers.