On Thu, 23 Feb 2017 14:23:15 +0000 Stefan Hajnoczi wrote: > On Mon, Feb 20, 2017 at 03:41:00PM +0100, Greg Kurz wrote: > > + dirfd = local_opendir_nofollow(ctx, dirpath); > > + if (dirfd) { > > + goto out; > > } > > > > - buffer = rpath(ctx, path); > > - err = remove(buffer); > > - g_free(buffer); > > + if (fstatat(dirfd, path, &stbuf, AT_SYMLINK_NOFOLLOW) < 0) { > > + goto err_out; > > + } > > + > > + if (S_ISDIR(stbuf.st_mode)) { > > + flags |= AT_REMOVEDIR; > > + } > > + > > + err = local_unlinkat_common(ctx, dirfd, name, flags); > > The alternative is optimistically skip fstat but then do: > > if (err == EISDIR) { It would be err == -1 && errno == EISDIR actually. > err = local_unlinkat_common(ctx, dirfd, name, flags | AT_REMOVEDIR); > } > > It might be faster. > This would work for passthrough and mapped modes indeed. For mapped-file mode, things are more complicated though. If path points to a directory and we call local_unlinkat_common() without AT_REMOVEDIR, it won't unlink the metadata directory and unlinkat() will fail with ENOENT because the directory isn't empty... I'd rather try to optimize in a followup patch later to avoid the extra complexity. > Reviewed-by: Stefan Hajnoczi