示例#1
0
文件: mscp.c 项目: rroart/freevms
int get_mscp_chan(char * s)
{
    int sts;
    unsigned short int chan;
    struct _ucb * ucb;
    struct dsc$descriptor dsc;
    struct return_values r;
    struct _vcb * vcb;
    struct _aqb * aqb;
    dsc.dsc$a_pointer=do_file_translate(s);
    dsc.dsc$w_length=strlen(dsc.dsc$a_pointer);
    if (ioc$search(&r,&dsc)==SS$_NORMAL)
        return ((struct _ucb *)r.val1)->ucb$ps_adp;
    ucb = fl_init(s);
    vcb = (struct _vcb *) kmalloc(sizeof(struct _vcb),GFP_KERNEL);
    memset(vcb,0,sizeof(struct _vcb));
    vcb->vcb$b_type=DYN$C_VCB;
    aqb = (struct _aqb *) kmalloc(sizeof(struct _aqb),GFP_KERNEL);
    memset(aqb,0,sizeof(struct _aqb));
    aqb->aqb$b_type=DYN$C_AQB;
    qhead_init(&aqb->aqb$l_acpqfl);
    ucb->ucb$l_vcb=vcb;
    vcb->vcb$l_aqb=aqb;
    qhead_init(&vcb->vcb$l_fcbfl);
    vcb->vcb$l_cache = NULL; // ?
    sts = phyio_init(strlen(s),s,&ucb->ucb$l_vcb->vcb$l_aqb->aqb$l_mount_count,0,0); // check
    dsc.dsc$a_pointer=do_file_translate(s);
    dsc.dsc$w_length=strlen(dsc.dsc$a_pointer);
    sts=exe$assign(&dsc,&chan,0,0,0);
    ucb->ucb$ps_adp=chan; //wrong field and use, but....
    return chan;
}
示例#2
0
文件: dispatch.c 项目: rroart/freevms
void __init xqp_init(void)
{
#if 0
    int i;
    for(i=0; i<1; i++)
    {
        qhead_init(&xqps[i].xqp_head);
    }
#endif
}
示例#3
0
asmlinkage int exe$creprc(unsigned int *pidadr, void *image, void *input, void *output, void *error, struct _generic_64 *prvadr, unsigned int *quota, void*prcnam, unsigned int baspri, unsigned int uic, unsigned short int mbxunt, unsigned int stsflg,...) {
  unsigned long stack_here;
  struct _pcb * p, * cur;
  int retval;

  struct dsc$descriptor * imd = image, * ind = input, * oud = output, * erd = error;

  unsigned long clone_flags=CLONE_VFORK;
  //check pidadr

  ctl$gl_creprc_flags = stsflg;
  // check for PRC$M_NOUAF sometime

  if (stsflg&PRC$M_DETACH) {

  }
  if (uic) {

  }
  //setipl(IPL$_ASTDEL);//postpone this?
  cur=ctl$gl_pcb;
  vmslock(&SPIN_SCHED, IPL$_SCHED);
  vmslock(&SPIN_MMG, IPL$_MMG);
  p = alloc_task_struct();
  //bzero(p,sizeof(struct _pcb));//not wise?
  memset(p,0,sizeof(struct _pcb));

  // check more
  // compensate for no struct clone/copy
  p->sigmask_lock = SPIN_LOCK_UNLOCKED;
  p->alloc_lock = SPIN_LOCK_UNLOCKED;

  qhead_init(&p->pcb$l_astqfl);
  // and enable ast del to all modes

  p->pcb$b_type = DYN$C_PCB;

  p->pcb$b_asten=15;
  p->phd$b_astlvl=4;
  p->pr_astlvl=4;
  p->psl=0;
  p->pslindex=0;

  qhead_init(&p->pcb$l_lockqfl);
  // set capabilities
  p->pcb$l_permanent_capability = sch$gl_default_process_cap;
  p->pcb$l_capability = p->pcb$l_permanent_capability;
  // set affinity
  // set default fileprot
  // set arb
  // set mbx stuff
  // from setprn:
  if (prcnam) {
    struct dsc$descriptor *s=prcnam;
    strncpy(p->pcb$t_lname,s->dsc$a_pointer,s->dsc$w_length);
  }
  // set priv
  p->pcb$l_priv=ctl$gl_pcb->pcb$l_priv;
  // set pris
  p->pcb$b_prib=31-baspri;
  p->pcb$b_pri=31-baspri-6;
  //	if (p->pcb$b_pri<16) p->pcb$b_pri=16;
  p->pcb$w_quant=-QUANTUM;
  
  // set uic
  p->pcb$l_uic=ctl$gl_pcb->pcb$l_uic;
  // set vms pid
  // check process name
  // do something with pqb

  p->pcb$l_pqb=kmalloc(sizeof(struct _pqb),GFP_KERNEL);
  memset(p->pcb$l_pqb,0,sizeof(struct _pqb));

  struct _pqb * pqb = p->pcb$l_pqb;

  pqb->pqb$q_prvmsk = ctl$gq_procpriv;

  if (imd)
    memcpy(pqb->pqb$t_image,imd->dsc$a_pointer,imd->dsc$w_length);
  if (ind)
    memcpy(pqb->pqb$t_input,ind->dsc$a_pointer,ind->dsc$w_length);
  if (oud)
    memcpy(pqb->pqb$t_output,oud->dsc$a_pointer,oud->dsc$w_length);
  if (erd)
    memcpy(pqb->pqb$t_error,erd->dsc$a_pointer,erd->dsc$w_length);

  if (oud) // temp measure
    memcpy(p->pcb$t_terminal,oud->dsc$a_pointer,oud->dsc$w_length);

  // translate some logicals
  // copy security clearance
  // copy msg
  // copy flags
  // set jib
  // do quotas
  // process itmlst
  // set pcb$l_pqb
#if 0
  setipl(IPL$_MMG);
  vmslock(&SPIN_SCHED,-1);
  // find vacant slot in pcb vector
  // and store it
#endif  
  // make ipid and epid
  p->pcb$l_pid=alloc_ipid();
  {
    unsigned long *vec=sch$gl_pcbvec;
    vec[p->pcb$l_pid&0xffff]=p;
  }
  p->pcb$l_epid=exe$ipid_to_epid(p->pcb$l_pid);
  // should invoke sch$chse, put this at bottom?
  // setipl(0) and return

  // now lots of things from fork

	retval = -EAGAIN;
	/*
	 * Check if we are over our maximum process limit, but be sure to
	 * exclude root. This is needed to make it possible for login and
	 * friends to set the per-user process limit to something lower
	 * than the amount of processes root is running. -- Rik
	 */
#if 0
	if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur
	              && !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE))
		goto bad_fork_free;

	atomic_inc(&p->user->__count);
	atomic_inc(&p->user->processes);
#endif

	/*
	 * Counter increases are protected by
	 * the kernel lock so nr_threads can't
	 * increase under us (but it may decrease).
	 */

	get_exec_domain(p->exec_domain);

	if (p->binfmt && p->binfmt->module)
		__MOD_INC_USE_COUNT(p->binfmt->module);

	p->did_exec = 0;
	p->swappable = 0;
	p->state = TASK_UNINTERRUPTIBLE;

	//copy_flags(clone_flags, p);
	// not here?	p->pcb$l_pid = alloc_ipid();

	p->run_list.next = NULL;
	p->run_list.prev = NULL;

	p->p_cptr = NULL;
	init_waitqueue_head(&p->wait_chldexit);
	p->vfork_done = NULL;
	spin_lock_init(&p->alloc_lock);

	p->sigpending = 0;
	init_sigpending(&p->pending);

	p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
	p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
	init_timer(&p->real_timer);
	p->real_timer.data = (unsigned long) p;

	p->leader = 0;		/* session leadership doesn't inherit */
	p->tty_old_pgrp = 0;
	p->times.tms_utime = p->times.tms_stime = 0;
	p->times.tms_cutime = p->times.tms_cstime = 0;
	p->lock_depth = -1;		/* -1 = no lock */
	p->start_time = jiffies;

	INIT_LIST_HEAD(&p->local_pages);

	p->files = current->files;
	p->fs = current->fs;
	p->sig = current->sig;

	/* copy all the process information */
	if (copy_files(clone_flags, p))
		goto bad_fork_cleanup;
	if (copy_fs(clone_flags, p))
		goto bad_fork_cleanup_files;
	if (copy_sighand(clone_flags, p))
		goto bad_fork_cleanup_fs;

 bad_fork_cleanup:
 bad_fork_cleanup_files:
 bad_fork_cleanup_fs:

	// now a hole

	// now more from fork

	/* ok, now we should be set up.. */
	p->swappable = 1;
	p->exit_signal = 0;
	p->pdeath_signal = 0;

	/*
	 * "share" dynamic priority between parent and child, thus the
	 * total amount of dynamic priorities in the system doesnt change,
	 * more scheduling fairness. This is only important in the first
	 * timeslice, on the long run the scheduling behaviour is unchanged.
	 */

	/*
	 * Ok, add it to the run-queues and make it
	 * visible to the rest of the system.
	 *
	 * Let it rip!
	 */
	retval = p->pcb$l_epid;
	INIT_LIST_HEAD(&p->thread_group);

	/* Need tasklist lock for parent etc handling! */
	write_lock_irq(&tasklist_lock);

	/* CLONE_PARENT and CLONE_THREAD re-use the old parent */
	p->p_opptr = current->p_opptr;
	p->p_pptr = current->p_pptr;

        p->p_opptr = current /*->p_opptr*/;
        p->p_pptr = current /*->p_pptr*/;

	SET_LINKS(p);

	nr_threads++;
	write_unlock_irq(&tasklist_lock);

	//	printk("fork befwak\n");
	//wake_up_process(p);		/* do this last */
	//	wake_up_process2(p,PRI$_TICOM);		/* do this last */
	//goto fork_out;//??


	// now something from exec

	// wait, better do execve itself

	memcpy(p->rlim, current->rlim, sizeof(p->rlim));

	qhead_init(&p->pcb$l_sqfl);

	struct mm_struct * mm = mm_alloc();
	p->mm = mm;
	p->active_mm = mm;

	p->user = INIT_USER;

	spin_lock(&mmlist_lock);
#if 0
	list_add(&mm->mmlist, &p->p_pptr->mm->mmlist);
#endif
	mmlist_nr++;
	spin_unlock(&mmlist_lock);

	// Now we are getting into the area that is really the swappers

	// To be moved to shell.c and swp$shelinit later

	p->pcb$l_phd=kmalloc(sizeof(struct _phd),GFP_KERNEL);
	init_phd(p->pcb$l_phd);

	init_fork_p1pp(p,p->pcb$l_phd,ctl$gl_pcb,ctl$gl_pcb->pcb$l_phd);
#ifdef __x86_64__
	shell_init_other(p,ctl$gl_pcb,0x7ff80000-0x1000,0x7fffe000);
	shell_init_other(p,ctl$gl_pcb,0x7ff80000-0x2000,0x7fffe000);
	shell_init_other(p,ctl$gl_pcb,0x7ff90000-0x1000,0x7fffe000);
	shell_init_other(p,ctl$gl_pcb,0x7ff90000-0x2000,0x7fffe000);
	shell_init_other(p,ctl$gl_pcb,0x7ffa0000-0x1000,0x7fffe000);
	shell_init_other(p,ctl$gl_pcb,0x7ffa0000-0x2000,0x7fffe000);
#else
	shell_init_other(p,ctl$gl_pcb,0x7ff80000-0x1000,0x7fffe000);
	shell_init_other(p,ctl$gl_pcb,0x7ff80000-0x2000,0x7fffe000);
	shell_init_other(p,ctl$gl_pcb,0x7ff90000-0x1000,0x7fffe000);
	shell_init_other(p,ctl$gl_pcb,0x7ff90000-0x2000,0x7fffe000);
#endif
	int exe$procstrt(struct _pcb * p);
	struct pt_regs * regs = &pidadr;
	//printk("newthread %x\n",p),
	retval = new_thread(0, clone_flags, 0, 0, p, 0);

	int eip=0,esp=0;

	//	start_thread(regs,eip,esp);

	sch$chse(p, PRI$_TICOM);

	vmsunlock(&SPIN_MMG,-1);
	vmsunlock(&SPIN_SCHED,0);

	return SS$_NORMAL;

#if 0
	return sys_execve(((struct dsc$descriptor *)image)->dsc$a_pointer,0,0);

	return SS$_NORMAL;
#endif

#if 0
{
  char * filename=((struct dsc$descriptor *)image)->dsc$a_pointer;
  char ** argv=0;
  char ** envp=0;
  struct pt_regs * regs=0;
  struct linux_binprm bprm;
  struct file *file;
  int retval;
  int i;

	file = open_exec(filename);

	retval = PTR_ERR(file);
	if (IS_ERR(file))
		return retval;

	bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
	memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); 

	bprm.file = file;
	bprm.filename = filename;
	bprm.sh_bang = 0;
	bprm.loader = 0;
	bprm.exec = 0;
	if ((bprm.argc = count(argv, bprm.p / sizeof(void *))) < 0) {
		allow_write_access(file);
		fput(file);
		//printk("here 7 %x\n",bprm.argc);
		return bprm.argc;
	}

	if ((bprm.envc = count(envp, bprm.p / sizeof(void *))) < 0) {
		allow_write_access(file);
		fput(file);
		//printk("here 6\n");
		return bprm.envc;
	}

	retval = prepare_binprm(&bprm);
	//printk("here 4\n");
	if (retval < 0) 
		goto out; 

	retval = copy_strings_kernel(1, &bprm.filename, &bprm);
	//printk("here 3\n");
	if (retval < 0) 
		goto out; 

	bprm.exec = bprm.p;
	retval = copy_strings(bprm.envc, envp, &bprm);
	//printk("here 2\n");
	if (retval < 0) 
		goto out; 

	retval = copy_strings(bprm.argc, argv, &bprm);
	//printk("here 1\n");
	if (retval < 0) 
		goto out; 

	retval = search_binary_handler(&bprm,regs);
	if (retval >= 0)
		/* execve success */
		return retval;

out:
	/* Something went wrong, return the inode and free the argument pages*/
	allow_write_access(bprm.file);
	if (bprm.file)
		fput(bprm.file);

	for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
		struct page * page = bprm.page[i];
		if (page)
			__free_page(page);
	}

	return retval;
}
#endif

fork_out:
	return retval;

bad_fork_free:
	free_task_struct(p);
	goto fork_out;

}
示例#4
0
asmlinkage int exe$enq(unsigned int efn, unsigned int lkmode, struct _lksb *lksb, unsigned int flags, void *resnam, unsigned int parid, void (*astadr)(), unsigned long astprm, void (*blkastadr)(), unsigned int acmode, unsigned int rsdm_id) {
  int convert;
  int retval=SS$_NORMAL;
  int sts;

  // some tests. one only for now, should be more.
  if (lkmode>LCK$K_EXMODE) return SS$_BADPARAM;

  vmslock(&SPIN_SCS,IPL$_SCS); // check. probably too early
  convert=flags&LCK$M_CONVERT;
  if (!convert) {
    /* new lock */
    struct _rsb * res = 0;
    struct _rsb * old;
    struct _lkb * lck = 0, *par = 0;
    struct dsc$descriptor * resnamdsc;
    int sserror=0;

    resnamdsc=resnam;
    if (resnamdsc->dsc$w_length==0 || resnamdsc->dsc$w_length>RSB$K_MAXLEN) { 
      sserror=SS$_IVBUFLEN;
      goto error;
    }
    if (flags&LCK$M_EXPEDITE)
      if (lkmode!=LCK$K_NLMODE) {
	sserror=SS$_UNSUPPORTED;
	goto error;
      }

    if (lkmode!=LCK$K_NLMODE) {
      sserror=SS$_UNSUPPORTED;
      goto error;
    }

    res=kmalloc(sizeof(struct _rsb),GFP_KERNEL);
    memset(res,0,sizeof(struct _rsb));
    lck=kmalloc(sizeof(struct _lkb),GFP_KERNEL);
    memset(lck,0,sizeof(struct _lkb));

    lck->lkb$b_efn=efn;
    lck->lkb$l_flags=flags;
    lck->lkb$b_rqmode=lkmode;
    lck->lkb$l_cplastadr=astadr;
    lck->lkb$l_blkastadr=blkastadr;
    lck->lkb$l_astprm=astprm;
    lck->lkb$l_pid=current->pcb$l_pid;
    lck->lkb$l_lksb=lksb;
    qhead_init(&lck->lkb$l_sqfl);
    qhead_init(&lck->lkb$l_ownqfl);

    strncpy(res->rsb$t_resnam,resnamdsc->dsc$a_pointer,resnamdsc->dsc$w_length);
    res->rsb$b_rsnlen=resnamdsc->dsc$w_length;

    setipl(IPL$_SCS);
    // do scs spinlock
    //setipl(IPL$_ASTDEL);

    if (flags&LCK$M_SYSTEM) {
      /* priv checks */
    } else {
	
    }

    if (parid==0) {
      //list_add(&res->lr_childof, &ns->ns_root_list);
      //this is added to lck$gl_rrsfl down below, I think
    } else {
      //check valid lock
      // check lock access mode
      par=lockidtbl[parid];
      if (current->pcb$l_pid != par->lkb$l_pid) {
	vmsunlock(&SPIN_SCS,IPL$_ASTDEL);
	return SS$_IVLOCKID;
      }
      //check if parent granted, if not return SS$_PARNOTGRANT;
      if (par->lkb$b_state!=LKB$K_CONVERT  || par->lkb$b_state!=LKB$K_GRANTED) 
	if ((par->lkb$l_flags & LCK$M_CONVERT) == 0) {
	    vmsunlock(&SPIN_SCS,IPL$_ASTDEL);
	    return SS$_PARNOTGRANT;
	}
      par->lkb$w_refcnt++;
      res->rsb$l_parent = par->lkb$l_rsb; // should not be here?
      //check if uic-specific resource
      //check if system-wide
      //charge lock against quota
      //list_add(&res->lr_childof, &parent->lr_children);
      //res->rsb$l_rtrsb=enq_find_oldest_parent(r,p->lkb$l_rsb);
      lck->lkb$l_parent=par;
    }

    old=find_reshashtbl(resnamdsc);
    if (!old) {
      lck$gl_rsbcnt++;
      lck$gl_lckcnt++;
      if (flags & LCK$M_SYNCSTS) retval=SS$_SYNCH;
      qhead_init(&res->rsb$l_grqfl);
      qhead_init(&res->rsb$l_cvtqfl);
      qhead_init(&res->rsb$l_wtqfl);
      //insque(&lck->lkb$l_sqfl,res->rsb$l_grqfl);
      lck->lkb$l_rsb=res;
      insert_reshashtbl(res);
      if (parid==0) {
	insque(&res->rsb$l_rrsfl,lck$gl_rrsfl);
	qhead_init(&res->rsb$l_srsfl);
	res->rsb$b_depth=0;
	res->rsb$l_rtrsb=res;
	exe$clref(lck->lkb$b_efn);
	insque(&lck->lkb$l_ownqfl,&current->pcb$l_lockqfl);
	//?if (q->flags & LKB$M_DCPLAST) 
	
	lksb->lksb$l_lkid=insert_lck(lck);
	lksb->lksb$w_status=SS$_NORMAL;
	
	sts = lck$grant_lock(lck ,res ,-1,lkmode,flags,efn,res->rsb$b_ggmode);

	goto end;
      } else {
	// it has a parid non-zero
	res->rsb$l_csid=par->lkb$l_rsb->rsb$l_csid;
	par->lkb$l_rsb->rsb$w_refcnt++;
	res->rsb$b_depth=par->lkb$l_rsb->rsb$b_depth+1;
	//check maxdepth
	if (res->rsb$b_depth>10) { // pick a number ?
	  retval=SS$_EXDEPTH;
	  goto error;
	}
	res->rsb$l_rtrsb=par->lkb$l_rsb->rsb$l_rtrsb;
	insque(&res->rsb$l_srsfl,&par->lkb$l_rsb->rsb$l_srsfl);
	if (par->lkb$l_csid) { //remote
	  lck$snd_granted(lck);
	} else {
	  sts = lck$grant_lock(lck,res,-1,lkmode,flags,efn,res->rsb$b_ggmode);
	}
      }
    } else {
      /* old, found in resource hash table */
      /* something else? */
      int granted = 0;
      if (flags & LCK$M_SYNCSTS) retval=SS$_SYNCH;
      kfree(res);
      res=old;
      lck->lkb$l_rsb=res;

      //after, also check whether something in cvtqfl or wtqfl -> insque wtqfl

      if (0!=test_bit(res->rsb$b_ggmode,&lck$ar_compat_tbl[lck->lkb$b_rqmode])) {
	if (aqempty(res->rsb$l_wtqfl)) {
	  granted=1;
	  //sts = lck$grant_lock(lck ,res ,-1,lkmode,flags,efn);
	} else {
	  if (flags&LCK$M_NOQUEUE) {
	    res->rsb$w_lckcnt--;
	    kfree(lck);
	    vmsunlock(&SPIN_SCS,IPL$_ASTDEL);
	    return SS$_NOTQUEUED;
	  } else {
	    lck->lkb$b_state=LKB$K_WAITING;
	    insque(&lck->lkb$l_sqfl,res->rsb$l_wtqfl);
	    lksb->lksb$w_status=0;
	    lck->lkb$l_status|=LKB$M_ASYNC;
	    maybe_blkast(res,lck);
	  }
	}
      } else {
	// if not compatible
	if (flags&LCK$M_NOQUEUE) {
	  res->rsb$w_lckcnt--;
	  kfree(lck);
	  vmsunlock(&SPIN_SCS,IPL$_ASTDEL);
	  return SS$_NOTQUEUED;
	} else {
	  lck->lkb$b_state=LKB$K_WAITING;
	  insque(&lck->lkb$l_sqfl,res->rsb$l_wtqfl);
	  lksb->lksb$w_status=0;
	  lck->lkb$l_status|=LKB$M_ASYNC;
	  maybe_blkast(res,lck);
	  // insque(&lck->lkb$l_ownqfl,&current->pcb$l_lockqfl);
	}
      }

      lksb->lksb$l_lkid=insert_lck(lck);
      lksb->lksb$w_status=SS$_NORMAL;

      if ((granted & 1)==1) {
	if (0/*par->lkb$l_csid*/) { //remote
	  lck$snd_granted(lck);
	} else {
	  sts = lck$grant_lock(lck, res, -1,lkmode,flags,efn,res->rsb$b_ggmode);
	}
      }
    }
  end:
    /* raise ipl */
    vmsunlock(&SPIN_SCS,IPL$_ASTDEL);
    return retval;
  error:
    /* ipl back */
    kfree(res);
    kfree(lck);
    vmsunlock(&SPIN_SCS,IPL$_ASTDEL);
    return sserror;
    
  } else { // convert
    /* convert */
    int granted = 0, newmodes = 0;
    struct _lkb * lck;
    struct _rsb * res;
    void * dummy;
    int newmode;
    lck=lockidtbl[lksb->lksb$l_lkid];
    res=lck->lkb$l_rsb;
    if (lck->lkb$b_state!=LKB$K_GRANTED) {
      vmsunlock(&SPIN_SCS,IPL$_ASTDEL);
      return SS$_CVTUNGRANT;
    }
    lck->lkb$b_efn=efn;
    lck->lkb$l_flags=flags;
    lck->lkb$b_rqmode=lkmode;
    lck->lkb$l_cplastadr=astadr;
    lck->lkb$l_blkastadr=blkastadr;
    lck->lkb$l_astprm=astprm;
    lck->lkb$l_lksb=lksb;
    remque(&lck->lkb$l_sqfl,&lck->lkb$l_sqfl);// ?
    //remque(&res->rsb$l_grqfl,dummy); // superfluous
    if (aqempty(res->rsb$l_cvtqfl) && aqempty(res->rsb$l_grqfl)) {
      sts = lck$grant_lock(lck ,res,lck->lkb$b_grmode,lkmode,flags,efn,-1);
      vmsunlock(&SPIN_SCS,IPL$_ASTDEL);
      return SS$_NORMAL;
    } else { // convert, something in cvtqfl or grqfl
      if (res->rsb$b_cgmode!=lck->lkb$b_grmode) {
	newmode=res->rsb$b_ggmode;
      } else {
	newmode=find_highest(lck,res);
	newmodes= 0;
      }
      if (test_bit(lkmode,&lck$ar_compat_tbl[newmode])) {
	//sts = lck$grant_lock(lck,res,lck->lkb$b_grmode,lkmode,flags,efn);
	granted = 1;
      }
    }

    if (granted) {
      if (newmodes) {
	res->rsb$b_fgmode=newmode;
	res->rsb$b_ggmode=newmode;
	res->rsb$b_cgmode=newmode;
      }
      sts = lck$grant_lock(lck,res,lck->lkb$b_grmode,lkmode /*newmode*/,flags,efn,res->rsb$b_ggmode);
      grant_queued(res,newmode,1,1);
    } else {
      int wasempty=aqempty(&res->rsb$l_cvtqfl);
      lck->lkb$b_rqmode=lkmode;
      insque(&lck->lkb$l_sqfl,res->rsb$l_cvtqfl);
      lck->lkb$b_state=LKB$K_CONVERT;
      lksb->lksb$w_status=0;
      lck->lkb$l_status|=LKB$M_ASYNC;
      maybe_blkast(res,lck);
      if (wasempty)
	res->rsb$b_cgmode=newmode;
      sts=SS$_NORMAL;
    }
    vmsunlock(&SPIN_SCS,IPL$_ASTDEL);
    return sts;
  }
  vmsunlock(&SPIN_SCS,IPL$_ASTDEL);
}
示例#5
0
文件: acl.c 项目: Rick33/freevms
int create_fcb_acl(struct _fcb * fcb, struct _fh2 * fh2)
{
  struct _iosb iosb;
  unsigned int retsts;
  unsigned curvbn=1;
  unsigned extents = 0;
  struct _fh2 *head = 0;

  unsigned short *mp;
  long acep;
  struct _acedef * ace;

#if 0
  struct _vcb * vcb = xqp->current_vcb;
  struct _ucb * ucb;
  if (vcb->vcb$l_rvn) {
    struct _rvt * rvt = vcb->vcb$l_rvt;
    struct _ucb ** ucblst = rvt->rvt$l_ucblst;
    ucb = ucblst[fcb->fcb$b_fid_rvn - 1];
  } else 
    ucb = vcb->vcb$l_rvt;
#endif

  void qhead_init();
  qhead_init(&fcb->fcb$l_aclfl);

  if (fh2)
    head=fh2;
  mp = (unsigned short *) head + head->fh2$b_acoffset;
  acep = mp;
  ace = acep;
  
  while (ace->ace$b_size) {
    switch (ace->ace$b_type) {
    case ACE$C_AUDIT:
      break;
    case ACE$C_ALARM:
      break;
    case ACE$C_DIRDEF:
      break;
    case ACE$C_INFO:
      break;
    case ACE$C_KEYID:
      break;
    case ACE$C_RMSJNL_AI:
    case ACE$C_RMSJNL_AT:
    case ACE$C_RMSJNL_BI:
    case ACE$C_RMSJNL_RU:
    case ACE$C_RMSJNL_RU_DEFAULT:
      break;
    default:
      panic("ace does not exist\n");
      break;
    }
    struct _acldef * acl = kmalloc(sizeof(struct _acldef), GFP_KERNEL);
    struct _acedef * newace = kmalloc(ace->ace$b_size, GFP_KERNEL); // check. needed?
    memcpy(newace, ace, ace->ace$b_size);
    acl->acl$w_size = sizeof(struct _acldef);
    acl->acl$b_type = DYN$C_ACL;
    acl->acl$l_list = newace;
    void insque();
    insque(acl, &fcb->fcb$l_aclfl);

    acep += ace->ace$b_size;
    ace = acep;
  }
  retsts = SS$_NORMAL;
  return retsts;
}
示例#6
0
文件: mscp.c 项目: rroart/freevms
int mscplisten(void * packet, struct _cdt * c, struct _pdt * p)
{
    int sts;
    struct _iosb * iosb=kmalloc(sizeof(struct _iosb),GFP_KERNEL);
    struct _cdrp * cdrp;
    struct _scs * scs = packet;
    struct _scs1 * scs1 = scs;
    struct _ppd * ppd = scs;
    struct _cdt * cdt = &cdtl[scs->scs$l_dst_conid];
    struct _mscp_basic_pkt * basic = ((unsigned long)packet) + sizeof(*scs);
    void * next = basic;
    struct _transfer_commands * trans = basic;
    unsigned short int chan;//wasint chan =get_mscp_chan(cdt->cdt$l_condat);
    char * nam;
    $DESCRIPTOR(devnam,"d0a0");
    nam=devnam.dsc$a_pointer;
    nam[1]=basic->mscp$b_caa;
    nam[3]=48+basic->mscp$w_unit;

    exe$assign(&devnam,&chan,0,0,0);

    if (hrbq==0) qhead_init(&hrbq);

    //printk("packet %x %x %x %x\n",packet,ppd,ppd->ppd$b_opc,chan);

    switch (ppd->ppd$b_opc)
    {
    case PPD$C_REQDAT:
        goto read;
        break;
    case PPD$C_SNDDAT:
        goto write;
        break;
    case PPD$C_SNDDG:
        goto mscp;
        break;
    default:
        panic("ppdopc\n");

    }

mscp:
    {
        unsigned long lbn=trans->mscp$l_lbn;
        struct _hrb * hrb=kmalloc(sizeof(struct _hrb),GFP_KERNEL);
        cdrp = vmalloc(sizeof(struct _cdrp));
        memset(cdrp,0,sizeof(struct _cdrp));
        memset(hrb,0,sizeof(struct _hrb));
        hrb->hrb$l_lbn=lbn;
        hrb->hrb$l_cmd_time=scs1->scs$l_rspid; // wrong, but have to have some id...
        insque(hrb,&hrbq);
        if (basic->mscp$b_opcode == MSCP$K_OP_WRITE)
        {
            basic->mscp$b_opcode = MSCP$K_OP_END;
            cdrp->cdrp$w_cdrpsize=600;
            cdrp->cdrp$l_cdt=c;
            cdrp->cdrp$l_msg_buf=basic;
            cdrp->cdrp$l_xct_len=512;
            //scs_std$senddg(0,600,cdrp);
        }
        if (basic->mscp$b_opcode == MSCP$K_OP_READ)
        {
        }
        if (basic->mscp$b_opcode == MSCP$K_OP_GTUNT)
        {
            $DESCRIPTOR(disk,"dqa0");
            char * str = disk.dsc$a_pointer;
            str[3]='0'+basic->mscp$w_unit;
            long long dummy;
            int sts=ioc$search(&dummy, &disk);
            struct _gtunt * gtunt = kmalloc(sizeof(struct _gtunt),GFP_KERNEL);
            memset(gtunt, 0, sizeof(struct _gtunt));
            struct _mscp_basic_pkt * gtbas = gtunt;
            gtbas->mscp$b_opcode=MSCP$K_OP_GTUNT|MSCP$M_OP_END;
            gtbas->mscp$w_unit=basic->mscp$w_unit;
            if (sts==SS$_NORMAL)
                gtbas->mscp$w_status=MSCP$K_ST_SUCC;
            else
                gtbas->mscp$w_status=MSCP$K_ST_OFFLN;

            struct _cdrp * cdrp = vmalloc(sizeof(struct _cdrp));
            memset(cdrp,0,sizeof(struct _cdrp));

            cdrp->cdrp$w_cdrpsize=400;
            cdrp->cdrp$l_rspid=scs_std$alloc_rspid(0,0,cdrp,0);
            cdrp->cdrp$l_cdt=find_mscp_cdt();
            cdrp->cdrp$l_msg_buf=gtunt;
            cdrp->cdrp$l_xct_len=sizeof(struct _gtunt);
            if (cdrp->cdrp$l_cdt==0)
            {
                printk("gtunt srv no cdt\n");
                return;
            }
            scs_std$senddg(0,400,cdrp);

        }
        if (basic->mscp$b_opcode == (MSCP$K_OP_GTUNT|MSCP$M_OP_END) )
        {
            if (basic->mscp$w_status==MSCP$K_ST_SUCC)
            {
                struct _ddb * ddb;
                struct _ucb * ucb;
                char dev[16];
                extern struct _sb othersb;
                char len=othersb.sb$t_nodename[0];
                memcpy(dev,&othersb.sb$t_nodename[1],len);
                dev[len]='$';
                dev[len+1]='d';
                dev[len+2]='q';
                dev[len+3]='a';
                dev[len+4]='0';//+basic->mscp$w_unit;
                struct dsc$descriptor disk;
                disk.dsc$a_pointer=dev;
                disk.dsc$w_length=len+5;
                long long dummy;
                int sts=ioc$search(&dummy, &disk);
                if (sts!=SS$_NORMAL)
                {
                    ddb=ide_iodb_vmsinit(1);
                    du_iodb_clu_vmsinit(ddb->ddb$ps_ucb);
                    struct _ucb * ucb = ddb->ddb$ps_ucb;
                    ucb->ucb$l_ddt=&du$ddt;
                    if (ddb)
                        ddb->ddb$ps_sb=&othersb;
                }
                else
                {
                    long *l=&dummy;
                    struct _ucb * u = *l;
                    ddb = u->ucb$l_ddb;
                }
                int i=basic->mscp$w_unit;
                $DESCRIPTOR(d, "dqa0");
                char * c= d.dsc$a_pointer;
                c[3]='0'+i;
                ucb = ide_iodbunit_vmsinit(ddb,i,&d);
                ucb->ucb$l_ddt=&du$ddt;
                ((struct _mscp_ucb *)ucb)->ucb$w_mscpunit=ucb->ucb$w_unit;
                printk("UCB MSCPUNIT %x\n",((struct _mscp_ucb *)ucb)->ucb$w_mscpunit);
            }
        }
    }
    return;

read:
    {
        char * buf = vmalloc(1024);
        struct _irp * i=kmalloc(sizeof(struct _irp),GFP_KERNEL);
        struct _ucb * u;
        struct _hrb * hrb = find_hrb(scs1->scs$l_rspid);
        //printk("mscpread\n");
        remque(hrb,hrb);
        memset(i,0,sizeof(struct _irp));
        iosb->iosb$w_status=0;
        i->irp$b_type=DYN$C_IRP;
        i->irp$w_chan=chan;
        i->irp$l_func=IO$_READLBLK;
        i->irp$l_iosb=iosb;
        i->irp$l_qio_p1=buf;
        i->irp$l_qio_p2=512;
        i->irp$l_qio_p3=hrb->hrb$l_lbn;
        ((struct _acb *)i)->acb$b_rmod|=ACB$M_NODELETE; // bad idea to free this
        //printk("chan %x\n",chan);
        u=ctl$gl_ccbbase[chan].ccb$l_ucb;
        i->irp$l_ucb=u;
        i->irp$l_pid=current->pcb$l_pid;
        i->irp$l_sts|=IRP$M_BUFIO;
        i->irp$l_astprm=i;
        i->irp$l_ast=returnsome;
        i->irp$l_cdt=c;
        i->irp$l_rspid=scs1->scs$l_rspid;
        exe$insioq(i,u);
    }
    exe$dassgn(chan);
    return;
write:
    {
        struct _irp * i=kmalloc(sizeof(struct _irp),GFP_KERNEL);
        struct _ucb * u;
        struct _hrb * hrb = find_hrb(scs1->scs$l_rspid);
        //printk("mscpwrite\n");
        remque(hrb,hrb);
        memset(i,0,sizeof(struct _irp));
        iosb->iosb$w_status=0;
        i->irp$b_type=DYN$C_IRP;
        i->irp$w_chan=chan;
        i->irp$l_func=IO$_WRITELBLK;
        i->irp$l_iosb=iosb;
        i->irp$l_qio_p1=next;
        i->irp$l_qio_p2=512;
        i->irp$l_qio_p3=hrb->hrb$l_lbn;
        //printk("chan %x\n",chan);
        u=ctl$gl_ccbbase[chan].ccb$l_ucb;
        i->irp$l_ucb=u;
        i->irp$l_pid=current->pcb$l_pid;
        i->irp$l_sts|=IRP$M_BUFIO;
        i->irp$l_astprm=i;
        i->irp$l_ast=returnsome;
        i->irp$l_cdt=c;
        i->irp$l_rspid=scs1->scs$l_rspid;
        exe$insioq(i,u);
    }
    exe$dassgn(chan);
    return;
}
示例#7
0
文件: dispatch.c 项目: rroart/freevms
void xqp_init2(void)
{
    qhead_init(&xqp->xqp_head);
}