… | |
… | |
171 | use common::sense; |
171 | use common::sense; |
172 | |
172 | |
173 | use base 'Exporter'; |
173 | use base 'Exporter'; |
174 | |
174 | |
175 | BEGIN { |
175 | BEGIN { |
176 | our $VERSION = 4.6; |
176 | our $VERSION = 4.7; |
177 | |
177 | |
178 | our @AIO_REQ = qw(aio_sendfile aio_seek aio_read aio_write aio_open aio_close |
178 | our @AIO_REQ = qw(aio_sendfile aio_seek aio_read aio_write aio_open aio_close |
179 | aio_stat aio_lstat aio_unlink aio_rmdir aio_readdir aio_readdirx |
179 | aio_stat aio_lstat aio_unlink aio_rmdir aio_readdir aio_readdirx |
180 | aio_scandir aio_symlink aio_readlink aio_realpath aio_fcntl aio_ioctl |
180 | aio_scandir aio_symlink aio_readlink aio_realpath aio_fcntl aio_ioctl |
181 | aio_sync aio_fsync aio_syncfs aio_fdatasync aio_sync_file_range |
181 | aio_sync aio_fsync aio_syncfs aio_fdatasync aio_sync_file_range |
… | |
… | |
1109 | aioreq_pri $pri; |
1109 | aioreq_pri $pri; |
1110 | add $grp aio_stat $wd, sub { |
1110 | add $grp aio_stat $wd, sub { |
1111 | return $grp->result () if $_[0]; |
1111 | return $grp->result () if $_[0]; |
1112 | my $now = time; |
1112 | my $now = time; |
1113 | my $hash1 = join ":", (stat _)[0,1,3,7,9]; |
1113 | my $hash1 = join ":", (stat _)[0,1,3,7,9]; |
|
|
1114 | my $rdxflags = READDIR_DIRS_FIRST; |
|
|
1115 | |
|
|
1116 | if ((stat _)[3] < 2) { |
|
|
1117 | # at least one non-POSIX filesystem exists |
|
|
1118 | # that returns useful DT_type values: btrfs, |
|
|
1119 | # so optimise for this here by requesting dents |
|
|
1120 | $rdxflags |= READDIR_DENTS; |
|
|
1121 | } |
1114 | |
1122 | |
1115 | # read the directory entries |
1123 | # read the directory entries |
1116 | aioreq_pri $pri; |
1124 | aioreq_pri $pri; |
1117 | add $grp aio_readdirx $wd, READDIR_DIRS_FIRST, sub { |
1125 | add $grp aio_readdirx $wd, $rdxflags, sub { |
1118 | my $entries = shift |
1126 | my ($entries, $flags) = @_ |
1119 | or return $grp->result (); |
1127 | or return $grp->result (); |
|
|
1128 | |
|
|
1129 | if ($rdxflags & READDIR_DENTS) { |
|
|
1130 | # if we requested type values, see if we can use them directly. |
|
|
1131 | |
|
|
1132 | # if there were any DT_UNKNOWN entries then we assume we |
|
|
1133 | # don't know. alternatively, we could assume that if we get |
|
|
1134 | # one DT_DIR, then all directories are indeed marked with |
|
|
1135 | # DT_DIR, but this seems not required for btrfs, and this |
|
|
1136 | # is basically the "btrfs can't get it's act together" code |
|
|
1137 | # branch. |
|
|
1138 | unless ($flags & READDIR_FOUND_UNKNOWN) { |
|
|
1139 | # now we have valid DT_ information for all entries, |
|
|
1140 | # so use it as an optimisation without further stat's. |
|
|
1141 | # they must also all be at the beginning of @$entries |
|
|
1142 | # by now. |
|
|
1143 | |
|
|
1144 | my $dirs; |
|
|
1145 | |
|
|
1146 | if (@$entries) { |
|
|
1147 | for (0 .. $#$entries) { |
|
|
1148 | if ($entries->[$_][1] != DT_DIR) { |
|
|
1149 | # splice out directories |
|
|
1150 | $dirs = [splice @$entries, 0, $_]; |
|
|
1151 | last; |
|
|
1152 | } |
|
|
1153 | } |
|
|
1154 | |
|
|
1155 | # if we didn't find any non-dir, then all entries are dirs |
|
|
1156 | unless ($dirs) { |
|
|
1157 | ($dirs, $entries) = ($entries, []); |
|
|
1158 | } |
|
|
1159 | } else { |
|
|
1160 | # directory is empty, so there are no sbdirs |
|
|
1161 | $dirs = []; |
|
|
1162 | } |
|
|
1163 | |
|
|
1164 | # either splice'd the directories out or the dir was empty. |
|
|
1165 | # convert dents to filenames |
|
|
1166 | $_ = $_->[0] for @$dirs; |
|
|
1167 | $_ = $_->[0] for @$entries; |
|
|
1168 | |
|
|
1169 | return $grp->result ($dirs, $entries); |
|
|
1170 | } |
|
|
1171 | |
|
|
1172 | # cannot use, so return to our old ways |
|
|
1173 | # by pretending we only scanned for names. |
|
|
1174 | $_ = $_->[0] for @$entries; |
|
|
1175 | } |
1120 | |
1176 | |
1121 | # stat the dir another time |
1177 | # stat the dir another time |
1122 | aioreq_pri $pri; |
1178 | aioreq_pri $pri; |
1123 | add $grp aio_stat $wd, sub { |
1179 | add $grp aio_stat $wd, sub { |
1124 | my $hash2 = join ":", (stat _)[0,1,3,7,9]; |
1180 | my $hash2 = join ":", (stat _)[0,1,3,7,9]; |