Whamcloud - gitweb
LU-17705 ptlrpc: replace synchronize_rcu() with rcu_barrier()
[fs/lustre-release.git] / lustre / tests / check_fhandle_syscalls.c
index 95e3002..2fdd124 100644 (file)
 #include <sys/stat.h>
 #include <sys/syscall.h>
 
-#include <libcfs/libcfs.h>
-#include <lustre/lustre_user.h>
+#include <linux/lustre/lustre_user.h>
 
 #define MAX_HANDLE_SZ 128
 
-#if !defined(HAVE_FHANDLE_GLIBC_SUPPORT) && defined(HAVE_FHANDLE_SYSCALLS)
+static void usage(char *prog)
+{
+       fprintf(stderr, "usage: %s <filepath> <mount2>\n",
+               prog);
+       fprintf(stderr, "the absolute path of a test file on a "
+               "lustre file system is needed.\n");
+       exit(1);
+}
+
+
+#ifndef HAVE_FHANDLE_GLIBC_SUPPORT
 /* Because the kernel supports this functions doesn't mean that glibc does.
  * Just in case we define what we need */
 struct file_handle {
@@ -88,7 +97,6 @@ struct file_handle {
 #define __NR_open_by_handle_at 265
 #endif
 
-
 #endif
 
 static inline int
@@ -106,29 +114,98 @@ open_by_handle_at(int mnt_fd, struct file_handle *fh, int mode)
 }
 #endif
 
-void usage(char *prog)
+static int debug_mark(const char *msg)
 {
-       fprintf(stderr, "usage: %s <filepath>\n",
-               prog);
-       fprintf(stderr, "the absolute path of a test file on a "
-               "lustre file system is needed.\n");
-       exit(1);
+       char cmd[4096] = "";
+
+       snprintf(cmd, sizeof(cmd), "../utils/lctl mark %s 2>/dev/null", msg);
+       return system(cmd);
+}
+
+/* verify a file contents */
+static int check_access(const char *filename,
+                int mnt_fd, struct file_handle *fh, struct stat *st_orig)
+{
+       int fd2, rc, len, offset;
+       struct stat st;
+       char *readbuf = NULL;
+
+       debug_mark("before open by handle");
+       /* Open the file handle */
+       fd2 = open_by_handle_at(mnt_fd, fh, O_RDONLY |
+                               (S_ISDIR(st_orig->st_mode) ? O_DIRECTORY : 0));
+       debug_mark("after open by handle");
+       if (fd2 < 0) {
+               fprintf(stderr, "open_by_handle_at(%s) error: %s\n", filename,
+                       strerror(errno));
+               if (errno == ESTALE)
+                       fprintf(stderr, "second mountpoint not mounted?\n");
+               rc = errno;
+               goto out_f_handle;
+       }
+
+       /* Get file size */
+       bzero(&st, sizeof(struct stat));
+       debug_mark("before stat");
+       rc = fstat(fd2, &st);
+       debug_mark("after stat");
+       if (rc < 0) {
+               fprintf(stderr, "fstat(%s) error: %s\n", filename,
+                       strerror(errno));
+               rc = errno;
+               goto out_fd2;
+       }
+
+       /* we can't check a ctime due unlink update */
+       if (st_orig->st_size != st.st_size ||
+           st_orig->st_ino != st.st_ino ||
+           st_orig->st_mode != st.st_mode ||
+           st_orig->st_mtime != st.st_mtime) {
+               fprintf(stderr,
+                       "stat data mismatch between fopen and fhandle case\n");
+               rc = EINVAL;
+               goto out_fd2;
+       }
+
+       if (st.st_size && S_ISREG(st.st_mode)) {
+               len = st.st_blksize;
+               readbuf = malloc(len);
+               if (readbuf == NULL) {
+                       fprintf(stderr, "malloc(%d) error: %s\n", len,
+                               strerror(errno));
+                       rc = errno;
+                       goto out_fd2;
+               }
+
+               for (offset = 0; offset < st.st_size; offset += len) {
+                       /* read from the file */
+                       rc = read(fd2, readbuf, len);
+                       if (rc < 0) {
+                               fprintf(stderr, "read(%s) error: %s\n",
+                                       filename, strerror(errno));
+                               rc = errno;
+                               goto out_readbuf;
+                       }
+               }
+       }
+       rc = 0;
+out_readbuf:
+       free(readbuf);
+out_fd2:
+       close(fd2);
+out_f_handle:
+       return rc;
 }
 
 int main(int argc, char **argv)
 {
-#ifdef HAVE_FHANDLE_SYSCALLS
-       char *filename, *file, *mount_point = NULL, *readbuf = NULL;
-       int ret, rc = -EINVAL, mnt_id, mnt_fd, fd1, fd2, i, len, offset;
+       char *filename, *file;
+       int ret, rc = -EINVAL, mnt_fd, mnt_id, fd1, i;
        struct file_handle *fh = NULL;
-       int file_size, mtime, ctime;
        struct lu_fid *parent, *fid;
-       struct mntent *ent;
        struct stat st;
-       __ino_t inode;
-       FILE *mntpt;
 
-       if (argc != 2)
+       if (argc != 3)
                usage(argv[0]);
 
        file = argv[1];
@@ -137,7 +214,15 @@ int main(int argc, char **argv)
                goto out;
        }
 
+       if (*argv[2] != '/') {
+               fprintf(stderr, "Need the absolete path of the mount point\n");
+               goto out;
+       }
+       filename = rindex(file, '/') + 1;
+
+       debug_mark("before first open");
        fd1 = open(file, O_RDONLY);
+       debug_mark("after first open");
        if (fd1 < 0) {
                fprintf(stderr, "open file %s error: %s\n",
                        file, strerror(errno));
@@ -147,7 +232,9 @@ int main(int argc, char **argv)
 
        /* Get file stats using fd1 from traditional open */
        bzero(&st, sizeof(struct stat));
+       debug_mark("before first stat");
        rc = fstat(fd1, &st);
+       debug_mark("after first stat");
        if (rc < 0) {
                fprintf(stderr, "fstat(%s) error: %s\n", file,
                        strerror(errno));
@@ -155,41 +242,12 @@ int main(int argc, char **argv)
                goto out_fd1;
        }
 
-       inode = st.st_ino;
-       mtime = st.st_mtime;
-       ctime = st.st_ctime;
-       file_size = st.st_size;
-
-       /* Now for the setup to use fhandles */
-       mntpt = setmntent("/etc/mtab", "r");
-       if (mntpt == NULL) {
-               fprintf(stderr, "setmntent error: %s\n",
-                       strerror(errno));
-               rc = errno;
-               goto out_fd1;
-       }
-
-       while (NULL != (ent = getmntent(mntpt))) {
-               if ((strncmp(file, ent->mnt_dir, strlen(ent->mnt_dir)) == 0) &&
-                   (strcmp(ent->mnt_type, "lustre") == 0)) {
-                       mount_point = ent->mnt_dir;
-                       break;
-               }
-       }
-       endmntent(mntpt);
-
-       if (mount_point == NULL) {
-               fprintf(stderr, "file is not located on a lustre file "
-                       "system?\n");
-               goto out_fd1;
-       }
-
-       filename = rindex(file, '/') + 1;
-
        /* Open mount point directory */
-       mnt_fd = open(mount_point, O_DIRECTORY);
+       debug_mark("before directory open");
+       mnt_fd = open(argv[2], O_DIRECTORY);
+       debug_mark("after directory open");
        if (mnt_fd < 0) {
-               fprintf(stderr, "open(%s) error: %s\n)", mount_point,
+               fprintf(stderr, "open(%s) error: %s\n)", argv[2],
                        strerror(errno));
                rc = errno;
                goto out_fd1;
@@ -206,8 +264,10 @@ int main(int argc, char **argv)
        fh->handle_bytes = MAX_HANDLE_SZ;
 
        /* Convert name to handle */
-       ret = name_to_handle_at(mnt_fd, filename, fh, &mnt_id,
+       debug_mark("before get handle");
+       ret = name_to_handle_at(AT_FDCWD, file, fh, &mnt_id,
                                AT_SYMLINK_FOLLOW);
+       debug_mark("after get handle");
        if (ret) {
                fprintf(stderr, "name_by_handle_at(%s) error: %s\n", filename,
                        strerror(errno));
@@ -216,8 +276,8 @@ int main(int argc, char **argv)
        }
 
        /* Print out the contents of the file handle */
-       fprintf(stdout, "fh_bytes: %u\nfh_type: %d\nfh_data: ",
-               fh->handle_bytes, fh->handle_type);
+       fprintf(stdout, "file: %s\nfh_bytes: %u\nfh_type: %d\nfh_data: ",
+               file, fh->handle_bytes, fh->handle_type);
        for (i = 0; i < fh->handle_bytes; i++)
                fprintf(stdout, "%02x ", fh->f_handle[i]);
        fprintf(stdout, "\n");
@@ -229,62 +289,35 @@ int main(int argc, char **argv)
        fprintf(stdout, "file's parent FID is "DFID"\n", PFID(parent));
        fprintf(stdout, "file FID is "DFID"\n", PFID(fid));
 
-       /* Open the file handle */
-       fd2 = open_by_handle_at(mnt_fd, fh, O_RDONLY);
-       if (fd2 < 0) {
-               fprintf(stderr, "open_by_handle_at(%s) error: %s\n", filename,
-                       strerror(errno));
-               rc = errno;
+       fprintf(stdout, "access via mount point '%s' - ", argv[2]);
+       fflush(stdout);
+       rc = check_access(filename, mnt_fd, fh, &st);
+       if (rc != 0)
                goto out_f_handle;
-       }
-
-       /* Get file size */
-       bzero(&st, sizeof(struct stat));
-       rc = fstat(fd2, &st);
-       if (rc < 0) {
-               fprintf(stderr, "fstat(%s) error: %s\n", filename,
-                       strerror(errno));
-               rc = errno;
-               goto out_fd2;
-       }
-
-       if (ctime != st.st_ctime || file_size != st.st_size ||
-           inode != st.st_ino || mtime != st.st_mtime) {
-               fprintf(stderr, "stat data does not match between fopen "
-                       "and fhandle case\n");
-               goto out_fd2;
-       }
-
-       if (st.st_size) {
-               len = st.st_blksize;
-               readbuf = malloc(len);
-               if (readbuf == NULL) {
-                       fprintf(stderr, "malloc(%d) error: %s\n", len,
-                               strerror(errno));
-                       rc = errno;
-                       goto out_fd2;
+       fprintf(stdout, "OK \n");
+       fflush(stdout);
+
+       if (S_ISREG(st.st_mode)) {
+               fprintf(stdout, "access after unlink - ");
+               fflush(stdout);
+               ret = unlink(file);
+               if (ret < 0) {
+                       fprintf(stderr,
+                               "can't unlink '%s'. check permissions?\n",
+                               file);
+                       goto out_f_handle;
                }
 
-               for (offset = 0; offset < st.st_size; offset += len) {
-                       /* read from the file */
-                       rc = read(fd2, readbuf, len);
-                       if (rc < 0) {
-                               fprintf(stderr, "read(%s) error: %s\n",
-                                       filename, strerror(errno));
-                               rc = errno;
-                               goto out_readbuf;
-                       }
-               }
+               rc = check_access(filename, mnt_fd, fh, &st);
+               if (rc != 0)
+                       goto out_f_handle;
+               fprintf(stdout, "OK\n");
+               fflush(stdout);
        }
 
        rc = 0;
        fprintf(stdout, "check_fhandle_syscalls test Passed!\n");
 
-out_readbuf:
-       if (readbuf != NULL)
-               free(readbuf);
-out_fd2:
-       close(fd2);
 out_f_handle:
        free(fh);
 out_mnt_fd:
@@ -293,11 +326,4 @@ out_fd1:
        close(fd1);
 out:
        return rc;
-#else /* !HAVE_FHANDLE_SYSCALLS */
-       if (argc != 2)
-               usage(argv[0]);
-
-       fprintf(stderr, "HAVE_FHANDLE_SYSCALLS not defined\n");
-       return 0;
-#endif /* HAVE_FHANDLE_SYSCALLS */
 }