static void local_mapped_file_attr(FsContext *ctx, const char *path, struct stat *stbuf) { FILE *fp; char buf[ATTR_MAX]; char *attr_path; attr_path = local_mapped_attr_path(ctx, path); fp = local_fopen(attr_path, "r"); g_free(attr_path); if (!fp) { return; } memset(buf, 0, ATTR_MAX); while (fgets(buf, ATTR_MAX, fp)) { if (!strncmp(buf, "virtfs.uid", 10)) { stbuf->st_uid = atoi(buf+11); } else if (!strncmp(buf, "virtfs.gid", 10)) { stbuf->st_gid = atoi(buf+11); } else if (!strncmp(buf, "virtfs.mode", 11)) { stbuf->st_mode = atoi(buf+12); } else if (!strncmp(buf, "virtfs.rdev", 11)) { stbuf->st_rdev = atoi(buf+12); } memset(buf, 0, ATTR_MAX); } fclose(fp); }
static int local_rename(FsContext *ctx, const char *oldpath, const char *newpath) { int err; char buffer[PATH_MAX], buffer1[PATH_MAX]; if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { err = local_create_mapped_attr_dir(ctx, newpath); if (err < 0) { return err; } /* rename the .virtfs_metadata files */ err = rename(local_mapped_attr_path(ctx, oldpath, buffer), local_mapped_attr_path(ctx, newpath, buffer1)); if (err < 0 && errno != ENOENT) { return err; } } return rename(rpath(ctx, oldpath, buffer), rpath(ctx, newpath, buffer1)); }
static int local_remove(FsContext *ctx, const char *path) { int err; struct stat stbuf; char *buffer; if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { buffer = rpath(ctx, path); err = lstat(buffer, &stbuf); g_free(buffer); if (err) { goto err_out; } /* * If directory remove .virtfs_metadata contained in the * directory */ if (S_ISDIR(stbuf.st_mode)) { buffer = g_strdup_printf("%s/%s/%s", ctx->fs_root, path, VIRTFS_META_DIR); err = remove(buffer); g_free(buffer); if (err < 0 && errno != ENOENT) { /* * We didn't had the .virtfs_metadata file. May be file created * in non-mapped mode ?. Ignore ENOENT. */ goto err_out; } } /* * Now remove the name from parent directory * .virtfs_metadata directory */ buffer = local_mapped_attr_path(ctx, path); err = remove(buffer); g_free(buffer); if (err < 0 && errno != ENOENT) { /* * We didn't had the .virtfs_metadata file. May be file created * in non-mapped mode ?. Ignore ENOENT. */ goto err_out; } } buffer = rpath(ctx, path); err = remove(buffer); g_free(buffer); err_out: return err; }
static int local_unlinkat(FsContext *ctx, V9fsPath *dir, const char *name, int flags) { int ret; V9fsString fullname; char *buffer; v9fs_string_init(&fullname); v9fs_string_sprintf(&fullname, "%s/%s", dir->data, name); if (ctx->export_flags & V9FS_SM_MAPPED_FILE) { if (flags == AT_REMOVEDIR) { /* * If directory remove .virtfs_metadata contained in the * directory */ buffer = g_strdup_printf("%s/%s/%s", ctx->fs_root, fullname.data, VIRTFS_META_DIR); ret = remove(buffer); g_free(buffer); if (ret < 0 && errno != ENOENT) { /* * We didn't had the .virtfs_metadata file. May be file created * in non-mapped mode ?. Ignore ENOENT. */ goto err_out; } } /* * Now remove the name from parent directory * .virtfs_metadata directory. */ buffer = local_mapped_attr_path(ctx, fullname.data); ret = remove(buffer); g_free(buffer); if (ret < 0 && errno != ENOENT) { /* * We didn't had the .virtfs_metadata file. May be file created * in non-mapped mode ?. Ignore ENOENT. */ goto err_out; } } /* Remove the name finally */ buffer = rpath(ctx, fullname.data); ret = remove(buffer); g_free(buffer); err_out: v9fs_string_free(&fullname); return ret; }
static int local_link(FsContext *ctx, V9fsPath *oldpath, V9fsPath *dirpath, const char *name) { int ret; V9fsString newpath; char *buffer, *buffer1; v9fs_string_init(&newpath); v9fs_string_sprintf(&newpath, "%s/%s", dirpath->data, name); buffer = rpath(ctx, oldpath->data); buffer1 = rpath(ctx, newpath.data); ret = link(buffer, buffer1); g_free(buffer); g_free(buffer1); /* now link the virtfs_metadata files */ if (!ret && (ctx->export_flags & V9FS_SM_MAPPED_FILE)) { /* Link the .virtfs_metadata files. Create the metada directory */ ret = local_create_mapped_attr_dir(ctx, newpath.data); if (ret < 0) { goto err_out; } buffer = local_mapped_attr_path(ctx, oldpath->data); buffer1 = local_mapped_attr_path(ctx, newpath.data); ret = link(buffer, buffer1); g_free(buffer); g_free(buffer1); if (ret < 0 && errno != ENOENT) { goto err_out; } } err_out: v9fs_string_free(&newpath); return ret; }
static int local_set_mapped_file_attr(FsContext *ctx, const char *path, FsCred *credp) { FILE *fp; int ret = 0; char buf[ATTR_MAX]; char attr_path[PATH_MAX]; int uid = -1, gid = -1, mode = -1, rdev = -1; fp = local_fopen(local_mapped_attr_path(ctx, path, attr_path), "r"); if (!fp) { goto create_map_file; } memset(buf, 0, ATTR_MAX); while (fgets(buf, ATTR_MAX, fp)) { if (!strncmp(buf, "virtfs.uid", 10)) { uid = atoi(buf+11); } else if (!strncmp(buf, "virtfs.gid", 10)) { gid = atoi(buf+11); } else if (!strncmp(buf, "virtfs.mode", 11)) { mode = atoi(buf+12); } else if (!strncmp(buf, "virtfs.rdev", 11)) { rdev = atoi(buf+12); } memset(buf, 0, ATTR_MAX); } fclose(fp); goto update_map_file; create_map_file: ret = local_create_mapped_attr_dir(ctx, path); if (ret < 0) { goto err_out; } update_map_file: fp = local_fopen(attr_path, "w"); if (!fp) { ret = -1; goto err_out; } if (credp->fc_uid != -1) { uid = credp->fc_uid; } if (credp->fc_gid != -1) { gid = credp->fc_gid; } if (credp->fc_mode != -1) { mode = credp->fc_mode; } if (credp->fc_rdev != -1) { rdev = credp->fc_rdev; } if (uid != -1) { fprintf(fp, "virtfs.uid=%d\n", uid); } if (gid != -1) { fprintf(fp, "virtfs.gid=%d\n", gid); } if (mode != -1) { fprintf(fp, "virtfs.mode=%d\n", mode); } if (rdev != -1) { fprintf(fp, "virtfs.rdev=%d\n", rdev); } fclose(fp); err_out: return ret; }