static IOCtx _ioctx_create_open (Npuser *user, Path path, int flags, u32 mode) { IOCtx ioctx; struct stat sb; ioctx = malloc (sizeof (*ioctx)); if (!ioctx) { np_uerror (ENOMEM); goto error; } pthread_mutex_init (&ioctx->lock, NULL); ioctx->refcount = 1; ioctx->lock_type = LOCK_UN; ioctx->dir = NULL; ioctx->open_flags = flags; ioctx->user = user; np_user_incref (user); ioctx->prev = ioctx->next = NULL; ioctx->fd = open (path->s, flags, mode); if (ioctx->fd < 0) { np_uerror (errno); goto error; } if (fstat (ioctx->fd, &sb) < 0) { np_uerror (errno); goto error; } ioctx->iounit = 0; /* if iounit=0, v9fs will use msize-P9_IOHDRSZ */ #ifndef __MACH__ if (S_ISDIR(sb.st_mode) && !(ioctx->dir = fdopendir (ioctx->fd))) { np_uerror (errno); goto error; } #endif if (S_ISDIR(sb.st_mode) && !(ioctx->dir = opendir (path->s))) { np_uerror (errno); goto error; } diod_ustat2qid (&sb, &ioctx->qid); return ioctx; error: if (ioctx) _ioctx_close_destroy (ioctx, 0); return NULL; }
int ioctx_close (Npfid *fid, int seterrno) { Fid *f = fid->aux; int n; int rc = 0; NP_ASSERT (f->ioctx != NULL); xpthread_mutex_lock (&f->path->lock); n = _ioctx_decref (f->ioctx); if (n == 0) _unlink_ioctx (&f->path->ioctx, f->ioctx); xpthread_mutex_unlock (&f->path->lock); if (n == 0) rc = _ioctx_close_destroy (f->ioctx, seterrno); f->ioctx = NULL; return rc; }