mdt_identity_upcall is currently calling call_usermodehelper
with an rwlock held, which is a no-no since it allocates memory
and schedules. Just replace the rwlock with a rw_semaphore.
Change-Id: I7b063a4db47313fbae6241da7bcec2c397b8e8c4
Signed-off-by: Oleg Drokin <oleg.drokin@intel.com>
Signed-off-by: Niu Yawei <yawei.niu@intel.com>
Reviewed-on: http://review.whamcloud.com/14432
Reviewed-by: Dmitry Eremin <dmitry.eremin@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
struct upcall_cache {
struct list_head uc_hashtable[UC_CACHE_HASH_SIZE];
spinlock_t uc_lock;
struct upcall_cache {
struct list_head uc_hashtable[UC_CACHE_HASH_SIZE];
spinlock_t uc_lock;
- rwlock_t uc_upcall_rwlock;
+ struct rw_semaphore uc_upcall_rwsem;
char uc_name[40]; /* for upcall */
char uc_upcall[UC_CACHE_UPCALL_MAXPATH];
char uc_name[40]; /* for upcall */
char uc_upcall[UC_CACHE_UPCALL_MAXPATH];
/* There is race condition:
* "uc_upcall" was changed just after "is_identity_get_disabled" check.
*/
/* There is race condition:
* "uc_upcall" was changed just after "is_identity_get_disabled" check.
*/
- read_lock(&cache->uc_upcall_rwlock);
+ down_read(&cache->uc_upcall_rwsem);
CDEBUG(D_INFO, "The upcall is: '%s'\n", cache->uc_upcall);
if (unlikely(!strcmp(cache->uc_upcall, "NONE"))) {
CDEBUG(D_INFO, "The upcall is: '%s'\n", cache->uc_upcall);
if (unlikely(!strcmp(cache->uc_upcall, "NONE"))) {
- read_unlock(&cache->uc_upcall_rwlock);
- return rc;
+ up_read(&cache->uc_upcall_rwsem);
+ return rc;
}
static int mdt_identity_parse_downcall(struct upcall_cache *cache,
}
static int mdt_identity_parse_downcall(struct upcall_cache *cache,
struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
struct upcall_cache *hash = mdt->mdt_identity_cache;
struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
struct upcall_cache *hash = mdt->mdt_identity_cache;
- read_lock(&hash->uc_upcall_rwlock);
+ down_read(&hash->uc_upcall_rwsem);
seq_printf(m, "%s\n", hash->uc_upcall);
seq_printf(m, "%s\n", hash->uc_upcall);
- read_unlock(&hash->uc_upcall_rwlock);
+ up_read(&hash->uc_upcall_rwsem);
GOTO(failed, rc = -EFAULT);
/* Remove any extraneous bits from the upcall (e.g. linefeeds) */
GOTO(failed, rc = -EFAULT);
/* Remove any extraneous bits from the upcall (e.g. linefeeds) */
- write_lock(&hash->uc_upcall_rwlock);
+ down_write(&hash->uc_upcall_rwsem);
sscanf(kernbuf, "%s", hash->uc_upcall);
sscanf(kernbuf, "%s", hash->uc_upcall);
- write_unlock(&hash->uc_upcall_rwlock);
+ up_write(&hash->uc_upcall_rwsem);
if (strcmp(hash->uc_name, mdt_obd_name(mdt)) != 0)
CWARN("%s: write to upcall name %s\n",
if (strcmp(hash->uc_name, mdt_obd_name(mdt)) != 0)
CWARN("%s: write to upcall name %s\n",
RETURN(ERR_PTR(-ENOMEM));
spin_lock_init(&cache->uc_lock);
RETURN(ERR_PTR(-ENOMEM));
spin_lock_init(&cache->uc_lock);
- rwlock_init(&cache->uc_upcall_rwlock);
+ init_rwsem(&cache->uc_upcall_rwsem);
for (i = 0; i < UC_CACHE_HASH_SIZE; i++)
INIT_LIST_HEAD(&cache->uc_hashtable[i]);
strlcpy(cache->uc_name, name, sizeof(cache->uc_name));
for (i = 0; i < UC_CACHE_HASH_SIZE; i++)
INIT_LIST_HEAD(&cache->uc_hashtable[i]);
strlcpy(cache->uc_name, name, sizeof(cache->uc_name));