From: Venky Shankar Date: Mon, 19 Sep 2022 11:38:36 +0000 (-0400) Subject: client: refresh snapdir attrs on parent inode updation X-Git-Tag: v18.1.0~1003^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=794c74cebd9ecbd82e7431f424af8f631b75de89;p=ceph.git client: refresh snapdir attrs on parent inode updation Snapdir attrs (ui, gid, etc..) are set its respective parent attributes, however, those are never updated when the attributes of the parent inode get updated. There seems to be no reason to no to update snapdir attributes. This change also updates POSIX ACLs. Fixes: http://tracker.ceph.com/issues/57084 Signed-off-by: Venky Shankar --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 997f147fec7f8..2a4ae51da5307 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -1046,6 +1046,7 @@ Inode * Client::add_update_inode(InodeStat *st, utime_t from, issued |= in->caps_dirty(); int new_issued = ~issued & (int)st->cap.caps; + bool need_snapdir_attr_refresh = false; if ((new_version || (new_issued & CEPH_CAP_AUTH_SHARED)) && !(issued & CEPH_CAP_AUTH_EXCL)) { in->mode = st->mode; @@ -1055,6 +1056,7 @@ Inode * Client::add_update_inode(InodeStat *st, utime_t from, in->snap_btime = st->snap_btime; in->snap_metadata = st->snap_metadata; in->fscrypt_auth = st->fscrypt_auth; + need_snapdir_attr_refresh = true; } if ((new_version || (new_issued & CEPH_CAP_LINK_SHARED)) && @@ -1063,6 +1065,7 @@ Inode * Client::add_update_inode(InodeStat *st, utime_t from, } if (new_version || (new_issued & CEPH_CAP_ANY_RD)) { + need_snapdir_attr_refresh = true; update_inode_file_time(in, issued, st->time_warp_seq, st->ctime, st->mtime, st->atime); } @@ -1100,6 +1103,7 @@ Inode * Client::add_update_inode(InodeStat *st, utime_t from, auto p = st->xattrbl.cbegin(); decode(in->xattrs, p); in->xattr_version = st->xattr_version; + need_snapdir_attr_refresh = true; } if (st->inline_version > in->inline_version) { @@ -1152,6 +1156,13 @@ Inode * Client::add_update_inode(InodeStat *st, utime_t from, in->snap_caps |= st->cap.caps; } + if (need_snapdir_attr_refresh && in->is_dir() && in->snapid == CEPH_NOSNAP) { + vinodeno_t vino(in->ino, CEPH_SNAPDIR); + if (inode_map.count(vino)) { + refresh_snapdir_attrs(inode_map[vino], in); + } + } + return in; } @@ -7994,6 +8005,12 @@ int Client::_do_setattr(Inode *in, struct ceph_statx *stx, int mask, if (!mask) { in->change_attr++; + if (in->is_dir() && in->snapid == CEPH_NOSNAP) { + vinodeno_t vino(in->ino, CEPH_SNAPDIR); + if (inode_map.count(vino)) { + refresh_snapdir_attrs(inode_map[vino], in); + } + } return 0; } @@ -11914,34 +11931,40 @@ int Client::get_caps_issued(const char *path, const UserPerm& perms) // ========================================= // low level +void Client::refresh_snapdir_attrs(Inode *in, Inode *diri) { + ldout(cct, 10) << __func__ << ": snapdir inode=" << *in + << ", inode=" << *diri << dendl; + in->ino = diri->ino; + in->snapid = CEPH_SNAPDIR; + in->mode = diri->mode; + in->uid = diri->uid; + in->gid = diri->gid; + in->nlink = 1; + in->mtime = diri->mtime; + in->ctime = diri->ctime; + in->btime = diri->btime; + in->atime = diri->atime; + in->size = diri->size; + in->change_attr = diri->change_attr; + + in->dirfragtree.clear(); + in->snapdir_parent = diri; + // copy posix acls to snapshotted inode + in->xattrs.clear(); + for (auto &[xattr_key, xattr_value] : diri->xattrs) { + if (xattr_key.rfind("system.", 0) == 0) { + in->xattrs[xattr_key] = xattr_value; + } + } +} + Inode *Client::open_snapdir(Inode *diri) { Inode *in; vinodeno_t vino(diri->ino, CEPH_SNAPDIR); if (!inode_map.count(vino)) { in = new Inode(this, vino, &diri->layout); - - in->ino = diri->ino; - in->snapid = CEPH_SNAPDIR; - in->mode = diri->mode; - in->uid = diri->uid; - in->gid = diri->gid; - in->nlink = 1; - in->mtime = diri->mtime; - in->ctime = diri->ctime; - in->btime = diri->btime; - in->atime = diri->atime; - in->size = diri->size; - in->change_attr = diri->change_attr; - - in->dirfragtree.clear(); - in->snapdir_parent = diri; - // copy posix acls to snapshotted inode - for (auto &[xattr_key, xattr_value] : diri->xattrs) { - if (xattr_key.rfind("system.", 0) == 0) { - in->xattrs[xattr_key] = xattr_value; - } - } + refresh_snapdir_attrs(in, diri); diri->flags |= I_SNAPDIR_OPEN; inode_map[vino] = in; if (use_faked_inos()) diff --git a/src/client/Client.h b/src/client/Client.h index a1e63d7d5b6d9..6c1132f75883e 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -985,6 +985,7 @@ protected: void update_snap_trace(const bufferlist& bl, SnapRealm **realm_ret, bool must_flush=true); void invalidate_snaprealm_and_children(SnapRealm *realm); + void refresh_snapdir_attrs(Inode *in, Inode *diri); Inode *open_snapdir(Inode *diri); int get_fd() {