} while (0)
#define mutex_destroy(lock) sx_destroy(lock)
#define mutex_enter(lock) sx_xlock(lock)
+#define mutex_enter_interruptible(lock) sx_xlock_sig(lock)
#define mutex_enter_nested(lock, type) sx_xlock(lock)
#define mutex_tryenter(lock) sx_try_xlock(lock)
#define mutex_exit(lock) sx_xunlock(lock)
#define NESTED_SINGLE 1
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
#define mutex_enter_nested(mp, subclass) \
{ \
ASSERT3P(mutex_owner(mp), !=, current); \
spl_mutex_lockdep_on_maybe(mp); \
spl_mutex_set_owner(mp); \
}
-#else /* CONFIG_DEBUG_LOCK_ALLOC */
-#define mutex_enter_nested(mp, subclass) \
-{ \
+
+#define mutex_enter_interruptible(mp) \
+/* CSTYLED */ \
+({ \
+ int _rc_; \
+ \
ASSERT3P(mutex_owner(mp), !=, current); \
spl_mutex_lockdep_off_maybe(mp); \
- mutex_lock(MUTEX(mp)); \
+ _rc_ = mutex_lock_interruptible(MUTEX(mp)); \
spl_mutex_lockdep_on_maybe(mp); \
- spl_mutex_set_owner(mp); \
-}
-#endif /* CONFIG_DEBUG_LOCK_ALLOC */
+ if (!_rc_) { \
+ spl_mutex_set_owner(mp); \
+ } \
+ \
+ _rc_; \
+})
#define mutex_enter(mp) mutex_enter_nested((mp), 0)
extern void spa_write_cachefile(spa_t *, boolean_t, boolean_t, boolean_t);
extern void spa_config_load(void);
-extern nvlist_t *spa_all_configs(uint64_t *);
+extern int spa_all_configs(uint64_t *generation, nvlist_t **pools);
extern void spa_config_set(spa_t *spa, nvlist_t *config);
extern nvlist_t *spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg,
int getstats);
extern void mutex_init(kmutex_t *mp, char *name, int type, void *cookie);
extern void mutex_destroy(kmutex_t *mp);
extern void mutex_enter(kmutex_t *mp);
+extern int mutex_enter_check_return(kmutex_t *mp);
extern void mutex_exit(kmutex_t *mp);
extern int mutex_tryenter(kmutex_t *mp);
#define NESTED_SINGLE 1
#define mutex_enter_nested(mp, class) mutex_enter(mp)
+#define mutex_enter_interruptible(mp) mutex_enter_check_return(mp)
/*
* RW locks
*/
mp->m_owner = pthread_self();
}
+int
+mutex_enter_check_return(kmutex_t *mp)
+{
+ int error = pthread_mutex_lock(&mp->m_lock);
+ if (error == 0)
+ mp->m_owner = pthread_self();
+ return (error);
+}
+
int
mutex_tryenter(kmutex_t *mp)
{
* So we have to invent the ZFS_IOC_CONFIG ioctl to grab the configuration
* information for all pool visible within the zone.
*/
-nvlist_t *
-spa_all_configs(uint64_t *generation)
+int
+spa_all_configs(uint64_t *generation, nvlist_t **pools)
{
- nvlist_t *pools;
spa_t *spa = NULL;
if (*generation == spa_config_generation)
- return (NULL);
+ return (SET_ERROR(EEXIST));
- pools = fnvlist_alloc();
+ int error = mutex_enter_interruptible(&spa_namespace_lock);
+ if (error)
+ return (SET_ERROR(EINTR));
- mutex_enter(&spa_namespace_lock);
+ *pools = fnvlist_alloc();
while ((spa = spa_next(spa)) != NULL) {
if (INGLOBALZONE(curproc) ||
zone_dataset_visible(spa_name(spa), NULL)) {
mutex_enter(&spa->spa_props_lock);
- fnvlist_add_nvlist(pools, spa_name(spa),
+ fnvlist_add_nvlist(*pools, spa_name(spa),
spa->spa_config);
mutex_exit(&spa->spa_props_lock);
}
*generation = spa_config_generation;
mutex_exit(&spa_namespace_lock);
- return (pools);
+ return (0);
}
void
nvlist_t *configs;
int error;
- if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL)
- return (SET_ERROR(EEXIST));
+ error = spa_all_configs(&zc->zc_cookie, &configs);
+ if (error)
+ return (error);
error = put_nvlist(zc, configs);