+static int cancel_lru_locks(char *prefix)
+{
+ char cmd[256], line[1024];
+ FILE *file;
+ pid_t child;
+ int len = 1024, rc = 0;
+
+ child = fork();
+ if (child < 0)
+ return errno;
+ else if (child) {
+ int status;
+ rc = waitpid(child, &status, WNOHANG);
+ if (rc == child)
+ rc = 0;
+ return rc;
+ }
+
+ if (prefix)
+ sprintf(cmd, "ls /proc/fs/lustre/ldlm/namespaces/*-%s-*/lru_size", prefix);
+ else
+ sprintf(cmd, "ls /proc/fs/lustre/ldlm/namespaces/*/lru_size");
+
+ file = popen(cmd, "r");
+ if (file == NULL) {
+ perror("popen()");
+ return errno;
+ }
+
+ while (fgets(line, len, file)) {
+ FILE *f;
+
+ if (!strlen(line))
+ continue;
+ /* trim newline character */
+ *(line + strlen(line) - 1) = '\0';
+ f = fopen(line, "w");
+ if (f == NULL) {
+ perror("fopen()");
+ rc = errno;
+ break;
+ }
+ rc = fwrite("clear", strlen("clear") + 1, 1, f);
+ if (rc < 1) {
+ perror("fwrite()");
+ rc = errno;
+ fclose(f);
+ break;
+ }
+ fclose(f);
+ }
+
+ pclose(file);
+ _exit(rc);
+}
+
+/* don't dead lock while read/write file to/from the buffer which
+ * mmaped to just this file */
+static int mmap_tst5(char *mnt)
+{
+ char *ptr, mmap_file[256];
+ int region, fd, off, rc = 0;
+
+ region = page_size * 40;
+ off = page_size * 10;
+ sprintf(mmap_file, "%s/%s", mnt, "mmap_file5");
+
+ if (unlink(mmap_file) && errno != ENOENT) {
+ perror("unlink()");
+ return errno;
+ }
+
+ fd = open(mmap_file, O_CREAT|O_RDWR, 0600);
+ if (fd < 0) {
+ perror(mmap_file);
+ return errno;
+ }
+ ftruncate(fd, region);
+
+ ptr = mmap(NULL, region, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED) {
+ perror("mmap()");
+ rc = errno;
+ goto out_close;
+ }
+ memset(ptr, 'a', region);
+
+ /* cancel unused locks */
+ rc = cancel_lru_locks("osc");
+ if (rc)
+ goto out_unmap;
+
+ /* read/write region of file and buffer should be overlap */
+ rc = read(fd, ptr + off, off * 2);
+ if (rc != off * 2) {
+ perror("read()");
+ rc = errno;
+ goto out_unmap;
+ }
+ rc = write(fd, ptr + off, off * 2);
+ if (rc != off * 2) {
+ perror("write()");
+ rc = errno;
+ }
+ rc = 0;
+out_unmap:
+ munmap(ptr, region);
+out_close:
+ close(fd);
+ unlink(mmap_file);
+ return rc;
+}
+
+/* mmap write to a file form client1 then mmap read from client2 */
+static int mmap_tst6(char *mnt)
+{
+ char mmap_file[256], mmap_file2[256];
+ char *ptr = NULL, *ptr2 = NULL;
+ int fd = 0, fd2 = 0, rc = 0;
+
+ sprintf(mmap_file, "%s/%s", mnt, "mmap_file6");
+ sprintf(mmap_file2, "%s/%s", dir2, "mmap_file6");
+ if (unlink(mmap_file) && errno != ENOENT) {
+ perror("unlink()");
+ return errno;
+ }
+
+ fd = open(mmap_file, O_CREAT|O_RDWR, 0600);
+ if (fd < 0) {
+ perror(mmap_file);
+ return errno;
+ }
+ ftruncate(fd, page_size);
+
+ fd2 = open(mmap_file2, O_RDWR, 0600);
+ if (fd2 < 0) {
+ perror(mmap_file2);
+ goto out;
+ }
+
+ ptr = mmap(NULL, page_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED) {
+ perror("mmap()");
+ rc = errno;
+ goto out;
+ }
+
+ ptr2 = mmap(NULL, page_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd2, 0);
+ if (ptr2 == MAP_FAILED) {
+ perror("mmap()");
+ rc = errno;
+ goto out;
+ }
+
+ rc = cancel_lru_locks("osc");
+ if (rc)
+ goto out;
+
+ memcpy(ptr, "blah", strlen("blah"));
+ if (strncmp(ptr, ptr2, strlen("blah"))) {
+ fprintf(stderr, "client2 mmap mismatch!\n");
+ rc = EFAULT;
+ goto out;
+ }
+ memcpy(ptr2, "foo", strlen("foo"));
+ if (strncmp(ptr, ptr2, strlen("foo"))) {
+ fprintf(stderr, "client1 mmap mismatch!\n");
+ rc = EFAULT;
+ }
+out:
+ if (ptr2)
+ munmap(ptr2, page_size);
+ if (ptr)
+ munmap(ptr, page_size);
+ if (fd2 > 0)
+ close(fd2);
+ if (fd > 0)
+ close(fd);
+ unlink(mmap_file);
+ return rc;
+}
+