void netfs_release_peropen (struct peropen *po) { if (refcount_deref (&po->refcnt) > 0) return; pthread_mutex_lock (&po->np->lock); if (po->root_parent) mach_port_deallocate (mach_task_self (), po->root_parent); if (po->shadow_root && po->shadow_root != po->np) { pthread_mutex_lock (&po->shadow_root->lock); netfs_nput (po->shadow_root); } if (po->shadow_root_parent) mach_port_deallocate (mach_task_self (), po->shadow_root_parent); if (po->lock_status != LOCK_UN) fshelp_acquire_lock (&po->np->userlock, &po->lock_status, &po->np->lock, LOCK_UN); netfs_nput (po->np); free (po->path); free (po); }
/* Worker function to delete nodes that don't have any more local references or links. */ void * forked_node_delete (void *arg) { struct fnd *args = arg; pthread_mutex_lock (&args->dir->lock); netfs_attempt_unlink ((struct iouser *)-1, args->dir, args->name); netfs_nput (args->dir); free (args->name); free (args); return 0; };
error_t netfs_S_dir_mkfile (struct protid *diruser, int flags, mode_t mode, mach_port_t *newfile, mach_msg_type_name_t *newfiletype) { error_t err; struct node *np; struct iouser *user; struct protid *newpi; pthread_mutex_lock (&diruser->po->np->lock); err = netfs_attempt_mkfile (diruser->user, diruser->po->np, mode, &np); if (!err) { /* the dir is now unlocked and NP is locked */ flags &= OPENONLY_STATE_MODES; err = iohelp_dup_iouser (&user, diruser->user); if (! err) { newpi = netfs_make_protid (netfs_make_peropen (np, flags, diruser->po), user); if (newpi) { *newfile = ports_get_right (newpi); *newfiletype = MACH_MSG_TYPE_MAKE_SEND; ports_port_deref (newpi); } else { err = errno; iohelp_free_iouser (user); } } netfs_nput (np); } return err; }
/* Called by libnetfs when node NP has no more references. (See <hurd/libnetfs.h> for details. */ void netfs_node_norefs (struct node *np) { if (np->nn->dead_dir) { struct fnd *args; pthread_t thread; error_t err; args = malloc (sizeof (struct fnd)); assert (args); netfs_nref (np); args->dir = np->nn->dead_dir; args->name = np->nn->dead_name; np->nn->dead_dir = 0; np->nn->dead_name = 0; netfs_nput (np); /* Do this in a separate thread so that we don't wait for it; it acquires a lock on the dir, which we are not allowed to do. */ err = pthread_create (&thread, NULL, forked_node_delete, args); if (!err) pthread_detach (thread); else { errno = err; perror ("pthread_create"); } } else { if (np->nn->dtrans == SYMLINK) free (np->nn->transarg.name); free (np); } }