#include <llog_swab.h>
#include <lustre_disk.h>
-#include <lustre_ioctl.h>
+#include <uapi/linux/lustre_ioctl.h>
#include <lustre_log.h>
-#include <lustre_param.h>
+#include <uapi/linux/lustre_param.h>
#include <obd.h>
#include <obd_class.h>
void lustre_deregister_lwp_item(struct obd_export **exp)
{
struct lwp_register_item *lri;
+ bool removed = false;
+ int repeat = 0;
spin_lock(&lwp_register_list_lock);
list_for_each_entry(lri, &lwp_register_list, lri_list) {
if (exp == lri->lri_exp) {
list_del_init(&lri->lri_list);
- spin_unlock(&lwp_register_list_lock);
-
- lustre_put_lwp_item(lri);
- return;
+ removed = true;
+ break;
}
}
spin_unlock(&lwp_register_list_lock);
+
+ if (!removed)
+ return;
+
+ /* See lustre_notify_lwp_list(), in some extreme race conditions,
+ * the notify callback could be still on the fly, we need to wait
+ * for the callback done before moving on to free the data used
+ * by callback. */
+ while (atomic_read(&lri->lri_ref) > 1) {
+ CDEBUG(D_MOUNT, "lri reference count %u, repeat: %d\n",
+ atomic_read(&lri->lri_ref), repeat);
+ repeat++;
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(cfs_time_seconds(1));
+ }
+ lustre_put_lwp_item(lri);
}
EXPORT_SYMBOL(lustre_deregister_lwp_item);
lustre_cfg_bufs_set_string(bufs, 1,
lustre_cfg_string(cfg, 1));
- lcfg = lustre_cfg_new(LCFG_ADD_CONN, bufs);
- if (lcfg == NULL)
+ OBD_ALLOC(lcfg, lustre_cfg_len(bufs->lcfg_bufcount, bufs->lcfg_buflen));
+ if (!lcfg)
GOTO(out_cfg, rc = -ENOMEM);
+ lustre_cfg_init(lcfg, LCFG_ADD_CONN, bufs);
+
rc = class_add_conn(lwp, lcfg);
if (rc)
CERROR("%s: can't add conn: rc = %d\n", lwpname, rc);
- if (lcfg != NULL)
- lustre_cfg_free(lcfg);
+ if (lcfg)
+ OBD_FREE(lcfg, lustre_cfg_len(lcfg->lcfg_bufcount,
+ lcfg->lcfg_buflens));
out_cfg:
if (bufs != NULL)
OBD_FREE_PTR(bufs);
lustre_cfg_bufs_reset(bufs, lwp->obd_name);
lustre_cfg_bufs_set_string(bufs, 1, NULL);
- lcfg = lustre_cfg_new(LCFG_CLEANUP, bufs);
- if (lcfg == NULL)
+ OBD_ALLOC(lcfg, lustre_cfg_len(bufs->lcfg_bufcount,
+ bufs->lcfg_buflen));
+ if (!lcfg)
GOTO(out, rc = -ENOMEM);
+ lustre_cfg_init(lcfg, LCFG_CLEANUP, bufs);
/* Disconnect import first. NULL is passed for the '@env',
* since it will not be used. */
rc = lwp->obd_lu_dev->ld_ops->ldo_process_config(NULL,
lwp->obd_lu_dev, lcfg);
- lustre_cfg_free(lcfg);
+ OBD_FREE(lcfg, lustre_cfg_len(lcfg->lcfg_bufcount,
+ lcfg->lcfg_buflens));
if (rc != 0 && rc != -ETIMEDOUT) {
CERROR("%s: fail to disconnect LWP: rc = %d\n",
lwp->obd_name, rc);
/*
* Xattr support for Lustre servers
*/
+#ifdef HAVE_IOP_XATTR
static ssize_t lustre_getxattr(struct dentry *dentry, const char *name,
void *buffer, size_t size)
{
{
return -EOPNOTSUPP;
}
+#endif
static ssize_t lustre_listxattr(struct dentry *d_entry, char *name,
size_t size)
}
static const struct inode_operations server_inode_operations = {
+#ifdef HAVE_IOP_XATTR
.setxattr = lustre_setxattr,
.getxattr = lustre_getxattr,
+#endif
.listxattr = lustre_listxattr,
};