static void _usercache_add (Npsrv *srv, Npuser *u) { Npusercache *uc = srv->usercache; u->next = uc->users; uc->users = u; np_user_incref (u); }
Npuser * np_uid2user (Npsrv *srv, uid_t uid) { Npusercache *uc = srv->usercache; Npuser *u = NULL; xpthread_mutex_lock (&uc->lock); if (!(u = _usercache_lookup (srv, NULL, uid))) if ((u = _real_lookup_byuid (srv, uid))) _usercache_add (srv, u); xpthread_mutex_unlock (&uc->lock); if (u) np_user_incref (u); return u; }
Npuser * np_uname2user (Npsrv *srv, char *uname) { Npusercache *uc = srv->usercache; Npuser *u = NULL; xpthread_mutex_lock (&uc->lock); if (!(u = _usercache_lookup (srv, uname, P9_NONUNAME))) if ((u = _real_lookup_byname (srv, uname))) _usercache_add (srv, u); xpthread_mutex_unlock (&uc->lock); if (u) np_user_incref (u); return u; }
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; }
/* Take another reference on afid->user and return it. * If afid was for a different user return NULL. */ Npuser * np_afid2user (Npfid *afid, Npstr *uname, u32 n_uname) { Npuser *u = NULL; if (n_uname != P9_NONUNAME) { if (n_uname != afid->user->uid) { np_uerror (EPERM); goto done; } } else { if (np_strcmp (uname, afid->user->uname) != 0) { np_uerror (EPERM); goto done; } } u = afid->user; np_user_incref (u); done: return u; }
Npfcall * np_walk(Npreq *req, Npfcall *tc) { int i; Npconn *conn = req->conn; Npfid *fid = req->fid; Npfid *newfid = NULL; Npfcall *rc = NULL; Npqid wqids[P9_MAXWELEM]; if (!fid) { np_uerror (EIO); goto done; } #if 0 if (!(fid->type & P9_QTDIR)) { np_uerror(ENOTDIR); goto done; } #endif /* FIXME: error if fid has been opened */ if (tc->u.twalk.nwname > P9_MAXWELEM) { np_uerror(EIO); goto done; } if (tc->u.twalk.fid != tc->u.twalk.newfid) { newfid = np_fid_find(conn, tc->u.twalk.newfid); if (newfid) { np_uerror(EIO); goto done; } newfid = np_fid_create(conn, tc->u.twalk.newfid, NULL); if (!newfid) goto done; if (fid->type & P9_QTTMP) { if (!np_ctl_clone (fid, newfid)) goto done; } else { if (!conn->srv->clone) goto done; if (!(*conn->srv->clone)(fid, newfid)) goto done; } np_user_incref(fid->user); newfid->user = fid->user; np_tpool_incref(fid->tpool); newfid->tpool = fid->tpool; newfid->type = fid->type; if (!(newfid->aname = strdup (fid->aname))) { np_uerror (ENOMEM); goto done; } } else newfid = fid; np_fid_incref(newfid); if (!(newfid->type & P9_QTTMP)) { if (np_setfsid (req, newfid->user, -1) < 0) goto done; } for(i = 0; i < tc->u.twalk.nwname;) { if (newfid->type & P9_QTTMP) { if (!np_ctl_walk (newfid, &tc->u.twalk.wnames[i], &wqids[i])) break; } else { if (!conn->srv->walk) { np_uerror (ENOSYS); break; } if (!(*conn->srv->walk)(newfid, &tc->u.twalk.wnames[i], &wqids[i])) break; } newfid->type = wqids[i].type; i++; if (i<(tc->u.twalk.nwname) && !(newfid->type & P9_QTDIR)) break; } if (i==0 && tc->u.twalk.nwname!=0) goto done; np_uerror(0); if (tc->u.twalk.fid != tc->u.twalk.newfid) np_fid_incref(newfid); rc = np_create_rwalk(i, wqids); done: np_fid_decref(newfid); return rc; }