Пример #1
0
static int
xmem_freesp(struct vnode *vp, struct flock64 *lp, int flag)
{
	register int i;
	register struct xmemnode *xp = VTOXN(vp);
	int error;

	ASSERT(vp->v_type == VREG);
	ASSERT(lp->l_start >= 0);

	if (lp->l_len != 0)
		return (EINVAL);

	rw_enter(&xp->xn_rwlock, RW_WRITER);
	if (xp->xn_size == lp->l_start) {
		rw_exit(&xp->xn_rwlock);
		return (0);
	}

	/*
	 * Check for any mandatory locks on the range
	 */
	if (MANDLOCK(vp, xp->xn_mode)) {
		long save_start;

		save_start = lp->l_start;

		if (xp->xn_size < lp->l_start) {
			/*
			 * "Truncate up" case: need to make sure there
			 * is no lock beyond current end-of-file. To
			 * do so, we need to set l_start to the size
			 * of the file temporarily.
			 */
			lp->l_start = xp->xn_size;
		}
		lp->l_type = F_WRLCK;
		lp->l_sysid = 0;
		lp->l_pid = ttoproc(curthread)->p_pid;
		i = (flag & (FNDELAY|FNONBLOCK)) ? 0 : SLPFLCK;
		if ((i = reclock(vp, lp, i, 0, lp->l_start, NULL)) != 0 ||
		    lp->l_type != F_UNLCK) {
			rw_exit(&xp->xn_rwlock);
			return (i ? i : EAGAIN);
		}

		lp->l_start = save_start;
	}

	rw_enter(&xp->xn_contents, RW_WRITER);
	error = xmemnode_trunc((struct xmount *)VFSTOXM(vp->v_vfsp),
						xp, lp->l_start);
	rw_exit(&xp->xn_contents);
	rw_exit(&xp->xn_rwlock);
	return (error);
}
Пример #2
0
/* ARGSUSED */
int
fs_frlock(register vnode_t *vp, int cmd, struct flock64 *bfp, int flag,
	offset_t offset, flk_callback_t *flk_cbp, cred_t *cr,
	caller_context_t *ct)
{
	int frcmd;
	int nlmid;
	int error = 0;
	flk_callback_t serialize_callback;
	int serialize = 0;
	v_mode_t mode;

	switch (cmd) {

	case F_GETLK:
	case F_O_GETLK:
		if (flag & F_REMOTELOCK) {
			frcmd = RCMDLCK;
		} else if (flag & F_PXFSLOCK) {
			frcmd = PCMDLCK;
		} else {
			frcmd = 0;
			bfp->l_pid = ttoproc(curthread)->p_pid;
			bfp->l_sysid = 0;
		}
		break;

	case F_SETLK_NBMAND:
		/*
		 * Are NBMAND locks allowed on this file?
		 */
		if (!vp->v_vfsp ||
		    !(vp->v_vfsp->vfs_flag & VFS_NBMAND)) {
			error = EINVAL;
			goto done;
		}
		if (vp->v_type != VREG) {
			error = EINVAL;
			goto done;
		}
		/*FALLTHROUGH*/

	case F_SETLK:
		if (flag & F_REMOTELOCK) {
			frcmd = SETFLCK|RCMDLCK;
		} else if (flag & F_PXFSLOCK) {
			frcmd = SETFLCK|PCMDLCK;
		} else {
			frcmd = SETFLCK;
			bfp->l_pid = ttoproc(curthread)->p_pid;
			bfp->l_sysid = 0;
		}
		if (cmd == F_SETLK_NBMAND &&
		    (bfp->l_type == F_RDLCK || bfp->l_type == F_WRLCK)) {
			frcmd |= NBMLCK;
		}

		if (nbl_need_check(vp)) {
			nbl_start_crit(vp, RW_WRITER);
			serialize = 1;
			if (frcmd & NBMLCK) {
				mode = (bfp->l_type == F_RDLCK) ?
				    V_READ : V_RDANDWR;
				if (vn_is_mapped(vp, mode)) {
					error = EAGAIN;
					goto done;
				}
			}
		}
		break;

	case F_SETLKW:
		if (flag & F_REMOTELOCK) {
			frcmd = SETFLCK|SLPFLCK|RCMDLCK;
		} else if (flag & F_PXFSLOCK) {
			frcmd = SETFLCK|SLPFLCK|PCMDLCK;
		} else {
			frcmd = SETFLCK|SLPFLCK;
			bfp->l_pid = ttoproc(curthread)->p_pid;
			bfp->l_sysid = 0;
		}

		if (nbl_need_check(vp)) {
			nbl_start_crit(vp, RW_WRITER);
			serialize = 1;
		}
		break;

	case F_HASREMOTELOCKS:
		nlmid = GETNLMID(bfp->l_sysid);
		if (nlmid != 0) {	/* booted as a cluster */
			l_has_rmt(bfp) =
			    cl_flk_has_remote_locks_for_nlmid(vp, nlmid);
		} else {		/* not booted as a cluster */
			l_has_rmt(bfp) = flk_has_remote_locks(vp);
		}

		goto done;

	default:
		error = EINVAL;
		goto done;
	}

	/*
	 * If this is a blocking lock request and we're serializing lock
	 * requests, modify the callback list to leave the critical region
	 * while we're waiting for the lock.
	 */

	if (serialize && (frcmd & SLPFLCK) != 0) {
		flk_add_callback(&serialize_callback,
		    frlock_serialize_blocked, vp, flk_cbp);
		flk_cbp = &serialize_callback;
	}

	error = reclock(vp, bfp, frcmd, flag, offset, flk_cbp);

done:
	if (serialize)
		nbl_end_crit(vp);

	return (error);
}
Пример #3
0
int main (int argc, char * argv[]){
  struct record current;
  int record_no;
  int fd, pos, i,n;
  char yes;
  char operation;
  int amount;
  fd = open("Account_File", O_RDWR);
  while(1){
    printf("enter account number \n");
    scanf("%d%*c", &record_no);
    if(!(record_no>= 0 && record_no<NUM_RECORDS))
      break;
    printf("enter operation name \n");
    scanf("%c%*c", &operation);
    
    switch(operation){
      case 'r':
        reclock(fd, record_no, sizeof(struct record), F_RDLCK);
        pos = record_no* sizeof(struct record);
        lseek(fd, pos, SEEK_SET);
        n = read(fd, &current, sizeof(struct record));
        display(&current);
        reclock(fd, record_no, sizeof(struct record), F_UNLCK);
        break;
      case 'd':
        reclock(fd, record_no, sizeof(struct record), F_WRLCK);
        pos = record_no*sizeof (struct record);
        lseek(fd, pos, SEEK_SET);
        n = read(fd, &current, sizeof(struct record));
        display(&current);
        printf("enter amount \n");
        scanf("%d%*c", &amount);
        current.balance += amount;
        lseek(fd,pos,SEEK_SET);
        write(fd, &current, sizeof(struct record));
        reclock(fd, record_no, sizeof(struct record), F_UNLCK);
        break;
      case 'w':
        reclock(fd, record_no, sizeof(struct record), F_WRLCK);
        pos = record_no*sizeof(struct record);
        lseek(fd, pos, SEEK_SET);
        n = read(fd, &current, sizeof(struct record));
        display(&current);
        printf("enter amount to withdraw\n");
        scanf ("%d%*c", &amount);
        current.balance -=amount;
        lseek(fd, pos, SEEK_SET);
        write(fd, &current, sizeof(struct record));
        reclock(fd, record_no, sizeof(struct record), F_UNLCK);
        break;
      case 't':
        reclock(fd, record_no, sizeof(struct record), F_WRLCK);
        pos = record_no* sizeof(struct record);
        lseek(fd, pos, SEEK_SET);
        n = read(fd, &current, sizeof(struct record));
        display(&current);
        printf("enter the target record_no \n");
        scanf("%d%*c", &record_no);
        printf("enter the amount for transfer\n");
        scanf("%d%*c", &amount);
        current.balance -=amount;
        lseek(fd, pos, SEEK_SET);
        write(fd, &current, sizeof(struct record));
        reclock(fd, record_no, sizeof(struct record), F_UNLCK);

        reclock(fd, record_no, sizeof(struct record), F_WRLCK);
        pos = record_no* sizeof(struct record);
        lseek(fd, pos, SEEK_SET);
        n = read(fd, &current, sizeof(struct record));
        current.balance += amount;
        lseek(fd, pos, SEEK_SET);
        write(fd, &current, sizeof(struct record));
        reclock(fd, record_no, sizeof(struct record), F_UNLCK);
        break;
      default:
        printf("ilegal input \n");
        continue;
    };
  }
  close(fd);
}