]> Zhao Yanbai Git Server - minix.git/commit
VFS: fix locking bugs
authorThomas Veerman <thomas@minix3.org>
Fri, 30 Nov 2012 12:49:53 +0000 (12:49 +0000)
committerThomas Veerman <thomas@minix3.org>
Fri, 11 Jan 2013 09:18:35 +0000 (09:18 +0000)
commit7c8b3ddfedbf67ace632beb1aade5bd94f21f792
tree067de0f9e630c2656417b4bb364c44f49293e688
parentecf9b40841def9a4f717a9dfaa2cbc856adbd9da
VFS: fix locking bugs

.sync and fsync used unnecessarily restrictive locking type
.fsync violated locking order by obtaining a vmnt lock after a filp lock
.fsync contained a TOCTOU bug
.new_node violated locking rules (didn't upgrade lock upon file creation)
.do_pipe used unnecessarily restrictive locking type
.always lock pipes exclusively; even a read operation might require to do
 a write on a vnode object (update pipe size)
.when opening a file with O_TRUNC, upgrade vnode lock when truncating
.utime used unnecessarily restrictive locking type
.path parsing:
  .always acquire VMNT_WRITE or VMNT_EXCL on vmnt and downgrade to
   VMNT_READ if that was what was actually requested. This prevents the
   following deadlock scenario:
   thread A:
     lock_vmnt(vmp, TLL_READSER);
     lock_vnode(vp, TLL_READSER);
     upgrade_vmnt_lock(vmp, TLL_WRITE);

   thread B:
     lock_vmnt(vmp, TLL_READ);
     lock_vnode(vp, TLL_READSER);

   thread A will be stuck in upgrade_vmnt_lock and thread B is stuck in
   lock_vnode. This happens when, for example, thread A tries create a
   new node (open.c:new_node) and thread B tries to do eat_path to
   change dir (stadir.c:do_chdir). When the path is being resolved, a
   vnode is always locked with VNODE_OPCL (TLL_READSER) and then
   downgraded to VNODE_READ if read-only is actually requested. Thread
   A locks the vmnt with VMNT_WRITE (TLL_READSER) which still allows
   VMNT_READ locks. Thread B can't acquire a lock on the vnode because
   thread A has it; Thread A can't upgrade its vmnt lock to VMNT_WRITE
   (TLL_WRITE) because thread B has a VMNT_READ lock on it.

   By serializing vmnt locks during path parsing, thread B can only
   acquire a lock on vmp when thread A has completely finished its
   operation.
12 files changed:
servers/vfs/filedes.c
servers/vfs/link.c
servers/vfs/misc.c
servers/vfs/open.c
servers/vfs/path.c
servers/vfs/pipe.c
servers/vfs/proto.h
servers/vfs/read.c
servers/vfs/time.c
servers/vfs/tll.c
servers/vfs/vmnt.c
servers/vfs/vnode.c