On Thursday 03 March 2011 5:39:55 pm Stefan Hajnoczi wrote: > > + v9fs_write_request(fs_ctx->chroot_socket, request); > > + fd = v9fs_receivefd(fs_ctx->chroot_socket, &sock_error); > > + if (fd < 0 && sock_error) { > > + fs_ctx->chroot_ioerror = 1; > > + } > > chroot_ioerror, sock_error, and their FdInfo bits are redundant code. > The chroot child could just exit on error and the parent would get > errors when writing the request here, which is the same effect as > manually returning -EIO in this function. There is no need to > introduce variables and bits to communicate this failure mode. > > Once that simplification has been made, FdInfo becomes just an -errno > value to pass back the result of open(2) and friends. That means we > can completely drop FdInfo and the fi_fd field which doesn't actually > hold a useful fd value for the QEMU process but just a -errno. >
But we need to pass the fd to qemu process, so it could not be -errno. When fd >= 0 its a valid fd otherwise its a errno. > Instead send back only an int -errno return code from the chroot child. > > You mentioned wanting to distinguish between socket errors and > blocking syscall errors but since there isn't any real error handling > that makes use of that information (and I'm not sure there is a good > error handling strategy that could be used), this is all just adding > complexity. > > > +/* Helper routine to fill V9fsFileObjectRequest structure */ > > +static int fill_fileobjectrequest(V9fsFileObjectRequest *request, > > + const char *path, FsCred *credp) > > +{ > > + if (strlen(path) > PATH_MAX) { > > + return -ENAMETOOLONG; > > + } > > Off-by-one error. It should strlen(path) >= PATH_MAX to account for > the NUL terminator. > Ok, I Will change! > > + memset(request, 0, sizeof(*request)); > > + request->data.path_len = strlen(path); > > + strcpy(request->path.path, path); > > + if (credp) { > > + request->data.mode = credp->fc_mode; > > + request->data.uid = credp->fc_uid; > > + request->data.gid = credp->fc_gid; > > + request->data.dev = credp->fc_rdev; > > + } > > + return 0; > > +} > > + > > +static int passthrough_open(FsContext *fs_ctx, const char *path, int > > flags) +{ > > + V9fsFileObjectRequest request; > > + int fd; > > + > > + fd = fill_fileobjectrequest(&request, path, NULL); > > + if (fd < 0) { > > + errno = -fd; > > Please don't use errno to communicate errors back. In this function > it would be perfectly fine to return fd here since it is already a > -errno. > > It's not safe to use errno since it's value can be lost by calling any > external function - its value may be modified even if no error occurs. > I quoted from the errno(3) man page in a previous review: > "a function that succeeds *is* allowed to change errno" > > > + return -1; > > + } > > + request.data.flags = flags; > > + request.data.type = T_OPEN; > > + fd = v9fs_request(fs_ctx, &request); > > + return fd; > > +} > > > > static int local_lstat(FsContext *fs_ctx, const char *path, struct stat > > *stbuf) { > > @@ -138,14 +175,27 @@ static int local_closedir(FsContext *ctx, DIR *dir) > > return closedir(dir); > > } > > > > -static int local_open(FsContext *ctx, const char *path, int flags) > > +static int local_open(FsContext *fs_ctx, const char *path, int flags) > > { > > - return open(rpath(ctx, path), flags); > > + if (fs_ctx->fs_sm == SM_PASSTHROUGH) { > > + return passthrough_open(fs_ctx, path, flags); > > + } else { > > + return open(rpath(fs_ctx, path), flags); > > + } > > } > > > > -static DIR *local_opendir(FsContext *ctx, const char *path) > > +static DIR *local_opendir(FsContext *fs_ctx, const char *path) > > { > > - return opendir(rpath(ctx, path)); > > + if (fs_ctx->fs_sm == SM_PASSTHROUGH) { > > + int fd; > > + fd = passthrough_open(fs_ctx, path, O_DIRECTORY); > > + if (fd < 0) { > > + return NULL; > > + } > > + return fdopendir(fd); > > + } else { > > + return opendir(rpath(fs_ctx, path)); > > + } > > Perhaps we should use a local_operations struct or similar function > pointer table instead of adding fs_ctx->fs_sm conditionals everywhere. That would have more code duplication when compared to additional conditionals. i.e, We need to create local_passthrough_opendir, local_passthrough_open, .. etc. > > Also it would be neat to reuse the local implementations on the chroot > child side instead of instead of splitting code paths, but I'm not > sure whether that is possible. I am not sure what do you mean by reusing the virtio-9p-local.c implementation in chilld side. That may involve breaking down existing local functions? ---- M. Mohan Kumar