/** * Get service name (svname) from string * rc < 0 on error * if endptr isn't NULL it is set to end of fsname * */ int server_name2svname(const char *label, char *svname, const char **endptr, size_t svsize) { int rc; const char *dash; /* We use server_name2fsname() just for parsing */ rc = server_name2fsname(label, NULL, &dash); if (rc != 0) return rc; if (endptr != NULL) *endptr = dash; if (strlcpy(svname, dash + 1, svsize) >= svsize) return -E2BIG; return 0; }
/* Get the index from the obd name. rc = server type, or rc < 0 on error if endptr isn't NULL it is set to end of name */ static int server_name2index(const char *svname, __u32 *idx, const char **endptr) { unsigned long index; int rc; const char *dash; /* We use server_name2fsname() just for parsing */ rc = server_name2fsname(svname, NULL, &dash); if (rc != 0) return rc; dash++; if (strncmp(dash, "MDT", 3) == 0) rc = LDD_F_SV_TYPE_MDT; else if (strncmp(dash, "OST", 3) == 0) rc = LDD_F_SV_TYPE_OST; else return -EINVAL; dash += 3; if (strncmp(dash, "all", 3) == 0) { if (endptr != NULL) *endptr = dash + 3; return rc | LDD_F_SV_ALL; } index = simple_strtoul(dash, (char **)endptr, 16); if (idx != NULL) *idx = index; /* Account for -mdc after index that is possible when specifying mdt */ if (endptr != NULL && strncmp(LUSTRE_MDC_NAME, *endptr + 1, sizeof(LUSTRE_MDC_NAME)-1) == 0) *endptr += sizeof(LUSTRE_MDC_NAME); return rc; }
/* * Create a new qsd_instance to be associated with backend osd device * identified by \dev. * * \param env - the environment passed by the caller * \param svname - is the service name of the OSD device creating this instance * \param dev - is the dt_device where to store quota index files * \param osd_proc - is the procfs parent directory where to create procfs file * related to this new qsd instance * * \retval - pointer to new qsd_instance associated with dev \dev on success, * appropriate error on failure */ struct qsd_instance *qsd_init(const struct lu_env *env, char *svname, struct dt_device *dev, cfs_proc_dir_entry_t *osd_proc) { struct qsd_thread_info *qti = qsd_info(env); struct qsd_instance *qsd; int rc, type, idx; ENTRY; /* only configure qsd for MDT & OST */ type = server_name2index(svname, &idx, NULL); if (type != LDD_F_SV_TYPE_MDT && type != LDD_F_SV_TYPE_OST) RETURN(NULL); /* allocate qsd instance */ OBD_ALLOC_PTR(qsd); if (qsd == NULL) RETURN(ERR_PTR(-ENOMEM)); /* generic initializations */ rwlock_init(&qsd->qsd_lock); CFS_INIT_LIST_HEAD(&qsd->qsd_link); thread_set_flags(&qsd->qsd_upd_thread, SVC_STOPPED); init_waitqueue_head(&qsd->qsd_upd_thread.t_ctl_waitq); CFS_INIT_LIST_HEAD(&qsd->qsd_upd_list); spin_lock_init(&qsd->qsd_adjust_lock); CFS_INIT_LIST_HEAD(&qsd->qsd_adjust_list); qsd->qsd_prepared = false; qsd->qsd_started = false; /* copy service name */ if (strlcpy(qsd->qsd_svname, svname, sizeof(qsd->qsd_svname)) >= sizeof(qsd->qsd_svname)) GOTO(out, rc = -E2BIG); /* grab reference on osd device */ lu_device_get(&dev->dd_lu_dev); lu_ref_add(&dev->dd_lu_dev.ld_reference, "qsd", qsd); qsd->qsd_dev = dev; /* we only support pool ID 0 (default data or metadata pool) for the * time being. A different pool ID could be assigned to this target via * the configuration log in the future */ qsd->qsd_pool_id = 0; /* get fsname from svname */ rc = server_name2fsname(svname, qti->qti_buf, NULL); if (rc) { CERROR("%s: fail to extract filesystem name\n", svname); GOTO(out, rc); } /* look up quota setting for the filesystem the target belongs to */ qsd->qsd_fsinfo = qsd_get_fsinfo(qti->qti_buf, 1); if (qsd->qsd_fsinfo == NULL) { CERROR("%s: failed to locate filesystem information\n", svname); GOTO(out, rc = -EINVAL); } /* add in the list of lquota_fsinfo */ mutex_lock(&qsd->qsd_fsinfo->qfs_mutex); list_add_tail(&qsd->qsd_link, &qsd->qsd_fsinfo->qfs_qsd_list); mutex_unlock(&qsd->qsd_fsinfo->qfs_mutex); /* register procfs directory */ qsd->qsd_proc = lprocfs_seq_register(QSD_DIR, osd_proc, lprocfs_quota_qsd_vars, qsd); if (IS_ERR(qsd->qsd_proc)) { rc = PTR_ERR(qsd->qsd_proc); qsd->qsd_proc = NULL; CERROR("%s: fail to create quota slave proc entry (%d)\n", svname, rc); GOTO(out, rc); } EXIT; out: if (rc) { qsd_fini(env, qsd); return ERR_PTR(rc); } RETURN(qsd); }