Re: flock, FAGAIN, and FWOULDBLOCK

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Feb 22, 2009 at 05:49:24PM -0500, Kyle McMartin wrote:
> > according to the flock(2) man page, flock should return EWOULDBLOCK 
> > when a file is locked and the LOCK_NB flag was selected. But on hppa, 
> > it seems to return EAGAIN which is not the same. Where is the bug 
> > here? In the kernel, glibc, or manpages-dev?
> > 
> > This causes problems in apr since it only checks for EWOULDBLOCK.
> > 
> 
> Ugh. Fail.
> 
> EWOULDBLOCK is defined to be EAGAIN on every architecture but parisc,
> since HPUX has different errno values for EAGAIN and EWOULDBLOCK.
> 
> Definitely a kernel bug, if posix says it should return EWOULDBLOCK...
> 

This is really going to suck, it looks like a lot of the locking
primitives used EAGAIN and EWOULDBLOCK interchangeably... The fcntl
manpage says 'EAGAIN or EWOULDBLOCK' so is flock(2) the only problem
here? From a quick glance at posix, fcntl(2) returning EAGAIN is
correct.

My guess is, I'll be able to sort this out with a simple

diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 71b3195..18e8542 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -156,6 +156,17 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
 
 /* Fucking broken ABI */
 
+asmlinkage long parisc_flock(unsigned int fd, unsigned int cmd)
+{
+	long ret;
+
+	ret = sys_flock(fd, cmd);
+	if (ret == -EAGAIN)
+		ret = -EWOULDBLOCK;	/* fuck you HPUX */
+
+	return ret;
+}
+
 #ifdef CONFIG_64BIT
 asmlinkage long parisc_truncate64(const char __user * path,
 					unsigned int high, unsigned int low)
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 303d2b6..8c62951 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -226,7 +226,7 @@
 	/* it is POSSIBLE that select will be OK because even though fd_set
 	 * contains longs, the macros and sizes are clever. */
 	ENTRY_COMP(select)
-	ENTRY_SAME(flock)
+	ENTRY_OURS(flock)
 	ENTRY_SAME(msync)
 	/* struct iovec contains pointers */
 	ENTRY_COMP(readv)		/* 145 */

but somehow I suspect this interchangeable use of EAGAIN and EWOULDBLOCK
is going to reveal latent problems in this part of the kernel I would
rather not delve into...

cheers, Kyle
--
To unsubscribe from this list: send the line "unsubscribe linux-arch" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel]     [Kernel Newbies]     [x86 Platform Driver]     [Netdev]     [Linux Wireless]     [Netfilter]     [Bugtraq]     [Linux Filesystems]     [Yosemite Discussion]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]

  Powered by Linux