⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 potemkin.c

📁 Coda分布式文件系统源代码。其特色在于可以支持离线文件操作以及在线后的自动更新
💻 C
📖 第 1 页 / 共 4 页
字号:
    fid_ent_t       *root;    if (!RootFid) {	root = fid_create(".", NULL);	CODA_ASSERT(ds_hash_insert(FidTab, root));	root->type = C_VDIR;	RootFep = root;	RootFid = &(root->fid);    }    out->coda_root.VFid.Volume = RootFid->Volume;    out->coda_root.VFid.Vnode = RootFid->Vnode;    out->coda_root.VFid.Unique = RootFid->Unique;    out->oh.result = 0;    if (verbose) {	printf("Returning root: fid (%x.%x.%x)\n",RootFid->Volume,	       RootFid->Vnode, RootFid->Unique);    }    *reply = VC_OUTSIZE(coda_root_out);    return;}voidDoOpen(union inputArgs *in, union outputArgs *out, int *reply){    ViceFid              *fp;    int                  *flags;    fid_ent_t            *fep;    fid_ent_t             dummy;    char                 *path=NULL;    struct stat           sbuf;    fp = &(in->coda_open.VFid);    flags = &(in->coda_open.flags);    dummy.fid = *fp;    CODA_ASSERT((fep = ds_hash_member(FidTab, &dummy)) != NULL);        path = fid_fullname(fep);    if (verbose) {	printf("Geting dev,inode for fid (%x.%x.%x): %s",fp->Volume,	       fp->Vnode, fp->Unique, path);	fflush(stdout);    }    if (lstat(path,&sbuf)) {	out->oh.result = errno;	goto exit;    }    out->coda_open.dev = sbuf.st_dev;    out->coda_open.inode = sbuf.st_ino;     out->oh.result = 0;    if (verbose) {	printf("....found\n");	fflush(stdout);    } exit:    if (path) free(path);    *reply = VC_OUTSIZE(coda_open_out);    return;}voidDoOpenByPath(union inputArgs *in, union outputArgs *out, int *reply){    ViceFid              *fp;    int                  *flags;    fid_ent_t            *fep;    fid_ent_t             dummy;    char                 *path=NULL;    struct stat           sbuf;    char *slash;    char *begin;    fp = &(in->coda_open_by_path.VFid);    flags = &(in->coda_open_by_path.flags);    dummy.fid = *fp;    CODA_ASSERT((fep = ds_hash_member(FidTab, &dummy)) != NULL);        path = fid_fullname(fep);    if (verbose) {	printf("Geting name for fid (%x.%x.%x): %s",fp->Volume,	       fp->Vnode, fp->Unique, path);	fflush(stdout);    }    if (lstat(path,&sbuf)) {	out->oh.result = errno;	goto exit;    }    begin = (char *)(&out->coda_open_by_path.path + 1);    out->coda_open_by_path.path = begin - (char *)out;    if (verbose)      printf("Rootdir %s path %s, total %s\n", RootDir, path, begin);    sprintf(begin, "%s/%s", RootDir, path);#if defined(DJGPP) || defined(__CYGWIN32__)    slash = begin;    for (slash = begin ; *slash ; slash++ ) {	    if ( *slash == '/' ) 		    *slash='\\';    }    printf("Rootdir %s path %s, total %s\n", RootDir, path, begin);#endif    out->oh.result = 0;    if (verbose) {	printf("....found\n");	fflush(stdout);    } exit:    if (path) free(path);    *reply = sizeof (struct coda_open_by_path_out) + 				strlen(begin) + 1;    return;}voidDoClose(union inputArgs *in, union outputArgs *out, int *reply){    ViceFid  *fp;    fp = &(in->coda_close.VFid);    /* Close always succeeds */    if (verbose) {	printf("Trival close for fid (%x.%x.%x)\n", fp->Volume,	       fp->Vnode, fp->Unique);	fflush(stdout);    }    out->oh.result = 0;    *reply = VC_OUT_NO_DATA;    return;}voidDoAccess(union inputArgs *in, union outputArgs *out, int *reply){    ViceFid  *fp;    fp = &(in->coda_close.VFid);    /* Access always succeeds, for now */    if (verbose) {	printf("Trival access for fid (%x.%x.%x)\n", fp->Volume,	       fp->Vnode, fp->Unique);	fflush(stdout);    }    out->oh.result = 0;    *reply = VC_OUT_NO_DATA;    return;}voidDoLookup(union inputArgs *in, union outputArgs *out, int *reply){    ViceFid           *fp;    char              *name;    fid_ent_t         *fep;    fid_ent_t         *childp=NULL;    bool               created=FALSE;    fid_ent_t          dummy;    ds_list_iter_t    *iter;    char              *path=NULL;    struct stat        sbuf;        fp = &(in->coda_lookup.VFid);    CODA_ASSERT((int)in->coda_lookup.name == VC_INSIZE(coda_lookup_in));    name = (char*)in + (int)in->coda_lookup.name;    if (verbose) {	printf("Doing lookup of (%s) in fid (%x.%x.%x)\n",	       name, fp->Volume, fp->Vnode, fp->Unique);	fflush(stdout);    }        /* We'd better be looking up in a directory */    dummy.fid = *fp;    CODA_ASSERT((fep = (fid_ent_t *) ds_hash_member (FidTab, &dummy)) != NULL);    if (fep->type != C_VDIR) {	out->oh.result = ENOTDIR;	goto exit;    }    /* Step 0: Special case '.' and '..' */    if (!strcmp(name, ".")) {	childp = fep;	goto found;    }    if (!strcmp(name, "..")) {	if (fep == RootFep) {	    fprintf(stderr,"AACK!  DoLookup of '..' through root!\n");	    out->oh.result = EBADF;	    goto exit;	}	childp = fep->parent;	goto found;    }        /* Step 0.5: Special case '@sys' */    if (!strcmp(name, "@sys")) {	name = SYS_STRING;    }    /* Begin normal pathname lookup. */    /* Step 1: have we resolved it before? */    iter = ds_list_iter_create(fep->kids);    while ((childp = ds_list_iter_next(iter)) != NULL) {	if (!strcmp(childp->name, name))	    break;    }    ds_list_iter_destroy(iter);    if (!childp) {	/* Didn't find it */	/* Step 2: look in the actual directory for the child */	path = fid_fullname(fep);	if (!child_exists(path,name)) {	    /* No such child */	    out->oh.result = ENOENT;	    goto exit;	}	    	/* Create a fid entry for this child */	childp = fid_create(name, fep);	created = TRUE;	if (path) free(path);	path = fid_fullname(childp);	if (lstat(path,&sbuf)) {      /* Can't read? */	    out->oh.result = ENOENT;	    goto exit;	}	if (fid_assign_type(childp, &sbuf)) {	    out->oh.result = ENOENT;	    goto exit;	}	/* Remember that we have this vnode */	CODA_ASSERT(ds_hash_insert(FidTab, childp));	CODA_ASSERT(ds_list_insert(fep->kids, childp));    } found:    /* Okay. We now have a valid vnode in childp, we'll succeed */    out->coda_lookup.VFid = childp->fid;    out->coda_lookup.vtype = childp->type;    out->oh.result = 0;    if (verbose) {	printf("....found\n");	fflush(stdout);    } exit:    if (out->oh.result && created && childp)        {	/* Error -- We don't want the child */	free(childp);    }    if (path) free(path);    *reply = VC_OUTSIZE(coda_lookup_out);    return;}/* Phase 2a: Reading/Writing */voidDoGetattr(union inputArgs *in, union outputArgs *out, int *reply){    ViceFid          *fp;    fid_ent_t        *fep;    fid_ent_t         dummy;    struct stat       st;    struct coda_vattr     *vbuf;    char             *path = NULL;        fp = &(in->coda_getattr.VFid);    vbuf = &(out->coda_getattr.attr);    if (verbose) {	printf("Doing getattr for fid (%x.%x.%x)\n",	       fp->Volume, fp->Vnode, fp->Unique);    }        dummy.fid = *fp;    CODA_ASSERT((fep = (fid_ent_t *) ds_hash_member (FidTab, &dummy)) != NULL);    path = fid_fullname(fep);    if (lstat(path,&st)) {	out->oh.result = errno;    } else {	if (fid_assign_type(fep, &st)) {	    out->oh.result = ENOENT;	    goto exit;	}	fill_vattr(&st, fep, vbuf);    }        out->oh.result = 0; exit:    if (path) free(path);    *reply = VC_OUTSIZE(coda_getattr_out);    return;}voidDoReaddir(union inputArgs *in, union outputArgs *out, int *reply){    /* Do nothing: it's handled by FFS/LFS */    out->oh.result = EOPNOTSUPP;    return;}voidDoRdwr(union inputArgs *in, union outputArgs *out, int *reply){    /* Do nothing: it's handled by FFS/LFS */    out->oh.result = EOPNOTSUPP;    return;}/* Phase 2b - namespace changes */voidDoCreate(union inputArgs *in, union outputArgs *out, int *reply){    ViceFid         *fp;    fid_ent_t       *fep;    ViceFid         *newFp;    fid_ent_t       *newFep=NULL;    fid_ent_t        dummy;    struct coda_vattr    *attr;    struct coda_vattr    *newAttr;    struct coda_cred    *cred;    int              exclp;    int              mode;    int              readp;    int              writep;    int              truncp;    int              oflags=0;    int              omode;  /* Shouldn't this be just mode? */    bool             created=FALSE;    char            *name=NULL;    char            *path=NULL;    ds_list_iter_t  *iter;    struct stat      sbuf;    int              fd;    uid_t            suid;    gid_t            sgid;    fp = &(in->coda_create.VFid);    attr = &(in->coda_create.attr);    cred = &(in->ih.cred);    exclp = in->coda_create.excl;    mode = in->coda_create.mode;    readp = mode & C_M_READ;    writep = mode & C_M_WRITE;    truncp = (attr->va_size == 0);    CODA_ASSERT((int)in->coda_create.name == VC_INSIZE(coda_create_in));    name = (char*)in + (int)in->coda_create.name;    newFp = &(out->coda_create.VFid);    newAttr = &(out->coda_create.attr);    if (verbose) {	printf("Doing create of (%s) in fid (%x.%x.%x) mode 0%o %s\n",	       name, fp->Volume, fp->Vnode, fp->Unique, mode, 	       (exclp ? "excl" : ""));    }        /* Where are we creating this? */    dummy.fid = *fp;    CODA_ASSERT((fep = (fid_ent_t *) ds_hash_member(FidTab, &dummy)) != NULL);    if (fep->type != C_VDIR) {	printf("Ack!  Trying to create in a non-directory!\n");	out->oh.result = ENOTDIR;	goto exit;    }        /* Step 0: Is the name-to-be-created okay? */    /* Don't allow any creation of '.', '..', ''; they already must exist. */    if ((!strcmp(name, ".")) 	|| (!strcmp(name, ".."))	|| (!strcmp(name, "")))    {	printf("CREATE: create of '.', '..' or ''\n");	out->oh.result = EINVAL;	goto exit;    }        /* Don't allow names of the form @XXXXXXXX.XXXXXXXX.XXXXXXXX */    if ((strlen(name) == 27) 	&& (name[0] == '@') 	&& (name[9] == '.') 	&& (name[18] == '.'))    {	out->oh.result = EINVAL;	goto exit;    }    /* Step 1: does this child already exist? */    path = fid_fullname(fep);    /*I'm not currently checking to see that     * previously-existing-files continue to have the same vtype.     * (I'll just reset it if it's different, which would be a     * rather serious disaster.)       */    if (child_exists(path, name)) {	if (exclp) {	    out->oh.result = EEXIST;	    goto exit;	}	/* Do we know about the child yet? */	iter = ds_list_iter_create(fep->kids);	while ((newFep = ds_list_iter_next(iter)) != NULL) {	    if (!strcmp(newFep->name, name)) {		break;	    }	}	ds_list_iter_destroy(iter);    }	    if (!newFep) {	/* 	 * XXX This is either a completely new file, or a file that we	 * have not yet created a fid for.  We should create a new	 * fid_ent_t for it.	 */	newFep = fid_create(name, fep);	created = TRUE;    }    /*      * Now, we have to set the path to it so that the open-for-create     * and later stat will happen correctly.  (We'll need to do the     * stat to correctly set the type of the fep.     */    if (path) free (path);    path = fid_fullname(newFep);	    /*      * Okay, now do the create.     * I'll be lazy and do so with an actual open.  (Which we have     * to do eventually anyway if we are truncating.  Should I worry     * about this here?  Not sure...)       */    /* Set the open flags */    /* XXX - this code assumes O_RDONLY is 0 */    if (writep) {	if (readp) {	    oflags |= O_RDWR;	} else {	    oflags |= O_WRONLY;	}    }    oflags |= O_CREAT;    if (truncp) {	oflags |= O_TRUNC;    }    if (exclp) {	oflags |= O_EXCL;    }    /* Set the mode bits */    omode = mode & 0777;   /* XXX - but that's what the man page says */    /* Set the creator for this file */    suid = getuid();    sgid = getgid();    CODA_ASSERT(!setgid(cred->cr_groupid));    CODA_ASSERT(!seteuid(cred->cr_uid));    /* Do the open */    if ((fd = open(path, oflags, omode)) < 0) {	out->oh.result = errno;	CODA_ASSERT(!seteuid(suid));	CODA_ASSERT(!setgid(sgid));	goto exit;    } else {	close(fd);    }    /* Reset our effective uid/gid */    CODA_ASSERT(!seteuid(suid));    CODA_ASSERT(!setgid(sgid));    /* Stat the thing so that we can set it's type correctly. */    /* Complain miserably if it isn't a plain file! */    if (lstat(path,&sbuf)) {	out->oh.result = errno;	goto exit;    }    if (fid_assign_type(newFep, &sbuf)) {	out->oh.result = ENOENT;	goto exit;    }    if (newFep->type != C_VREG) {	printf("AACK!  Create is 'creating' a non-file file of type %d!\n",	       newFep->type);    }    /* We are now doomed to succeed :-) */    /* Record this fid, and finish off */    out->oh.result = 0;    CODA_ASSERT(ds_hash_insert(FidTab, newFep));    CODA_ASSERT(ds_list_insert(fep->kids, newFep));    /* Set the return values for the create call */    *newFp = newFep->fid;    fill_vattr(&sbuf, newFep, newAttr); exit:    if (out->oh.result && created && newFep) {	/* We don't keep the newFep if there was an error */	free(newFep);    }    if (path) free(path);    *reply = VC_OUTSIZE(coda_create_out);    return;}voidDoRemove(union inputArgs *in, union outputArgs *out, int *reply){    ViceFid         *fp;    fid_ent_t       *fep;    fid_ent_t       *victimFep=NULL;    bool             created=FALSE;    struct coda_cred    *cred;    fid_ent_t        dummy;    char            *name=NULL;    char            *path=NULL;    ds_list_iter_t  *iter;    struct stat      sbuf;    uid_t            suid;    gid_t            sgid;    fp = &(in->coda_remove.VFid);    cred = &(in->ih.cred);    CODA_ASSERT((int)in->coda_remove.name == VC_INSIZE(coda_remove_in));    name = (char*)in + (int)in->coda_remove.name;        if (verbose) {	printf("Doing remove of (%s) in fid (%x.%x.%x)\n",	       name, fp->Volume, fp->Vnode, fp->Unique);    }        /* Get the directory from which we are removing */    dummy.fid = *fp;    CODA_ASSERT((fep = (fid_ent_t *) ds_hash_member(FidTab, &dummy)) != NULL);    if (fep->type != C_VDIR) {	printf("REMOVE: parent not directory!\n");	out->oh.result = ENOTDIR;	goto exit;    }    /* Step 0: Check to ensure that removes don't happen to '.', '..', or '' */    if ((!strcmp(name, "."))	|| (!strcmp(name, ".."))	|| (!strcmp(name, "")))     {	printf("REMOVE: remove of '.', '..' or ''\n");	out->oh.result = EINVAL;	goto exit;    }        /* Don't allow names of the form @XXXXXXXX.XXXXXXXX.XXXXXXXX */    if ((strlen(name) == 27) 	&& (name[0] == '@') 	&& (name[9] == '.') 	&& (name[18] == '.'))    {	out->oh.result = EINVAL;	goto exit;    }    path = fid_fullname(fep);    /* Step 1: find the child */    if (!child_exists(path,name)) {	printf("REMOVE: child didn't exist!\n");	out->oh.result = ENOENT;	goto exit;    }    /* Do we know about the child yet? */    iter = ds_list_iter_create(fep->kids);    while ((victimFep = ds_list_iter_next(iter)) != NULL) {	if (!strcmp(victimFep->name, name)) {	    break;	}    }    ds_list_iter_destroy(iter);        if (!victimFep) {	/* 	 * We're going to create a victimFep as a temporary; this is	 * only to make the code simpler.  I know that it isn't	 * that efficient, but...	 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -