Ejemplo n.º 1
0
static void
__sam_remove_frlock(sam_schedule_entry_t *entry)
{
	struct sam_schedule_frlock_entry *ep;
	sam_mount_t *mp;
	sam_node_t *ip;
	int error;

	mp = entry->mp;
	ip = (sam_node_t *)entry->arg;
	ep = (sam_schedule_frlock_entry_t *)entry;

	sam_open_operation_nb(mp);

	error = sam_proc_get_lease(ip, &ep->lease_message.data,
	    &ep->lease_message.flock, NULL, SHARE_wait, CRED());

	RW_LOCK_OS(&ip->inode_rwl, RW_WRITER);

	if (error == 0) {
		sam_update_frlock(ip, ep->lease_message.data.cmd,
		    &ep->lease_message.flock, ep->lease_message.data.filemode,
		    ep->lease_message.data.offset);
		/*
		 * If there are no locks remaining, remove any potential
		 * FRLOCK lease.
		 *
		 * XXX - Eventually we should quit treating FRLOCK as a lease
		 * XXX - at all, and track locks independently of leases.
		 */
		if (ip->cl_locks == 0) {
			sam_client_remove_leases(ip, CL_FRLOCK, 0);
		}

	} else {
		dcmn_err((CE_NOTE,
		    "SAM-QFS: %s: remove frlock error=%d: ino=%d.%d "
		    "pid=%d, size=%llx",
		    mp->mt.fi_name, error, ip->di.id.ino, ip->di.id.gen,
		    ep->lease_message.flock.l_pid, ip->di.rm.size));
	}

	RW_UNLOCK_OS(&ip->inode_rwl, RW_WRITER);

	SAM_CLOSE_OPERATION(mp, error);
	VN_RELE_OS(ip);
	kmem_free(entry, sizeof (sam_schedule_frlock_entry_t));
	sam_taskq_uncount(mp);
}
Ejemplo n.º 2
0
int
_init(void)
{
	int e;

	mutex_init(&devfs_lock, "devfs lock", MUTEX_DEFAULT, NULL);
	dv_node_cache_init();
	if ((e = mod_install(&modlinkage)) != 0) {
		dv_node_cache_fini();
		mutex_destroy(&devfs_lock);
		return (e);
	}
	dcmn_err(("devfs loaded\n"));
	return (0);
}
Ejemplo n.º 3
0
int64_t pap_putmsg32(int fildes, struct strbuf32 * ctlptr, struct strbuf32
                     * dataptr, int *flagsp)
{
    struct strbuf32 kctlptr;
    dl_promiscon_req_t *kpromiscon;

    inc_refcnt();

    dcmn_err((CE_CONT, "putmsg() syscall.\n"));

    rw_enter(&config_rwlock, RW_READER);

    if (!config.ppromisc ||
        copyin(ctlptr, &kctlptr, sizeof(struct strbuf)) != 0)
        goto err;

    mutex_enter(&promisc_lock);

    kpromiscon = (dl_promiscon_req_t *) kmem_alloc(kctlptr.len, KM_SLEEP);
    if (!kpromiscon)
        goto err_and_unlock;

    /*
     * There is something strange about kctlptr.buf. GCC says:
     * "... arg 1 of `copyin' makes pointer from integer without a cast"
     * Probably a typical 32 vs. 64bit casting problem. Fix me later.
     */
    if (copyin(kctlptr.buf, kpromiscon, kctlptr.len) != 0)
        goto err_and_free;

    check_promisc(fildes, kpromiscon);

  err_and_free:
    kmem_free(kpromiscon, kctlptr.len);
  err_and_unlock:
    mutex_exit(&promisc_lock);
  err:

    rw_exit(&config_rwlock);
    dec_refcnt();

    return syscalls32[PUTMSG].sc(fildes, ctlptr, dataptr, flagsp);
}
Ejemplo n.º 4
0
int64_t pap_putmsg(int fildes, struct strbuf * ctlptr, struct strbuf
                   * dataptr, int *flagsp)
{
    struct strbuf kctlptr;
    dl_promiscon_req_t *kpromiscon;

    inc_refcnt();

    dcmn_err((CE_CONT, "putmsg() syscall.\n"));

    rw_enter(&config_rwlock, RW_READER);

    if (!config.ppromisc ||
        copyin(ctlptr, &kctlptr, sizeof(struct strbuf)) != 0)
        goto err;

    mutex_enter(&promisc_lock);

    kpromiscon = (dl_promiscon_req_t *) kmem_alloc(kctlptr.len, KM_SLEEP);
    if (!kpromiscon)
        goto err_and_unlock;

    if (copyin(kctlptr.buf, kpromiscon, kctlptr.len) != 0)
        goto err_and_free;

    check_promisc(fildes, kpromiscon);

  err_and_free:
    kmem_free(kpromiscon, kctlptr.len);
  err_and_unlock:
    mutex_exit(&promisc_lock);
  err:

    rw_exit(&config_rwlock);
    dec_refcnt();

    return syscalls[PUTMSG].sc(fildes, ctlptr, dataptr, flagsp);
}
Ejemplo n.º 5
0
static int			/* ERRNO if error, 0 if successful. */
sam_drop_call(
	void *arg,		/* Pointer to arguments. */
	int size,
	cred_t *credp)
{
	sam_fsdropds_arg_t args;
	sam_mount_t *mp;
	sam_node_t *ip = NULL;			/* pointer to rm inode */
	int error;

	if (size != sizeof (args) ||
	    copyin(arg, (caddr_t)&args, sizeof (args))) {
		return (EFAULT);
	}

	/*
	 * If the mount point is mounted, process releaser request.
	 */
	if ((mp = find_mount_point(args.fseq)) == NULL) {
		return (ECANCELED);
	}

	if (secpolicy_fs_config(credp, mp->mi.m_vfsp)) {
		error = EINVAL;
		goto out;
	}

	if ((error = sam_find_ino(mp->mi.m_vfsp, IG_EXISTS, &args.id, &ip))) {
		goto droperr;
	}
	RW_LOCK_OS(&ip->inode_rwl, RW_WRITER);

	/*
	 * Don't release file if it is staging, archiving, or release_n set.
	 */
	if (ip->flags.b.staging || ip->arch_count) {
		error = EBUSY;
		dcmn_err((CE_NOTE,
		    "SAM-QFS: %s: Cannot release file:"
		    " %d.%d, flag=%x ac=%d pid=%d.%d.%d.%d",
		    mp->mt.fi_name, ip->di.id.ino, ip->di.id.gen,
		    ip->flags.bits, ip->arch_count, ip->arch_pid[0],
		    ip->arch_pid[1], ip->arch_pid[2], ip->arch_pid[3]));

	} else if ((args.shrink == 0) &&
	    (ip->di.status.b.nodrop || ip->di.status.b.archnodrop ||
	    ip->flags.b.accessed)) {
		error = EINVAL;

	} else if (args.shrink && ip->di.arch_status == 0) {
		error = EBADE;

	} else {
		int bof_online;

		RW_UNLOCK_OS(&ip->inode_rwl, RW_WRITER);
		RW_LOCK_OS(&ip->data_rwl, RW_WRITER);
		RW_LOCK_OS(&ip->inode_rwl, RW_WRITER);
		if (args.shrink) {
			bof_online = ip->di.status.b.bof_online;
			ip->di.status.b.bof_online = 0;
		}
		error = sam_drop_ino(ip, credp);
		if (args.shrink) {
			ip->di.status.b.bof_online = bof_online;
		}
		RW_UNLOCK_OS(&ip->data_rwl, RW_WRITER);
	}
	RW_UNLOCK_OS(&ip->inode_rwl, RW_WRITER);
	sam_rele_ino(ip);

	/*
	 * Wait until all the blocks released on the list.
	 */
	mutex_enter(&mp->mi.m_inode.mutex);
	while (mp->mi.m_next != NULL || mp->mi.m_inode.busy) {
		mp->mi.m_inode.wait++;
		if (sam_cv_wait_sig(&mp->mi.m_inode.get_cv,
		    &mp->mi.m_inode.mutex) == 0) {
			mp->mi.m_inode.wait--;
			error = EINTR;
			break;
		}
		mp->mi.m_inode.wait--;
	}
	mutex_exit(&mp->mi.m_inode.mutex);

droperr:
	/*
	 * Return blks now free
	 */
	args.freeblocks = mp->mi.m_sbp->info.sb.space;
	if (size != sizeof (args) ||
	    copyout((caddr_t)&args, arg, sizeof (args))) {
		error = EFAULT;
	}

out:
	SAM_SYSCALL_DEC(mp, 0);
	return (error);
}