#define OBD_MD_FID (0x0000000080000000LL) /* lustre_id data */
#define OBD_MD_MEA (0x0000000100000000LL) /* shows we are interested in MEA */
#define OBD_MD_FLEALIST (0x0000000200000000LL) /* list extended attributes */
-#define OBD_MD_FLACL_ACCESS (0x0000000400000000LL) /*access acl*/
+#define OBD_MD_FLACL_ACCESS (0x0000000400000000LL) /* access acl */
+#define OBD_MD_RACL (0x0000000800000000LL) /* remote acl */
#define OBD_MD_FLNOTOBD (~(OBD_MD_FLBLOCKS | OBD_MD_LINKNAME | \
OBD_MD_FLEASIZE | OBD_MD_FLHANDLE | \
MDS_UNPIN = 43,
MDS_SYNC = 44,
MDS_DONE_WRITING = 45,
+ MDS_ACCESS_CHECK = 46,
MDS_LAST_OPC
} mds_cmd_t;
extern void lustre_swab_mds_body (struct mds_body *b);
+struct mds_remote_perm {
+ __u32 mrp_auth_uid;
+ __u32 mrp_auth_gid;
+ __u16 mrp_perm;
+ __u8 mrp_allow_setuid;
+ __u8 mrp_allow_setgid;
+};
+
struct lustre_md {
- struct mds_body *body;
- struct lov_stripe_md *lsm;
- struct mea *mea;
- struct posix_acl *acl_access;
+ struct mds_body *body;
+ struct lov_stripe_md *lsm;
+ struct mea *mea;
+ struct posix_acl *posix_acl;
+ struct mds_remote_perm *remote_perm;
};
+void lustre_swab_remote_perm(struct mds_remote_perm *p);
+
struct mdc_op_data {
struct lustre_id id1;
struct lustre_id id2;
#include <linux/namei.h>
+/* forward declarations */
+struct remote_acl;
+
/* careful, this is easy to screw up */
#define PAGE_CACHE_MAXBYTES ((__u64)(~0UL) << PAGE_CACHE_SHIFT)
__u64 lli_open_fd_write_count;
struct obd_client_handle *lli_mds_exec_och;
__u64 lli_open_fd_exec_count;
- struct posix_acl *lli_acl_access;
+
+ struct posix_acl *lli_posix_acl;
+ struct remote_acl *lli_remote_acl;
};
// FIXME: replace the name of this with LL_I to conform to kernel stuff
int (*m_getattr)(struct obd_export *, struct lustre_id *,
__u64, const char *, int,
unsigned int, struct ptlrpc_request **);
+ int (*m_access_check)(struct obd_export *, struct lustre_id *,
+ struct ptlrpc_request **);
int (*m_getattr_lock)(struct obd_export *, struct lustre_id *,
char *, int, __u64,
unsigned int, struct ptlrpc_request **);
RETURN(rc);
}
+static inline int md_access_check(struct obd_export *exp, struct lustre_id *id,
+ struct ptlrpc_request **request)
+{
+ int rc;
+ ENTRY;
+ EXP_CHECK_MD_OP(exp, access_check);
+ MD_COUNTER_INCREMENT(exp->exp_obd, access_check);
+ rc = MDP(exp->exp_obd, access_check)(exp, id, request);
+ RETURN(rc);
+}
+
static inline int md_change_cbdata(struct obd_export *exp, struct lustre_id *id,
ldlm_iterator_t it, void *data)
{
#define OBD_FAIL_MDS_PAUSE_OPEN 0x129
#define OBD_FAIL_MDS_STATFS_LCW_SLEEP 0x12a
#define OBD_FAIL_MDS_OPEN_CREATE 0x12b
+#define OBD_FAIL_MDS_ACCESS_CHECK_NET 0x12c
+#define OBD_FAIL_MDS_ACCESS_CHECK_PACK 0x12d
#define OBD_FAIL_OST 0x200
#define OBD_FAIL_OST_CONNECT_NET 0x201
lli = ll_i2info(dentry->d_inode);
spin_lock(&lli->lli_lock);
- if (lli->lli_acl_access != NULL)
- posix_acl_release(lli->lli_acl_access);
- lli->lli_acl_access = acl;
+ if (lli->lli_posix_acl != NULL)
+ posix_acl_release(lli->lli_posix_acl);
+ lli->lli_posix_acl = acl;
spin_unlock(&lli->lli_lock);
}
EXIT;
struct ptlrpc_request *req = NULL;
struct ll_inode_info *lli = ll_i2info(inode);
struct posix_acl *acl;
- int rc;
+ int rc = 0;
ENTRY;
sbi = ll_i2sbi(inode);
GOTO(out, rc);
}
- ll_lookup_finish_locks(&it, &de);
- ll_intent_free(&it);
-
- spin_lock(&lli->lli_lock);
- acl = posix_acl_dup(ll_i2info(inode)->lli_acl_access);
- spin_unlock(&lli->lli_lock);
+ if (sbi->ll_remote) {
+ rc = ll_remote_acl_permission(inode, mask);
+ } else {
+ spin_lock(&lli->lli_lock);
+ acl = posix_acl_dup(ll_i2info(inode)->lli_posix_acl);
+ spin_unlock(&lli->lli_lock);
- if (!acl)
- GOTO(out, rc = -EAGAIN);
+ if (!acl)
+ rc = -EAGAIN;
+ else {
+ rc = posix_acl_permission(inode, acl, mask);
+ posix_acl_release(acl);
+ }
+ }
- rc = posix_acl_permission(inode, acl, mask);
- posix_acl_release(acl);
+ ll_lookup_finish_locks(&it, &de);
+ ll_intent_free(&it);
out:
if (req)
LLAP__ORIGIN_MAX,
};
+/*
+ * remote ACL stuff
+ */
+#define REMOTE_ACL_HASHSIZE 16
+
+struct remote_acl {
+ struct list_head ra_perm_cache[REMOTE_ACL_HASHSIZE];
+ spinlock_t ra_lock;
+ /* we use one sem per inode, it's kind of coarse: one user must
+ * wait if another user is updating the perm on this inode. but
+ * I guess this is fine is real world usage.
+ */
+ struct semaphore ra_update_sem;
+};
+
+struct lustre_remote_perm {
+ struct list_head lrp_list;
+ uid_t lrp_auth_uid; /* authenticated uid */
+ gid_t lrp_auth_gid; /* authenticated gid */
+ uint16_t lrp_perm; /* permission bits */
+ uint16_t lrp_valid:1, /* lrp_perm is valid */
+ lrp_setuid:1, /* allow setuid */
+ lrp_setgid:1; /* allow setgid */
+ struct list_head lrp_setxid_perms; /* setxid perms list */
+};
+
+struct remote_perm_setxid {
+ struct list_head list; /* permission list */
+ uid_t uid;
+ gid_t gid;
+ uint16_t perm;
+};
+
/* llite/lproc_llite.c */
int lprocfs_register_mountpoint(struct proc_dir_entry *parent,
struct super_block *sb, char *lov,
int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
unsigned long maxage);
void ll_update_inode(struct inode *inode, struct lustre_md *);
+int ll_fetch_remote_perm(struct inode *inode, struct ptlrpc_request *req,
+ uint16_t *perm);
int it_disposition(struct lookup_intent *it, int flag);
void it_set_disposition(struct lookup_intent *it, int flag);
void ll_read_inode2(struct inode *inode, void *opaque);
int ll_show_options(struct seq_file *m, struct vfsmount *mnt);
int ll_flush_cred(struct inode *inode);
+int ll_remote_acl_permission(struct inode *inode, int mode);
+int ll_remote_acl_update(struct inode *inode, struct mds_remote_perm *perm);
+void ll_inode_invalidate_acl(struct inode *inode);
+
/* llite/special.c */
extern struct inode_operations ll_special_inode_operations;
extern struct file_operations ll_special_chr_inode_fops;
return LDLM_ITER_CONTINUE;
}
+static void remote_acl_free(struct remote_acl *racl);
+
void ll_clear_inode(struct inode *inode)
{
struct lustre_id id;
strlen(lli->lli_symlink_name) + 1);
lli->lli_symlink_name = NULL;
}
+
+ if (lli->lli_posix_acl) {
+ LASSERT(lli->lli_remote_acl == NULL);
+ posix_acl_release(lli->lli_posix_acl);
+ lli->lli_posix_acl = NULL;
+ }
+
+ if (lli->lli_remote_acl) {
+ LASSERT(lli->lli_posix_acl == NULL);
+ remote_acl_free(lli->lli_remote_acl);
+ lli->lli_remote_acl = NULL;
+ }
+
lli->lli_inode_magic = LLI_INODE_DEAD;
EXIT;
return 0;
}
+
+/********************************
+ * remote acl *
+ ********************************/
+
+static struct remote_acl *remote_acl_alloc(void)
+{
+ struct remote_acl *racl;
+ int i;
+
+ OBD_ALLOC(racl, sizeof(*racl));
+ if (!racl)
+ return NULL;
+
+ spin_lock_init(&racl->ra_lock);
+ init_MUTEX(&racl->ra_update_sem);
+
+ for (i = 0; i < REMOTE_ACL_HASHSIZE; i++)
+ INIT_LIST_HEAD(&racl->ra_perm_cache[i]);
+
+ return racl;
+}
+
+/*
+ * caller should guarantee no race here.
+ */
+static void remote_perm_flush_xperms(struct lustre_remote_perm *perm)
+{
+ struct remote_perm_setxid *xperm;
+
+ while (!list_empty(&perm->lrp_setxid_perms)) {
+ xperm = list_entry(perm->lrp_setxid_perms.next,
+ struct remote_perm_setxid,
+ list);
+ list_del(&xperm->list);
+ OBD_FREE(xperm, sizeof(*xperm));
+ }
+}
+
+/*
+ * caller should guarantee no race here.
+ */
+static void remote_acl_flush(struct remote_acl *racl)
+{
+ struct list_head *head;
+ struct lustre_remote_perm *perm, *tmp;
+ int i;
+
+ for (i = 0; i < REMOTE_ACL_HASHSIZE; i++) {
+ head = &racl->ra_perm_cache[i];
+
+ list_for_each_entry_safe(perm, tmp, head, lrp_list) {
+ remote_perm_flush_xperms(perm);
+ list_del(&perm->lrp_list);
+ OBD_FREE(perm, sizeof(*perm));
+ }
+ }
+}
+
+static void remote_acl_free(struct remote_acl *racl)
+{
+ if (!racl)
+ return;
+
+ down(&racl->ra_update_sem);
+ spin_lock(&racl->ra_lock);
+ remote_acl_flush(racl);
+ spin_unlock(&racl->ra_lock);
+ up(&racl->ra_update_sem);
+
+ OBD_FREE(racl, sizeof(*racl));
+}
+
+static inline int remote_acl_hashfunc(__u32 id)
+{
+ return (id & (REMOTE_ACL_HASHSIZE - 1));
+}
+
+static
+int __remote_acl_check(struct remote_acl *racl, unsigned int *perm)
+{
+ struct list_head *head;
+ struct lustre_remote_perm *lperm;
+ struct remote_perm_setxid *xperm;
+ int found = 0, rc = -ENOENT;
+
+ LASSERT(racl);
+ head = &racl->ra_perm_cache[remote_acl_hashfunc(current->uid)];
+ spin_lock(&racl->ra_lock);
+
+ list_for_each_entry(lperm, head, lrp_list) {
+ if (lperm->lrp_auth_uid == current->uid) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found)
+ goto out;
+
+ if (lperm->lrp_auth_uid == current->fsuid &&
+ lperm->lrp_auth_gid == current->fsgid) {
+ if (lperm->lrp_valid) {
+ *perm = lperm->lrp_perm;
+ rc = 0;
+ }
+ goto out;
+ } else if ((!lperm->lrp_setuid &&
+ lperm->lrp_auth_uid != current->fsuid) ||
+ (!lperm->lrp_setgid &&
+ lperm->lrp_auth_gid != current->fsgid)) {
+ *perm = 0;
+ rc = 0;
+ goto out;
+ }
+
+ list_for_each_entry(xperm, &lperm->lrp_setxid_perms, list) {
+ if (xperm->uid == current->fsuid &&
+ xperm->gid == current->fsgid) {
+ *perm = xperm->perm;
+ rc = 0;
+ goto out;
+ }
+ }
+
+out:
+ spin_unlock(&racl->ra_lock);
+ return rc;
+}
+
+static
+int __remote_acl_update(struct remote_acl *racl,
+ struct mds_remote_perm *mperm,
+ struct lustre_remote_perm *lperm,
+ struct remote_perm_setxid *xperm)
+{
+ struct list_head *head;
+ struct lustre_remote_perm *lp;
+ struct remote_perm_setxid *xp;
+ int found = 0, setuid = 0, setgid = 0;
+
+ LASSERT(racl);
+ LASSERT(mperm);
+ LASSERT(lperm);
+ LASSERT(current->uid == mperm->mrp_auth_uid);
+
+ if (current->fsuid != mperm->mrp_auth_uid)
+ setuid = 1;
+ if (current->fsgid != mperm->mrp_auth_gid)
+ setgid = 1;
+
+ head = &racl->ra_perm_cache[remote_acl_hashfunc(current->uid)];
+ spin_lock(&racl->ra_lock);
+
+ list_for_each_entry(lp, head, lrp_list) {
+ if (lp->lrp_auth_uid == current->uid) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ OBD_FREE(lperm, sizeof(*lperm));
+
+ if (!lp->lrp_valid && !setuid && !setgid) {
+ lp->lrp_perm = mperm->mrp_perm;
+ lp->lrp_valid = 1;
+ }
+
+ /* sanity check for changes of setxid rules */
+ if ((lp->lrp_setuid != 0) != (mperm->mrp_allow_setuid != 0)) {
+ CWARN("setuid changes: %d => %d\n",
+ (lp->lrp_setuid != 0),
+ (mperm->mrp_allow_setuid != 0));
+ lp->lrp_setuid = (mperm->mrp_allow_setuid != 0);
+ }
+
+ if ((lp->lrp_setgid != 0) != (mperm->mrp_allow_setgid != 0)) {
+ CWARN("setgid changes: %d => %d\n",
+ (lp->lrp_setgid != 0),
+ (mperm->mrp_allow_setgid != 0));
+ lp->lrp_setgid = (mperm->mrp_allow_setgid != 0);
+ }
+
+ if (!lp->lrp_setuid && !lp->lrp_setgid &&
+ !list_empty(&lp->lrp_setxid_perms)) {
+ remote_perm_flush_xperms(lp);
+ }
+ } else {
+ /* initialize lperm and linked into hashtable
+ */
+ INIT_LIST_HEAD(&lperm->lrp_setxid_perms);
+ lperm->lrp_auth_uid = mperm->mrp_auth_uid;
+ lperm->lrp_auth_gid = mperm->mrp_auth_gid;
+ lperm->lrp_setuid = (mperm->mrp_allow_setuid != 0);
+ lperm->lrp_setgid = (mperm->mrp_allow_setgid != 0);
+ list_add(&lperm->lrp_list, head);
+
+ if (!setuid && !setgid) {
+ /* in this case, i'm the authenticated user,
+ * and mrp_perm is for me.
+ */
+ lperm->lrp_perm = mperm->mrp_perm;
+ lperm->lrp_valid = 1;
+ spin_unlock(&racl->ra_lock);
+
+ if (xperm)
+ OBD_FREE(xperm, sizeof(*xperm));
+ return 0;
+ }
+
+ lp = lperm;
+ /* fall through */
+ }
+
+ LASSERT(lp->lrp_setuid || lp->lrp_setgid ||
+ list_empty(&lp->lrp_setxid_perms));
+
+ /* if no xperm supplied, we are all done here */
+ if (!xperm) {
+ spin_unlock(&racl->ra_lock);
+ return 0;
+ }
+
+ /* whether we allow setuid/setgid */
+ if ((!lp->lrp_setuid && setuid) || (!lp->lrp_setgid && setgid)) {
+ OBD_FREE(xperm, sizeof(*xperm));
+ spin_unlock(&racl->ra_lock);
+ return 0;
+ }
+
+ /* traverse xperm list */
+ list_for_each_entry(xp, &lp->lrp_setxid_perms, list) {
+ if (xp->uid == current->fsuid &&
+ xp->gid == current->fsgid) {
+ if (xp->perm != mperm->mrp_perm) {
+ /* actually this should not happen */
+ CWARN("perm changed: %o => %o\n",
+ xp->perm, mperm->mrp_perm);
+ xp->perm = mperm->mrp_perm;
+ }
+ OBD_FREE(xperm, sizeof(*xperm));
+ spin_unlock(&racl->ra_lock);
+ return 0;
+ }
+ }
+
+ /* finally insert this xperm */
+ xperm->uid = current->fsuid;
+ xperm->gid = current->fsgid;
+ xperm->perm = mperm->mrp_perm;
+ list_add(&xperm->list, &lp->lrp_setxid_perms);
+
+ spin_unlock(&racl->ra_lock);
+ return 0;
+}
+
+/*
+ * remote_acl semaphore must be held by caller
+ */
+static
+int remote_acl_update_locked(struct remote_acl *racl,
+ struct mds_remote_perm *mperm)
+{
+ struct lustre_remote_perm *lperm;
+ struct remote_perm_setxid *xperm;
+ int setuid = 0, setgid = 0;
+
+ might_sleep();
+
+ if (current->uid != mperm->mrp_auth_uid) {
+ CERROR("current uid %u while authenticated as %u\n",
+ current->uid, mperm->mrp_auth_uid);
+ return -EINVAL;
+ }
+
+ if (current->fsuid != mperm->mrp_auth_uid)
+ setuid = 1;
+ if (current->fsgid == mperm->mrp_auth_gid)
+ setgid = 1;
+
+ OBD_ALLOC(lperm, sizeof(*lperm));
+ if (!lperm)
+ return -ENOMEM;
+
+ if ((setuid || setgid) &&
+ !(setuid && !mperm->mrp_allow_setuid) &&
+ !(setgid && !mperm->mrp_allow_setgid)) {
+ OBD_ALLOC(xperm, sizeof(*xperm));
+ if (!xperm) {
+ OBD_FREE(lperm, sizeof(*lperm));
+ return -ENOMEM;
+ }
+ } else
+ xperm = NULL;
+
+ return __remote_acl_update(racl, mperm, lperm, xperm);
+}
+
+/*
+ * return -EACCES at any error cases
+ */
+int ll_remote_acl_permission(struct inode *inode, int mode)
+{
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct remote_acl *racl = ll_i2info(inode)->lli_remote_acl;
+ struct ptlrpc_request *req = NULL;
+ struct lustre_id id;
+ struct mds_remote_perm *mperm;
+ int rc = -EACCES, perm;
+
+ if (!racl)
+ return -EACCES;
+
+ if (__remote_acl_check(racl, &perm) == 0) {
+ return ((perm & mode) == mode ? 0 : -EACCES);
+ }
+
+ might_sleep();
+
+ /* doing update
+ */
+ down(&racl->ra_update_sem);
+
+ /* we might lose the race when obtain semaphore,
+ * so check again.
+ */
+ if (__remote_acl_check(racl, &perm) == 0) {
+ if ((perm & mode) == mode)
+ rc = 0;
+ goto out;
+ }
+
+ /* really fetch from mds
+ */
+ ll_inode2id(&id, inode);
+ if (md_access_check(sbi->ll_md_exp, &id, &req))
+ goto out;
+
+ /* status non-zero indicate there's more apparent error
+ * detected by mds, e.g. didn't allow this user at all.
+ * we simply ignore and didn't cache it.
+ */
+ if (req->rq_repmsg->status)
+ goto out;
+
+ mperm = lustre_swab_repbuf(req, 1, sizeof(*mperm),
+ lustre_swab_remote_perm);
+ LASSERT(mperm);
+ LASSERT_REPSWABBED(req, 1);
+
+ if ((mperm->mrp_perm & mode) == mode)
+ rc = 0;
+
+ remote_acl_update_locked(racl, mperm);
+out:
+ if (req)
+ ptlrpc_req_finished(req);
+
+ up(&racl->ra_update_sem);
+ return rc;
+}
+
+int ll_remote_acl_update(struct inode *inode, struct mds_remote_perm *perm)
+{
+ struct remote_acl *racl = ll_i2info(inode)->lli_remote_acl;
+ int rc;
+
+ LASSERT(perm);
+
+ if (!racl)
+ return -EACCES;
+
+ down(&racl->ra_update_sem);
+ rc = remote_acl_update_locked(racl, perm);
+ up(&racl->ra_update_sem);
+
+ return rc;
+}
+
+void ll_inode_invalidate_acl(struct inode *inode)
+{
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct ll_inode_info *lli = ll_i2info(inode);
+
+ if (sbi->ll_remote) {
+ struct remote_acl *racl = lli->lli_remote_acl;
+
+ LASSERT(!lli->lli_posix_acl);
+ if (racl) {
+ down(&racl->ra_update_sem);
+ spin_lock(&racl->ra_lock);
+ remote_acl_flush(lli->lli_remote_acl);
+ spin_unlock(&racl->ra_lock);
+ up(&racl->ra_update_sem);
+ }
+ } else {
+ LASSERT(!lli->lli_remote_acl);
+ spin_lock(&lli->lli_lock);
+ posix_acl_release(lli->lli_posix_acl);
+ lli->lli_posix_acl = NULL;
+ spin_unlock(&lli->lli_lock);
+ }
+}
+
void ll_update_inode(struct inode *inode, struct lustre_md *md)
{
struct ll_inode_info *lli = ll_i2info(inode);
struct lov_stripe_md *lsm = md->lsm;
struct mds_body *body = md->body;
struct mea *mea = md->mea;
- struct posix_acl *ll_acl_access = md->acl_access;
+ struct posix_acl *posix_acl = md->posix_acl;
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
ENTRY;
LASSERT((lsm != NULL) == ((body->valid & OBD_MD_FLEASIZE) != 0));
if (body->valid & OBD_MD_FLGENER)
id_gen(&lli->lli_id) = id_gen(&body->id1);
- spin_lock(&lli->lli_lock);
- if (ll_acl_access != NULL) {
- if (lli->lli_acl_access != NULL)
- posix_acl_release(lli->lli_acl_access);
- lli->lli_acl_access = ll_acl_access;
+ /* local/remote ACL */
+ if (sbi->ll_remote) {
+ LASSERT(md->posix_acl == NULL);
+ if (md->remote_perm) {
+ ll_remote_acl_update(inode, md->remote_perm);
+ OBD_FREE(md->remote_perm, sizeof(*md->remote_perm));
+ md->remote_perm = NULL;
+ }
+ } else {
+ LASSERT(md->remote_perm == NULL);
+ spin_lock(&lli->lli_lock);
+ if (posix_acl != NULL) {
+ if (lli->lli_posix_acl != NULL)
+ posix_acl_release(lli->lli_posix_acl);
+ lli->lli_posix_acl = posix_acl;
+ }
+ spin_unlock(&lli->lli_lock);
}
- spin_unlock(&lli->lli_lock);
-
+
if (body->valid & OBD_MD_FLID)
inode->i_ino = id_ino(&body->id1);
if (body->valid & OBD_MD_FLGENER)
LASSERT(!lli->lli_smd);
+ if (ll_i2sbi(inode)->ll_remote) {
+ lli->lli_remote_acl = remote_acl_alloc();
+ /* if failed alloc, nobody will be able to access this inode */
+ }
+
/* Core attributes from the MDS first. This is a new inode, and
* the VFS doesn't zero times in the core inode so we have to do
* it ourselves. They will be overwritten by either MDS or OST
truncate_inode_pages(inode->i_mapping, 0);
}
+ /* we can't invalide acl here: suppose we touch a new file
+ * under a dir, blocking ast on dir will lead to open failure
+ * on client, although succeed on mds. it's kind of weird,
+ * the real fix i think is improve client-vfs interaction.
+ */
+#if 0
+ ll_inode_invalidate_acl(inode);
+#endif
+
if (inode->i_sb->s_root &&
inode != inode->i_sb->s_root->d_inode &&
(bits & MDS_INODELOCK_LOOKUP))
RETURN(rc);
}
+static int lmv_access_check(struct obd_export *exp,
+ struct lustre_id *id,
+ struct ptlrpc_request **request)
+{
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+ int rc, i = id_group(id);
+ ENTRY;
+
+ rc = lmv_check_connect(obd);
+ if (rc)
+ RETURN(rc);
+
+ LASSERT(i < lmv->desc.ld_tgt_count);
+ rc = md_access_check(lmv->tgts[i].ltd_exp, id, request);
+ RETURN(rc);
+}
+
static int lmv_change_cbdata(struct obd_export *exp,
struct lustre_id *id,
ldlm_iterator_t it,
.m_get_real_obd = lmv_get_real_obd,
.m_valid_attrs = lmv_valid_attrs,
.m_delete_inode = lmv_delete_inode,
+ .m_access_check = lmv_access_check,
};
int __init lmv_init(void)
}
LDLM_ERROR(data->lock, "lock on inode without such object\n");
dump_lsm(D_ERROR, data->lsm);
- portals_debug_dumpstack(NULL);
RETURN(-ENXIO);
} else if (keylen >= strlen("size_to_stripe") &&
strcmp(key, "size_to_stripe") == 0) {
RETURN (rc);
}
+int mdc_access_check(struct obd_export *exp, struct lustre_id *id,
+ struct ptlrpc_request **request)
+
+{
+ struct ptlrpc_request *req;
+ struct mds_body *body;
+ int size[2] = {0, sizeof(*body)};
+ int rc;
+ ENTRY;
+
+ size[0] = lustre_secdesc_size();
+ req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_MDS_VERSION,
+ MDS_ACCESS_CHECK, 2, size, NULL);
+ if (!req)
+ GOTO(out, rc = -ENOMEM);
+
+ lustre_pack_secdesc(req, size[0]);
+ body = lustre_msg_buf(req->rq_reqmsg, MDS_REQ_REC_OFF, sizeof (*body));
+ memcpy(&body->id1, id, sizeof(*id));
+
+ req->rq_replen = lustre_msg_size(2, size);
+ mdc_get_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
+ rc = ptlrpc_queue_wait(req);
+ mdc_put_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
+ if (rc != 0) {
+ ptlrpc_req_finished (req);
+ req = NULL;
+ } else {
+ body = lustre_swab_repbuf (req, 0, sizeof (*body),
+ lustre_swab_mds_body);
+ if (body == NULL) {
+ CERROR ("Can't unpack mds_body\n");
+ RETURN (-EPROTO);
+ }
+ }
+
+ out:
+ *request = req;
+ RETURN (rc);
+}
+
int mdc_getattr_lock(struct obd_export *exp, struct lustre_id *id,
char *filename, int namelen, __u64 valid,
unsigned int ea_size, struct ptlrpc_request **request)
unsigned int offset, struct obd_export *exp_lov,
struct lustre_md *md)
{
+ struct lov_mds_md *lmm;
+ struct posix_acl *acl;
+ struct mds_remote_perm *perm;
void *buf;
- int rc = 0;
int size, acl_off;
- struct posix_acl *acl;
- struct lov_mds_md *lmm;
+ int rc = 0;
ENTRY;
LASSERT(md != NULL);
LASSERT_REPSWABBED(req, offset);
- if (!(md->body->valid & OBD_MD_FLEASIZE) &&
+ if (!(md->body->valid & OBD_MD_FLEASIZE) &&
!(md->body->valid & OBD_MD_FLDIREA))
RETURN(0);
S_ISSOCK(md->body->mode));
}
- acl_off = (md->body->valid & OBD_MD_FLEASIZE) ? (offset + 2) :
- (offset + 1);
+ /* if anything wrong when unpacking md, we don't check acl
+ * stuff, for simplicity
+ */
+ if (rc)
+ RETURN(rc);
if (md->body->valid & OBD_MD_FLACL_ACCESS) {
- size = le32_to_cpu(*(__u32 *) lustre_msg_buf(req->rq_repmsg,
- acl_off, 4));
- buf = lustre_msg_buf(req->rq_repmsg, acl_off + 1, size);
-
- acl = posix_acl_from_xattr(buf, size);
- if (IS_ERR(acl)) {
- rc = PTR_ERR(acl);
- CERROR("convert xattr to acl failed: %d\n", rc);
- RETURN(rc);
- } else if (acl) {
- rc = posix_acl_valid(acl);
- if (rc) {
- CERROR("acl valid error: %d\n", rc);
- posix_acl_release(acl);
- RETURN(rc);
+ acl_off = (md->body->valid & OBD_MD_FLEASIZE) ?
+ (offset + 2) : (offset + 1);
+
+ if (md->body->valid & OBD_MD_RACL) {
+
+ buf = lustre_swab_repbuf(req, acl_off, sizeof(*perm),
+ lustre_swab_remote_perm);
+ if (buf == NULL) {
+ CERROR("Can't unpack remote perm\n");
+ RETURN(0);
}
- }
- md->acl_access = acl;
+ OBD_ALLOC(perm, sizeof(*perm));
+ if (!perm)
+ RETURN(0);
+ memcpy(perm, buf, sizeof(*perm));
+
+ md->remote_perm = perm;
+ } else {
+ size = le32_to_cpu(*(__u32 *) lustre_msg_buf(
+ req->rq_repmsg, acl_off, 4));
+ buf = lustre_msg_buf(req->rq_repmsg, acl_off + 1, size);
+
+ acl = posix_acl_from_xattr(buf, size);
+ if (IS_ERR(acl)) {
+ rc = PTR_ERR(acl);
+ CERROR("convert xattr to acl failed: %d\n", rc);
+ RETURN(0);
+ } else if (acl) {
+ rc = posix_acl_valid(acl);
+ if (rc) {
+ CERROR("acl valid error: %d\n", rc);
+ posix_acl_release(acl);
+ RETURN(0);
+ }
+ }
+
+ md->posix_acl = acl;
+ }
}
+
RETURN(rc);
}
.m_get_real_obd = mdc_get_real_obd,
.m_change_cbdata_name = mdc_change_cbdata_name,
.m_change_cbdata = mdc_change_cbdata,
+ .m_access_check = mdc_access_check,
};
int __init mdc_init(void)
RETURN(rc);
}
-int mds_pack_acl(struct obd_device *obd, struct lustre_msg *repmsg, int offset,
- struct mds_body *body, struct inode *inode)
+static
+int mds_pack_posix_acl(struct lustre_msg *repmsg, int offset,
+ struct mds_body *body, struct inode *inode)
{
struct dentry de = { .d_inode = inode };
__u32 buflen, *sizep;
RETURN(0);
}
-/*
- * here we take simple rule: once uid/fsuid is root, we also squash
- * the gid/fsgid, don't care setuid/setgid attributes.
- */
-int mds_squash_root(struct mds_obd *mds, struct mds_req_sec_desc *rsd,
- ptl_nid_t *peernid)
+static
+int mds_pack_remote_perm(struct ptlrpc_request *req, int reply_off,
+ struct mds_body *body, struct inode *inode)
{
- if (!mds->mds_squash_uid || *peernid == mds->mds_nosquash_nid)
- return 0;
+ struct lustre_sec_desc *lsd;
+ struct mds_remote_perm *perm;
+ __u32 lsd_perms;
- if (rsd->rsd_uid && rsd->rsd_fsuid)
- return 0;
+ LASSERT(inode->i_op);
+ LASSERT(inode->i_op->permission);
+ LASSERT(req->rq_export->exp_mds_data.med_remote);
- CDEBUG(D_SEC, "squash req from "LPX64":"
- "(%u:%u-%u:%u/%x)=>(%u:%u-%u:%u/%x)\n", *peernid,
- rsd->rsd_uid, rsd->rsd_gid,
- rsd->rsd_fsuid, rsd->rsd_fsgid, rsd->rsd_cap,
- rsd->rsd_uid ? rsd->rsd_uid : mds->mds_squash_uid,
- rsd->rsd_uid ? rsd->rsd_gid : mds->mds_squash_gid,
- rsd->rsd_fsuid ? rsd->rsd_fsuid : mds->mds_squash_uid,
- rsd->rsd_fsuid ? rsd->rsd_fsgid : mds->mds_squash_gid,
- rsd->rsd_cap & ~CAP_FS_MASK);
+ perm = (struct mds_remote_perm *)
+ lustre_msg_buf(req->rq_repmsg, reply_off, sizeof(perm));
+ if (!perm)
+ return -EINVAL;
- if (rsd->rsd_uid == 0) {
- rsd->rsd_uid = mds->mds_squash_uid;
- rsd->rsd_gid = mds->mds_squash_gid;
- }
- if (rsd->rsd_fsuid == 0) {
- rsd->rsd_fsuid = mds->mds_squash_uid;
- rsd->rsd_fsgid = mds->mds_squash_gid;
+ memset(perm, 0, sizeof(*perm));
+
+ /* obtain authenticated uid/gid and LSD permissions, which
+ * might be different from current process context, from LSD
+ */
+ lsd = mds_get_lsd(current->uid);
+ if (!lsd) {
+ CWARN("can't LSD of uid %u\n", current->uid);
+ RETURN(-EPERM);
}
- rsd->rsd_cap &= ~CAP_FS_MASK;
- return 1;
+ perm->mrp_auth_uid = lsd->lsd_uid;
+ perm->mrp_auth_gid = lsd->lsd_gid;
+
+ lsd_perms = mds_lsd_get_perms(lsd, 1, 0, req->rq_peer.peer_id.nid);
+ if (lsd_perms & LSD_PERM_SETUID)
+ perm->mrp_allow_setuid = 1;
+ if (lsd_perms & LSD_PERM_SETGID)
+ perm->mrp_allow_setgid = 1;
+
+ mds_put_lsd(lsd);
+
+ /* permission bits of current user
+ * XXX this is low efficient, could we do it in one blow?
+ */
+ if (inode->i_op->permission(inode, MAY_EXEC, NULL) == 0)
+ perm->mrp_perm |= MAY_EXEC;
+ if (inode->i_op->permission(inode, MAY_WRITE, NULL) == 0)
+ perm->mrp_perm |= MAY_WRITE;
+ if (inode->i_op->permission(inode, MAY_READ, NULL) == 0)
+ perm->mrp_perm |= MAY_READ;
+
+ body->valid |= (OBD_MD_FLACL_ACCESS | OBD_MD_RACL);
+
+ RETURN(0);
+}
+
+int mds_pack_acl(struct ptlrpc_request *req, int reply_off,
+ struct mds_body *body, struct inode *inode)
+{
+ int rc;
+
+ if (!req->rq_export->exp_mds_data.med_remote)
+ rc = mds_pack_posix_acl(req->rq_repmsg, reply_off, body, inode);
+ else
+ rc = mds_pack_remote_perm(req, reply_off, body, inode);
+
+ return rc;
}
static int mds_getattr_internal(struct obd_device *obd, struct dentry *dentry,
struct ptlrpc_request *req, int req_off,
- struct mds_body *reqbody, int reply_off)
+ struct mds_body *reqbody, int reply_off,
+ struct mds_req_sec_desc *rsd)
{
struct mds_export_data *med = &req->rq_export->u.eu_mds_data;
struct inode *inode = dentry->d_inode;
if (reqbody->valid & OBD_MD_FLACL_ACCESS) {
int inc = (reqbody->valid & OBD_MD_FLEASIZE) ? 2 : 1;
- rc = mds_pack_acl(obd, req->rq_repmsg, reply_off + inc,
- body, inode);
- }
+ rc = mds_pack_acl(req, reply_off + inc, body, inode);
+ }
if (rc == 0)
mds_body_do_reverse_map(med, body);
/* may co-exist with OBD_MD_FLEASIZE */
if (body->valid & OBD_MD_FLACL_ACCESS) {
- size[bufcount++] = 4;
- size[bufcount++] = xattr_acl_size(LL_ACL_MAX_ENTRIES);
+ if (req->rq_export->exp_mds_data.med_remote) {
+ size[bufcount++] = sizeof(struct mds_remote_perm);
+ } else {
+ size[bufcount++] = 4;
+ size[bufcount++] = xattr_acl_size(LL_ACL_MAX_ENTRIES);
+ }
}
if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETATTR_PACK)) {
}
}
- rc = mds_getattr_internal(obd, dchild, req, offset, body, reply_offset);
+ rc = mds_getattr_internal(obd, dchild, req, offset, body,
+ reply_offset, rsd);
if (rc)
GOTO(cleanup, rc); /* returns the lock to the client */
GOTO(out_pop, rc);
}
- req->rq_status = mds_getattr_internal(obd, de, req, offset, body, 0);
+ req->rq_status = mds_getattr_internal(obd, de, req, offset, body,
+ 0, rsd);
l_dput(de);
EXIT;
return rc;
}
+static int mds_access_check(struct ptlrpc_request *req, int offset)
+{
+ struct obd_device *obd = req->rq_export->exp_obd;
+ struct lvfs_run_ctxt saved;
+ struct dentry *de;
+ struct mds_req_sec_desc *rsd;
+ struct mds_body *body;
+ struct lvfs_ucred uc;
+ int rep_size[2] = {sizeof(*body),
+ sizeof(struct mds_remote_perm)};
+ int rc = 0;
+ ENTRY;
+
+ if (!req->rq_export->exp_mds_data.med_remote) {
+ CERROR("from local client "LPU64"\n", req->rq_peer.peer_id.nid);
+ RETURN(-EINVAL);
+ }
+
+ rsd = lustre_swab_mds_secdesc(req, MDS_REQ_SECDESC_OFF);
+ if (!rsd) {
+ CERROR("Can't unpack security desc\n");
+ RETURN(-EFAULT);
+ }
+
+ body = lustre_swab_reqbuf(req, offset, sizeof(*body),
+ lustre_swab_mds_body);
+ if (body == NULL) {
+ CERROR ("Can't unpack body\n");
+ RETURN (-EFAULT);
+ }
+
+ MD_COUNTER_INCREMENT(obd, access_check);
+
+ rc = mds_init_ucred(&uc, req, rsd);
+ if (rc) {
+ CERROR("init ucred error: %d\n", rc);
+ RETURN(rc);
+ }
+ push_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
+
+ de = mds_id2dentry(obd, &body->id1, NULL);
+ if (IS_ERR(de)) {
+ CERROR("grab ino "LPU64": err %ld\n",
+ body->id1.li_stc.u.e3s.l3s_ino, PTR_ERR(de));
+ GOTO(out_pop, rc = PTR_ERR(de));
+ }
+
+ rc = lustre_pack_reply(req, 2, rep_size, NULL);
+ if (rc) {
+ CERROR("pack reply error: %d\n", rc);
+ GOTO(out_dput, rc = -EINVAL);
+ }
+
+ body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*body));
+ LASSERT(body);
+
+ rc = mds_pack_remote_perm(req, 1, body, de->d_inode);
+ EXIT;
+
+out_dput:
+ l_dput(de);
+out_pop:
+ pop_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
+ mds_exit_ucred(&uc);
+ return rc;
+}
+
static int mds_obd_statfs(struct obd_device *obd, struct obd_statfs *osfs,
unsigned long max_age)
{
case MDS_GETSTATUS:
case MDS_GETATTR:
case MDS_GETATTR_LOCK:
+ case MDS_ACCESS_CHECK:
case MDS_READPAGE:
case MDS_REINT:
case MDS_CLOSE:
rc = mds_getattr(req, MDS_REQ_REC_OFF);
break;
+ case MDS_ACCESS_CHECK:
+ DEBUG_REQ(D_INODE, req, "access_check");
+ OBD_FAIL_RETURN(OBD_FAIL_MDS_ACCESS_CHECK_NET, 0);
+ rc = mds_access_check(req, MDS_REQ_REC_OFF);
+ break;
+
case MDS_GETATTR_LOCK: {
struct lustre_handle lockh;
DEBUG_REQ(D_INODE, req, "getattr_lock");
reply_buffers = 3;
if (it->opc & ( IT_OPEN | IT_GETATTR | IT_LOOKUP | IT_CHDIR )) {
- reply_buffers = 5;
- repsize[3] = 4;
- repsize[4] = xattr_acl_size(LL_ACL_MAX_ENTRIES);
+ if (req->rq_export->exp_mds_data.med_remote) {
+ reply_buffers = 4;
+ repsize[3] = sizeof(struct mds_remote_perm);
+ } else {
+ reply_buffers = 5;
+ repsize[3] = 4;
+ repsize[4] = xattr_acl_size(LL_ACL_MAX_ENTRIES);
+ }
}
rc = lustre_pack_reply(req, reply_buffers, repsize, NULL);
/* mds/handler.c */
int mds_getattr_size(struct obd_device *obd, struct dentry *dentry,
struct ptlrpc_request *req, struct mds_body *body);
-int mds_squash_root(struct mds_obd *mds, struct mds_req_sec_desc *rsd,
- ptl_nid_t *peernid);
int mds_handle(struct ptlrpc_request *req);
extern struct lvfs_callback_ops mds_lvfs_ops;
int mds_dt_clean(struct obd_device *obd);
struct mds_body *repbody, int req_off, int reply_off);
int mds_pack_ealist(struct dentry *dentry, struct ptlrpc_request *req,
struct mds_body *repbody, int reply_off);
-int mds_pack_acl(struct obd_device *, struct lustre_msg *, int offset,
- struct mds_body *, struct inode *);
+int mds_pack_acl(struct ptlrpc_request *req, int reply_off,
+ struct mds_body *body, struct inode *inode);
int mds_pack_inode2id(struct obd_device *, struct lustre_id *,
struct inode *, int);
RETURN(rc);
}
+/*
+ * here we take simple rule: once uid/fsuid is root, we also squash
+ * the gid/fsgid, don't care setuid/setgid attributes.
+ */
+static
+int mds_squash_root(struct mds_obd *mds, struct mds_req_sec_desc *rsd,
+ ptl_nid_t *peernid)
+{
+ if (!mds->mds_squash_uid || *peernid == mds->mds_nosquash_nid)
+ return 0;
+
+ if (rsd->rsd_uid && rsd->rsd_fsuid)
+ return 0;
+
+ CDEBUG(D_SEC, "squash req from "LPX64":"
+ "(%u:%u-%u:%u/%x)=>(%u:%u-%u:%u/%x)\n", *peernid,
+ rsd->rsd_uid, rsd->rsd_gid,
+ rsd->rsd_fsuid, rsd->rsd_fsgid, rsd->rsd_cap,
+ rsd->rsd_uid ? rsd->rsd_uid : mds->mds_squash_uid,
+ rsd->rsd_uid ? rsd->rsd_gid : mds->mds_squash_gid,
+ rsd->rsd_fsuid ? rsd->rsd_fsuid : mds->mds_squash_uid,
+ rsd->rsd_fsuid ? rsd->rsd_fsgid : mds->mds_squash_gid,
+ rsd->rsd_cap & ~CAP_FS_MASK);
+
+ if (rsd->rsd_uid == 0) {
+ rsd->rsd_uid = mds->mds_squash_uid;
+ rsd->rsd_gid = mds->mds_squash_gid;
+ }
+ if (rsd->rsd_fsuid == 0) {
+ rsd->rsd_fsuid = mds->mds_squash_uid;
+ rsd->rsd_fsgid = mds->mds_squash_gid;
+ }
+ rsd->rsd_cap &= ~CAP_FS_MASK;
+
+ return 1;
+}
+
/********************************
* MDS uid/gid mapping handling *
********************************/
}
}
}
-
- rc = mds_pack_acl(obd, req->rq_repmsg, 3, body, dchild->d_inode);
+ rc = mds_pack_acl(req, 3, body, dchild->d_inode);
if (rc < 0) {
- CERROR("mds_pack_acl: rc = %d\n", rc);
+ CERROR("pack posix acl: rc = %d\n", rc);
up(&dchild->d_inode->i_sem);
RETURN(rc);
}
LPROCFS_MD_OP_INIT(num_private_stats, stats, done_writing);
LPROCFS_MD_OP_INIT(num_private_stats, stats, enqueue);
LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr);
+ LPROCFS_MD_OP_INIT(num_private_stats, stats, access_check);
LPROCFS_MD_OP_INIT(num_private_stats, stats, getattr_lock);
LPROCFS_MD_OP_INIT(num_private_stats, stats, intent_lock);
LPROCFS_MD_OP_INIT(num_private_stats, stats, link);
{ MDS_UNPIN, "mds_unpin" },
{ MDS_SYNC, "mds_sync" },
{ MDS_DONE_WRITING, "mds_done_writing" },
+ { MDS_ACCESS_CHECK, "mds_access_check"},
{ LDLM_ENQUEUE, "ldlm_enqueue" },
{ LDLM_CONVERT, "ldlm_convert" },
{ LDLM_CANCEL, "ldlm_cancel" },
__swab16s(&r->r_error_cnt);
}
+void lustre_swab_remote_perm(struct mds_remote_perm *p)
+{
+ __swab32s(&p->mrp_auth_uid);
+ __swab32s(&p->mrp_auth_gid);
+ __swab16s(&p->mrp_perm);
+}
+
/* no one calls this */
int llog_log_swabbed(struct llog_log_hdr *hdr)
{
EXPORT_SYMBOL(lustre_swab_lustre_fid);
EXPORT_SYMBOL(lustre_swab_mds_status_req);
EXPORT_SYMBOL(lustre_swab_mds_secdesc);
+EXPORT_SYMBOL(lustre_swab_remote_perm);
EXPORT_SYMBOL(lustre_swab_mds_body);
EXPORT_SYMBOL(lustre_swab_mds_rec_setattr);
EXPORT_SYMBOL(lustre_swab_mds_rec_create);
return;
}
LASSERT(list_empty(&gmsg->gum_list));
+#if 0
LASSERT(list_empty(&gmsg->gum_base.list));
+#else
+ /* XXX */
+ if (!list_empty(&gmsg->gum_base.list)) {
+ CWARN("msg %p: list: %p/%p/%p, copied %d, err %d, wq %d\n",
+ gmsg, &gmsg->gum_base.list,
+ gmsg->gum_base.list.prev, gmsg->gum_base.list.next,
+ gmsg->gum_base.copied, gmsg->gum_base.errno,
+ list_empty(&gmsg->gum_waitq.task_list));
+ LBUG();
+ }
+#endif
OBD_FREE(gmsg, sizeof(*gmsg));
EXIT;
}
static void
gss_unhash_msg_nolock(struct gss_upcall_msg *gmsg)
{
- ENTRY;
- if (list_empty(&gmsg->gum_list)) {
- EXIT;
+ LASSERT(spin_is_locked(&gmsg->gum_gsec->gs_lock));
+
+ if (list_empty(&gmsg->gum_list))
return;
- }
list_del_init(&gmsg->gum_list);
wake_up(&gmsg->gum_waitq);
+ LASSERT(atomic_read(&gmsg->gum_refcount) > 1);
atomic_dec(&gmsg->gum_refcount);
- CDEBUG(D_SEC, "gmsg %p refcount now %d\n",
- gmsg, atomic_read(&gmsg->gum_refcount));
- LASSERT(atomic_read(&gmsg->gum_refcount) > 0);
- EXIT;
}
static void
struct gss_upcall_msg *gmsg;
ENTRY;
+ LASSERT(spin_is_locked(&gsec->gs_lock));
+
list_for_each_entry(gmsg, &gsec->gs_upcalls, gum_list) {
if (memcmp(&gmsg->gum_data, gmd, sizeof(*gmd)))
continue;
if (strcmp(gmsg->gum_obdname, obdname))
continue;
+ LASSERT(atomic_read(&gmsg->gum_refcount) > 0);
atomic_inc(&gmsg->gum_refcount);
CDEBUG(D_SEC, "found gmsg at %p: obdname %s, uid %d, ref %d\n",
gmsg, obdname, gmd->gum_uid,
memcpy(&gmsg->gum_data, gmd, sizeof(*gmd));
rpcmsg = &gmsg->gum_base;
+ INIT_LIST_HEAD(&rpcmsg->list);
rpcmsg->data = &gmsg->gum_data;
rpcmsg->len = sizeof(gmsg->gum_data);
+ rpcmsg->copied = 0;
+ rpcmsg->errno = 0;
EXIT;
}
#endif /* __KERNEL__ */
gss_put_ctx(gcred->gc_ctx);
}
- CDEBUG(D_SEC, "GSS_SEC: destroy cred %p\n", gcred);
+ CDEBUG(D_SEC, "sec.gss %p: destroy cred %p\n", cred->pc_sec, gcred);
OBD_FREE(gcred, sizeof(*gcred));
EXIT;
static unsigned long ratelimit;
ENTRY;
+ LASSERT(list_empty(&msg->list));
+
if (msg->errno >= 0) {
EXIT;
return;
gmsg = container_of(msg, struct gss_upcall_msg, gum_base);
CDEBUG(D_SEC, "destroy gmsg %p\n", gmsg);
+ LASSERT(atomic_read(&gmsg->gum_refcount) > 0);
atomic_inc(&gmsg->gum_refcount);
gss_unhash_msg(gmsg);
if (msg->errno == -ETIMEDOUT || msg->errno == -EPIPE) {
unsigned long now = get_seconds();
if (time_after(now, ratelimit)) {
- CWARN("GSS_SEC upcall timed out.\n"
+ CWARN("sec.gss upcall timed out.\n"
"Please check user daemon is running!\n");
ratelimit = now + 15;
}
gmsg = list_entry(gsec->gs_upcalls.next,
struct gss_upcall_msg, gum_list);
+ LASSERT(list_empty(&gmsg->gum_base.list));
gmsg->gum_base.errno = -EPIPE;
atomic_inc(&gmsg->gum_refcount);
gss_unhash_msg_nolock(gmsg);
current->fsuid = save_uid;
- CDEBUG(D_SEC, "Create GSS security instance at %p(external %p)\n",
- gsec, sec);
+ CDEBUG(D_SEC, "Create sec.gss %p\n", gsec);
RETURN(sec);
#ifdef __KERNEL__
ENTRY;
gsec = container_of(sec, struct gss_sec, gs_base);
- CDEBUG(D_SEC, "Destroy GSS security instance at %p\n", gsec);
+ CDEBUG(D_SEC, "Destroy sec.gss %p\n", gsec);
LASSERT(gsec->gs_mech);
LASSERT(!atomic_read(&sec->ps_refcount));
}
}
cache_get(&item->h);
- //set_bit(CACHE_HASHED, &item->h.flags);
+ set_bit(CACHE_HASHED, &item->h.flags);
item->h.next = *head;
*head = &item->h;
rsi_cache.entries++;
LASSERT(sectypes[major] == type);
if (atomic_read(&type->pst_inst)) {
- CERROR("%s: still have %d, instances\n",
+ CERROR("%s: still have %d instances\n",
type->pst_name, atomic_read(&type->pst_inst));
spin_unlock(§ypes_lock);
return -EINVAL;
if (!force)
continue;
list_del_init(&cred->pc_hash);
+ CDEBUG(D_SEC, "sec %p: flush busy(%d) cred %p "
+ "by force\n", sec,
+ atomic_read(&cred->pc_refcount), cred);
} else
list_move(&cred->pc_hash, &freelist);
{
LASSERT(!atomic_read(&cred->pc_refcount));
- CDEBUG(D_SEC, "NULL_SEC: destroy cred %p\n", cred);
+ CDEBUG(D_SEC, "sec.null %p: destroy cred %p\n", cred->pc_sec, cred);
OBD_FREE(cred, sizeof(*cred));
}
sec->ps_nextgc = 0; /* never do gc */
sec->ps_flags = 0;
- CDEBUG(D_SEC, "Create NULL security module at %p\n", sec);
+ CDEBUG(D_SEC, "Create sec.null module at %p\n", sec);
RETURN(sec);
}
{
ENTRY;
- CDEBUG(D_SEC, "Destroy NULL security module at %p\n", sec);
+ CDEBUG(D_SEC, "Destroy sec.null %p\n", sec);
LASSERT(!atomic_read(&sec->ps_refcount));
OBD_FREE(sec, sizeof(*sec));
rc = ptlrpcs_register(&null_type);
if (rc)
- CERROR("failed to register NULL security: %d\n", rc);
+ CERROR("failed to register sec.null: %d\n", rc);
return rc;
}
rc = ptlrpcs_unregister(&null_type);
if (rc)
- CERROR("cannot unregister NULL security: %d\n", rc);
+ CERROR("cannot unregister sec.null: %d\n", rc);
return rc;
}
CHECK_VALUE(MDS_UNPIN);
CHECK_VALUE(MDS_SYNC);
CHECK_VALUE(MDS_DONE_WRITING);
+ CHECK_VALUE(MDS_ACCESS_CHECK);
CHECK_VALUE(MDS_LAST_OPC);
CHECK_VALUE(REINT_SETATTR);