* check_caps * * Examine currently used and wanted versus held caps. Release, flush or ack * revoked caps to the MDS as appropriate. * * @param in the inode to check * @param flags flags to apply to cap check */
| 4224 | * @param flags flags to apply to cap check |
| 4225 | */ |
| 4226 | void Client::check_caps(const InodeRef& in, unsigned flags) |
| 4227 | { |
| 4228 | unsigned wanted = in->caps_wanted(); |
| 4229 | unsigned used = get_caps_used(in.get()); |
| 4230 | unsigned cap_used; |
| 4231 | |
| 4232 | int implemented; |
| 4233 | int issued = in->caps_issued(&implemented); |
| 4234 | int revoking = implemented & ~issued; |
| 4235 | |
| 4236 | int orig_used = used; |
| 4237 | used = adjust_caps_used_for_lazyio(used, issued, implemented); |
| 4238 | |
| 4239 | int retain = wanted | used | CEPH_CAP_PIN; |
| 4240 | if (!is_unmounting() && in->nlink > 0) { |
| 4241 | if (wanted) { |
| 4242 | retain |= CEPH_CAP_ANY; |
| 4243 | } else if (in->is_dir() && |
| 4244 | (issued & CEPH_CAP_FILE_SHARED) && |
| 4245 | (in->flags & I_COMPLETE)) { |
| 4246 | // we do this here because we don't want to drop to Fs (and then |
| 4247 | // drop the Fs if we do a create!) if that alone makes us send lookups |
| 4248 | // to the MDS. Doing it in in->caps_wanted() has knock-on effects elsewhere |
| 4249 | wanted = CEPH_CAP_ANY_SHARED | CEPH_CAP_FILE_EXCL; |
| 4250 | retain |= wanted; |
| 4251 | } else { |
| 4252 | retain |= CEPH_CAP_ANY_SHARED; |
| 4253 | // keep RD only if we didn't have the file open RW, |
| 4254 | // because then the mds would revoke it anyway to |
| 4255 | // journal max_size=0. |
| 4256 | if (in->max_size == 0) |
| 4257 | retain |= CEPH_CAP_ANY_RD; |
| 4258 | } |
| 4259 | } |
| 4260 | |
| 4261 | ldout(cct, 10) << __func__ << " on " << *in |
| 4262 | << " wanted " << ccap_string(wanted) |
| 4263 | << " used " << ccap_string(used) |
| 4264 | << " issued " << ccap_string(issued) |
| 4265 | << " revoking " << ccap_string(revoking) |
| 4266 | << " flags=" << flags |
| 4267 | << dendl; |
| 4268 | |
| 4269 | if (in->snapid != CEPH_NOSNAP) |
| 4270 | return; //snap caps last forever, can't write |
| 4271 | |
| 4272 | if (in->caps.empty()) |
| 4273 | return; // guard if at end of func |
| 4274 | |
| 4275 | if (!(orig_used & CEPH_CAP_FILE_BUFFER) && |
| 4276 | (revoking & used & (CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO))) { |
| 4277 | if (_release(in.get())) |
| 4278 | used &= ~(CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO); |
| 4279 | } |
| 4280 | |
| 4281 | for (auto &[mds, cap] : in->caps) { |
| 4282 | auto session = mds_sessions.at(mds); |
| 4283 |
no test coverage detected