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); }
/* 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); }
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, ¤t, sizeof(struct record)); display(¤t); 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, ¤t, sizeof(struct record)); display(¤t); printf("enter amount \n"); scanf("%d%*c", &amount); current.balance += amount; lseek(fd,pos,SEEK_SET); write(fd, ¤t, 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, ¤t, sizeof(struct record)); display(¤t); printf("enter amount to withdraw\n"); scanf ("%d%*c", &amount); current.balance -=amount; lseek(fd, pos, SEEK_SET); write(fd, ¤t, 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, ¤t, sizeof(struct record)); display(¤t); 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, ¤t, 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, ¤t, sizeof(struct record)); current.balance += amount; lseek(fd, pos, SEEK_SET); write(fd, ¤t, sizeof(struct record)); reclock(fd, record_no, sizeof(struct record), F_UNLCK); break; default: printf("ilegal input \n"); continue; }; } close(fd); }