want = file_wanted | used;
retain = want;
- if (!mdsc->stopping)
+ if (!mdsc->stopping) {
retain |= CEPH_CAP_PIN |
(S_ISDIR(inode->i_mode) ? CEPH_CAP_ANY_RDCACHE :
CEPH_CAP_ANY_RD);
+
+ /* keep any EXCL bits too, while we are holding caps anyway */
+ if (want)
+ retain |= CEPH_CAP_ANY_EXCL;
+ }
retain &= ~drop;
dout(10, "check_caps %p file_wanted %s used %s retain %s issued %s\n",
if (!revoking && mdsc->stopping && (used == 0))
goto ack;
- /* adjust wanted? */
- if (cap->mds_wanted != want)
- goto ack;
-
- if ((cap->issued & ~retain) == 0)
- continue; /* nothing extra, all good */
+ if ((cap->issued & ~retain) == 0 &&
+ cap->mds_wanted == want)
+ continue; /* nothing extra, wanted is correct */
/* delay cap release for a bit? */
if (!is_delayed &&
struct inode *inode;
struct ceph_cap *cap;
struct list_head *p, *n;
- int wanted, last_cap;
+ int wanted;
dout(10, "trim_rdcaps for mds%d\n", session->s_mds);
list_for_each_safe(p, n, &session->s_rdcaps) {
+ int last_cap = 0;
+
cap = list_entry(p, struct ceph_cap, session_rdcaps);
inode = &cap->ci->vfs_inode;
spin_lock(&inode->i_lock);
if (__ceph_caps_issued(ci, NULL) & CEPH_CAP_AUTH_EXCL) {
- dout(10, " holding auth EXCL, doing locally\n");
+ dout(10, "chown holding auth EXCL, doing locally\n");
if (ia_valid & ATTR_UID)
inode->i_uid = attr->ia_uid;
if (ia_valid & ATTR_GID)
spin_lock(&inode->i_lock);
if (__ceph_caps_issued(ci, NULL) & CEPH_CAP_AUTH_EXCL) {
- dout(10, " holding auth EXCL, doing locally\n");
+ dout(10, "chmod holding auth EXCL, doing locally\n");
inode->i_mode = attr->ia_mode;
inode->i_ctime = CURRENT_TIME;
ci->i_dirty_caps |= CEPH_CAP_AUTH_EXCL;