X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fllite%2Fxattr.c;h=461a0baeed1ce3828c8e635a6c86e3fd3053fbb7;hp=9fea17e18ed44fd8775e9524e46d62c0796264f2;hb=7af958a556ef2be0219ba279631b05a7b2a58cee;hpb=427e6a469722cf14b2cd80cec991a4154b4aae50;ds=sidebyside diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index 9fea17e..461a0ba 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2014, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -37,6 +37,7 @@ #include #include #include +#include #include #define DEBUG_SUBSYSTEM S_LLITE @@ -48,6 +49,22 @@ #include "llite_internal.h" +/* xattr related to IMA(Integrity Measurement Architecture) */ +#ifndef XATTR_NAME_IMA +#define XATTR_NAME_IMA "security.ima" +#endif +#ifndef XATTR_NAME_EVM +#define XATTR_NAME_EVM "security.evm" +#endif + +#ifndef XATTR_NAME_POSIX_ACL_ACCESS +# define XATTR_NAME_POSIX_ACL_ACCESS POSIX_ACL_XATTR_ACCESS +#endif + +#ifndef XATTR_NAME_POSIX_ACL_DEFAULT +# define XATTR_NAME_POSIX_ACL_DEFAULT POSIX_ACL_XATTR_DEFAULT +#endif + #define XATTR_USER_T (1) #define XATTR_TRUSTED_T (2) #define XATTR_SECURITY_T (3) @@ -59,10 +76,10 @@ static int get_xattr_type(const char *name) { - if (!strcmp(name, POSIX_ACL_XATTR_ACCESS)) + if (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS)) return XATTR_ACL_ACCESS_T; - if (!strcmp(name, POSIX_ACL_XATTR_DEFAULT)) + if (!strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT)) return XATTR_ACL_DEFAULT_T; if (!strncmp(name, XATTR_USER_PREFIX, @@ -110,13 +127,16 @@ int ll_setxattr_common(struct inode *inode, const char *name, struct ll_sb_info *sbi = ll_i2sbi(inode); struct ptlrpc_request *req = NULL; int xattr_type, rc; - struct obd_capa *oc; - posix_acl_xattr_header *new_value = NULL; - struct rmtacl_ctl_entry *rce = NULL; - ext_acl_xattr_header *acl = NULL; const char *pv = value; ENTRY; + /*FIXME: enable IMA when the conditions are ready */ + if (strncmp(name, XATTR_NAME_IMA, + sizeof(XATTR_NAME_IMA)) == 0 || + strncmp(name, XATTR_NAME_EVM, + sizeof(XATTR_NAME_EVM)) == 0) + return -EOPNOTSUPP; + xattr_type = get_xattr_type(name); rc = xattr_type_filter(sbi, xattr_type); if (rc) @@ -131,10 +151,13 @@ int ll_setxattr_common(struct inode *inode, const char *name, #endif return -EPERM; - /* b10667: ignore lustre special xattr for now */ - if ((xattr_type == XATTR_TRUSTED_T && strcmp(name, "trusted.lov") == 0) || - (xattr_type == XATTR_LUSTRE_T && strcmp(name, "lustre.lov") == 0)) - RETURN(0); + /* b10667: ignore lustre special xattr for now */ + if (strcmp(name, XATTR_NAME_HSM) == 0 || + (xattr_type == XATTR_TRUSTED_T && + strcmp(name, XATTR_NAME_LOV) == 0) || + (xattr_type == XATTR_LUSTRE_T && + strcmp(name, "lustre.lov") == 0)) + RETURN(0); /* b15587: ignore security.capability xattr for now */ if ((xattr_type == XATTR_SECURITY_T && @@ -146,62 +169,8 @@ int ll_setxattr_common(struct inode *inode, const char *name, strcmp(name, "security.selinux") == 0) RETURN(-EOPNOTSUPP); -#ifdef CONFIG_FS_POSIX_ACL - if (sbi->ll_flags & LL_SBI_RMT_CLIENT && - (xattr_type == XATTR_ACL_ACCESS_T || - xattr_type == XATTR_ACL_DEFAULT_T)) { - rce = rct_search(&sbi->ll_rct, current_pid()); - if (rce == NULL || - (rce->rce_ops != RMT_LSETFACL && - rce->rce_ops != RMT_RSETFACL)) - RETURN(-EOPNOTSUPP); - - if (rce->rce_ops == RMT_LSETFACL) { - struct eacl_entry *ee; - - ee = et_search_del(&sbi->ll_et, current_pid(), - ll_inode2fid(inode), xattr_type); - LASSERT(ee != NULL); - if (valid & OBD_MD_FLXATTR) { - acl = lustre_acl_xattr_merge2ext( - (posix_acl_xattr_header *)value, - size, ee->ee_acl); - if (IS_ERR(acl)) { - ee_free(ee); - RETURN(PTR_ERR(acl)); - } - size = CFS_ACL_XATTR_SIZE(\ - le32_to_cpu(acl->a_count), \ - ext_acl_xattr); - pv = (const char *)acl; - } - ee_free(ee); - } else if (rce->rce_ops == RMT_RSETFACL) { - int acl_size = lustre_posix_acl_xattr_filter( - (posix_acl_xattr_header *)value, - size, &new_value); - if (unlikely(acl_size < 0)) - RETURN(acl_size); - size = acl_size; - - pv = (const char *)new_value; - } else - RETURN(-EOPNOTSUPP); - - valid |= rce_ops2valid(rce->rce_ops); - } -#endif - oc = ll_mdscapa_get(inode); - rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, - valid, name, pv, size, 0, flags, - ll_i2suppgid(inode), &req); - capa_put(oc); -#ifdef CONFIG_FS_POSIX_ACL - if (new_value != NULL) - lustre_posix_acl_xattr_free(new_value, size); - if (acl != NULL) - lustre_ext_acl_xattr_free(acl); -#endif + rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), valid, name, pv, + size, 0, flags, ll_i2suppgid(inode), &req); if (rc) { if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) { LCONSOLE_INFO("Disabling user_xattr feature because " @@ -215,6 +184,37 @@ int ll_setxattr_common(struct inode *inode, const char *name, RETURN(0); } +static int get_hsm_state(struct inode *inode, __u32 *hus_states) +{ + struct md_op_data *op_data; + struct hsm_user_state *hus; + int rc; + + OBD_ALLOC_PTR(hus); + if (hus == NULL) + return -ENOMEM; + + op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0, + LUSTRE_OPC_ANY, hus); + if (!IS_ERR(op_data)) { + rc = obd_iocontrol(LL_IOC_HSM_STATE_GET, ll_i2mdexp(inode), + sizeof(*op_data), op_data, NULL); + if (rc == 0) + *hus_states = hus->hus_states; + else + CDEBUG(D_VFSTRACE, "obd_iocontrol failed. rc = %d\n", + rc); + + ll_finish_md_op_data(op_data); + } else { + rc = PTR_ERR(op_data); + CDEBUG(D_VFSTRACE, "Could not prepare the opdata. rc = %d\n", + rc); + } + OBD_FREE_PTR(hus); + return rc; +} + int ll_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { @@ -228,20 +228,40 @@ int ll_setxattr(struct dentry *dentry, const char *name, ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1); - if ((strncmp(name, XATTR_TRUSTED_PREFIX, - sizeof(XATTR_TRUSTED_PREFIX) - 1) == 0 && - strcmp(name + sizeof(XATTR_TRUSTED_PREFIX) - 1, "lov") == 0) || - (strncmp(name, XATTR_LUSTRE_PREFIX, - sizeof(XATTR_LUSTRE_PREFIX) - 1) == 0 && - strcmp(name + sizeof(XATTR_LUSTRE_PREFIX) - 1, "lov") == 0)) { + if ((strncmp(name, XATTR_TRUSTED_PREFIX, + sizeof(XATTR_TRUSTED_PREFIX) - 1) == 0 && + strcmp(name + sizeof(XATTR_TRUSTED_PREFIX) - 1, "lov") == 0) || + (strncmp(name, XATTR_LUSTRE_PREFIX, + sizeof(XATTR_LUSTRE_PREFIX) - 1) == 0 && + strcmp(name + sizeof(XATTR_LUSTRE_PREFIX) - 1, "lov") == 0)) { struct lov_user_md *lump = (struct lov_user_md *)value; - int rc = 0; - - /* Attributes that are saved via getxattr will always have - * the stripe_offset as 0. Instead, the MDS should be - * allowed to pick the starting OST index. b=17846 */ - if (lump != NULL && lump->lmm_stripe_offset == 0) - lump->lmm_stripe_offset = -1; + int rc = 0; + + /* Attributes that are saved via getxattr will always have + * the stripe_offset as 0. Instead, the MDS should be + * allowed to pick the starting OST index. b=17846 */ + if (lump != NULL && lump->lmm_stripe_offset == 0) + lump->lmm_stripe_offset = -1; + /* Avoid anyone directly setting the RELEASED flag. */ + if (lump != NULL && + (lump->lmm_pattern & LOV_PATTERN_F_RELEASED)) { + /* Only if we have a released flag check if the file + * was indeed archived. */ + __u32 state = HS_NONE; + rc = get_hsm_state(inode, &state); + if (rc != 0) + RETURN(rc); + if (!(state & HS_ARCHIVED)) { + CDEBUG(D_VFSTRACE, + "hus_states state = %x, pattern = %x\n", + state, lump->lmm_pattern); + /* Here the state is: real file is not + * archived but user is requesting to set + * the RELEASED flag so we mask off the + * released flag from the request */ + lump->lmm_pattern ^= LOV_PATTERN_F_RELEASED; + } + } if (lump != NULL && S_ISREG(inode->i_mode)) { struct file f; @@ -253,7 +273,7 @@ int ll_setxattr(struct dentry *dentry, const char *name, return 0; /* b=10667: ignore error */ memset(&f, 0, sizeof(f)); /* f.f_flags is used below */ - f.f_dentry = dentry; + f.f_path.dentry = dentry; rc = ll_lov_setstripe_ea_info(inode, &f, it_flags, lump, lum_size); /* b=10667: rc always be 0 here for now */ @@ -295,8 +315,6 @@ int ll_getxattr_common(struct inode *inode, const char *name, struct mdt_body *body; int xattr_type, rc; void *xdata; - struct obd_capa *oc; - struct rmtacl_ctl_entry *rce = NULL; struct ll_inode_info *lli = ll_i2info(inode); ENTRY; @@ -328,26 +346,12 @@ int ll_getxattr_common(struct inode *inode, const char *name, RETURN(-EOPNOTSUPP); #ifdef CONFIG_FS_POSIX_ACL - if (sbi->ll_flags & LL_SBI_RMT_CLIENT && - (xattr_type == XATTR_ACL_ACCESS_T || - xattr_type == XATTR_ACL_DEFAULT_T)) { - rce = rct_search(&sbi->ll_rct, current_pid()); - if (rce == NULL || - (rce->rce_ops != RMT_LSETFACL && - rce->rce_ops != RMT_LGETFACL && - rce->rce_ops != RMT_RSETFACL && - rce->rce_ops != RMT_RGETFACL)) - RETURN(-EOPNOTSUPP); - } - /* posix acl is under protection of LOOKUP lock. when calling to this, * we just have path resolution to the target inode, so we have great * chance that cached ACL is uptodate. */ - if (xattr_type == XATTR_ACL_ACCESS_T && - !(sbi->ll_flags & LL_SBI_RMT_CLIENT)) { - - struct posix_acl *acl; + if (xattr_type == XATTR_ACL_ACCESS_T) { + struct posix_acl *acl; spin_lock(&lli->lli_lock); acl = posix_acl_dup(lli->lli_posix_acl); @@ -365,7 +369,10 @@ int ll_getxattr_common(struct inode *inode, const char *name, #endif do_getxattr: - if (sbi->ll_xattr_cache_enabled && xattr_type != XATTR_ACL_ACCESS_T) { + if (sbi->ll_xattr_cache_enabled && + xattr_type != XATTR_ACL_ACCESS_T && + (xattr_type != XATTR_SECURITY_T || + strcmp(name, "security.selinux") != 0)) { rc = ll_xattr_cache_get(inode, name, buffer, size, valid); if (rc == -EAGAIN) goto getxattr_nocache; @@ -386,11 +393,8 @@ do_getxattr: } } else { getxattr_nocache: - oc = ll_mdscapa_get(inode); - rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, - valid | (rce ? rce_ops2valid(rce->rce_ops) : 0), - name, NULL, 0, size, 0, &req); - capa_put(oc); + rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), + valid, name, NULL, 0, size, 0, &req); if (rc < 0) GOTO(out_xattr, rc); @@ -421,22 +425,6 @@ getxattr_nocache: rc = body->mbo_eadatasize; } -#ifdef CONFIG_FS_POSIX_ACL - if (rce != NULL && rce->rce_ops == RMT_LSETFACL) { - ext_acl_xattr_header *acl; - - acl = lustre_posix_acl_xattr_2ext(buffer, rc); - if (IS_ERR(acl)) - GOTO(out, rc = PTR_ERR(acl)); - - rc = ee_add(&sbi->ll_et, current_pid(), ll_inode2fid(inode), - xattr_type, acl); - if (unlikely(rc < 0)) { - lustre_ext_acl_xattr_free(acl); - GOTO(out, rc); - } - } -#endif EXIT; out_xattr: @@ -462,7 +450,7 @@ static ssize_t ll_getxattr_lov(struct inode *inode, void *buf, size_t buf_size) .cl_buf.lb_buf = buf, .cl_buf.lb_len = buf_size, }; - int refcheck; + __u16 refcheck; if (obj == NULL) RETURN(-ENODATA);