Created
June 18, 2019 00:30
-
-
Save zarmin/68e546e53a3a38e6612cc074befd477b to your computer and use it in GitHub Desktop.
hanwen/go-fuse, nfs, readdir EINVAL error reproduce
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#include <fcntl.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <dirent.h> | |
#include <sys/syscall.h> | |
#include <stdint.h> | |
void checkerror(int retval) { | |
int _errno = errno; | |
if (retval < 0) { | |
fprintf(stderr, "retno=%d, errno=%d, error=%s\n", retval, _errno, strerror(_errno)); | |
exit(1); | |
} | |
} | |
char testdir[] = "testdir"; | |
int maxindex = 1000; | |
void cleanup() { | |
if (chdir(testdir) >= 0) { | |
for(int i = 0; i<= maxindex; i++) { | |
char buffer[100]; | |
sprintf(buffer, "%04d", i); | |
rmdir(buffer); | |
} | |
chdir(".."); | |
checkerror(rmdir(testdir)); | |
} | |
} | |
void deletedirs(int start, int stop) { | |
char buffer[100]; | |
for(int i = start; i < stop; i++) { | |
sprintf(buffer, "%s/%04d", testdir, i); | |
rmdir(buffer); | |
} | |
} | |
void createdirs() { | |
checkerror(mkdir(testdir, 0777)); | |
checkerror(chdir(testdir)); | |
for(int i = 0; i< maxindex; i++) { | |
char buffer[100]; | |
sprintf(buffer, "%04d", i); | |
checkerror(mkdir(buffer, 0777)); | |
} | |
checkerror(chdir("..")); | |
} | |
#define BUF_SIZE 256 | |
struct linux_dirent { | |
long d_ino; | |
off_t d_off; | |
unsigned short d_reclen; | |
char d_name[]; | |
}; | |
void listdir() { | |
int fd, nread; | |
char buf[BUF_SIZE]; | |
int dirfrom = 100; | |
fd = open(testdir, O_RDONLY | O_DIRECTORY); | |
checkerror(fd); | |
for (;;) { | |
nread = syscall(SYS_getdents, fd, buf, BUF_SIZE); | |
checkerror(nread); | |
if (nread == 0) { | |
break; | |
} | |
for (int bpos = 0; bpos < nread; ) { | |
struct linux_dirent* d = (struct linux_dirent *) (buf + bpos); | |
// uint64_t ino = d->d_ino; | |
// char d_type = d_type = *(buf + bpos + d->d_reclen - 1); | |
// printf("%s\t%8ld\t%d\n", d->d_name, ino, (int)d_type); | |
bpos += d->d_reclen; | |
} | |
deletedirs(dirfrom, dirfrom+1); | |
dirfrom += 1; | |
} | |
close(fd); | |
} | |
int main(void) { | |
printf("start\n"); | |
cleanup(); | |
createdirs(); | |
listdir(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment