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); }
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); }
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); }
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); }
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); }