Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#include        "all.h"

#include        "9p1.h"

void
fcall9p1(Chan *cp, Fcall *in, Fcall *ou)
{
        int t;

        rlock(&mainlock);
        t = in->type;
        if(t < 0 || t >= MAXSYSCALL || (t&1) || !call9p1[t]) {
                print("bad message type %d\n", t);
                panic("");
        }
        ou->type = t+1;
        ou->err = 0;

        rlock(&cp->reflock);
        (*call9p1[t])(cp, in, ou);
        runlock(&cp->reflock);

        if(ou->err && CHAT(cp))
                print("\terror: %s\n", errstr9p[ou->err]);
        runlock(&mainlock);
}

int
con_session(void)
{
        Fcall in, ou;

        in.type = Tsession;
        fcall9p1(cons.chan, &in, &ou);
        return ou.err;
}

int
con_attach(int fid, char *uid, char *arg)
{
        Fcall in, ou;

        in.type = Tattach;
        in.fid = fid;
        strncpy(in.uname, uid, NAMELEN);
        strncpy(in.aname, arg, NAMELEN);
        fcall9p1(cons.chan, &in, &ou);
        return ou.err;
}

int
con_clone(int fid1, int fid2)
{
        Fcall in, ou;

        in.type = Tclone;
        in.fid = fid1;
        in.newfid = fid2;
        fcall9p1(cons.chan, &in, &ou);
        return ou.err;
}

int
con_walk(int fid, char *name)
{
        Fcall in, ou;

        in.type = Twalk;
        in.fid = fid;
        strncpy(in.name, name, NAMELEN);
        fcall9p1(cons.chan, &in, &ou);
        return ou.err;
}

int
con_open(int fid, int mode)
{
        Fcall in, ou;

        in.type = Topen;
        in.fid = fid;
        in.mode = mode;
        fcall9p1(cons.chan, &in, &ou);
        return ou.err;
}

int
con_read(int fid, char *data, Off offset, int count)
{
        Fcall in, ou;

        in.type = Tread;
        in.fid = fid;
        in.offset = offset;
        in.count = count;
        ou.data = data;
        fcall9p1(cons.chan, &in, &ou);
        if(ou.err)
                return 0;
        return ou.count;
}

int
con_write(int fid, char *data, Off offset, int count)
{
        Fcall in, ou;

        in.type = Twrite;
        in.fid = fid;
        in.data = data;
        in.offset = offset;
        in.count = count;
        fcall9p1(cons.chan, &in, &ou);
        if(ou.err)
                return 0;
        return ou.count;
}

int
con_remove(int fid)
{
        Fcall in, ou;

        in.type = Tremove;
        in.fid = fid;
        fcall9p1(cons.chan, &in, &ou);
        return ou.err;
}

int
con_create(int fid, char *name, int uid, int gid, long perm, int mode)
{
        Fcall in, ou;

        in.type = Tcreate;
        in.fid = fid;
        strncpy(in.name, name, NAMELEN);
        in.perm = perm;
        in.mode = mode;
        cons.uid = uid;                 /* beyond ugly */
        cons.gid = gid;
        fcall9p1(cons.chan, &in, &ou);
        return ou.err;
}

int
doclri(File *f)
{
        Iobuf *p, *p1;
        Dentry *d, *d1;
        int err;

        err = 0;
        p = 0;
        p1 = 0;
        if(f->fs->dev->type == Devro) {
                err = Eronly;
                goto out;
        }
        /*
         * check on parent directory of file to be deleted
         */
        if(f->wpath == 0 || f->wpath->addr == f->addr) {
                err = Ephase;
                goto out;
        }
        p1 = getbuf(f->fs->dev, f->wpath->addr, Brd);
        d1 = getdir(p1, f->wpath->slot);
        if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) {
                err = Ephase;
                goto out;
        }

        accessdir(p1, d1, FWRITE, 0);
        putbuf(p1);
        p1 = 0;

        /*
         * check on file to be deleted
         */
        p = getbuf(f->fs->dev, f->addr, Brd);
        d = getdir(p, f->slot);

        /*
         * do it
         */
        memset(d, 0, sizeof(Dentry));
        settag(p, Tdir, QPNONE);
        freewp(f->wpath);
        freefp(f);

out:
        if(p1)
                putbuf(p1);
        if(p)
                putbuf(p);
        return err;
}

void
f_fstat(Chan *cp, Fcall *in, Fcall *ou)
{
        File *f;
        Iobuf *p;
        Dentry *d;
        int i;

        if(CHAT(cp)) {
                print("c_fstat %d\n", cp->chan);
                print("\tfid = %d\n", in->fid);
        }

        p = 0;
        f = filep(cp, in->fid, 0);
        if(!f) {
                ou->err = Efid;
                goto out;
        }
        p = getbuf(f->fs->dev, f->addr, Brd);
        d = getdir(p, f->slot);
        if(d == 0)
                goto out;

        print("name = %.*s\n", NAMELEN, d->name);
        print("uid = %d; gid = %d; muid = %d\n", d->uid, d->gid, d->muid);
        print("size = %lld; qid = %llux/%lux\n", (Wideoff)d->size,
                (Wideoff)d->qid.path, d->qid.version);
        print("atime = %ld; mtime = %ld\n", d->atime, d->mtime);
        print("dblock =");
        for(i=0; i<NDBLOCK; i++)
                print(" %lld", (Wideoff)d->dblock[i]);
        for (i = 0; i < NIBLOCK; i++)
                print("; iblocks[%d] = %lld", i, (Wideoff)d->iblocks[i]);
        print("\n\n");

out:
        if(p)
                putbuf(p);
        ou->fid = in->fid;
        if(f)
                qunlock(f);
}

void
f_clri(Chan *cp, Fcall *in, Fcall *ou)
{
        File *f;

        if(CHAT(cp)) {
                print("c_clri %d\n", cp->chan);
                print("\tfid = %d\n", in->fid);
        }

        f = filep(cp, in->fid, 0);
        if(!f) {
                ou->err = Efid;
                goto out;
        }
        ou->err = doclri(f);

out:
        ou->fid = in->fid;
        if(f)
                qunlock(f);
}

int
con_clri(int fid)
{
        Fcall in, ou;
        Chan *cp;

        in.type = Tremove;
        in.fid = fid;
        cp = cons.chan;

        rlock(&mainlock);
        ou.type = Tremove+1;
        ou.err = 0;

        rlock(&cp->reflock);
        f_clri(cp, &in, &ou);
        runlock(&cp->reflock);

        runlock(&mainlock);
        return ou.err;
}

int
con_fstat(int fid)
{
        Fcall in, ou;
        Chan *cp;

        in.type = Tstat;
        in.fid = fid;
        cp = cons.chan;

        rlock(&mainlock);
        ou.type = Tstat+1;
        ou.err = 0;

        rlock(&cp->reflock);
        f_fstat(cp, &in, &ou);
        runlock(&cp->reflock);

        runlock(&mainlock);
        return ou.err;
}