#include <linux/stat.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
-#include <asm/segment.h>
#include <libcfs/kp30.h>
#include <obd.h>
static int mdt_identity_do_upcall(struct upcall_cache *cache,
struct upcall_cache_entry *entry)
{
- char keystr[16];
+ char *upcall, keystr[16];
char *argv[] = {
[0] = cache->uc_upcall,
[1] = cache->uc_name,
[1] = "PATH=/sbin:/usr/sbin",
[2] = NULL
};
- int rc;
+ int size, rc;
ENTRY;
+ /* There is race condition:
+ * "uc_upcall" was changed just after "is_identity_get_disabled" check.
+ */
+ size = strlen(cache->uc_upcall) + 1;
+ OBD_ALLOC(upcall, size);
+ if (unlikely(!upcall))
+ RETURN(-ENOMEM);
+
+ read_lock(&cache->uc_upcall_rwlock);
+ memcpy(upcall, cache->uc_upcall, size - 1);
+ read_unlock(&cache->uc_upcall_rwlock);
+ upcall[size - 1] = 0;
+ if (unlikely(!strcmp(upcall, "NONE"))) {
+ CERROR("no upcall set\n");
+ GOTO(out, rc = -EREMCHG);
+ }
+
+ argv[0] = upcall;
+
snprintf(keystr, sizeof(keystr), LPU64, entry->ue_key);
- LASSERTF(strcmp(cache->uc_upcall, "NONE"), "no upcall set!");
CDEBUG(D_INFO, "The upcall is: %s \n", cache->uc_upcall);
rc = USERMODEHELPER(argv[0], argv, envp);
argv[0], argv[1], argv[2]);
rc = 0;
}
- RETURN(rc);
+ EXIT;
+out:
+ OBD_FREE(upcall, size);
+ return rc;
}
static int mdt_identity_parse_downcall(struct upcall_cache *cache,
struct upcall_cache_entry *entry;
if (!cache)
- return NULL;
+ return ERR_PTR(-ENOENT);
entry = upcall_cache_get_entry(cache, (__u64)uid, NULL);
- if (IS_ERR(entry)) {
- CERROR("upcall_cache_get_entry failed: %ld\n", PTR_ERR(entry));
- return NULL;
- }
-
- return &entry->u.identity;
+ if (IS_ERR(entry))
+ return ERR_PTR(PTR_ERR(entry));
+ else if (unlikely(!entry))
+ return ERR_PTR(-ENOENT);
+ else
+ return &entry->u.identity;
}
void mdt_identity_put(struct upcall_cache *cache, struct md_identity *identity)
* it must be perm[0].mp_nid, and act as default perm.
*/
__u32 mdt_identity_get_perm(struct md_identity *identity,
- __u32 is_rmtclient, lnet_nid_t nid)
+ __u32 is_rmtclient, lnet_nid_t nid)
{
struct md_perm *perm;
int i;