- char keystr[16];
- char *argv[] = {
- [0] = cache->uc_upcall,
- [1] = cache->uc_name,
- [2] = keystr,
- [3] = NULL
- };
- char *envp[] = {
- [0] = "HOME=/",
- [1] = "PATH=/sbin:/usr/sbin",
- [2] = NULL
- };
- struct timeval start, end;
- int rc;
- ENTRY;
-
- /* There is race condition:
- * "uc_upcall" was changed just after "is_identity_get_disabled" check.
- */
- cfs_read_lock(&cache->uc_upcall_rwlock);
- CDEBUG(D_INFO, "The upcall is: '%s'\n", cache->uc_upcall);
-
- if (unlikely(!strcmp(cache->uc_upcall, "NONE"))) {
- CERROR("no upcall set\n");
- GOTO(out, rc = -EREMCHG);
- }
-
- argv[0] = cache->uc_upcall;
- snprintf(keystr, sizeof(keystr), LPU64, entry->ue_key);
-
- cfs_gettimeofday(&start);
- rc = USERMODEHELPER(argv[0], argv, envp);
- cfs_gettimeofday(&end);
- if (rc < 0) {
- CERROR("%s: error invoking upcall %s %s %s: rc %d; "
- "check /proc/fs/lustre/mdt/%s/identity_upcall, "
- "time %ldus\n",
- cache->uc_name, argv[0], argv[1], argv[2], rc,
- cache->uc_name, cfs_timeval_sub(&end, &start, NULL));
- } else {
- CDEBUG(D_HA, "%s: invoked upcall %s %s %s, time %ldus\n",
- cache->uc_name, argv[0], argv[1], argv[2],
- cfs_timeval_sub(&end, &start, NULL));
- rc = 0;
- }
- EXIT;
+ char keystr[16];
+ char *argv[] = {
+ [0] = cache->uc_upcall,
+ [1] = cache->uc_name,
+ [2] = keystr,
+ [3] = NULL
+ };
+ char *envp[] = {
+ [0] = "HOME=/",
+ [1] = "PATH=/sbin:/usr/sbin",
+ [2] = NULL
+ };
+ ktime_t start, end;
+ int rc;
+
+ ENTRY;
+ /* There is race condition:
+ * "uc_upcall" was changed just after "is_identity_get_disabled" check.
+ */
+ down_read(&cache->uc_upcall_rwsem);
+ CDEBUG(D_INFO, "The upcall is: '%s'\n", cache->uc_upcall);
+
+ if (unlikely(!strcmp(cache->uc_upcall, "NONE"))) {
+ CERROR("no upcall set\n");
+ GOTO(out, rc = -EREMCHG);
+ }
+
+ argv[0] = cache->uc_upcall;
+ snprintf(keystr, sizeof(keystr), "%llu", entry->ue_key);
+
+ start = ktime_get();
+ rc = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
+ end = ktime_get();
+ if (rc < 0) {
+ CERROR("%s: error invoking upcall %s %s %s: rc %d; check /proc/fs/lustre/mdt/%s/identity_upcall, time %ldus\n",
+ cache->uc_name, argv[0], argv[1], argv[2], rc,
+ cache->uc_name, (long)ktime_us_delta(end, start));
+ } else {
+ CDEBUG(D_HA, "%s: invoked upcall %s %s %s, time %ldus\n",
+ cache->uc_name, argv[0], argv[1], argv[2],
+ (long)ktime_us_delta(end, start));
+ rc = 0;
+ }
+ EXIT;