From: Xiubo Li Date: Mon, 11 Oct 2021 08:32:51 +0000 (+0800) Subject: client: try to buffer the truncate if we have the Fx caps X-Git-Tag: v16.2.11~526^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ac16b7bab2d540a02fa5daa3287e999f9635ff5a;p=ceph.git client: try to buffer the truncate if we have the Fx caps If the Fx caps is issued and new size is larger we can try to buffer the truncate, and just ignore in case the new size equals to current size. Signed-off-by: Xiubo Li (cherry picked from commit b557d642aeb21acf8b456a4addf6da63b17e1f68) --- diff --git a/src/client/Client.cc b/src/client/Client.cc index d6d55a9a5987..4261ba140ee0 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -7680,6 +7680,35 @@ int Client::_do_setattr(Inode *in, struct ceph_statx *stx, int mask, } } + if (mask & CEPH_SETATTR_SIZE) { + if ((uint64_t)stx->stx_size >= mdsmap->get_max_filesize()) { + //too big! + ldout(cct,10) << "unable to set size to " << stx->stx_size << ". Too large!" << dendl; + return -CEPHFS_EFBIG; + } + + ldout(cct,10) << "changing size to " << stx->stx_size << dendl; + if (in->caps_issued_mask(CEPH_CAP_FILE_EXCL) && + !(mask & CEPH_SETATTR_KILL_SGUID) && + stx->stx_size >= in->size) { + if (stx->stx_size > in->size) { + in->size = in->reported_size = stx->stx_size; + in->cap_dirtier_uid = perms.uid(); + in->cap_dirtier_gid = perms.gid(); + in->mark_caps_dirty(CEPH_CAP_FILE_EXCL); + mask &= ~(CEPH_SETATTR_SIZE); + mask |= CEPH_SETATTR_MTIME; + } else { + // ignore it when size doesn't change + mask &= ~(CEPH_SETATTR_SIZE); + } + } else { + args.setattr.size = stx->stx_size; + inode_drop |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_RD | + CEPH_CAP_FILE_WR; + } + } + if (in->caps_issued_mask(CEPH_CAP_FILE_EXCL)) { if (mask & (CEPH_SETATTR_MTIME|CEPH_SETATTR_ATIME)) { if (mask & CEPH_SETATTR_MTIME) @@ -7721,18 +7750,6 @@ force_request: req->inode_drop |= CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR; } - if (mask & CEPH_SETATTR_SIZE) { - if ((uint64_t)stx->stx_size < mdsmap->get_max_filesize()) { - req->head.args.setattr.size = stx->stx_size; - ldout(cct,10) << "changing size to " << stx->stx_size << dendl; - } else { //too big! - put_request(req); - ldout(cct,10) << "unable to set size to " << stx->stx_size << ". Too large!" << dendl; - return -CEPHFS_EFBIG; - } - req->inode_drop |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_RD | - CEPH_CAP_FILE_WR; - } req->head.args.setattr.mask = mask; req->regetattr_mask = mask;