2 * open_by_handle.c - attempt to create a file handle and open it
3 * with open_by_handle_at() syscall
5 * Copyright (C) 2017 CTERA Networks. All Rights Reserved.
6 * Author: Amir Goldstein <amir73il@gmail.com>
11 * Copyright (C) 2010 Red Hat, Inc. All Rights reserved.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #include <sys/types.h>
36 #include <linux/limits.h>
41 struct file_handle fh;
42 unsigned char fid[MAX_HANDLE_SZ];
45 int main(int argc, char **argv)
53 int mount_fd, mount_id;
56 fprintf(stderr, "usage: open_by_handle <test_dir>\n");
61 mount_fd = open(test_dir, O_RDONLY|O_DIRECTORY);
63 perror("open test_dir");
68 * create a large number of files to force allocation of new inode
71 for (i=0; i < NUMFILES; i++) {
72 sprintf(fname, "%s/file%06d", test_dir, i);
73 fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0644);
75 printf("Warning (%s,%d), open(%s) failed.\n", __FILE__, __LINE__, fname);
82 /* sync to get the new inodes to hit the disk */
85 /* create the handles */
86 for (i=0; i < NUMFILES; i++) {
87 sprintf(fname, "%s/file%06d", test_dir, i);
88 handle[i].fh.handle_bytes = MAX_HANDLE_SZ;
89 ret = name_to_handle_at(AT_FDCWD, fname, &handle[i].fh, &mount_id, 0);
91 perror("name_to_handle");
96 /* unlink the files */
97 for (i=0; i < NUMFILES; i++) {
98 sprintf(fname, "%s/file%06d", test_dir, i);
106 /* sync to get log forced for unlink transactions to hit the disk */
109 /* sync once more FTW */
113 * now drop the caches so that unlinked inodes are reclaimed and
114 * buftarg page cache is emptied so that the inode cluster has to be
115 * fetched from disk again for the open_by_handle() call.
117 ret = system("echo 3 > /proc/sys/vm/drop_caches");
119 perror("drop_caches");
124 * now try to open the files by the stored handles. Expecting ENOENT
127 for (i=0; i < NUMFILES; i++) {
129 fd = open_by_handle_at(mount_fd, &handle[i].fh, O_RDWR);
130 if (fd < 0 && (errno == ENOENT || errno == ESTALE)) {
134 printf("open_by_handle(%d) opened an unlinked file!\n", i);
137 printf("open_by_handle(%d) returned %d incorrectly on an unlinked file!\n", i, errno);