patch-1.3.86 linux/fs/locks.c
Next file: linux/fs/namei.c
Previous file: linux/drivers/sound/Readme.cards
Back to the patch index
Back to the overall index
- Lines: 143
- Date:
Wed Apr 10 08:41:08 1996
- Orig file:
v1.3.85/linux/fs/locks.c
- Orig date:
Mon Apr 8 19:01:45 1996
diff -u --recursive --new-file v1.3.85/linux/fs/locks.c linux/fs/locks.c
@@ -58,15 +58,16 @@
* once we've checked for blocking and deadlocking.
* Andy Walker (andy@lysaker.kvaerner.no), April 03, 1996.
*
- * NOTE:
- * Starting to look at mandatory locks - using SunOS as a model.
- * Probably a configuration option because mandatory locking can cause
- * all sorts of chaos with runaway processes.
- *
* Initial implementation of mandatory locks. SunOS turned out to be
* a rotten model, so I implemented the "obvious" semantics.
* See 'linux/Documentation/mandatory.txt' for details.
* Andy Walker (andy@lysaker.kvaerner.no), April 06, 1996.
+ *
+ * Don't allow mandatory locks on mmap()'ed files. Added simple functions to
+ * check if a file has mandatory locks, used by mmap(), open() and creat() to
+ * see if system call should be rejected. Ref. HP-UX/SunOS/Solaris Reference
+ * Manual, Section 2.
+ * Andy Walker (andy@lysaker.kvaerner.no), April 09, 1996.
*/
#include <linux/malloc.h>
@@ -195,7 +196,7 @@
(flock.l_type == F_SHLCK))
return (-EINVAL);
- if (!posix_make_lock(filp, &file_lock, &flock))
+ if (!filp->f_inode || !posix_make_lock(filp, &file_lock, &flock))
return (-EINVAL);
for (fl = filp->f_inode->i_flock; fl != NULL; fl = fl->fl_next) {
@@ -227,6 +228,7 @@
struct file *filp;
struct file_lock file_lock;
struct flock flock;
+ struct inode *inode;
/*
* Get arguments and validate them ...
@@ -239,6 +241,21 @@
if (error)
return (error);
+ if (!(inode = filp->f_inode))
+ return (-EINVAL);
+
+ /* Don't allow mandatory locks on files that may be memory mapped
+ * and shared.
+ */
+ if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID && inode->i_mmap) {
+ struct vm_area_struct *vma = inode->i_mmap;
+ do {
+ if (vma->vm_flags & VM_MAYSHARE)
+ return (-EAGAIN);
+ vma = vma->vm_next_share;
+ } while (vma != inode->i_mmap);
+ }
+
memcpy_fromfs(&flock, l, sizeof(flock));
if (!posix_make_lock(filp, &file_lock, &flock))
return (-EINVAL);
@@ -246,16 +263,16 @@
switch (flock.l_type) {
case F_RDLCK :
if (!(filp->f_mode & 1))
- return -EBADF;
+ return (-EBADF);
break;
case F_WRLCK :
if (!(filp->f_mode & 2))
- return -EBADF;
+ return (-EBADF);
break;
case F_SHLCK :
case F_EXLCK :
if (!(filp->f_mode & 3))
- return -EBADF;
+ return (-EBADF);
break;
case F_UNLCK :
break;
@@ -288,21 +305,44 @@
return;
}
-int locks_verify(int read_write, struct inode *inode, struct file *filp,
- unsigned int offset, unsigned int count)
+int locks_verify_locked(struct inode *inode)
{
/* Candidates for mandatory locking have the setgid bit set
* but no group execute bit - an otherwise meaningless combination.
*/
if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
- return (locks_locked_mandatory(read_write, inode, filp,
- offset, count));
+ return (locks_mandatory_locked(inode));
+ return (0);
+}
+
+int locks_mandatory_locked(struct inode *inode)
+{
+ struct file_lock *fl;
+
+ /* Search the lock list for this inode for any POSIX locks.
+ */
+ for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
+ if (fl->fl_flags == F_POSIX && fl->fl_owner != current)
+ return (-EAGAIN);
+ }
+ return (0);
+}
+
+int locks_verify_area(int read_write, struct inode *inode, struct file *filp,
+ unsigned int offset, unsigned int count)
+{
+ /* Candidates for mandatory locking have the setgid bit set
+ * but no group execute bit - an otherwise meaningless combination.
+ */
+ if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+ return (locks_mandatory_area(read_write, inode, filp, offset,
+ count));
return (0);
}
-int locks_locked_mandatory(int read_write, struct inode *inode,
- struct file *filp, unsigned int offset,
- unsigned int count)
+int locks_mandatory_area(int read_write, struct inode *inode,
+ struct file *filp, unsigned int offset,
+ unsigned int count)
{
struct file_lock *fl;
@@ -352,9 +392,6 @@
struct flock *l)
{
off_t start;
-
- if (!filp->f_inode) /* just in case */
- return (0);
switch (l->l_type) {
case F_RDLCK :
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this