On Thu, 23 Feb 2017 14:23:15 +0000 Stefan Hajnoczi <[email protected]> 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 <[email protected]>
pgpLfkfmBiM8T.pgp
Description: OpenPGP digital signature
