static void _stop_callback_thread(void *td) { struct _recall_thread *_rt = td; void *tret; _rt->stop = true; panfs_um_cancel_recalls(_rt->fd, 0); pthread_join(_rt->thread, &tret); DBG_PRNT("_rt->thread => %ld\n", (long)tret); gsh_free(_rt); }
/** * @brief Release a DS handle * * @param[in] ds_pub The object to release */ static void lustre_release(struct fsal_ds_handle *const ds_pub) { /* The private 'full' DS handle */ struct lustre_ds *ds = container_of(ds_pub, struct lustre_ds, ds); fsal_ds_handle_fini(&ds->ds); gsh_free(ds); }
void nsm_disconnect() { if (nsm_count == 0 && nsm_clnt != NULL) { gsh_clnt_destroy(nsm_clnt); nsm_clnt = NULL; AUTH_DESTROY(nsm_auth); nsm_auth = NULL; gsh_free(nodename); nodename = NULL; } }
static int op_dsread(struct nfs_argop4 *op, compound_data_t *data, struct nfs_resop4 *resp) { READ4args * const arg_READ4 = &op->nfs_argop4_u.opread; READ4res * const res_READ4 = &resp->nfs_resop4_u.opread; /* NFSv4 return code */ nfsstat4 nfs_status = 0; /* Buffer into which data is to be read */ void *buffer = NULL; /* End of file flag */ bool eof = false; /* Don't bother calling the FSAL if the read length is 0. */ if (arg_READ4->count == 0) { res_READ4->READ4res_u.resok4.eof = FALSE; res_READ4->READ4res_u.resok4.data.data_len = 0; res_READ4->READ4res_u.resok4.data.data_val = NULL; res_READ4->status = NFS4_OK; return res_READ4->status; } /* Construct the FSAL file handle */ buffer = gsh_malloc_aligned(4096, arg_READ4->count); res_READ4->READ4res_u.resok4.data.data_val = buffer; nfs_status = data->current_ds->dsh_ops.read( data->current_ds, op_ctx, &arg_READ4->stateid, arg_READ4->offset, arg_READ4->count, res_READ4->READ4res_u.resok4.data.data_val, &res_READ4->READ4res_u.resok4.data.data_len, &eof); if (nfs_status != NFS4_OK) { gsh_free(buffer); res_READ4->READ4res_u.resok4.data.data_val = NULL; } if (eof) res_READ4->READ4res_u.resok4.eof = TRUE; else res_READ4->READ4res_u.resok4.eof = FALSE; res_READ4->status = nfs_status; return res_READ4->status; }
static fsal_status_t readsymlink(struct fsal_obj_handle *obj_hdl, struct gsh_buffdesc *link_content, bool refresh) { fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR; int retval = 0; struct gpfs_fsal_obj_handle *myself = NULL; fsal_status_t status; if (obj_hdl->type != SYMBOLIC_LINK) { fsal_error = ERR_FSAL_FAULT; goto out; } myself = container_of(obj_hdl, struct gpfs_fsal_obj_handle, obj_handle); if (refresh) { /* lazy load or LRU'd storage */ size_t retlink; char link_buff[PATH_MAX]; retlink = PATH_MAX - 1; if (myself->u.symlink.link_content != NULL) { gsh_free(myself->u.symlink.link_content); myself->u.symlink.link_content = NULL; myself->u.symlink.link_size = 0; } status = GPFSFSAL_readlink(obj_hdl, op_ctx, link_buff, &retlink); if (FSAL_IS_ERROR(status)) return status; myself->u.symlink.link_content = gsh_malloc(retlink + 1); memcpy(myself->u.symlink.link_content, link_buff, retlink); myself->u.symlink.link_content[retlink] = '\0'; myself->u.symlink.link_size = retlink + 1; } if (myself->u.symlink.link_content == NULL) { fsal_error = ERR_FSAL_FAULT; /* probably a better error?? */ goto out; } link_content->len = myself->u.symlink.link_size; link_content->addr = gsh_malloc(link_content->len); memcpy(link_content->addr, myself->u.symlink.link_content, link_content->len); out: return fsalstat(fsal_error, retval); }
static fsal_status_t readsymlink(struct fsal_obj_handle *obj_hdl, const struct req_op_context *opctx, struct gsh_buffdesc *link_content, bool refresh) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct glusterfs_export *glfs_export = container_of(obj_hdl->export, struct glusterfs_export, export); struct glusterfs_handle *objhandle = container_of(obj_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif link_content->len = 1024; // bad bad!!! need to determine size link_content->addr = gsh_malloc(link_content->len); if (link_content->addr == NULL) { status = gluster2fsal_error(rc); goto out; } rc = glfs_h_readlink(glfs_export->gl_fs, objhandle->glhandle, link_content->addr, link_content->len); if (rc < 0) { status = gluster2fsal_error(errno); goto out; } /* Check if return buffer overflowed, it is still '\0' terminated */ link_content->len = (strlen(link_content->addr) + 1); out: if (status.major != ERR_FSAL_NO_ERROR) { gsh_free(link_content->addr); link_content->addr = NULL; link_content->len = 0; } #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_readsymlink); #endif return status; }
/* Allocate and fill in group_data structure */ static struct group_data *uid2grp_allocate_by_name( const struct gsh_buffdesc *name) { struct passwd p; struct passwd *pp; char *namebuff = alloca(name->len + 1); struct group_data *gdata = NULL; char *buff; long buff_size; memcpy(namebuff, name->addr, name->len); *(namebuff + name->len) = '\0'; buff_size = sysconf(_SC_GETPW_R_SIZE_MAX); if (buff_size == -1) { LogMajor(COMPONENT_IDMAPPER, "sysconf failure: %d", errno); return NULL; } buff = alloca(buff_size); if ((getpwnam_r(namebuff, &p, buff, buff_size, &pp) != 0) || (pp == NULL)) { LogEvent(COMPONENT_IDMAPPER, "getpwnam_r %s failed", namebuff); return gdata; } gdata = gsh_malloc(sizeof(struct group_data) + strlen(p.pw_name)); if (gdata == NULL) { LogEvent(COMPONENT_IDMAPPER, "failed to allocate group data"); return gdata; } gdata->uname.len = strlen(p.pw_name); gdata->uname.addr = (char *)gdata + sizeof(struct group_data); memcpy(gdata->uname.addr, p.pw_name, gdata->uname.len); gdata->uid = p.pw_uid; gdata->gid = p.pw_gid; if (!my_getgrouplist_alloc(p.pw_name, p.pw_gid, gdata)) { gsh_free(gdata); return NULL; } PTHREAD_MUTEX_init(&gdata->lock, NULL); gdata->epoch = time(NULL); gdata->refcount = 0; return gdata; }
/** * @brief Release a DS object * * @param[in] obj_pub The object to release * * @return NFS Status codes. */ static void release(struct fsal_ds_handle *const ds_pub) { int rc = 0; struct glfs_ds_handle *ds = container_of(ds_pub, struct glfs_ds_handle, ds); fsal_ds_handle_fini(&ds->ds); if (ds->glhandle) { rc = glfs_h_close(ds->glhandle); if (rc) { LogMajor(COMPONENT_PNFS, "glfs_h_close returned error %s(%d)", strerror(errno), errno); } } gsh_free(ds); }
static int ChangeoverExports() { #if 0 exportlist_t *pcurrent = NULL; /** * @@TODO@@ This is all totally bogus code now that exports are under the * control of the export manager. Left as unfinished business. */ if (nfs_param.pexportlist) pcurrent = nfs_param.pexportlist->next; while(pcurrent != NULL) { /* Leave the head so that the list may be replaced later without * changing the reference pointer in worker threads. */ if (pcurrent == nfs_param.pexportlist) break; nfs_param.pexportlist->next = RemoveExportEntry(pcurrent); pcurrent = nfs_param.pexportlist->next; } /* Allocate memory if needed, could have started with NULL exports */ if (nfs_param.pexportlist == NULL) nfs_param.pexportlist = gsh_malloc(sizeof(exportlist_t)); if (nfs_param.pexportlist == NULL) return ENOMEM; /* Changed the old export list head to the new export list head. * All references to the exports list should be up-to-date now. */ memcpy(nfs_param.pexportlist, temp_pexportlist, sizeof(exportlist_t)); /* We no longer need the head that was created for * the new list since the export list is built as a linked list. */ gsh_free(temp_pexportlist); temp_pexportlist = NULL; return 0; #else return ENOTSUP; #endif }
void avl_unit_clear_tree(struct avltree *t) { avl_unit_val_t *v; struct avltree_node *node, *next_node; if (avltree_size(t) < 1) return; node = avltree_first(t); while (node) { next_node = avltree_next(node); v = avltree_container_of(node, avl_unit_val_t, node_hk); avltree_remove(&v->node_hk, &avl_tree_1); gsh_free(v->name); avl_unit_free_val(v); node = next_node; } }
static fsal_status_t handle_release(struct fsal_obj_handle *obj_hdl) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct glusterfs_handle *objhandle = container_of(obj_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif rc = fsal_obj_handle_uninit(&objhandle->handle); if (rc != 0) { status = gluster2fsal_error(rc); goto out; } if (objhandle->glfd) { rc = glfs_close(objhandle->glfd); if (rc) { status = gluster2fsal_error(errno); /* cleanup as much as possible */ } } if (objhandle->glhandle) { rc = glfs_h_close(objhandle->glhandle); if (rc) { status = gluster2fsal_error(errno); goto out; } } gsh_free(objhandle); out: #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_handle_release); #endif return status; }
static void fridgethr_remove( fridge_entry_t * pfe ) { if( pfe == NULL ) return ; P( fridge_mutex ) ; if( pfe->pprev != NULL ) pfe->pprev->pnext = pfe->pnext ; if( pfe->pnext != NULL ) pfe->pnext->pprev = pfe->pprev ; if( pfe->pnext == NULL && pfe->pprev == NULL ) /* Is the fridge empty ? */ fridge_content = NULL ; V( fridge_mutex ) ; gsh_free(pfe) ; return ; } /* fridgethr_remove */
FILE *open_memstream(char **cp, size_t *lenp) { struct memstream *ms; int save_errno; FILE *fp; *cp = NULL; *lenp = 0; ms = gsh_malloc(sizeof(*ms)); ms->cp = cp; ms->lenp = lenp; ms->offset = 0; fp = funopen(ms, memstream_read, memstream_write, memstream_seek, memstream_close); if (fp == NULL) { save_errno = errno; gsh_free(ms); errno = save_errno; } return fp; }
bool pwentuid2grp(uid_t uid, struct gsh_buffdesc *name, struct group_data *pgdata) { char buff[1024]; struct passwd p; struct passwd *pp; if ((getpwuid_r(uid, &p, buff, MAXPATHLEN, &pp) != 0) || (pp == NULL)) { LogEvent(COMPONENT_IDMAPPER, "getpwnam_r %u failed", uid); return false; } /** @todo Waste of memory here. To be fixed */ pgdata->pgroups = (gid_t *) gsh_malloc(MAX_GRP * sizeof(gid_t)); if (pgdata->pgroups == NULL) return false; pgdata->nbgroups = MAX_GRP; if (getgrouplist (p.pw_name, p.pw_gid, pgdata->pgroups, &pgdata->nbgroups) == -1) { LogEvent(COMPONENT_IDMAPPER, "getgrouplist %s failed", p.pw_name); gsh_free(pgdata->pgroups); return false; } /* Resize pgroups to what it should be */ pgdata->pgroups = gsh_realloc(pgdata->pgroups, pgdata->nbgroups * sizeof(gid_t)); /* Set puid */ name->addr = p.pw_name; name->len = strlen(p.pw_name); /* Set uid/gid */ pgdata->uid = p.pw_uid; pgdata->gid = p.pw_gid; return true; }
/* Here and not static because proxy.c needs this function * but we also need access to pxy_exp_ops - I'd rather * keep the later static then the former */ fsal_status_t pxy_create_export(struct fsal_module *fsal_hdl, void *parse_node, struct config_error_type *err_type, const struct fsal_up_vector *up_ops) { struct pxy_export *exp = gsh_calloc(1, sizeof(*exp)); struct pxy_fsal_module *pxy = container_of(fsal_hdl, struct pxy_fsal_module, module); if (!exp) return fsalstat(ERR_FSAL_NOMEM, ENOMEM); if (fsal_export_init(&exp->exp) != 0) { gsh_free(exp); return fsalstat(ERR_FSAL_NOMEM, ENOMEM); } pxy_export_ops_init(&exp->exp.exp_ops); exp->exp.up_ops = up_ops; exp->info = &pxy->special; exp->exp.fsal = fsal_hdl; op_ctx->fsal_export = &exp->exp; return fsalstat(ERR_FSAL_NO_ERROR, 0); }
static void nfs_read_ok(exportlist_t * pexport, struct svc_req *preq, nfs_res_t * pres, char *data, fsal_size_t read_size, fsal_attrib_list_t *attr, int eof) { if((read_size == 0) && (data != NULL)) { gsh_free(data); data = NULL; } switch (preq->rq_vers) { case NFS_V2: pres->res_read2.READ2res_u.readok.data.nfsdata2_val = data; pres->res_read2.READ2res_u.readok.data.nfsdata2_len = read_size; nfs2_FSALattr_To_Fattr(pexport, attr, &(pres->res_read2.READ2res_u.readok.attributes)); pres->res_attr2.status = NFS_OK; break; case NFS_V3: /* Build Post Op Attributes */ nfs_SetPostOpAttr(pexport, attr, &(pres->res_read3.READ3res_u.resok.file_attributes)); pres->res_read3.READ3res_u.resok.eof = eof; pres->res_read3.READ3res_u.resok.count = read_size; pres->res_read3.READ3res_u.resok.data.data_val = data; pres->res_read3.READ3res_u.resok.data.data_len = read_size; pres->res_read3.status = NFS3_OK; break; } /* switch */ }
int main(int argc, char **argv) { int c; int port = 0; int state = 0, sflag = 0; char mon_client[STR_SIZE], mflag = 0; char remote_addr_s[STR_SIZE], rflag = 0; char local_addr_s[STR_SIZE], lflag = 0; notify arg; CLIENT *clnt; struct netbuf *buf; char port_str[20]; struct sockaddr_in local_addr; int fd; while ((c = getopt(argc, argv, "p:r:m:l:s:")) != EOF) switch (c) { case 'p': port = atoi(optarg); break; case 's': state = atoi(optarg); sflag = 1; break; case 'm': if (strlen(optarg) >= STR_SIZE) { fprintf(stderr, ERR_MSG1, "monitor host"); exit(1); } strcpy(mon_client, optarg); mflag = 1; break; case 'r': if (strlen(optarg) >= STR_SIZE) { fprintf(stderr, ERR_MSG1, "remote address"); exit(1); } strcpy(remote_addr_s, optarg); rflag = 1; break; case 'l': if (strlen(optarg) >= STR_SIZE) { fprintf(stderr, ERR_MSG1, "local address"); exit(1); } strcpy(local_addr_s, optarg); lflag = 1; break; case '?': default: fprintf(stderr, USAGE, argv[0]); exit(1); break; } if ((sflag + lflag + mflag + rflag) != 4) { fprintf(stderr, USAGE, argv[0]); exit(1); } /* create a udp socket */ fd = socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_UDP); if (fd < 0) { fprintf(stderr, "socket call failed. errno=%d\n", errno); exit(1); } /* set up the sockaddr for local endpoint */ memset(&local_addr, 0, sizeof(struct sockaddr_in)); local_addr.sin_family = PF_INET; local_addr.sin_port = htons(port); local_addr.sin_addr.s_addr = inet_addr(local_addr_s); if (bind(fd, (struct sockaddr *)&local_addr, sizeof(struct sockaddr)) < 0) { fprintf(stderr, "bind call failed. errno=%d\n", errno); exit(1); } /* find the port for SM service of the remote server */ buf = rpcb_find_mapped_addr( "udp", SM_PROG, SM_VERS, remote_addr_s); /* handle error here, for example, * client side blocking rpc call */ if (buf == NULL) { close(fd); exit(1); } /* convert port to string format */ sprintf(port_str, "%d", htons(((struct sockaddr_in *) buf->buf)->sin_port)); clnt = clnt_dg_ncreate(fd, buf, SM_PROG, SM_VERS, 0, 0); arg.my_name = mon_client; arg.state = state; nsm_notify_1(&arg, clnt); /* free resources */ gsh_free(buf->buf); gsh_free(buf); clnt_destroy(clnt); close(fd); return 0; }
int nlm_process_parameters(struct svc_req * preq, bool_t exclusive, nlm4_lock * alock, fsal_lock_param_t * plock, cache_entry_t ** ppentry, fsal_op_context_t * pcontext, care_t care, state_nsm_client_t ** ppnsm_client, state_nlm_client_t ** ppnlm_client, state_owner_t ** ppowner, state_block_data_t ** ppblock_data) { cache_inode_fsal_data_t fsal_data; fsal_attrib_list_t attr; cache_inode_status_t cache_status; SVCXPRT *ptr_svc = preq->rq_xprt; int rc; *ppnsm_client = NULL; *ppnlm_client = NULL; *ppowner = NULL; /* Convert file handle into a cache entry */ if(alock->fh.n_len > MAX_NETOBJ_SZ || !nfs3_FhandleToFSAL((nfs_fh3 *) &alock->fh, &fsal_data.fh_desc, pcontext)) { /* handle is not valid */ return NLM4_STALE_FH; } /* Now get the cached inode attributes */ *ppentry = cache_inode_get(&fsal_data, &attr, pcontext, NULL, &cache_status); if(*ppentry == NULL) { /* handle is not valid */ return NLM4_STALE_FH; } *ppnsm_client = get_nsm_client(care, ptr_svc, alock->caller_name); if(*ppnsm_client == NULL) { /* If NSM Client is not found, and we don't care (such as unlock), * just return GRANTED (the unlock must succeed, there can't be * any locks). */ if(care != CARE_NOT) rc = NLM4_DENIED_NOLOCKS; else rc = NLM4_GRANTED; goto out_put; } *ppnlm_client = get_nlm_client(care, ptr_svc, *ppnsm_client, alock->caller_name); if(*ppnlm_client == NULL) { /* If NLM Client is not found, and we don't care (such as unlock), * just return GRANTED (the unlock must succeed, there can't be * any locks). */ dec_nsm_client_ref(*ppnsm_client); if(care != CARE_NOT) rc = NLM4_DENIED_NOLOCKS; else rc = NLM4_GRANTED; goto out_put; } *ppowner = get_nlm_owner(care, *ppnlm_client, &alock->oh, alock->svid); if(*ppowner == NULL) { LogDebug(COMPONENT_NLM, "Could not get NLM Owner"); dec_nsm_client_ref(*ppnsm_client); dec_nlm_client_ref(*ppnlm_client); *ppnlm_client = NULL; /* If owner is not found, and we don't care (such as unlock), * just return GRANTED (the unlock must succeed, there can't be * any locks). */ if(care != CARE_NOT) rc = NLM4_DENIED_NOLOCKS; else rc = NLM4_GRANTED; goto out_put; } if(ppblock_data != NULL) { *ppblock_data = gsh_calloc(1, sizeof(**ppblock_data)); /* Fill in the block data, if we don't get one, we will just proceed * without (which will mean the lock doesn't block. */ if(*ppblock_data != NULL) { if(copy_xprt_addr(&(*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_hostaddr, ptr_svc) == 0) { LogFullDebug(COMPONENT_NLM, "copy_xprt_addr failed for Program %d, Version %d, Function %d", (int)preq->rq_prog, (int)preq->rq_vers, (int)preq->rq_proc); gsh_free(*ppblock_data); *ppblock_data = NULL; rc = NLM4_FAILED; goto out_put; } (*ppblock_data)->sbd_granted_callback = nlm_granted_callback; (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh.n_bytes = (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh_buf; (*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh.n_len = alock->fh.n_len; memcpy((*ppblock_data)->sbd_block_data.sbd_nlm_block_data.sbd_nlm_fh_buf, alock->fh.n_bytes, alock->fh.n_len); /* FSF TODO: Ultimately I think the following will go away, we won't need the context, just the export */ /* Copy credentials from pcontext */ #ifdef _USE_HPSS /** @todo : PhD: Think about removing hpsscred_t from FSAL */ (*ppblock_data)->sbd_credential.user = pcontext->credential.hpss_usercred.Uid ; (*ppblock_data)->sbd_credential.group = pcontext->credential.hpss_usercred.Gid ; #else (*ppblock_data)->sbd_credential = pcontext->credential; /* Copy the alt groups list */ if(pcontext->credential.nbgroups != 0) { (*ppblock_data)->sbd_credential.alt_groups = gsh_malloc(sizeof(gid_t) * pcontext->credential.nbgroups); if((*ppblock_data)->sbd_credential.alt_groups == NULL) { gsh_free(*ppblock_data); *ppblock_data = NULL; rc = NLM4_FAILED; goto out_put; } memcpy((*ppblock_data)->sbd_credential.alt_groups, pcontext->credential.alt_groups, pcontext->credential.nbgroups); } #endif } } /* Fill in plock */ plock->lock_type = exclusive ? FSAL_LOCK_W : FSAL_LOCK_R; plock->lock_start = alock->l_offset; plock->lock_length = alock->l_len; LogFullDebug(COMPONENT_NLM, "Parameters Processed"); return -1; out_put: cache_inode_put(*ppentry); *ppentry = NULL; return rc; }
void netobj_free(netobj * obj) { if(obj->n_bytes) gsh_free(obj->n_bytes); }
int _9p_symlink(struct _9p_request_data *req9p, void *worker_data, u32 *plenout, char *preply) { char *cursor = req9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE; u16 *msgtag = NULL; u32 *fid = NULL; u16 *name_len = NULL; char *name_str = NULL; u16 *linkcontent_len = NULL; char *linkcontent_str = NULL; u32 *gid = NULL; struct _9p_fid *pfid = NULL; struct _9p_qid qid_symlink; cache_entry_t *pentry_symlink = NULL; char symlink_name[MAXNAMLEN]; uint64_t fileid; cache_inode_status_t cache_status; uint32_t mode = 0777; cache_inode_create_arg_t create_arg; memset(&create_arg, 0, sizeof(create_arg)); /* Get data */ _9p_getptr(cursor, msgtag, u16); _9p_getptr(cursor, fid, u32); _9p_getstr(cursor, name_len, name_str); _9p_getstr(cursor, linkcontent_len, linkcontent_str); _9p_getptr(cursor, gid, u32); LogDebug(COMPONENT_9P, "TSYMLINK: tag=%u fid=%u name=%.*s linkcontent=%.*s gid=%u", (u32) *msgtag, *fid, *name_len, name_str, *linkcontent_len, linkcontent_str, *gid); if (*fid >= _9P_FID_PER_CONN) return _9p_rerror(req9p, worker_data, msgtag, ERANGE, plenout, preply); pfid = req9p->pconn->fids[*fid]; /* Check that it is a valid fid */ if (pfid == NULL || pfid->pentry == NULL) { LogDebug(COMPONENT_9P, "request on invalid fid=%u", *fid); return _9p_rerror(req9p, worker_data, msgtag, EIO, plenout, preply); } if ((pfid->op_context.export_perms->options & EXPORT_OPTION_WRITE_ACCESS) == 0) return _9p_rerror(req9p, worker_data, msgtag, EROFS, plenout, preply); op_ctx = &pfid->op_context; snprintf(symlink_name, MAXNAMLEN, "%.*s", *name_len, name_str); create_arg.link_content = gsh_malloc(MAXPATHLEN); if (create_arg.link_content == NULL) return _9p_rerror(req9p, worker_data, msgtag, EFAULT, plenout, preply); snprintf(create_arg.link_content, MAXPATHLEN, "%.*s", *linkcontent_len, linkcontent_str); /* Let's do the job */ /* BUGAZOMEU: @todo : the gid parameter is not used yet, * flags is not yet used */ cache_status = cache_inode_create(pfid->pentry, symlink_name, SYMBOLIC_LINK, mode, &create_arg, &pentry_symlink); if (create_arg.link_content != NULL) gsh_free(create_arg.link_content); if (pentry_symlink == NULL) { return _9p_rerror(req9p, worker_data, msgtag, _9p_tools_errno(cache_status), plenout, preply); } /* This is not a TATTACH fid */ pfid->from_attach = false; cache_status = cache_inode_fileid(pentry_symlink, &fileid); /* put the entry: * we don't want to remember it even if cache_inode_fileid fails. */ cache_inode_put(pentry_symlink); if (cache_status != CACHE_INODE_SUCCESS) { return _9p_rerror(req9p, worker_data, msgtag, _9p_tools_errno(cache_status), plenout, preply); } /* Build the qid */ qid_symlink.type = _9P_QTSYMLINK; qid_symlink.version = 0; qid_symlink.path = fileid; /* Build the reply */ _9p_setinitptr(cursor, preply, _9P_RSYMLINK); _9p_setptr(cursor, msgtag, u16); _9p_setqid(cursor, qid_symlink); _9p_setendptr(cursor, preply); _9p_checkbound(cursor, preply, plenout); LogDebug(COMPONENT_9P, "RSYMLINK: tag=%u fid=%u name=%.*s qid=(type=%u,version=%u,path=%llu)", (u32) *msgtag, *fid, *name_len, name_str, qid_symlink.type, qid_symlink.version, (unsigned long long)qid_symlink.path); return 1; }
int nfs_Create(nfs_arg_t *parg, exportlist_t *pexport, fsal_op_context_t *pcontext, nfs_worker_data_t *pworker, struct svc_req *preq, nfs_res_t *pres) { char *str_file_name = NULL; fsal_name_t file_name; fsal_accessmode_t mode = 0; cache_entry_t *file_pentry = NULL; cache_entry_t *parent_pentry = NULL; fsal_attrib_list_t parent_attr; fsal_attrib_list_t attr; fsal_attrib_list_t attr_parent_after; fsal_attrib_list_t attr_newfile; fsal_attrib_list_t attributes_create; fsal_attrib_list_t *ppre_attr; cache_inode_status_t cache_status = CACHE_INODE_SUCCESS; cache_inode_status_t cache_status_lookup; cache_inode_file_type_t parent_filetype; int rc = NFS_REQ_OK; #ifdef _USE_QUOTA fsal_status_t fsal_status ; #endif if(isDebug(COMPONENT_NFSPROTO)) { char str[LEN_FH_STR]; switch (preq->rq_vers) { case NFS_V2: str_file_name = parg->arg_create2.where.name; break; case NFS_V3: str_file_name = parg->arg_create3.where.name; break; } nfs_FhandleToStr(preq->rq_vers, &(parg->arg_create2.where.dir), &(parg->arg_create3.where.dir), NULL, str); LogDebug(COMPONENT_NFSPROTO, "REQUEST PROCESSING: Calling nfs_Create handle: %s name: %s", str, str_file_name); } if((preq->rq_vers == NFS_V3) && (nfs3_Is_Fh_Xattr(&(parg->arg_create3.where.dir)))) { rc = nfs3_Create_Xattr(parg, pexport, pcontext, preq, pres); goto out; } if(preq->rq_vers == NFS_V3) { /* to avoid setting it on each error case */ pres->res_create3.CREATE3res_u.resfail.dir_wcc.before.attributes_follow = FALSE; pres->res_create3.CREATE3res_u.resfail.dir_wcc.after.attributes_follow = FALSE; ppre_attr = NULL; } if((parent_pentry = nfs_FhandleToCache(preq->rq_vers, &(parg->arg_create2.where.dir), &(parg->arg_create3.where.dir), NULL, &(pres->res_dirop2.status), &(pres->res_create3.status), NULL, &parent_attr, pcontext, &rc)) == NULL) { /* Stale NFS FH ? */ goto out; } /* get directory attributes before action (for V3 reply) */ ppre_attr = &parent_attr; /* Extract the filetype */ parent_filetype = cache_inode_fsal_type_convert(parent_attr.type); /* * Sanity checks: new file name must be non-null; parent must be a * directory. */ if(parent_filetype != DIRECTORY) { switch (preq->rq_vers) { case NFS_V2: pres->res_dirop2.status = NFSERR_NOTDIR; break; case NFS_V3: pres->res_create3.status = NFS3ERR_NOTDIR; break; } rc = NFS_REQ_OK; goto out; } switch (preq->rq_vers) { case NFS_V2: str_file_name = parg->arg_create2.where.name; if(parg->arg_create2.attributes.mode != (unsigned int)-1) { mode = unix2fsal_mode(parg->arg_create2.attributes.mode); } else { mode = 0; } break; case NFS_V3: str_file_name = parg->arg_create3.where.name; if(parg->arg_create3.how.mode == EXCLUSIVE) { /* * Client has not provided mode information. * If the create works, the client will issue * a separate setattr request to fix up the * file's mode, so pick arbitrary value for now. */ mode = 0; } else if(parg->arg_create3.how.createhow3_u.obj_attributes.mode.set_it == TRUE) mode = unix2fsal_mode(parg->arg_create3.how.createhow3_u.obj_attributes.mode. set_mode3_u.mode); else mode = 0; break; } #ifdef _USE_QUOTA /* if quota support is active, then we should check is the FSAL allows inode creation or not */ fsal_status = FSAL_check_quota( pexport->fullpath, FSAL_QUOTA_INODES, FSAL_OP_CONTEXT_TO_UID( pcontext ) ) ; if( FSAL_IS_ERROR( fsal_status ) ) { switch (preq->rq_vers) { case NFS_V2: pres->res_dirop2.status = NFSERR_DQUOT ; break; case NFS_V3: pres->res_create3.status = NFS3ERR_DQUOT; break; } rc = NFS_REQ_OK ; goto out; } #endif /* _USE_QUOTA */ // if(str_file_name == NULL || strlen(str_file_name) == 0) if(str_file_name == NULL || *str_file_name == '\0' ) { if(preq->rq_vers == NFS_V2) pres->res_dirop2.status = NFSERR_IO; if(preq->rq_vers == NFS_V3) pres->res_create3.status = NFS3ERR_INVAL; } else { if((cache_status = cache_inode_error_convert(FSAL_str2name(str_file_name, FSAL_MAX_NAME_LEN, &file_name))) == CACHE_INODE_SUCCESS) { /* * Lookup file to see if it exists. If so, use it. Otherwise * create a new one. */ file_pentry = cache_inode_lookup(parent_pentry, &file_name, &attr, pcontext, &cache_status_lookup); if((cache_status_lookup == CACHE_INODE_NOT_FOUND) || ((cache_status_lookup == CACHE_INODE_SUCCESS) && (parg->arg_create3.how.mode == UNCHECKED))) { /* Create the file */ if((parg->arg_create3.how.mode == UNCHECKED) && (cache_status_lookup == CACHE_INODE_SUCCESS)) { cache_status = CACHE_INODE_SUCCESS; attr_newfile = attr; } else file_pentry = cache_inode_create(parent_pentry, &file_name, REGULAR_FILE, mode, NULL, &attr_newfile, pcontext, &cache_status); if(file_pentry != NULL) { /* * Look at sattr to see if some attributes are to be set at creation time */ attributes_create.asked_attributes = 0ULL; switch (preq->rq_vers) { case NFS_V2: if(nfs2_Sattr_To_FSALattr(&attributes_create, &parg->arg_create2.attributes) == 0) { pres->res_dirop2.status = NFSERR_IO; rc = NFS_REQ_OK; goto out; break; } break; case NFS_V3: if(nfs3_Sattr_To_FSALattr(&attributes_create, &parg->arg_create3.how.createhow3_u. obj_attributes) == 0) { pres->res_create3.status = NFS3ERR_INVAL; rc = NFS_REQ_OK; goto out; } break; } /* Mode is managed above (in cache_inode_create), there is no need * to manage it */ if(attributes_create.asked_attributes & FSAL_ATTR_MODE) attributes_create.asked_attributes &= ~FSAL_ATTR_MODE; /* Some clients (like Solaris 10) try to set the size of the file to 0 * at creation time. The FSAL create empty file, so we ignore this */ if(attributes_create.asked_attributes & FSAL_ATTR_SIZE) attributes_create.asked_attributes &= ~FSAL_ATTR_SIZE; if(attributes_create.asked_attributes & FSAL_ATTR_SPACEUSED) attributes_create.asked_attributes &= ~FSAL_ATTR_SPACEUSED; /* Are there attributes to be set (additional to the mode) ? */ if(attributes_create.asked_attributes != 0ULL && attributes_create.asked_attributes != FSAL_ATTR_MODE) { /* A call to cache_inode_setattr is required */ if(cache_inode_setattr(file_pentry, &attributes_create, pcontext, &cache_status) != CACHE_INODE_SUCCESS) { /* If we are here, there was an error */ nfs_SetFailedStatus(pcontext, pexport, preq->rq_vers, cache_status, &pres->res_dirop2.status, &pres->res_create3.status, NULL, NULL, parent_pentry, ppre_attr, &(pres->res_create3.CREATE3res_u.resfail. dir_wcc), NULL, NULL, NULL); if(nfs_RetryableError(cache_status)) { rc = NFS_REQ_DROP; goto out; } rc = NFS_REQ_OK; goto out; } /* Get the resulting attributes from the Cache Inode */ if(cache_inode_getattr(file_pentry, &attr_newfile, pcontext, &cache_status) != CACHE_INODE_SUCCESS) { /* If we are here, there was an error */ nfs_SetFailedStatus(pcontext, pexport, preq->rq_vers, cache_status, &pres->res_dirop2.status, &pres->res_create3.status, NULL, NULL, parent_pentry, ppre_attr, &(pres->res_create3.CREATE3res_u.resfail. dir_wcc), NULL, NULL, NULL); if(nfs_RetryableError(cache_status)) { rc = NFS_REQ_DROP; goto out; } rc = NFS_REQ_OK; goto out; } } switch (preq->rq_vers) { case NFS_V2: /* Build file handle */ if(nfs2_FSALToFhandle( &(pres->res_dirop2.DIROP2res_u.diropok.file), &file_pentry->handle, pexport) == 0) pres->res_dirop2.status = NFSERR_IO; else { if(!nfs2_FSALattr_To_Fattr( pexport, &attr_newfile, &(pres->res_dirop2.DIROP2res_u. diropok.attributes))) pres->res_dirop2.status = NFSERR_IO; else pres->res_dirop2.status = NFS_OK; } break; case NFS_V3: /* Build file handle */ pres->res_create3.status = nfs3_AllocateFH(&pres->res_create3.CREATE3res_u .resok.obj.post_op_fh3_u.handle); if (pres->res_create3.status != NFS3_OK) { rc = NFS_REQ_OK; goto out; } /* Set Post Op Fh3 structure */ if(nfs3_FSALToFhandle( &(pres->res_create3.CREATE3res_u.resok .obj.post_op_fh3_u.handle), &file_pentry->handle, pexport) == 0) { gsh_free(pres->res_create3.CREATE3res_u.resok.obj. post_op_fh3_u.handle.data.data_val); pres->res_create3.status = NFS3ERR_BADHANDLE; rc = NFS_REQ_OK; goto out; } /* Set Post Op Fh3 structure */ pres->res_create3.CREATE3res_u.resok.obj.handle_follows = TRUE; /* Get the attributes of the parent after the operation */ attr_parent_after = parent_pentry->attributes; /* Build entry attributes */ nfs_SetPostOpAttr(pexport, &attr_newfile, &(pres->res_create3.CREATE3res_u.resok. obj_attributes)); /* * Build Weak Cache Coherency data */ nfs_SetWccData(pexport, ppre_attr, &attr_parent_after, &(pres->res_create3.CREATE3res_u .resok.dir_wcc)); pres->res_create3.status = NFS3_OK; break; } /* switch */ rc = NFS_REQ_OK; goto out; } } else { if(cache_status_lookup == CACHE_INODE_SUCCESS) { /* Trying to create a file that already exists */ cache_status = CACHE_INODE_ENTRY_EXISTS; switch (preq->rq_vers) { case NFS_V2: pres->res_dirop2.status = NFSERR_EXIST; break; case NFS_V3: pres->res_create3.status = NFS3ERR_EXIST; break; } } else { /* Server fault */ cache_status = cache_status_lookup; switch (preq->rq_vers) { case NFS_V2: pres->res_dirop2.status = NFSERR_IO; break; case NFS_V3: pres->res_create3.status = NFS3ERR_INVAL; break; } } nfs_SetFailedStatus(pcontext, pexport, preq->rq_vers, cache_status, &pres->res_dirop2.status, &pres->res_create3.status, NULL, NULL, parent_pentry, ppre_attr, &(pres->res_create3.CREATE3res_u.resfail.dir_wcc), NULL, NULL, NULL); rc = NFS_REQ_OK; goto out; } /* if( cache_status_lookup == CACHE_INODE_NOT_FOUND ) */ } } /* Set the exit status */ nfs_SetFailedStatus(pcontext, pexport, preq->rq_vers, cache_status, &pres->res_dirop2.status, &pres->res_create3.status, NULL, NULL, parent_pentry, ppre_attr, &(pres->res_create3.CREATE3res_u.resfail.dir_wcc), NULL, NULL, NULL); /* If we are here, there was an error */ if(nfs_RetryableError(cache_status)) { rc = NFS_REQ_DROP; goto out; } rc = NFS_REQ_OK; out: /* return references */ if (file_pentry) cache_inode_put(file_pentry); if (parent_pentry) cache_inode_put(parent_pentry); return (rc); } /* nfs_Create */
struct hash_table * hashtable_init(struct hash_param *hparam) { /* The hash table being constructed */ struct hash_table *ht = NULL; /* The index for initializing each partition */ uint32_t index = 0; /* Read-Write Lock attributes, to prevent write starvation under GLIBC */ pthread_rwlockattr_t rwlockattr; /* Hash partition */ struct hash_partition *partition = NULL; /* The number of fully initialized partitions */ uint32_t completed = 0; if (pthread_rwlockattr_init(&rwlockattr) != 0) return NULL; /* At some point factor this out into the OS directory. it is necessary to prevent writer starvation under GLIBC. */ #ifdef GLIBC if ((pthread_rwlockattr_setkind_np (&rwlockattrs, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)) != 0) { LogCrit(COMPONENT_HASHTABLE, "Unable to set writer-preference on lock attribute."); goto deconstruct; } #endif /* GLIBC */ ht = gsh_calloc(1, sizeof(struct hash_table) + (sizeof(struct hash_partition) * hparam->index_size)); /* Fixup entry size */ if (hparam->flags & HT_FLAG_CACHE) { if (!hparam->cache_entry_count) /* works fine with a good hash algo */ hparam->cache_entry_count = 32767; } /* We need to save copy of the parameters in the table. */ ht->parameter = *hparam; for (index = 0; index < hparam->index_size; ++index) { partition = (&ht->partitions[index]); RBT_HEAD_INIT(&(partition->rbt)); if (pthread_rwlock_init(&partition->lock, &rwlockattr) != 0) { LogCrit(COMPONENT_HASHTABLE, "Unable to initialize lock in hash table."); goto deconstruct; } /* Allocate a cache if requested */ if (hparam->flags & HT_FLAG_CACHE) partition->cache = gsh_calloc(1, cache_page_size(ht)); completed++; } ht->node_pool = pool_basic_init(NULL, sizeof(rbt_node_t)); ht->data_pool = pool_basic_init(NULL, sizeof(struct hash_data)); pthread_rwlockattr_destroy(&rwlockattr); return ht; deconstruct: while (completed != 0) { if (hparam->flags & HT_FLAG_CACHE) gsh_free(ht->partitions[completed - 1].cache); PTHREAD_RWLOCK_destroy(&(ht->partitions[completed - 1].lock)); completed--; } if (ht->node_pool) pool_destroy(ht->node_pool); if (ht->data_pool) pool_destroy(ht->data_pool); gsh_free(ht); return ht = NULL; }
int _9p_xattrcreate(struct _9p_request_data *req9p, u32 *plenout, char *preply) { char *cursor = req9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE; int create; u16 *msgtag = NULL; u32 *fid = NULL; u64 *size; u32 *flag; u16 *name_len; char *name_str; struct _9p_fid *pfid = NULL; fsal_status_t fsal_status = { .major = ERR_FSAL_NO_ERROR, .minor = 0 }; char name[MAXNAMLEN+1]; /* Get data */ _9p_getptr(cursor, msgtag, u16); _9p_getptr(cursor, fid, u32); _9p_getstr(cursor, name_len, name_str); _9p_getptr(cursor, size, u64); _9p_getptr(cursor, flag, u32); LogDebug(COMPONENT_9P, "TXATTRCREATE: tag=%u fid=%u name=%.*s size=%llu flag=%u", (u32) *msgtag, *fid, *name_len, name_str, (unsigned long long)*size, *flag); if (*fid >= _9P_FID_PER_CONN) return _9p_rerror(req9p, msgtag, ERANGE, plenout, preply); if (*size > _9P_XATTR_MAX_SIZE) return _9p_rerror(req9p, msgtag, ENOSPC, plenout, preply); pfid = req9p->pconn->fids[*fid]; /* Check that it is a valid fid */ if (pfid == NULL || pfid->pentry == NULL) { LogDebug(COMPONENT_9P, "request on invalid fid=%u", *fid); return _9p_rerror(req9p, msgtag, EIO, plenout, preply); } /* set op_ctx, it will be useful if FSAL is later called */ _9p_init_opctx(pfid, req9p); if ((op_ctx->export_perms->options & EXPORT_OPTION_WRITE_ACCESS) == 0) return _9p_rerror(req9p, msgtag, EROFS, plenout, preply); if (*name_len >= sizeof(name)) { LogDebug(COMPONENT_9P, "request with name too long (%u)", *name_len); return _9p_rerror(req9p, msgtag, ENAMETOOLONG, plenout, preply); } snprintf(name, sizeof(name), "%.*s", *name_len, name_str); if (*size == 0LL) { /* Size == 0 : this is in fact a call to removexattr */ LogDebug(COMPONENT_9P, "TXATTRCREATE: tag=%u fid=%u : will remove xattr %s", (u32) *msgtag, *fid, name); fsal_status = pfid->pentry->obj_ops.remove_extattr_by_name(pfid->pentry, name); if (FSAL_IS_ERROR(fsal_status)) return _9p_rerror(req9p, msgtag, _9p_tools_errno(fsal_status), plenout, preply); } else { /* Size != 0 , this is a creation/replacement of xattr */ /* Create the xattr at the FSAL level and cache result */ pfid->xattr = gsh_malloc(sizeof(*pfid->xattr) + *size); pfid->xattr->xattr_size = *size; pfid->xattr->xattr_offset = 0LL; pfid->xattr->xattr_write = _9P_XATTR_CAN_WRITE; strncpy(pfid->xattr->xattr_name, name, MAXNAMLEN); /* /!\ POSIX_ACL RELATED HOOK * Setting a POSIX ACL (using setfacl for example) means * settings a xattr named system.posix_acl_access BUT this * attribute is to be used and should not be created * (it exists already since acl feature is on) */ if (!strncmp(name, "system.posix_acl_access", MAXNAMLEN)) goto skip_create; /* try to create if flag doesn't have REPLACE bit */ if ((*flag & XATTR_REPLACE) == 0) create = true; else create = false; fsal_status = pfid->pentry->obj_ops.setextattr_value(pfid->pentry, name, pfid->xattr->xattr_content, *size, create); /* Try again with create = false if flag was set to 0 * and create failed because attribute already exists */ if (FSAL_IS_ERROR(fsal_status) && fsal_status.major == ERR_FSAL_EXIST && (*flag == 0)) { fsal_status = pfid->pentry->obj_ops.setextattr_value(pfid->pentry, name, pfid->xattr->xattr_content, *size, false); } if (FSAL_IS_ERROR(fsal_status)) { gsh_free(pfid->xattr); return _9p_rerror(req9p, msgtag, _9p_tools_errno(fsal_status), plenout, preply); } } skip_create: /* Build the reply */ _9p_setinitptr(cursor, preply, _9P_RXATTRCREATE); _9p_setptr(cursor, msgtag, u16); _9p_setendptr(cursor, preply); _9p_checkbound(cursor, preply, plenout); LogDebug(COMPONENT_9P, "RXATTRCREATE: tag=%u fid=%u name=%.*s size=%llu flag=%u", (u32) *msgtag, *fid, *name_len, name_str, (unsigned long long)*size, *flag); return 1; } /* _9p_xattrcreate */
/** * * nfs_Add_MountList_Entry: Adds a client to the mount list. * * Adds a client to the mount list. * * @param hostname [IN] the hostname for the client * @param dirpath [IN] the mounted path * * @return 1 if successful, 0 otherwise * */ int nfs_Add_MountList_Entry(char *hostname, char *dirpath) { #ifndef _NO_MOUNT_LIST mountlist pnew_mnt_list_entry; #endif /* Sanity check */ if(hostname == NULL || dirpath == NULL) return 0; #ifndef _NO_MOUNT_LIST /* Allocate the new entry */ if((pnew_mnt_list_entry = gsh_calloc(1, sizeof(struct mountbody))) == NULL) return 0; if((pnew_mnt_list_entry->ml_hostname = gsh_calloc(1, MAXHOSTNAMELEN + 1)) == NULL) { gsh_free(pnew_mnt_list_entry); return 0; } if((pnew_mnt_list_entry->ml_directory = gsh_calloc(1, MAXPATHLEN + 1)) == NULL) { gsh_free(pnew_mnt_list_entry->ml_hostname); gsh_free(pnew_mnt_list_entry); return 0; } /* Copy the data */ if (strmaxcpy(pnew_mnt_list_entry->ml_hostname, hostname, MAXHOSTNAMELEN) == -1) { gsh_free(pnew_mnt_list_entry->ml_directory); gsh_free(pnew_mnt_list_entry->ml_hostname); gsh_free(pnew_mnt_list_entry); return 0; } if (strmaxcpy(pnew_mnt_list_entry->ml_directory, dirpath, MAXPATHLEN) == -1) { gsh_free(pnew_mnt_list_entry->ml_directory); gsh_free(pnew_mnt_list_entry->ml_hostname); gsh_free(pnew_mnt_list_entry); return 0; } /* initialize next pointer */ pnew_mnt_list_entry->ml_next = NULL; /* This should occur only for the first mount */ if(MNT_List_head == NULL) { MNT_List_head = pnew_mnt_list_entry; } /* Append to the tail of the list */ if(MNT_List_tail == NULL) MNT_List_tail = pnew_mnt_list_entry; else { MNT_List_tail->ml_next = pnew_mnt_list_entry; MNT_List_tail = pnew_mnt_list_entry; } if(isFullDebug(COMPONENT_NFSPROTO)) nfs_Print_MountList(); #endif return 1; }
void *LUSTREFSAL_UP_Thread(void *Arg) { const struct fsal_up_vector *event_func; struct lustre_filesystem *lustre_fs = Arg; struct lcap_cl_ctx *ctx = NULL; struct changelog_rec *rec; struct changelog_ext_jobid *jid; struct changelog_ext_rename *rnm; int flags = LCAP_CL_DIRECT|LCAP_CL_JOBID; int rc; long long last_idx = 0LL; long long managed_idx = 0LL; unsigned int req_count = 0; /* For wanting of a llapi call to get this information */ /* @todo: use information form fsal_filesystem here */ const char mdtname[] = "lustre-MDT0000"; const char chlg_reader[] = "cl1"; char my_jobid[JOBID_LEN]; /* Compute my jobid */ snprintf(my_jobid, JOBID_LEN, "%s.%d", exec_name, getuid()); /* get the FSAL_UP vector */ event_func = lustre_fs->up_ops; if (event_func == NULL) { LogFatal(COMPONENT_FSAL_UP, "FSAL up vector does not exist. Can not continue."); gsh_free(Arg); return NULL; } LogFullDebug(COMPONENT_FSAL_UP, "Initializing callback thread for %s MDT=%s my_jobid=%s", lustre_fs->fsname, mdtname, my_jobid); /* Wait for 2 seconds, until the rest of the server starts */ sleep(2); /* Main loop */ last_idx = 0LL; managed_idx = 0LL; while (true) { /* open changelog reading channel in lcap */ rc = lcap_changelog_start(&ctx, flags, mdtname, last_idx); if (rc) { LogFatal(COMPONENT_FSAL_UP, "could not read changelog, " "lcap_changelog_start:(%d,%s)", rc, strerror(-rc)); return NULL; } while ((rc = lcap_changelog_recv(ctx, &rec)) == 0) { if (rec->cr_flags & CLF_JOBID) jid = changelog_rec_jobid(rec); else break; if (rec->cr_index > managed_idx) { managed_idx = rec->cr_index; last_idx = rec->cr_index; req_count += 1; /* If jobid is an empty string, skip it */ if (jid->cr_jid[0] == '\0') { rc = lcap_changelog_free(ctx, &rec); if (rc) LogFatal(COMPONENT_FSAL_UP, "lcap_changelog_free: " "%d,%s\n", rc, strerror(-rc)); continue; } /* Do not care for records generated * by Ganesha's activity */ if (!strcmp(jid->cr_jobid, my_jobid)) { rc = lcap_changelog_free(ctx, &rec); if (rc) LogFatal(COMPONENT_FSAL_UP, "lcap_changelog_free: " "%d,%s\n", rc, strerror(-rc)); continue; } rc = lustre_changelog_upcall(lustre_fs, event_func, rec); if (rc) LogMajor(COMPONENT_FSAL, "error occured when dealing" " with a changelog record"); rc = lcap_changelog_free(ctx, &rec); if (rc) LogFatal(COMPONENT_FSAL_UP, "lcap_changelog_free: %d,%s\n", rc, strerror(-rc)); } } if (req_count > FLUSH_REQ_COUNT) { rc = lcap_changelog_clear(ctx, mdtname, chlg_reader, last_idx); if (rc) LogDebug(COMPONENT_FSAL_UP, "lcap_changelog_clear() exited" " with status %d, %s", rc, strerror(-rc)); else LogDebug(COMPONENT_FSAL_UP, "changelog records cleared"); req_count = 0; } /* clear si req_count > 0 et eof sans avoir vu de records */ if (rc < 0) LogDebug(COMPONENT_FSAL_UP, "lcap_changelog_recv() loop exited" " with status %d, %s", rc, strerror(-rc)); /* Close changelog file */ rc = lcap_changelog_fini(ctx); if (rc) LogFatal(COMPONENT_FSAL_UP, "lcap_changelog_fini: %d,%s\n", rc, strerror(-rc)); last_idx = 0LL; /* Sleep for one second to avoid too aggressive polling * on LUSTRE changelogs */ sleep(1); } return NULL; }
static struct pt_fsal_obj_handle *alloc_handle(ptfsal_handle_t *fh, struct attrlist *attributes, const char *link_content, ptfsal_handle_t *dir_fh, const char *unopenable_name, struct fsal_export *exp_hdl) { struct pt_fsal_obj_handle *hdl; hdl = gsh_malloc(sizeof(struct pt_fsal_obj_handle) + sizeof(ptfsal_handle_t)); if (hdl == NULL) return NULL; memset(hdl, 0, (sizeof(struct pt_fsal_obj_handle) + sizeof(ptfsal_handle_t))); hdl->handle = (ptfsal_handle_t *) &hdl[1]; memcpy(hdl->handle, fh, sizeof(ptfsal_handle_t)); hdl->obj_handle.type = attributes->type; hdl->obj_handle.fs = &pt_filesystem; if (hdl->obj_handle.type == REGULAR_FILE) { hdl->u.file.fd = -1; /* no open on this yet */ hdl->u.file.openflags = FSAL_O_CLOSED; } else if (hdl->obj_handle.type == SYMBOLIC_LINK && link_content != NULL) { size_t len = strlen(link_content) + 1; hdl->u.symlink.link_content = gsh_malloc(len); if (hdl->u.symlink.link_content == NULL) goto spcerr; memcpy(hdl->u.symlink.link_content, link_content, len); hdl->u.symlink.link_size = len; } else if (pt_unopenable_type(hdl->obj_handle.type) && dir_fh != NULL && unopenable_name != NULL) { hdl->u.unopenable.dir = gsh_malloc(sizeof(ptfsal_handle_t)); if (hdl->u.unopenable.dir == NULL) goto spcerr; memcpy(hdl->u.unopenable.dir, dir_fh, sizeof(ptfsal_handle_t)); hdl->u.unopenable.name = gsh_malloc(strlen(unopenable_name) + 1); if (hdl->u.unopenable.name == NULL) goto spcerr; strcpy(hdl->u.unopenable.name, unopenable_name); } hdl->obj_handle.attributes.mask = exp_hdl->ops->fs_supported_attrs(exp_hdl); memcpy(&hdl->obj_handle.attributes, attributes, sizeof(struct attrlist)); fsal_obj_handle_init(&hdl->obj_handle, exp_hdl, attributes->type); return hdl; spcerr: if (hdl->obj_handle.type == SYMBOLIC_LINK) { if (hdl->u.symlink.link_content != NULL) gsh_free(hdl->u.symlink.link_content); } else if (pt_unopenable_type(hdl->obj_handle.type)) { if (hdl->u.unopenable.name != NULL) gsh_free(hdl->u.unopenable.name); if (hdl->u.unopenable.dir != NULL) gsh_free(hdl->u.unopenable.dir); } gsh_free(hdl); /* elvis has left the building */ return NULL; }
void Release_nfs4_denied(LOCK4denied * denied) { if(denied->owner.owner.owner_val != unknown_owner.so_owner_val && denied->owner.owner.owner_val != NULL) gsh_free(denied->owner.owner.owner_val); }
int _9p_walk(struct _9p_request_data *req9p, void *worker_data, u32 *plenout, char *preply) { char *cursor = req9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE; unsigned int i = 0; u16 *msgtag = NULL; u32 *fid = NULL; u32 *newfid = NULL; u16 *nwname = NULL; u16 *wnames_len; char *wnames_str; uint64_t fileid; cache_inode_status_t cache_status; cache_entry_t *pentry = NULL; char name[MAXNAMLEN]; u16 *nwqid; struct _9p_fid *pfid = NULL; struct _9p_fid *pnewfid = NULL; /* Now Get data */ _9p_getptr(cursor, msgtag, u16); _9p_getptr(cursor, fid, u32); _9p_getptr(cursor, newfid, u32); _9p_getptr(cursor, nwname, u16); LogDebug(COMPONENT_9P, "TWALK: tag=%u fid=%u newfid=%u nwname=%u", (u32) *msgtag, *fid, *newfid, *nwname); if (*fid >= _9P_FID_PER_CONN) return _9p_rerror(req9p, worker_data, msgtag, ERANGE, plenout, preply); if (*newfid >= _9P_FID_PER_CONN) return _9p_rerror(req9p, worker_data, msgtag, ERANGE, plenout, preply); pfid = req9p->pconn->fids[*fid]; /* Check that it is a valid fid */ if (pfid == NULL || pfid->pentry == NULL) { LogDebug(COMPONENT_9P, "request on invalid fid=%u", *fid); return _9p_rerror(req9p, worker_data, msgtag, EIO, plenout, preply); } op_ctx = &pfid->op_context; pnewfid = gsh_calloc(1, sizeof(struct _9p_fid)); if (pnewfid == NULL) return _9p_rerror(req9p, worker_data, msgtag, ERANGE, plenout, preply); /* Is this a lookup or a fid cloning operation ? */ if (*nwname == 0) { /* Cloning operation */ memcpy((char *)pnewfid, (char *)pfid, sizeof(struct _9p_fid)); /* Set the new fid id */ pnewfid->fid = *newfid; /* This is not a TATTACH fid */ pnewfid->from_attach = false; /* Increments refcount */ (void) cache_inode_lru_ref(pnewfid->pentry, LRU_REQ_STALE_OK); } else { /* the walk is in fact a lookup */ pentry = pfid->pentry; for (i = 0; i < *nwname; i++) { _9p_getstr(cursor, wnames_len, wnames_str); snprintf(name, MAXNAMLEN, "%.*s", *wnames_len, wnames_str); LogDebug(COMPONENT_9P, "TWALK (lookup): tag=%u fid=%u newfid=%u (component %u/%u :%s)", (u32) *msgtag, *fid, *newfid, i + 1, *nwname, name); if (pnewfid->pentry == pentry) pnewfid->pentry = NULL; /* refcount +1 */ cache_status = cache_inode_lookup(pentry, name, &pnewfid->pentry); if (pnewfid->pentry == NULL) { gsh_free(pnewfid); return _9p_rerror(req9p, worker_data, msgtag, _9p_tools_errno(cache_status), plenout, preply); } if (pentry != pfid->pentry) cache_inode_put(pentry); pentry = pnewfid->pentry; } pnewfid->fid = *newfid; pnewfid->op_context = pfid->op_context; pnewfid->ppentry = pfid->pentry; strncpy(pnewfid->name, name, MAXNAMLEN-1); /* gdata ref is not hold : the pfid, which use same gdata */ /* will be clunked after pnewfid */ /* This clunk release the gdata */ pnewfid->gdata = pfid->gdata; /* This is not a TATTACH fid */ pnewfid->from_attach = false; cache_status = cache_inode_fileid(pnewfid->pentry, &fileid); if (cache_status != CACHE_INODE_SUCCESS) { gsh_free(pnewfid); return _9p_rerror(req9p, worker_data, msgtag, _9p_tools_errno(cache_status), plenout, preply); } /* Build the qid */ /* No cache, we want the client to stay synchronous * with the server */ pnewfid->qid.version = 0; pnewfid->qid.path = fileid; pnewfid->specdata.xattr.xattr_id = 0; pnewfid->specdata.xattr.xattr_content = NULL; switch (pnewfid->pentry->type) { case REGULAR_FILE: case CHARACTER_FILE: case BLOCK_FILE: case SOCKET_FILE: case FIFO_FILE: pnewfid->qid.type = _9P_QTFILE; break; case SYMBOLIC_LINK: pnewfid->qid.type = _9P_QTSYMLINK; break; case DIRECTORY: pnewfid->qid.type = _9P_QTDIR; break; default: LogMajor(COMPONENT_9P, "implementation error, you should not see this message !!!!!!"); gsh_free(pnewfid); return _9p_rerror(req9p, worker_data, msgtag, EINVAL, plenout, preply); break; } } /* keep info on new fid */ req9p->pconn->fids[*newfid] = pnewfid; /* As much qid as requested fid */ nwqid = nwname; /* Hold refcount on gdata */ uid2grp_hold_group_data(pnewfid->gdata); /* Build the reply */ _9p_setinitptr(cursor, preply, _9P_RWALK); _9p_setptr(cursor, msgtag, u16); _9p_setptr(cursor, nwqid, u16); for (i = 0; i < *nwqid; i++) { /** @todo: should be different qids * for each directory walked through */ _9p_setqid(cursor, pnewfid->qid); } _9p_setendptr(cursor, preply); _9p_checkbound(cursor, preply, plenout); LogDebug(COMPONENT_9P, "RWALK: tag=%u fid=%u newfid=%u nwqid=%u fileid=%llu pentry=%p refcount=%i", (u32) *msgtag, *fid, *newfid, *nwqid, (unsigned long long)pnewfid->qid.path, pnewfid->pentry, pnewfid->pentry->lru.refcnt); return 1; }
static int xattr_format_value(caddr_t buffer, size_t *datalen, size_t maxlen) { size_t size_in = *datalen; size_t len = strnlen((char *)buffer, size_in); int i; if (len == size_in - 1 || len == size_in) { int ascii = true; char *str = buffer; int i; for (i = 0; i < len; i++) { if (!isprint(str[i]) && !isspace(str[i])) { ascii = false; break; } } if (ascii) { *datalen = size_in; /* add additional '\n', if missing */ if ((size_in + 1 < maxlen) && (str[len - 1] != '\n')) { str[len] = '\n'; str[len + 1] = '\0'; (*datalen) += 2; } return ERR_FSAL_NO_ERROR; } } /* byte, word, 32 or 64 bits */ if (size_in == 1) { unsigned char val = *((unsigned char *)buffer); *datalen = 1 + snprintf((char *)buffer, maxlen, "%hhu\n", val); return ERR_FSAL_NO_ERROR; } else if (size_in == 2) { unsigned short val = *((unsigned short *)buffer); *datalen = 1 + snprintf((char *)buffer, maxlen, "%hu\n", val); return ERR_FSAL_NO_ERROR; } else if (size_in == 4) { unsigned int val = *((unsigned int *)buffer); *datalen = 1 + snprintf((char *)buffer, maxlen, "%u\n", val); return ERR_FSAL_NO_ERROR; } else if (size_in == 8) { unsigned long long val = *((unsigned long long *)buffer); *datalen = 1 + snprintf((char *)buffer, maxlen, "%llu\n", val); return ERR_FSAL_NO_ERROR; } else { /* 2 bytes per initial byte +'0x' +\n +\0 */ char *curr_out; char *tmp_buf = (char *)gsh_malloc(3 * size_in + 4); if (!tmp_buf) return ERR_FSAL_NOMEM; curr_out = tmp_buf; curr_out += sprintf(curr_out, "0x"); /* hexa representation */ for (i = 0; i < size_in; i++) { unsigned char *p8 = (unsigned char *)(buffer + i); if ((i % 4 == 3) && (i != size_in - 1)) curr_out += sprintf(curr_out, "%02hhX.", *p8); else curr_out += sprintf(curr_out, "%02hhX", *p8); } *curr_out = '\n'; curr_out++; *curr_out = '\0'; curr_out++; strncpy((char *)buffer, tmp_buf, maxlen); *datalen = strlen(tmp_buf) + 1; if (*datalen > maxlen) *datalen = maxlen; gsh_free(tmp_buf); return ERR_FSAL_NO_ERROR; } }
int nfs4_op_getdevicelist(struct nfs_argop4 *op, compound_data_t *data, struct nfs_resop4 *resp) { /* Convenience alias for arguments */ GETDEVICELIST4args * const arg_GETDEVICELIST4 = &op->nfs_argop4_u.opgetdevicelist; /* Convenience alias for response */ GETDEVICELIST4res * const res_GETDEVICELIST4 = &resp->nfs_resop4_u.opgetdevicelist; /* NFS4 return code */ nfsstat4 nfs_status = 0; /* Input/output and output parameters of FSAL function */ struct fsal_getdevicelist_res res; /* Structure for callback */ struct cb_data cb_opaque; resp->resop = NFS4_OP_GETDEVICELIST; if (data->minorversion == 0) return res_GETDEVICELIST4->gdlr_status = NFS4ERR_INVAL; nfs_status = nfs4_sanity_check_FH(data, NO_FILE_TYPE, false); if (nfs_status != NFS4_OK) goto out; memset(&res, 0, sizeof(struct fsal_getdevicelist_res)); res.cookie = arg_GETDEVICELIST4->gdla_cookie; memcpy(&res.cookieverf, arg_GETDEVICELIST4->gdla_cookieverf, NFS4_VERIFIER_SIZE); cb_opaque.count = 0; cb_opaque.max = 32; cb_opaque.swexport = nfs_htonl64(op_ctx->export->export_id); res_GETDEVICELIST4->GETDEVICELIST4res_u.gdlr_resok4. gdlr_deviceid_list.gdlr_deviceid_list_val = gsh_malloc(cb_opaque.max * sizeof(deviceid4)); if (res_GETDEVICELIST4->GETDEVICELIST4res_u.gdlr_resok4. gdlr_deviceid_list.gdlr_deviceid_list_val == NULL) { nfs_status = NFS4ERR_SERVERFAULT; goto out; } cb_opaque.buffer = res_GETDEVICELIST4->GETDEVICELIST4res_u.gdlr_resok4. gdlr_deviceid_list.gdlr_deviceid_list_val; nfs_status = op_ctx->fsal_export->ops->getdevicelist( op_ctx->fsal_export, arg_GETDEVICELIST4->gdla_layout_type, &cb_opaque, cb, &res); if (nfs_status != NFS4_OK) { gsh_free(cb_opaque.buffer); goto out; } res_GETDEVICELIST4->GETDEVICELIST4res_u.gdlr_resok4.gdlr_cookie = res.cookie; memcpy(res_GETDEVICELIST4->GETDEVICELIST4res_u.gdlr_resok4. gdlr_cookieverf, &res.cookieverf, NFS4_VERIFIER_SIZE); res_GETDEVICELIST4->GETDEVICELIST4res_u.gdlr_resok4.gdlr_deviceid_list. gdlr_deviceid_list_len = cb_opaque.count; res_GETDEVICELIST4->GETDEVICELIST4res_u.gdlr_resok4.gdlr_eof = res.eof; nfs_status = NFS4_OK; out: res_GETDEVICELIST4->gdlr_status = nfs_status; return res_GETDEVICELIST4->gdlr_status; }