static int local_symlink(FsContext *fs_ctx, const char *oldpath,

                         V9fsPath *dir_path, const char *name, FsCred *credp)

{

    int err = -1;

    int serrno = 0;

    char *newpath;

    V9fsString fullname;

    char buffer[PATH_MAX];



    v9fs_string_init(&fullname);

    v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);

    newpath = fullname.data;



    /* Determine the security model */

    if (fs_ctx->fs_sm == SM_MAPPED) {

        int fd;

        ssize_t oldpath_size, write_size;

        fd = open(rpath(fs_ctx, newpath, buffer), O_CREAT|O_EXCL|O_RDWR,

                SM_LOCAL_MODE_BITS);

        if (fd == -1) {

            err = fd;

            goto out;

        }

        /* Write the oldpath (target) to the file. */

        oldpath_size = strlen(oldpath);

        do {

            write_size = write(fd, (void *)oldpath, oldpath_size);

        } while (write_size == -1 && errno == EINTR);



        if (write_size != oldpath_size) {

            serrno = errno;

            close(fd);

            err = -1;

            goto err_end;

        }

        close(fd);

        /* Set cleint credentials in symlink's xattr */

        credp->fc_mode = credp->fc_mode|S_IFLNK;

        err = local_set_xattr(rpath(fs_ctx, newpath, buffer), credp);

        if (err == -1) {

            serrno = errno;

            goto err_end;

        }

    } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||

               (fs_ctx->fs_sm == SM_NONE)) {

        err = symlink(oldpath, rpath(fs_ctx, newpath, buffer));

        if (err) {

            goto out;

        }

        err = lchown(rpath(fs_ctx, newpath, buffer), credp->fc_uid,

                     credp->fc_gid);

        if (err == -1) {

            /*

             * If we fail to change ownership and if we are

             * using security model none. Ignore the error

             */

            if (fs_ctx->fs_sm != SM_NONE) {

                serrno = errno;

                goto err_end;

            } else

                err = 0;

        }

    }

    goto out;



err_end:

    remove(rpath(fs_ctx, newpath, buffer));

    errno = serrno;

out:

    v9fs_string_free(&fullname);

    return err;

}

static int local_symlink(FsContext *fs_ctx, const char *oldpath,

                         V9fsPath *dir_path, const char *name, FsCred *credp)

{

    int err = -1;

    int serrno = 0;

    char *newpath;

    V9fsString fullname;

    char buffer[PATH_MAX];



    v9fs_string_init(&fullname);

    v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);

    newpath = fullname.data;



    

    if (fs_ctx->fs_sm == SM_MAPPED) {

        int fd;

        ssize_t oldpath_size, write_size;

        fd = open(rpath(fs_ctx, newpath, buffer), O_CREAT|O_EXCL|O_RDWR,

                SM_LOCAL_MODE_BITS);

        if (fd == -1) {

            err = fd;

            goto out;

        }

        

        oldpath_size = strlen(oldpath);

        do {

            write_size = write(fd, (void *)oldpath, oldpath_size);

        } while (write_size == -1 && errno == EINTR);



        if (write_size != oldpath_size) {

            serrno = errno;

            close(fd);

            err = -1;

            goto err_end;

        }

        close(fd);

        

        credp->fc_mode = credp->fc_mode|S_IFLNK;

        err = local_set_xattr(rpath(fs_ctx, newpath, buffer), credp);

        if (err == -1) {

            serrno = errno;

            goto err_end;

        }

    } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||

               (fs_ctx->fs_sm == SM_NONE)) {

        err = symlink(oldpath, rpath(fs_ctx, newpath, buffer));

        if (err) {

            goto out;

        }

        err = lchown(rpath(fs_ctx, newpath, buffer), credp->fc_uid,

                     credp->fc_gid);

        if (err == -1) {

            







            if (fs_ctx->fs_sm != SM_NONE) {

                serrno = errno;

                goto err_end;

            } else

                err = 0;

        }

    }

    goto out;



err_end:

    remove(rpath(fs_ctx, newpath, buffer));

    errno = serrno;

out:

    v9fs_string_free(&fullname);

    return err;

}

static int FUNC_0(FsContext *VAR_0, const char *VAR_1,

                         V9fsPath *VAR_2, const char *VAR_3, FsCred *VAR_4)

{

    int VAR_5 = -1;

    int VAR_6 = 0;

    char *VAR_7;

    V9fsString fullname;

    char VAR_8[PATH_MAX];



    v9fs_string_init(&fullname);

    v9fs_string_sprintf(&fullname, "%s/%s", VAR_2->data, VAR_3);

    VAR_7 = fullname.data;



    

    if (VAR_0->fs_sm == SM_MAPPED) {

        int VAR_9;

        ssize_t oldpath_size, write_size;

        VAR_9 = open(rpath(VAR_0, VAR_7, VAR_8), O_CREAT|O_EXCL|O_RDWR,

                SM_LOCAL_MODE_BITS);

        if (VAR_9 == -1) {

            VAR_5 = VAR_9;

            goto out;

        }

        

        oldpath_size = strlen(VAR_1);

        do {

            write_size = write(VAR_9, (void *)VAR_1, oldpath_size);

        } while (write_size == -1 && errno == EINTR);



        if (write_size != oldpath_size) {

            VAR_6 = errno;

            close(VAR_9);

            VAR_5 = -1;

            goto err_end;

        }

        close(VAR_9);

        

        VAR_4->fc_mode = VAR_4->fc_mode|S_IFLNK;

        VAR_5 = local_set_xattr(rpath(VAR_0, VAR_7, VAR_8), VAR_4);

        if (VAR_5 == -1) {

            VAR_6 = errno;

            goto err_end;

        }

    } else if ((VAR_0->fs_sm == SM_PASSTHROUGH) ||

               (VAR_0->fs_sm == SM_NONE)) {

        VAR_5 = symlink(VAR_1, rpath(VAR_0, VAR_7, VAR_8));

        if (VAR_5) {

            goto out;

        }

        VAR_5 = lchown(rpath(VAR_0, VAR_7, VAR_8), VAR_4->fc_uid,

                     VAR_4->fc_gid);

        if (VAR_5 == -1) {

            







            if (VAR_0->fs_sm != SM_NONE) {

                VAR_6 = errno;

                goto err_end;

            } else

                VAR_5 = 0;

        }

    }

    goto out;



err_end:

    remove(rpath(VAR_0, VAR_7, VAR_8));

    errno = VAR_6;

out:

    v9fs_string_free(&fullname);

    return VAR_5;

}

static int FUNC_0(FsContext *VAR_0, const char *VAR_1,
V9fsPath *VAR_2, const char *VAR_3, FsCred *VAR_4)
{ int VAR_5 = -1; int VAR_6 = 0; char *VAR_7; V9fsString fullname; char VAR_8[PATH_MAX]; v9fs_string_init(&fullname); v9fs_string_sprintf(&fullname, "%s/%s", VAR_2->data, VAR_3); VAR_7 = fullname.data; if (VAR_0->fs_sm == SM_MAPPED) { int VAR_9; ssize_t oldpath_size, write_size; VAR_9 = open(rpath(VAR_0, VAR_7, VAR_8), O_CREAT|O_EXCL|O_RDWR,
SM_LOCAL_MODE_BITS); if (VAR_9 == -1) { VAR_5 = VAR_9; goto out; } oldpath_size = strlen(VAR_1); do { write_size = write(VAR_9, (void *)VAR_1, oldpath_size); } while (write_size == -1 && errno == EINTR); if (write_size != oldpath_size) { VAR_6 = errno; close(VAR_9); VAR_5 = -1; goto err_end; } close(VAR_9); VAR_4->fc_mode = VAR_4->fc_mode|S_IFLNK; VAR_5 = local_set_xattr(rpath(VAR_0, VAR_7, VAR_8), VAR_4); if (VAR_5 == -1) { VAR_6 = errno; goto err_end; } } else if ((VAR_0->fs_sm == SM_PASSTHROUGH) || (VAR_0->fs_sm == SM_NONE)) { VAR_5 = symlink(VAR_1, rpath(VAR_0, VAR_7, VAR_8)); if (VAR_5) { goto out; } VAR_5 = lchown(rpath(VAR_0, VAR_7, VAR_8), VAR_4->fc_uid,
VAR_4->fc_gid); if (VAR_5 == -1) { if (VAR_0->fs_sm != SM_NONE) { VAR_6 = errno; goto err_end; } else VAR_5 = 0; } } goto out; err_end:
remove(rpath(VAR_0, VAR_7, VAR_8)); errno = VAR_6; out:
v9fs_string_free(&fullname); return VAR_5; }