@@ -613,6 +613,7 @@ static int ll_xattr_get(const struct xattr_handler *handler,
ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
{
+ struct inode *dir = d_inode(dentry->d_parent);
struct inode *inode = d_inode(dentry);
struct ll_sb_info *sbi = ll_i2sbi(inode);
ktime_t kstart = ktime_get();
@@ -656,6 +657,20 @@ ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
hide_xattr = true;
}
+ /* Hide virtual project id xattr from the list when
+ * parent has the inherit flag and the same project id,
+ * so project id won't be messed up by copying the xattrs
+ * when mv to a tree with different project id.
+ */
+ if (get_xattr_type(xattr_name)->flags == XATTR_TRUSTED_T &&
+ strcmp(xattr_name, XATTR_NAME_PROJID) == 0) {
+ if (ll_i2info(inode)->lli_projid ==
+ ll_i2info(dir)->lli_projid &&
+ test_bit(LLIF_PROJECT_INHERIT,
+ &ll_i2info(dir)->lli_flags))
+ hide_xattr = true;
+ }
+
len = strnlen(xattr_name, rem - 1) + 1;
rem -= len;
if (!xattr_type_filter(sbi, hide_xattr ? NULL :
@@ -563,6 +563,21 @@ int ll_xattr_cache_get(struct inode *inode, const char *name, char *buffer,
else
rc = -ERANGE;
}
+ /* Return the project id when the virtual project id xattr
+ * is explicitly asked.
+ */
+ } else if (strcmp(name, XATTR_NAME_PROJID) == 0) {
+ /* 10 chars to hold u32 in decimal, plus ending \0 */
+ char projid[11];
+
+ rc = snprintf(projid, sizeof(projid),
+ "%u", lli->lli_projid);
+ if (size != 0) {
+ if (rc <= size)
+ memcpy(buffer, projid, rc);
+ else
+ rc = -ERANGE;
+ }
}
} else if (valid & OBD_MD_FLXATTRLS) {
rc = ll_xattr_cache_list(&lli->lli_xattrs,
@@ -1078,6 +1078,7 @@ struct lov_mds_md_v1 { /* LOV EA mds/wire data (little-endian) */
#define XATTR_NAME_SOM "trusted.som"
#define XATTR_NAME_HSM "trusted.hsm"
#define XATTR_NAME_LFSCK_NAMESPACE "trusted.lfsck_namespace"
+#define XATTR_NAME_PROJID "trusted.projid"
#define LL_XATTR_NAME_ENCRYPTION_CONTEXT XATTR_SECURITY_PREFIX"c"