aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2012-12-11 12:10:11 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2012-12-20 18:50:05 -0500
commit87fa55952b7347175c6e2f03874869ad2c055adb (patch)
tree8795b6a6794a1c3988cea32fb2471bd3cd235ef9 /fs/open.c
parent48f7530d3f722617aa7cfea62b09b0c1a8d0173e (diff)
vfs: have faccessat retry once on an ESTALE error
Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/open.c b/fs/open.c
index 07449b911a4..a994ccf39b4 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -316,6 +316,7 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
316 struct path path; 316 struct path path;
317 struct inode *inode; 317 struct inode *inode;
318 int res; 318 int res;
319 unsigned int lookup_flags = LOOKUP_FOLLOW;
319 320
320 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ 321 if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
321 return -EINVAL; 322 return -EINVAL;
@@ -338,8 +339,8 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
338 } 339 }
339 340
340 old_cred = override_creds(override_cred); 341 old_cred = override_creds(override_cred);
341 342retry:
342 res = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path); 343 res = user_path_at(dfd, filename, lookup_flags, &path);
343 if (res) 344 if (res)
344 goto out; 345 goto out;
345 346
@@ -374,6 +375,10 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
374 375
375out_path_release: 376out_path_release:
376 path_put(&path); 377 path_put(&path);
378 if (retry_estale(res, lookup_flags)) {
379 lookup_flags |= LOOKUP_REVAL;
380 goto retry;
381 }
377out: 382out:
378 revert_creds(old_cred); 383 revert_creds(old_cred);
379 put_cred(override_cred); 384 put_cred(override_cred);