-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see [sun.com URL with a
- * copy of GPLv2].
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* GPL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* Author: Fan Yong <fanyong@clusterfs.com>
*/
-#ifndef EXPORT_SYMTAB
-# define EXPORT_SYMTAB
-#endif
-
#define DEBUG_SUBSYSTEM S_SEC
-
-#include <linux/lustre_acl.h>
+#include <lu_object.h>
+#include <lustre_acl.h>
#include <lustre_eacl.h>
#include <obd_support.h>
+#ifdef HAVE_SERVER_SUPPORT
+# include <lustre_idmap.h>
+# include <md_object.h>
+#endif /* HAVE_SERVER_SUPPORT */
#ifdef CONFIG_FS_POSIX_ACL
d->e_id = cpu_to_le32(s->e_id);
}
+#ifdef HAVE_SERVER_SUPPORT
/*
* Check permission based on POSIX ACL.
*/
-int lustre_posix_acl_permission(struct md_ucred *mu, struct lu_attr *la,
- int want, posix_acl_xattr_entry *entry,
- int count)
+int lustre_posix_acl_permission(struct lu_ucred *mu, struct lu_attr *la,
+ int want, posix_acl_xattr_entry *entry,
+ int count)
{
posix_acl_xattr_entry *pa, *pe, *mask_obj;
posix_acl_xattr_entry ae, me;
switch (ae.e_tag) {
case ACL_USER_OBJ:
/* (May have been checked already) */
- if (la->la_uid == mu->mu_fsuid)
- goto check_perm;
+ if (la->la_uid == mu->uc_fsuid)
+ goto check_perm;
break;
case ACL_USER:
- if (ae.e_id == mu->mu_fsuid)
- goto mask;
+ if (ae.e_id == mu->uc_fsuid)
+ goto mask;
break;
case ACL_GROUP_OBJ:
if (lustre_in_group_p(mu, la->la_gid)) {
EXPORT_SYMBOL(lustre_posix_acl_chmod_masq);
/*
+ * Returns 0 if the acl can be exactly represented in the traditional
+ * file mode permission bits, or else 1. Returns -E... on error.
+ */
+ int
+lustre_posix_acl_equiv_mode(posix_acl_xattr_entry *entry, mode_t *mode_p,
+ int count)
+{
+ posix_acl_xattr_entry *pa, *pe;
+ mode_t mode = 0;
+ int not_equiv = 0;
+
+ for (pa = &entry[0], pe = &entry[count - 1]; pa <= pe; pa++) {
+ __u16 perm = le16_to_cpu(pa->e_perm);
+ switch (le16_to_cpu(pa->e_tag)) {
+ case ACL_USER_OBJ:
+ mode |= (perm & S_IRWXO) << 6;
+ break;
+ case ACL_GROUP_OBJ:
+ mode |= (perm & S_IRWXO) << 3;
+ break;
+ case ACL_OTHER:
+ mode |= perm & S_IRWXO;
+ break;
+ case ACL_MASK:
+ mode = (mode & ~S_IRWXG) |
+ ((perm & S_IRWXO) << 3);
+ not_equiv = 1;
+ break;
+ case ACL_USER:
+ case ACL_GROUP:
+ not_equiv = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+ if (mode_p)
+ *mode_p = (*mode_p & ~S_IRWXUGO) | mode;
+ return not_equiv;
+}
+EXPORT_SYMBOL(lustre_posix_acl_equiv_mode);
+
+/*
* Modify acl when creating a new object.
*/
int lustre_posix_acl_create_masq(posix_acl_xattr_entry *entry, __u32 *pmode,
}
EXPORT_SYMBOL(lustre_posix_acl_create_masq);
+/*
+ * Convert server-side uid/gid in the posix ACL items to the client-side ones.
+ * convert rule:
+ * @CFS_IC_NOTHING
+ * nothing to be converted.
+ * @CFS_IC_ALL
+ * mapped ids are converted to client-side ones,
+ * unmapped ones are converted to "nobody".
+ * @CFS_IC_MAPPED
+ * only mapped ids are converted to "nobody".
+ * @CFS_IC_UNMAPPED
+ * only unmapped ids are converted to "nobody".
+ */
+int lustre_posix_acl_xattr_id2client(struct lu_ucred *mu,
+ struct lustre_idmap_table *t,
+ posix_acl_xattr_header *header,
+ int size, int flags)
+{
+ int count, i;
+ __u32 id;
+ ENTRY;
+
+ if (unlikely(size < 0))
+ RETURN(-EINVAL);
+ else if (!size)
+ RETURN(0);
+
+ if (unlikely(flags == CFS_IC_NOTHING))
+ RETURN(0);
+
+ count = CFS_ACL_XATTR_COUNT(size, posix_acl_xattr);
+ for (i = 0; i < count; i++) {
+ id = le32_to_cpu(header->a_entries[i].e_id);
+ switch (le16_to_cpu(header->a_entries[i].e_tag)) {
+ case ACL_USER_OBJ:
+ case ACL_GROUP_OBJ:
+ case ACL_MASK:
+ case ACL_OTHER:
+ if (id != ACL_UNDEFINED_ID)
+ RETURN(-EIO);
+ break;
+ case ACL_USER:
+ id = lustre_idmap_lookup_uid(mu, t, 1, id);
+ if (flags == CFS_IC_ALL) {
+ if (id == CFS_IDMAP_NOTFOUND)
+ id = NOBODY_UID;
+ header->a_entries[i].e_id = cpu_to_le32(id);
+ } else if (flags == CFS_IC_MAPPED) {
+ if (id != CFS_IDMAP_NOTFOUND)
+ header->a_entries[i].e_id =
+ cpu_to_le32(NOBODY_UID);
+ } else if (flags == CFS_IC_UNMAPPED) {
+ if (id == CFS_IDMAP_NOTFOUND)
+ header->a_entries[i].e_id =
+ cpu_to_le32(NOBODY_UID);
+ }
+ break;
+ case ACL_GROUP:
+ id = lustre_idmap_lookup_gid(mu, t, 1, id);
+ if (flags == CFS_IC_ALL) {
+ if (id == CFS_IDMAP_NOTFOUND)
+ id = NOBODY_GID;
+ header->a_entries[i].e_id = cpu_to_le32(id);
+ } else if (flags == CFS_IC_MAPPED) {
+ if (id != CFS_IDMAP_NOTFOUND)
+ header->a_entries[i].e_id =
+ cpu_to_le32(NOBODY_GID);
+ } else if (flags == CFS_IC_UNMAPPED) {
+ if (id == CFS_IDMAP_NOTFOUND)
+ header->a_entries[i].e_id =
+ cpu_to_le32(NOBODY_GID);
+ }
+ break;
+ default:
+ RETURN(-EIO);
+ }
+ }
+
+ RETURN(0);
+}
+EXPORT_SYMBOL(lustre_posix_acl_xattr_id2client);
+
+/*
+ * Converts client-side uid/gid in the extended ACL items to server-side ones.
+ * convert rule:
+ * mapped ids are converted to server-side ones,
+ * unmapped ones cause "EPERM" error.
+ */
+int lustre_ext_acl_xattr_id2server(struct lu_ucred *mu,
+ struct lustre_idmap_table *t,
+ ext_acl_xattr_header *header)
+{
+ int i, count = le32_to_cpu(header->a_count);
+ __u32 id;
+ ENTRY;
+
+ for (i = 0; i < count; i++) {
+ id = le32_to_cpu(header->a_entries[i].e_id);
+ switch (le16_to_cpu(header->a_entries[i].e_tag)) {
+ case ACL_USER_OBJ:
+ case ACL_GROUP_OBJ:
+ case ACL_MASK:
+ case ACL_OTHER:
+ if (id != ACL_UNDEFINED_ID)
+ RETURN(-EIO);
+ break;
+ case ACL_USER:
+ id = lustre_idmap_lookup_uid(mu, t, 0, id);
+ if (id == CFS_IDMAP_NOTFOUND)
+ RETURN(-EPERM);
+ else
+ header->a_entries[i].e_id = cpu_to_le32(id);
+ break;
+ case ACL_GROUP:
+ id = lustre_idmap_lookup_gid(mu, t, 0, id);
+ if (id == CFS_IDMAP_NOTFOUND)
+ RETURN(-EPERM);
+ else
+ header->a_entries[i].e_id = cpu_to_le32(id);
+ break;
+ default:
+ RETURN(-EIO);
+ }
+ }
+
+ RETURN(0);
+}
+EXPORT_SYMBOL(lustre_ext_acl_xattr_id2server);
+#endif /* HAVE_SERVER_SUPPORT */
+
/* if "new_count == 0", then "new = {a_version, NULL}", NOT NULL. */
static int lustre_posix_acl_xattr_reduce_space(posix_acl_xattr_header **header,
int old_count, int new_count)
EXPORT_SYMBOL(lustre_posix_acl_xattr_filter);
/*
- * Convert server-side uid/gid in the posix ACL items to the client-side ones.
- * convert rule:
- * @CFS_IC_NOTHING
- * nothing to be converted.
- * @CFS_IC_ALL
- * mapped ids are converted to client-side ones,
- * unmapped ones are converted to "nobody".
- * @CFS_IC_MAPPED
- * only mapped ids are converted to "nobody".
- * @CFS_IC_UNMAPPED
- * only unmapped ids are converted to "nobody".
- */
-int lustre_posix_acl_xattr_id2client(struct md_ucred *mu,
- struct lustre_idmap_table *t,
- posix_acl_xattr_header *header,
- int size, int flags)
-{
- int count, i;
- __u32 id;
- ENTRY;
-
- if (unlikely(size < 0))
- RETURN(-EINVAL);
- else if (!size)
- RETURN(0);
-
- if (unlikely(flags == CFS_IC_NOTHING))
- RETURN(0);
-
- count = CFS_ACL_XATTR_COUNT(size, posix_acl_xattr);
- for (i = 0; i < count; i++) {
- id = le32_to_cpu(header->a_entries[i].e_id);
- switch (le16_to_cpu(header->a_entries[i].e_tag)) {
- case ACL_USER_OBJ:
- case ACL_GROUP_OBJ:
- case ACL_MASK:
- case ACL_OTHER:
- if (id != ACL_UNDEFINED_ID)
- RETURN(-EIO);
- break;
- case ACL_USER:
- id = lustre_idmap_lookup_uid(mu, t, 1, id);
- if (flags == CFS_IC_ALL) {
- if (id == CFS_IDMAP_NOTFOUND)
- id = NOBODY_UID;
- header->a_entries[i].e_id = cpu_to_le32(id);
- } else if (flags == CFS_IC_MAPPED) {
- if (id != CFS_IDMAP_NOTFOUND)
- header->a_entries[i].e_id =
- cpu_to_le32(NOBODY_UID);
- } else if (flags == CFS_IC_UNMAPPED) {
- if (id == CFS_IDMAP_NOTFOUND)
- header->a_entries[i].e_id =
- cpu_to_le32(NOBODY_UID);
- }
- break;
- case ACL_GROUP:
- id = lustre_idmap_lookup_gid(mu, t, 1, id);
- if (flags == CFS_IC_ALL) {
- if (id == CFS_IDMAP_NOTFOUND)
- id = NOBODY_GID;
- header->a_entries[i].e_id = cpu_to_le32(id);
- } else if (flags == CFS_IC_MAPPED) {
- if (id != CFS_IDMAP_NOTFOUND)
- header->a_entries[i].e_id =
- cpu_to_le32(NOBODY_GID);
- } else if (flags == CFS_IC_UNMAPPED) {
- if (id == CFS_IDMAP_NOTFOUND)
- header->a_entries[i].e_id =
- cpu_to_le32(NOBODY_GID);
- }
- break;
- default:
- RETURN(-EIO);
- }
- }
- RETURN(0);
-}
-EXPORT_SYMBOL(lustre_posix_acl_xattr_id2client);
-
-/*
* Release the posix ACL space.
*/
void lustre_posix_acl_xattr_free(posix_acl_xattr_header *header, int size)
EXPORT_SYMBOL(lustre_posix_acl_xattr_free);
/*
- * Converts client-side uid/gid in the extended ACL items to server-side ones.
- * convert rule:
- * mapped ids are converted to server-side ones,
- * unmapped ones cause "EPERM" error.
- */
-int lustre_ext_acl_xattr_id2server(struct md_ucred *mu,
- struct lustre_idmap_table *t,
- ext_acl_xattr_header *header)
-
-{
- int i, count = le32_to_cpu(header->a_count);
- __u32 id;
- ENTRY;
-
- for (i = 0; i < count; i++) {
- id = le32_to_cpu(header->a_entries[i].e_id);
- switch (le16_to_cpu(header->a_entries[i].e_tag)) {
- case ACL_USER_OBJ:
- case ACL_GROUP_OBJ:
- case ACL_MASK:
- case ACL_OTHER:
- if (id != ACL_UNDEFINED_ID)
- RETURN(-EIO);
- break;
- case ACL_USER:
- id = lustre_idmap_lookup_uid(mu, t, 0, id);
- if (id == CFS_IDMAP_NOTFOUND)
- RETURN(-EPERM);
- else
- header->a_entries[i].e_id = cpu_to_le32(id);
- break;
- case ACL_GROUP:
- id = lustre_idmap_lookup_gid(mu, t, 0, id);
- if (id == CFS_IDMAP_NOTFOUND)
- RETURN(-EPERM);
- else
- header->a_entries[i].e_id = cpu_to_le32(id);
- break;
- default:
- RETURN(-EIO);
- }
- }
- RETURN(0);
-}
-EXPORT_SYMBOL(lustre_ext_acl_xattr_id2server);
-
-/*
* Release the extended ACL space.
*/
void lustre_ext_acl_xattr_free(ext_acl_xattr_header *header)
if (posix_header->a_entries[i].e_perm !=
ee->e_perm)
/* entry modified. */
- ee->e_perm =
+ ee->e_stat =
new->a_entries[j++].e_stat =
cpu_to_le32(ES_MOD);
else
/* entry unchanged. */
- ee->e_perm =
+ ee->e_stat =
new->a_entries[j++].e_stat =
cpu_to_le32(ES_UNC);
} else {
if (posix_header->a_entries[i].e_perm !=
ee->e_perm)
/* entry modified. */
- ee->e_perm =
+ ee->e_stat =
new->a_entries[j++].e_stat =
cpu_to_le32(ES_MOD);
else
/* entry unchanged. */
- ee->e_perm =
+ ee->e_stat =
new->a_entries[j++].e_stat =
cpu_to_le32(ES_UNC);
} else {