Skip to content

Commit

Permalink
lib/vfscore: Reorder locks in *at syscalls
Browse files Browse the repository at this point in the history
*at syscalls are implemented in Unikraft in two stages: (1) build the
full target path relative to the supplied dirfd, and (2) delegate to the
regular syscall. Previously these syscalls held the lock on the dirfd
vnode throughout steps (1) and (2); however, the sub-syscalls often need
to acquire the same lock (along with perhaps others), causing
double-lock asserts to trigger.
This commit changes this logic to only hold the vnode lock during step
(1) and release it immediately before (2). While this relaxes the
previous atomicity guarantees somewhat, holding the vnode lock on dirfd
only prevented concurrent changes to first-generation descendents, and
unorthogonal and arguably unexpected behavior. The useful purpose of
holding the dirfd lock is to ensure we build a full path that was (at
one point in time) valid, with the sub-syscalls implementing their own
atomicity guarantees as per usual.

Signed-off-by: Andrei Tatar <andrei@unikraft.io>
Reviewed-by: Maria Sfiraiala <maria.sfiraiala@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #951
  • Loading branch information
andreittr authored and unikraft-bot committed Aug 7, 2023
1 parent 10acf65 commit 3452e22
Showing 1 changed file with 9 additions and 9 deletions.
18 changes: 9 additions & 9 deletions lib/vfscore/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,11 @@ UK_LLSYSCALL_R_DEFINE(int, openat, int, dirfd, const char *, pathname,
strlcat(p, "/", PATH_MAX);
strlcat(p, pathname, PATH_MAX);

error = uk_syscall_r_open((long int)p, flags, mode);

vn_unlock(vp);
fdrop(fp);

error = uk_syscall_r_open((long int)p, flags, mode);

return error;
}

Expand Down Expand Up @@ -1295,11 +1295,11 @@ UK_SYSCALL_R_DEFINE(int, mkdirat, int, dirfd,
strlcat(p, "/", PATH_MAX);
strlcat(p, pathname, PATH_MAX);

error = uk_syscall_r_mkdir((long) p, (long) mode);

vn_unlock(vp);
fdrop(fp);

error = uk_syscall_r_mkdir((long) p, (long) mode);

return error;
}

Expand Down Expand Up @@ -1745,14 +1745,14 @@ static int __fxstatat_helper(int ver __unused, int dirfd, const char *pathname,
strlcat(p, "/", PATH_MAX);
strlcat(p, pathname, PATH_MAX);

vn_unlock(vp);
fdrop(fp);

if (flags & AT_SYMLINK_NOFOLLOW)
error = uk_syscall_r_lstat((long) p, (long) st);
else
error = uk_syscall_r_stat((long) p, (long) st);

vn_unlock(vp);
fdrop(fp);

return error;
}

Expand Down Expand Up @@ -2235,11 +2235,11 @@ UK_SYSCALL_R_DEFINE(int, faccessat, int, dirfd, const char*, pathname, int, mode
strlcat(p, "/", PATH_MAX);
strlcat(p, pathname, PATH_MAX);

error = uk_syscall_r_access((long) p, (long) mode);

vn_unlock(vp);
fdrop(fp);

error = uk_syscall_r_access((long) p, (long) mode);

out_error:
return error;
}
Expand Down

0 comments on commit 3452e22

Please sign in to comment.