src/t_dir_offset2: Add option to create or unlink file
authorAmir Goldstein <amir73il@gmail.com>
Sun, 25 Apr 2021 07:14:43 +0000 (10:14 +0300)
committerEryu Guan <guaneryu@gmail.com>
Sun, 16 May 2021 14:37:33 +0000 (22:37 +0800)
Will be used to test missing/stale entries after modifications to
an open dirfd.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Eryu Guan <guaneryu@gmail.com>
Signed-off-by: Eryu Guan <guaneryu@gmail.com>
src/t_dir_offset2.c

index 7af2451..75b41c1 100644 (file)
@@ -34,13 +34,13 @@ static uint64_t d_ino_history[HISTORY_LEN];
 
 void usage()
 {
-       fprintf(stderr, "usage: t_dir_offset2: <dir> [[bufsize] <filename> [-v]]\n");
+       fprintf(stderr, "usage: t_dir_offset2: <dir> [[bufsize] [-|+]<filename> [-v]]\n");
        exit(EXIT_FAILURE);
 }
 
 int main(int argc, char *argv[])
 {
-       int fd;
+       int fd, fd2 = -1;
        char buf[BUF_SIZE];
        int nread, bufsize = BUF_SIZE;
        struct linux_dirent64 *d;
@@ -49,7 +49,7 @@ int main(int argc, char *argv[])
        int retval = EXIT_SUCCESS;
        const char *filename = NULL;
        int exists = 0, found = 0;
-       int verbose = 0;
+       int modify = 0, verbose = 0;
 
        if (argc > 2) {
                bufsize = atoi(argv[2]);
@@ -60,6 +60,13 @@ int main(int argc, char *argv[])
 
                if (argc > 3) {
                        filename = argv[3];
+                       /* +<filename> creates, -<filename> removes */
+                       if (filename[0] == '+')
+                               modify = 1;
+                       else if (filename[0] == '-')
+                               modify = -1;
+                       if (modify)
+                               filename++;
                        if (argc > 4 && !strcmp(argv[4], "-v"))
                                verbose = 1;
                }
@@ -89,6 +96,49 @@ int main(int argc, char *argv[])
                        exit(EXIT_FAILURE);
                }
 
+               if (modify && fd2 < 0 && total == 0) {
+                       printf("getdents at offset 0 returned %d bytes\n", nread);
+
+                       /* create/unlink entry after first getdents */
+                       if (modify > 0) {
+                               if (openat(fd, filename, O_CREAT, 0600) < 0) {
+                                       perror("openat");
+                                       exit(EXIT_FAILURE);
+                               }
+                               exists = 1;
+                               printf("created entry %s\n", filename);
+                       } else if (modify < 0) {
+                               if (unlinkat(fd, filename, 0) < 0) {
+                                       perror("unlinkat");
+                                       exit(EXIT_FAILURE);
+                               }
+                               exists = 0;
+                               printf("unlinked entry %s\n", filename);
+                       }
+
+                       /*
+                        * Old fd may not return new entry and may return stale
+                        * entries which is allowed.  Keep old fd open and open
+                        * a new fd to check for stale or missing entries later.
+                        */
+                       fd2 = open(argv[1], O_RDONLY | O_DIRECTORY);
+                       if (fd2 < 0) {
+                               perror("open fd2");
+                               exit(EXIT_FAILURE);
+                       }
+               }
+
+               if (nread == 0) {
+                       if (fd2 < 0 || fd == fd2)
+                               break;
+
+                       /* Re-iterate with new fd leaving old fd open */
+                       fd = fd2;
+                       total = 0;
+                       found = 0;
+                       continue;
+               }
+
                if (nread == 0)
                        break;