diff options
author | Eric Wong <e@yhbt.net> | 2020-08-08 04:59:48 +0000 |
---|---|---|
committer | Eric Wong <e@yhbt.net> | 2020-08-08 10:47:11 +0000 |
commit | 683e5fbbfef867ff04b376b3d5230976004a6c7a (patch) | |
tree | 85b6cb3b3f40d88a51cf3b1d6902373f6318a836 /lib/PublicInbox/Spawn.pm | |
parent | 6e98887b3d539dd07c9d49e3334e48d720fc1e31 (diff) | |
download | public-inbox-683e5fbbfef867ff04b376b3d5230976004a6c7a.tar.gz |
support setting No_COW on Perl <5.22
fileno(DIRHANDLE) only works on Perl 5.22+, so we need to use dirfd(3) ourselves from Inline::C (or rely on chattr(1) being installed). While we're at it, rename `set_nodatacow' to `nodatacow_fd' for consistency with `nodatacow_dir'.
Diffstat (limited to 'lib/PublicInbox/Spawn.pm')
-rw-r--r-- | lib/PublicInbox/Spawn.pm | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/lib/PublicInbox/Spawn.pm b/lib/PublicInbox/Spawn.pm index 508d43fd..cb16fcf6 100644 --- a/lib/PublicInbox/Spawn.pm +++ b/lib/PublicInbox/Spawn.pm @@ -19,7 +19,7 @@ use strict; use parent qw(Exporter); use Symbol qw(gensym); use PublicInbox::ProcessPipe; -our @EXPORT_OK = qw/which spawn popen_rd/; +our @EXPORT_OK = qw/which spawn popen_rd nodatacow_dir/; our @RLIMITS = qw(RLIMIT_CPU RLIMIT_CORE RLIMIT_DATA); my $vfork_spawn = <<'VFORK_SPAWN'; @@ -159,11 +159,12 @@ my $set_nodatacow = $^O eq 'linux' ? <<'SET_NODATACOW' : ''; #include <sys/vfs.h> #include <linux/magic.h> #include <linux/fs.h> +#include <dirent.h> #include <errno.h> #include <stdio.h> #include <string.h> -void set_nodatacow(int fd) +void nodatacow_fd(int fd) { struct statfs buf; int val = 0; @@ -185,6 +186,19 @@ void set_nodatacow(int fd) if (ioctl(fd, FS_IOC_SETFLAGS, &val) < 0) fprintf(stderr, "FS_IOC_SET_FLAGS: %s\\n", strerror(errno)); } + +void nodatacow_dir(const char *dir) +{ + DIR *dh = opendir(dir); + int fd; + + if (!dh) croak("opendir(%s): %s", dir, strerror(errno)); + fd = dirfd(dh); + if (fd >= 0) + nodatacow_fd(fd); + /* ENOTSUP probably won't happen under Linux... */ + closedir(dh); +} SET_NODATACOW my $inline_dir = $ENV{PERL_INLINE_DIRECTORY} //= ( @@ -226,7 +240,8 @@ unless (defined $vfork_spawn) { unless ($set_nodatacow) { require PublicInbox::NDC_PP; no warnings 'once'; - *set_nodatacow = \&PublicInbox::NDC_PP::set_nodatacow; + *nodatacow_fd = \&PublicInbox::NDC_PP::nodatacow_fd; + *nodatacow_dir = \&PublicInbox::NDC_PP::nodatacow_dir; } undef $set_nodatacow; undef $vfork_spawn; |