LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: "J. Bruce Fields" <bfields@fieldses.org>
To: Peter Staubach <staubach@redhat.com>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	linux-nfs@vger.kernel.org,
	Andrew Morton <akpm@linux-foundation.org>,
	Trond Myklebust <trond.myklebust@fys.uio.no>,
	linux-fsdevel <linux-fsdevel@vger.kernel.org>
Subject: Re: [PATCH 0/3] enhanced ESTALE error handling
Date: Fri, 18 Jan 2008 10:46:07 -0500	[thread overview]
Message-ID: <20080118154607.GA4976@fieldses.org> (raw)
In-Reply-To: <4790C756.2040704@redhat.com>

On Fri, Jan 18, 2008 at 10:35:50AM -0500, Peter Staubach wrote:
> Hi.
>
> Here is a patch set which modifies the system to enhance the
> ESTALE error handling for system calls which take pathnames
> as arguments.

I think your cover letter may be bigger than any of the actual
patches....  I'm not complaining!  But would it be worth adding this
explanation and test code to Documentation/filesystems/ just to keep it
around?

--b.

>
> The error, ESTALE, was originally introduced to handle the
> situation where a file handle, which NFS uses to uniquely
> identify a file on the server, no longer refers to a valid file
> on the server.  This can happen when the file is removed on the
> server, either by an application on the server, some other
> client accessing the server, or sometimes even by another
> mounted file system from the same client.  It can also happen
> when the file resides upon a file system which is no longer
> exported.
>
> The error, ESTALE, is usually seen when cached directory
> information is used to convert a pathname to a dentry/inode pair.
> The information is discovered to be out of date or stale when a
> subsequent operation is sent to the NFS server.  This can easily
> happen in system calls such as stat(2) when the pathname is
> converted a dentry/inode pair using cached information, but then
> a subsequent GETATTR call to the server discovers that the file
> handle is no longer valid.
>
> System calls which take pathnames as arguments should never see
> ESTALE errors from situations like this.  These system calls
> should either fail with an ENOENT error if the pathname can not
> be successfully be translated to a dentry/inode pair or succeed
> or fail based on their own semantics.
>
> ESTALE errors which occur during the lookup process can be
> handled by dropping the dentry which refers to the non-existent
> file from the dcache and then restarting the lookup process.
> Care can be taken to ensure that forward progress is always
> being made in order to avoiding infinite loops.
>
> ESTALE errors which occur during operations subsequent to the
> lookup process can be handled by unwinding appropriately and
> then performing the lookup process again.  Eventually, either
> the lookup process will succeed or fail correctly or the
> subsequent operation will succeed or fail on its own merits.
>
> This support is desired in order to tighten up recovery from
> discovering stale resources due to the loose cache consistency
> semantics that file systems such as NFS employ.  In particular,
> there are several large Red Hat customers, converting from
> Solaris to Linux, who desire this support in order that their
> applications environments continue to work.
>
> Please note that system calls which do not take pathnames as
> arguments or perhaps use file descriptors to identify the
> file to be manipulated may still fail with ESTALE errors.
> There is no recovery possible with these systems calls like
> there is with system calls which take pathnames as arguments.
>
> This support was tested using the attached programs and
> running multiple copies on mounted file systems which do not
> share superblocks.  When two or more copies of this program
> are running, many ESTALE errors can be seen over the network.
>
> Comments?
>
>    Thanx...
>
>       ps

> #
> #define _XOPEN_SOURCE 500
> #define _LARGEFILE64_SOURCE
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <sys/statfs.h>
> #include <sys/inotify.h>
> #include <errno.h>
> #include <fcntl.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <signal.h>
> 
> void mkdir_test(void);
> void link_test(void);
> void open_test(void);
> void access_test(void);
> void chmod_test(void);
> void chown_test(void);
> void readlink_test(void);
> void utimes_test(void);
> void chdir_test(void);
> void chroot_test(void);
> void rename_test(void);
> void exec_test(void);
> void mknod_test(void);
> void statfs_test(void);
> void truncate_test(void);
> void xattr_test(void);
> void inotify_test(void);
> 
> struct tests {
> 	void (*test)(void);
> };
> 
> struct tests tests[] = {
> 	mkdir_test,
> 	link_test,
> 	open_test,
> 	access_test,
> 	chmod_test,
> 	chown_test,
> 	readlink_test,
> 	utimes_test,
> 	chdir_test,
> 	chroot_test,
> 	rename_test,
> 	exec_test,
> 	mknod_test,
> 	statfs_test,
> 	truncate_test,
> 	xattr_test,
> 	inotify_test
> };
> 
> pid_t test_pids[sizeof(tests) / sizeof(tests[0])];
> 
> pid_t parent_pid;
> 
> void kill_tests(int);
> 
> int
> main(int argc, char *argv[])
> {
> 	int i;
> 
> 	parent_pid = getpid();
> 
> 	sigset(SIGINT, kill_tests);
> 
> 	sighold(SIGINT);
> 
> 	for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
> 		test_pids[i] = fork();
> 		if (test_pids[i] == 0) {
> 			for (;;)
> 				(*tests[i].test)();
> 			/* NOTREACHED */
> 		}
> 	}
> 
> 	sigrelse(SIGINT);
> 
> 	pause();
> }
> 
> void
> kill_tests(int sig)
> {
> 	int i;
> 
> 	for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
> 		if (test_pids[i] != -1) {
> 			if (kill(test_pids[i], SIGTERM) < 0)
> 				perror("kill");
> 		}
> 	}
> 
> 	exit(0);
> }
> 
> void
> check_error(int error, char *operation)
> {
> 
> 	if (error < 0 && errno == ESTALE) {
> 		perror(operation);
> 		kill(parent_pid, SIGINT);
> 		pause();
> 	}
> }
> 
> void
> check_error_child(int error, char *operation)
> {
> 
> 	if (error < 0 && errno == ESTALE) {
> 		perror(operation);
> 		kill(parent_pid, SIGINT);
> 		exit(1);
> 	}
> }
> 
> void
> do_stats(char *file)
> {
> 	int error;
> 	struct stat stbuf;
> 	struct stat64 stbuf64;
> 
> 	error = stat(file, &stbuf);
> 	check_error(error, "stat");
> 
> 	error = stat64(file, &stbuf64);
> 	check_error(error, "stat64");
> 
> 	error = lstat(file, &stbuf);
> 	check_error(error, "lstat");
> 
> 	error = lstat64(file, &stbuf64);
> 	check_error(error, "lstat64");
> }
> 
> void
> do_stats_child(char *file)
> {
> 	int error;
> 	struct stat stbuf;
> 	struct stat64 stbuf64;
> 
> 	error = stat(file, &stbuf);
> 	check_error_child(error, "stat");
> 
> 	error = stat64(file, &stbuf64);
> 	check_error_child(error, "stat64");
> 
> 	error = lstat(file, &stbuf);
> 	check_error_child(error, "lstat");
> 
> 	error = lstat64(file, &stbuf64);
> 	check_error_child(error, "lstat64");
> }
> 
> char *mkdir_dirs[] = {
> 	"mkdir/a",
> 	"mkdir/a/b",
> 	"mkdir/a/b/c",
> 	"mkdir/a/b/c/d",
> 	"mkdir/a/b/c/d/e",
> 	"mkdir/a/b/c/d/e/f",
> 	"mkdir/a/b/c/d/e/f/g",
> 	"mkdir/a/b/c/d/e/f/g/h",
> 	"mkdir/a/b/c/d/e/f/g/h/i",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l/m",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l/m/n",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y",
> 	"mkdir/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z",
> 	NULL
> };
> 
> void
> mkdir_test()
> {
> 	int i;
> 	int error;
> 
> 	error = mkdir("mkdir", 0755);
> 	check_error(error, "mkdir");
> 
> 	for (i = 0; mkdir_dirs[i] != NULL; i++) {
> 		error = mkdir(mkdir_dirs[i], 0755);
> 		check_error(error, "mkdir");
> 		do_stats(mkdir_dirs[i]);
> 	}
> 
> 	while (--i >= 0) {
> 		do_stats(mkdir_dirs[i]);
> 		error = rmdir(mkdir_dirs[i]);
> 		check_error(error, "rmdir");
> 	}
> 
> 	error = rmdir("mkdir");
> 	check_error(error, "rmdir");
> }
> 
> char *link_file_a = "link/a";
> char *link_file_b = "link/b";
> 
> void
> link_test()
> {
> 	int error;
> 	int fd;
> 
> 	error = mkdir("link", 0755);
> 	check_error(error, "mkdir");
> 
> 	fd = open(link_file_a, O_CREAT, 0644);
> 	check_error(fd, "open");
> 
> 	(void) close(fd);
> 
> 	do_stats(link_file_a);
> 
> 	error = link(link_file_a, link_file_b);
> 	check_error(error, "link");
> 	do_stats(link_file_a);
> 	do_stats(link_file_b);
> 
> 	error = unlink(link_file_a);
> 	check_error(error, "unlink");
> 	do_stats(link_file_a);
> 	do_stats(link_file_b);
> 
> 	error = link(link_file_b, link_file_a);
> 	check_error(error, "link");
> 	do_stats(link_file_a);
> 	do_stats(link_file_b);
> 
> 	error = unlink(link_file_b);
> 	check_error(error, "unlink");
> 	do_stats(link_file_a);
> 	do_stats(link_file_b);
> 
> 	error = unlink(link_file_a);
> 	check_error(error, "unlink");
> 	do_stats(link_file_a);
> 	do_stats(link_file_b);
> 
> 	error = rmdir("link");
> 	check_error(error, "rmdir");
> }
> 
> char *open_file = "open/a";
> 
> void
> open_test()
> {
> 	int error;
> 	int fd;
> 
> 	error = mkdir("open", 0755);
> 	check_error(error, "mkdir");
> 
> 	fd = open(open_file, O_CREAT | O_RDWR, 0644);
> 	check_error(fd, "open: O_CREAT");
> 
> 	(void) close(fd);
> 
> 	do_stats(open_file);
> 
> 	fd = open(open_file, O_RDWR);
> 	check_error(fd, "open: O_RDWR");
> 
> 	(void) close(fd);
> 
> 	do_stats(open_file);
> 
> 	error = unlink(open_file);
> 	check_error(error, "unlink");
> 
> 	error = rmdir("open");
> 	check_error(error, "rmdir");
> }
> 
> char *access_file = "access/a";
> 
> void
> access_test()
> {
> 	int error;
> 	int fd;
> 
> 	error = mkdir("access", 0755);
> 	check_error(error, "mkdir");
> 
> 	fd = open(access_file, O_CREAT | O_RDWR, 0644);
> 	check_error(fd, "open: O_CREAT");
> 
> 	(void) close(fd);
> 
> 	do_stats(access_file);
> 
> 	error = access(access_file, F_OK);
> 	check_error(error, "access");
> 
> 	do_stats(access_file);
> 
> 	error = unlink(access_file);
> 	check_error(error, "unlink");
> 
> 	error = rmdir("access");
> 	check_error(error, "rmdir");
> }
> 
> char *chmod_file = "chmod/a";
> 
> void
> chmod_test()
> {
> 	int error;
> 	int fd;
> 
> 	error = mkdir("chmod", 0755);
> 	check_error(error, "mkdir");
> 
> 	fd = open(chmod_file, O_CREAT | O_RDWR, 0644);
> 	check_error(fd, "open: O_CREAT");
> 
> 	(void) close(fd);
> 
> 	do_stats(chmod_file);
> 
> 	error = chmod(chmod_file, 0600);
> 	check_error(error, "chmod");
> 
> 	do_stats(chmod_file);
> 
> 	error = unlink(chmod_file);
> 	check_error(error, "unlink");
> 
> 	error = rmdir("chmod");
> 	check_error(error, "rmdir");
> }
> 
> char *chown_file = "chown/a";
> 
> void
> chown_test()
> {
> 	int error;
> 	int fd;
> 
> 	error = mkdir("chown", 0755);
> 	check_error(error, "mkdir");
> 
> 	fd = open(chown_file, O_CREAT | O_RDWR, 0644);
> 	check_error(fd, "open: O_CREAT");
> 
> 	(void) close(fd);
> 
> 	do_stats(chown_file);
> 
> 	error = chown(chown_file, 4597, 4597);
> 	check_error(error, "chown");
> 
> 	do_stats(chown_file);
> 
> 	error = lchown(chown_file, 4596, 4596);
> 	check_error(error, "lchown");
> 
> 	do_stats(chown_file);
> 
> 	error = unlink(chown_file);
> 	check_error(error, "unlink");
> 
> 	error = rmdir("chown");
> 	check_error(error, "rmdir");
> }
> 
> char *readlink_file = "readlink/a";
> 
> void
> readlink_test()
> {
> 	int error;
> 	char buf[BUFSIZ];
> 
> 	error = mkdir("readlink", 0755);
> 	check_error(error, "mkdir");
> 
> 	error = symlink("b", readlink_file);
> 	check_error(error, "symlink");
> 
> 	do_stats(readlink_file);
> 
> 	error = readlink(readlink_file, buf, sizeof(buf));
> 	check_error(error, "readlink");
> 
> 	do_stats(readlink_file);
> 
> 	error = unlink(readlink_file);
> 	check_error(error, "unlink");
> 
> 	error = rmdir("readlink");
> 	check_error(error, "rmdir");
> }
> 
> char *utimes_file = "utimes/a";
> 
> void
> utimes_test()
> {
> 	int error;
> 	int fd;
> 
> 	error = mkdir("utimes", 0755);
> 	check_error(error, "mkdir");
> 
> 	fd = open(utimes_file, O_CREAT | O_RDWR, 0644);
> 	check_error(fd, "open: O_CREAT");
> 
> 	(void) close(fd);
> 
> 	do_stats(utimes_file);
> 
> 	error = utime(utimes_file, NULL);
> 	check_error(error, "utime");
> 
> 	do_stats(utimes_file);
> 
> 	error = utimes(utimes_file, NULL);
> 	check_error(error, "utimes");
> 
> 	do_stats(utimes_file);
> 
> 	error = unlink(utimes_file);
> 	check_error(error, "unlink");
> 
> 	error = rmdir("utimes");
> 	check_error(error, "rmdir");
> }
> 
> char *chdir_dir = "chdir/dir";
> 
> void
> chdir_test()
> {
> 	int error;
> 	int pid;
> 	int status;
> 
> 	error = mkdir("chdir", 0755);
> 	check_error(error, "mkdir");
> 
> 	pid = fork();
> 	if (pid == 0) {
> 		error = mkdir(chdir_dir, 0755);
> 		check_error_child(error, "mkdir");
> 
> 		do_stats_child(chdir_dir);
> 
> 		error = chdir(chdir_dir);
> 		check_error_child(error, "chdir");
> 
> 		do_stats_child(chdir_dir);
> 
> 		exit(0);
> 	}
> 
> 	(void) wait(&status);
> 
> 	do_stats(chdir_dir);
> 
> 	error = rmdir(chdir_dir);
> 	check_error(error, "rmdir");
> 
> 	error = rmdir("chdir");
> 	check_error(error, "rmdir");
> }
> 
> char *chroot_dir = "chroot/dir";
> 
> void
> chroot_test()
> {
> 	int error;
> 	int pid;
> 	int status;
> 
> 	error = mkdir("chroot", 0755);
> 	check_error(error, "mkdir");
> 
> 	pid = fork();
> 	if (pid == 0) {
> 		error = mkdir(chroot_dir, 0755);
> 		check_error_child(error, "mkdir");
> 
> 		do_stats_child(chroot_dir);
> 
> 		error = chroot(chroot_dir);
> 		check_error_child(error, "chroot");
> 
> 		do_stats_child(chroot_dir);
> 
> 		exit(0);
> 	}
> 
> 	(void) wait(&status);
> 
> 	do_stats(chroot_dir);
> 
> 	error = rmdir(chroot_dir);
> 	check_error(error, "rmdir");
> 
> 	error = rmdir("chroot");
> 	check_error(error, "rmdir");
> }
> 
> char *rename_file_a = "rename/a";
> char *rename_file_b = "rename/b";
> 
> void
> rename_test()
> {
> 	int error;
> 	int fd;
> 
> 	error = mkdir("rename", 0755);
> 	check_error(error, "mkdir");
> 
> 	fd = open(rename_file_a, O_CREAT, 0644);
> 	check_error(fd, "open");
> 
> 	(void) close(fd);
> 
> 	do_stats(rename_file_a);
> 
> 	error = rename(rename_file_a, rename_file_b);
> 	check_error(error, "rename");
> 
> 	do_stats(rename_file_a);
> 	do_stats(rename_file_b);
> 
> 	error = rename(rename_file_b, rename_file_a);
> 	check_error(error, "rename");
> 
> 	do_stats(rename_file_a);
> 	do_stats(rename_file_b);
> 
> 	error = unlink(rename_file_a);
> 	check_error(error, "unlink");
> 
> 	error = rmdir("rename");
> 	check_error(error, "rmdir");
> }
> 
> char *exec_file = "exec/a";
> char *exec_source_file = "exec_test";
> 
> void
> exec_test()
> {
> 	int error;
> 	int pid;
> 	int status;
> 
> 	error = mkdir("exec", 0755);
> 	check_error(error, "mkdir");
> 
> 	error = link(exec_source_file, exec_file);
> 	check_error(error, "link");
> 	do_stats(exec_file);
> 
> 	pid = fork();
> 	if (pid == 0) {
> 		error = execl(exec_file, exec_file, NULL);
> 		check_error_child(error, "execl");
> 
> 		exit(1);
> 	}
> 
> 	wait(&status);
> 
> 	do_stats(exec_file);
> 
> 	error = unlink(exec_file);
> 	check_error(error, "unlink");
> 
> 	error = rmdir("exec");
> 	check_error(error, "rmdir");
> }
> 
> char *mknod_file = "mknod/a";
> 
> void
> mknod_test()
> {
> 	int error;
> 
> 	error = mkdir("mknod", 0755);
> 	check_error(error, "mkdir");
> 
> 	error = mknod(mknod_file, S_IFCHR | 0644, 0);
> 	check_error(error, "mknod");
> 
> 	do_stats(mknod_file);
> 
> 	error = unlink(mknod_file);
> 	check_error(error, "unlink");
> 
> 	error = rmdir("mknod");
> 	check_error(error, "rmdir");
> }
> 
> void
> statfs_test()
> {
> 	int error;
> 	struct statfs stbuf;
> 	struct statfs64 stbuf64;
> 
> 	error = mkdir("statfs", 0755);
> 	check_error(error, "mkdir");
> 
> 	do_stats("statfs");
> 
> 	error = statfs("statfs", &stbuf);
> 	check_error(error, "statfs");
> 
> 	error = statfs64("statfs", &stbuf64);
> 	check_error(error, "statfs64");
> 
> 	error = rmdir("statfs");
> 	check_error(error, "rmdir");
> }
> 
> char *truncate_file = "truncate/a";
> 
> void
> truncate_test()
> {
> 	int error;
> 	int fd;
> 
> 	error = mkdir("truncate", 0755);
> 	check_error(error, "mkdir");
> 
> 	fd = open(truncate_file, O_CREAT | O_RDWR, 0644);
> 	check_error(fd, "open: O_CREAT");
> 
> 	(void) close(fd);
> 
> 	do_stats(truncate_file);
> 
> 	error = truncate(truncate_file, 1024);
> 	check_error(error, "truncate");
> 
> 	do_stats(truncate_file);
> 
> 	error = unlink(truncate_file);
> 	check_error(error, "unlink");
> 
> 	error = rmdir("truncate");
> 	check_error(error, "rmdir");
> }
> 
> char *xattr_file = "xattr/a";
> 
> #define ACL_USER_OBJ	(0x01)
> #define ACL_USER	(0x02)
> #define ACL_GROUP_OBJ	(0x04)
> #define ACL_MASK	(0x10)
> #define ACL_OTHER	(0x20)
> 
> struct posix_acl_xattr_entry {
> 	unsigned short e_tag;
> 	unsigned short e_perm;
> 	unsigned int e_id;
> };
> 
> #define POSIX_ACL_XATTR_VERSION	0x0002
> 
> struct posix_acl_xattr_header {
> 	unsigned int a_version;
> 	struct posix_acl_xattr_entry a_entries[5];
> };
> 
> void
> xattr_test()
> {
> 	int error;
> 	int fd;
> 	char buf[1024];
> 	struct posix_acl_xattr_header ents;
> 
> 	error = mkdir("xattr", 0755);
> 	check_error(error, "mkdir");
> 
> 	fd = open(xattr_file, O_CREAT | O_RDWR, 0444);
> 	check_error(fd, "open: O_CREAT");
> 
> 	(void) close(fd);
> 
> 	do_stats(xattr_file);
> 
> 	error = getxattr(xattr_file, "system.posix_acl_access", buf,
> 			sizeof (buf));
> 	check_error(error, "getxattr");
> 	error = lgetxattr(xattr_file, "system.posix_acl_access", buf,
> 			sizeof (buf));
> 	check_error(error, "lgetxattr");
> 
> 	ents.a_version = POSIX_ACL_XATTR_VERSION;
> 	ents.a_entries[0].e_tag = ACL_USER_OBJ;
> 	ents.a_entries[0].e_perm = 06;
> 	ents.a_entries[0].e_id = -1;
> 	ents.a_entries[1].e_tag = ACL_USER;
> 	ents.a_entries[1].e_perm = 06;
> 	ents.a_entries[1].e_id = 10;
> 	ents.a_entries[2].e_tag = ACL_GROUP_OBJ;
> 	ents.a_entries[2].e_perm = 06;
> 	ents.a_entries[2].e_id = -1;
> 	ents.a_entries[3].e_tag = ACL_MASK;
> 	ents.a_entries[3].e_perm = 06;
> 	ents.a_entries[3].e_id = -1;
> 	ents.a_entries[4].e_tag = ACL_OTHER;
> 	ents.a_entries[4].e_perm = 06;
> 	ents.a_entries[4].e_id = -1;
> 
> 	error = setxattr(xattr_file, "system.posix_acl_access",
> 			&ents, sizeof (ents), 0);
> 	check_error(error, "setxattr");
> 
> 	do_stats(xattr_file);
> 
> 	error = lsetxattr(xattr_file, "system.posix_acl_access",
> 			&ents, sizeof (ents), 0);
> 	check_error(error, "lsetxattr");
> 
> 	do_stats(xattr_file);
> 
> 	error = getxattr(xattr_file, "system.posix_acl_access", buf,
> 			sizeof (buf));
> 	check_error(error, "getxattr");
> 	error = lgetxattr(xattr_file, "system.posix_acl_access", buf,
> 			sizeof (buf));
> 	check_error(error, "lgetxattr");
> 
> 	error = listxattr(xattr_file, buf, sizeof (buf));
> 	check_error(error, "listxattr");
> 	error = llistxattr(xattr_file, buf, sizeof (buf));
> 	check_error(error, "llistxattr");
> 
> 	error = removexattr(xattr_file, "system.posix_acl_access");
> 	check_error(error, "removexattr");
> 
> 	do_stats(xattr_file);
> 
> 	error = setxattr(xattr_file, "system.posix_acl_access",
> 			&ents, sizeof (ents), 0);
> 	check_error(error, "setxattr");
> 
> 	do_stats(xattr_file);
> 
> 	error = lremovexattr(xattr_file, "system.posix_acl_access");
> 	check_error(error, "lremovexattr");
> 
> 	do_stats(xattr_file);
> 
> 	error = unlink(xattr_file);
> 	check_error(error, "unlink");
> 
> 	error = rmdir("xattr");
> 	check_error(error, "rmdir");
> }
> 
> char *inotify_file = "inotify/a";
> 
> void
> inotify_test()
> {
> 	int error;
> 	int fd;
> 	int wd;
> 
> 	error = mkdir("inotify", 0755);
> 	check_error(error, "mkdir");
> 
> 	fd = open(inotify_file, O_CREAT | O_RDWR, 0644);
> 	check_error(fd, "open: O_CREAT");
> 
> 	(void) close(fd);
> 
> 	do_stats(inotify_file);
> 
> 	fd = inotify_init();
> 	check_error(error, "inotify_init");
> 
> 	do_stats(inotify_file);
> 
> 	wd = inotify_add_watch(fd, inotify_file, IN_ALL_EVENTS);
> 	check_error(wd, "inotify_add_watch");
> 
> 	do_stats(inotify_file);
> 
> 	error = inotify_rm_watch(fd, wd);
> 	check_error(error, "inotify_rm_watch");
> 
> 	(void) close(fd);
> 
> 	do_stats(inotify_file);
> 
> 	error = unlink(inotify_file);
> 	check_error(error, "unlink");
> 
> 	error = rmdir("inotify");
> 	check_error(error, "rmdir");
> }

> #include <stdlib.h>
> 
> main()
> {
> 	exit(0);
> }


  reply	other threads:[~2008-01-18 15:46 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-18 15:35 Peter Staubach
2008-01-18 15:46 ` J. Bruce Fields [this message]
2008-01-18 16:41 ` Chuck Lever
2008-01-18 16:55   ` Peter Staubach
2008-01-18 17:17     ` Chuck Lever
2008-01-18 17:30       ` Peter Staubach
2008-01-18 17:52         ` Chuck Lever
2008-01-18 18:12           ` Peter Staubach
2008-01-18 18:37             ` J. Bruce Fields
2008-01-18 19:12               ` Peter Staubach
2008-01-18 18:17         ` Chuck Lever
2008-02-01 20:57 ` [PATCH 0/3] enhanced ESTALE error handling (v2) Peter Staubach
2008-03-10 20:23   ` [PATCH 0/3] enhanced ESTALE error handling (v3) Peter Staubach
2008-03-10 22:42     ` Andreas Dilger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080118154607.GA4976@fieldses.org \
    --to=bfields@fieldses.org \
    --cc=akpm@linux-foundation.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=staubach@redhat.com \
    --cc=trond.myklebust@fys.uio.no \
    --subject='Re: [PATCH 0/3] enhanced ESTALE error handling' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).