#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/xattr.h>
+#ifdef HAVE_LINUX_SELINUX_IS_ENABLED
#include <linux/selinux.h>
+#endif
#define DEBUG_SUBSYSTEM S_LLITE
#include <obd_support.h>
#include <lustre_dlm.h>
#include <lustre_eacl.h>
+#include <lustre_swab.h>
#include "llite_internal.h"
}
#endif
+#ifdef HAVE_LINUX_SELINUX_IS_ENABLED
+# define test_xattr_is_selinux_disabled(handler, name) \
+ ((handler)->flags == XATTR_SECURITY_T && \
+ !selinux_is_enabled() && \
+ strcmp((name), "selinux") == 0)
+#else
+# define test_xattr_is_selinux_disabled(handler, name) \
+ ((handler)->flags == XATTR_SECURITY_T && \
+ strcmp((name), "selinux") == 0)
+#endif
+
const struct xattr_handler *get_xattr_type(const char *name)
{
int i;
struct ptlrpc_request *req = NULL;
const char *pv = value;
char *fullname;
+ ktime_t kstart = ktime_get();
u64 valid;
int rc;
ENTRY;
/* When setxattr() is called with a size of 0 the value is
* unconditionally replaced by "". When removexattr() is
* called we get a NULL value and XATTR_REPLACE for flags. */
- if (!value && flags == XATTR_REPLACE) {
- ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_REMOVEXATTR, 1);
+ if (!value && flags == XATTR_REPLACE)
valid = OBD_MD_FLXATTRRM;
- } else {
- ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETXATTR, 1);
+ else
valid = OBD_MD_FLXATTR;
- }
/* FIXME: enable IMA when the conditions are ready */
if (handler->flags == XATTR_SECURITY_T &&
if ((handler->flags == XATTR_ACL_ACCESS_T ||
handler->flags == XATTR_ACL_DEFAULT_T) &&
-#ifdef HAVE_INODE_OWNER_OR_CAPABLE
!inode_owner_or_capable(inode))
-#else
- !is_owner_or_cap(inode))
-#endif
RETURN(-EPERM);
/* b10667: ignore lustre special xattr for now */
RETURN(0);
/* LU-549: Disable security.selinux when selinux is disabled */
- if (handler->flags == XATTR_SECURITY_T && !selinux_is_enabled() &&
- strcmp(name, "selinux") == 0)
+ if (test_xattr_is_selinux_disabled(handler, name))
RETURN(-EOPNOTSUPP);
/*
if (rc) {
if (rc == -EOPNOTSUPP && handler->flags == XATTR_USER_T) {
LCONSOLE_INFO("Disabling user_xattr feature because it is not supported on the server\n");
- sbi->ll_flags &= ~LL_SBI_USER_XATTR;
- }
+ sbi->ll_flags &= ~LL_SBI_USER_XATTR;
+ }
RETURN(rc);
- }
+ }
+
+ ptlrpc_req_finished(req);
+
+ ll_stats_ops_tally(ll_i2sbi(inode), valid == OBD_MD_FLXATTRRM ?
+ LPROC_LL_REMOVEXATTR : LPROC_LL_SETXATTR,
+ ktime_us_delta(ktime_get(), kstart));
- ptlrpc_req_finished(req);
RETURN(0);
}
const char *name, const void *value, size_t size,
int flags)
{
+ ktime_t kstart = ktime_get();
+ int op_type = flags == XATTR_REPLACE ? LPROC_LL_REMOVEXATTR :
+ LPROC_LL_SETXATTR;
+ int rc;
+
LASSERT(inode);
LASSERT(name);
/* lustre/trusted.lov.xxx would be passed through xattr API */
if (!strcmp(name, "lov")) {
- int op_type = flags == XATTR_REPLACE ? LPROC_LL_REMOVEXATTR :
- LPROC_LL_SETXATTR;
-
- ll_stats_ops_tally(ll_i2sbi(inode), op_type, 1);
-
- return ll_setstripe_ea(dentry, (struct lov_user_md *)value,
+ rc = ll_setstripe_ea(dentry, (struct lov_user_md *)value,
size);
+ ll_stats_ops_tally(ll_i2sbi(inode), op_type,
+ ktime_us_delta(ktime_get(), kstart));
+ return rc;
} else if (!strcmp(name, "lma") || !strcmp(name, "link")) {
- int op_type = flags == XATTR_REPLACE ? LPROC_LL_REMOVEXATTR :
- LPROC_LL_SETXATTR;
-
- ll_stats_ops_tally(ll_i2sbi(inode), op_type, 1);
+ ll_stats_ops_tally(ll_i2sbi(inode), op_type,
+ ktime_us_delta(ktime_get(), kstart));
return 0;
}
+ if (strncmp(name, "lov.", 4) == 0 &&
+ (__swab32(((struct lov_user_md *)value)->lmm_magic) &
+ le32_to_cpu(LOV_MAGIC_MASK)) == le32_to_cpu(LOV_MAGIC_MAGIC))
+ lustre_swab_lov_user_md((struct lov_user_md *)value, 0);
+
return ll_xattr_set_common(handler, dentry, inode, name, value, size,
flags);
}
struct ll_inode_info *lli = ll_i2info(inode);
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct ptlrpc_request *req = NULL;
- struct mdt_body *body;
void *xdata;
int rc;
ENTRY;
if (rc < 0)
GOTO(out_xattr, rc);
- body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
- LASSERT(body);
-
/* only detect the xattr size */
if (size == 0)
- GOTO(out, rc = body->mbo_eadatasize);
+ GOTO(out, rc);
- if (size < body->mbo_eadatasize) {
- CERROR("server bug: replied size %u > %u\n",
- body->mbo_eadatasize, (int)size);
+ if (size < rc)
GOTO(out, rc = -ERANGE);
- }
-
- if (body->mbo_eadatasize == 0)
- GOTO(out, rc = -ENODATA);
/* do not need swab xattr data */
xdata = req_capsule_server_sized_get(&req->rq_pill, &RMF_EADATA,
- body->mbo_eadatasize);
+ rc);
if (!xdata)
- GOTO(out, rc = -EFAULT);
+ GOTO(out, rc = -EPROTO);
- memcpy(buffer, xdata, body->mbo_eadatasize);
- rc = body->mbo_eadatasize;
+ memcpy(buffer, xdata, rc);
}
EXIT;
out_xattr:
if (rc == -EOPNOTSUPP && type == XATTR_USER_T) {
LCONSOLE_INFO("%s: disabling user_xattr feature because "
- "it is not supported on the server: rc = %d\n",
- ll_get_fsname(inode->i_sb, NULL, 0), rc);
+ "it is not supported on the server: rc = %d\n",
+ sbi->ll_fsname, rc);
sbi->ll_flags &= ~LL_SBI_USER_XATTR;
}
out:
const char *name, void *buffer, size_t size)
{
struct ll_sb_info *sbi = ll_i2sbi(inode);
+ ktime_t kstart = ktime_get();
char *fullname;
int rc;
ENTRY;
- ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR, 1);
-
rc = xattr_type_filter(sbi, handler);
if (rc)
RETURN(rc);
/* LU-549: Disable security.selinux when selinux is disabled */
- if (handler->flags == XATTR_SECURITY_T && !selinux_is_enabled() &&
- !strcmp(name, "selinux"))
+ if (test_xattr_is_selinux_disabled(handler, name))
RETURN(-EOPNOTSUPP);
-#ifdef CONFIG_FS_POSIX_ACL
+#ifdef CONFIG_LUSTRE_FS_POSIX_ACL
/* 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.
rc = ll_xattr_list(inode, fullname, handler->flags, buffer, size,
OBD_MD_FLXATTR);
kfree(fullname);
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETXATTR,
+ ktime_us_delta(ktime_get(), kstart));
+
RETURN(rc);
}
* recognizing layout gen as stripe offset when the
* file is restored. See LU-2809.
*/
- if (((struct lov_mds_md *)buf)->lmm_magic == LOV_MAGIC_COMP_V1)
+ if ((((struct lov_mds_md *)buf)->lmm_magic &
+ __swab32(LOV_MAGIC_MAGIC)) == __swab32(LOV_MAGIC_MAGIC))
+ lustre_swab_lov_user_md((struct lov_user_md *)buf,
+ cl.cl_size);
+
+ switch (((struct lov_mds_md *)buf)->lmm_magic) {
+ case LOV_MAGIC_V1:
+ case LOV_MAGIC_V3:
+ case LOV_MAGIC_SPECIFIC:
+ ((struct lov_mds_md *)buf)->lmm_layout_gen = 0;
+ break;
+ case LOV_MAGIC_COMP_V1:
+ case LOV_MAGIC_FOREIGN:
goto out_env;
+ default:
+ CERROR("Invalid LOV magic %08x\n",
+ ((struct lov_mds_md *)buf)->lmm_magic);
+ GOTO(out_env, rc = -EINVAL);
+ }
- ((struct lov_mds_md *)buf)->lmm_layout_gen = 0;
out_env:
cl_env_put(env, &refcheck);
RETURN(rc);
} else if (S_ISDIR(inode->i_mode)) {
struct ptlrpc_request *req = NULL;
+ struct ptlrpc_request *root_req = NULL;
struct lov_mds_md *lmm = NULL;
int lmm_size = 0;
- rc = ll_dir_getstripe(inode, (void **)&lmm, &lmm_size,
- &req, 0);
+ rc = ll_dir_getstripe_default(inode, (void **)&lmm, &lmm_size,
+ &req, &root_req, 0);
if (rc < 0)
GOTO(out_req, rc);
out_req:
if (req)
ptlrpc_req_finished(req);
+ if (root_req)
+ ptlrpc_req_finished(root_req);
RETURN(rc);
} else {
{
struct inode *inode = dentry->d_inode;
struct ll_sb_info *sbi = ll_i2sbi(inode);
+ ktime_t kstart = ktime_get();
char *xattr_name;
ssize_t rc, rc2;
size_t len, rem;
CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n",
PFID(ll_inode2fid(inode)), inode);
- ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_LISTXATTR, 1);
-
rc = ll_xattr_list(inode, NULL, XATTR_OTHER_T, buffer, size,
OBD_MD_FLXATTRLS);
if (rc < 0)
* exists.
*/
if (!size)
- RETURN(rc + sizeof(XATTR_LUSTRE_LOV));
+ goto out;
xattr_name = buffer;
rem = rc;
memcpy(buffer + rc, XATTR_LUSTRE_LOV, sizeof(XATTR_LUSTRE_LOV));
+out:
+ ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_LISTXATTR,
+ ktime_us_delta(ktime_get(), kstart));
+
RETURN(rc + sizeof(XATTR_LUSTRE_LOV));
}
&ll_user_xattr_handler,
&ll_trusted_xattr_handler,
&ll_security_xattr_handler,
-#ifdef CONFIG_FS_POSIX_ACL
+#ifdef CONFIG_LUSTRE_FS_POSIX_ACL
&ll_acl_access_xattr_handler,
&ll_acl_default_xattr_handler,
#endif