Messages in this thread Patch in this message |  | | Date | Thu, 22 Aug 2002 02:45:18 +0100 | From | Matthew Wilcox <> | Subject | Re: [PATCH] move BKL down a little in setfl |
| |
On Wed, Aug 21, 2002 at 03:50:27PM -0700, Linus Torvalds wrote: > This exits with the BKL held, as far as I can tell:
duh, you're right. here's a fixed patch:
diff -urpNX dontdiff linux-2.5.31/fs/fcntl.c linux-2.5.31-willy/fs/fcntl.c --- linux-2.5.31/fs/fcntl.c 2002-08-01 14:16:07.000000000 -0700 +++ linux-2.5.31-willy/fs/fcntl.c 2002-08-21 18:32:37.000000000 -0700 @@ -227,23 +227,16 @@ asmlinkage long sys_dup(unsigned int fil static int setfl(int fd, struct file * filp, unsigned long arg) { struct inode * inode = filp->f_dentry->d_inode; - int error; + int error = 0; - /* - * In the case of an append-only file, O_APPEND - * cannot be cleared - */ + /* O_APPEND cannot be cleared if the file is marked as append-only */ if (!(arg & O_APPEND) && IS_APPEND(inode)) return -EPERM; - /* Did FASYNC state change? */ - if ((arg ^ filp->f_flags) & FASYNC) { - if (filp->f_op && filp->f_op->fasync) { - error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0); - if (error < 0) - return error; - } - } + /* required for strict SunOS emulation */ + if (O_NONBLOCK != O_NDELAY) + if (arg & O_NDELAY) + arg |= O_NONBLOCK; if (arg & O_DIRECT) { if (!inode->i_mapping || !inode->i_mapping->a_ops || @@ -251,13 +244,19 @@ static int setfl(int fd, struct file * f return -EINVAL; } - /* required for strict SunOS emulation */ - if (O_NONBLOCK != O_NDELAY) - if (arg & O_NDELAY) - arg |= O_NONBLOCK; + lock_kernel(); + if ((arg ^ filp->f_flags) & FASYNC) { + if (filp->f_op && filp->f_op->fasync) { + error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0); + if (error < 0) + goto out; + } + } filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK); - return 0; + out: + unlock_kernel(); + return error; } static long do_fcntl(unsigned int fd, unsigned int cmd, @@ -283,9 +282,7 @@ static long do_fcntl(unsigned int fd, un err = filp->f_flags; break; case F_SETFL: - lock_kernel(); err = setfl(fd, filp, arg); - unlock_kernel(); break; case F_GETLK: err = fcntl_getlk(filp, (struct flock *) arg); -- Revolutions do not require corporate support. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |