patch-2.3.10 linux/fs/locks.c
Next file: linux/fs/minix/file.c
Previous file: linux/fs/ioctl.c
Back to the patch index
Back to the overall index
- Lines: 158
- Date:
Mon Jul 5 20:11:07 1999
- Orig file:
v2.3.9/linux/fs/locks.c
- Orig date:
Wed Jun 30 13:38:20 1999
diff -u --recursive --new-file v2.3.9/linux/fs/locks.c linux/fs/locks.c
@@ -341,7 +341,11 @@
error = filp->f_op->lock(filp, F_GETLK, &file_lock);
if (error < 0)
goto out_putf;
- fl = &file_lock;
+ else if (error == LOCK_USE_CLNT)
+ /* Bypass for NFS with no locking - 2.0.36 compat */
+ fl = posix_test_lock(filp, &file_lock);
+ else
+ fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
} else {
fl = posix_test_lock(filp, &file_lock);
}
@@ -402,14 +406,17 @@
* and shared.
*/
if (IS_MANDLOCK(inode) &&
- (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID &&
- inode->i_mmap) {
- struct vm_area_struct *vma = inode->i_mmap;
- error = -EAGAIN;
- do {
- if (vma->vm_flags & VM_MAYSHARE)
- goto out_putf;
- } while ((vma = vma->vm_next_share) != NULL);
+ (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) {
+ struct vm_area_struct *vma;
+ spin_lock(&inode->i_shared_lock);
+ for(vma = inode->i_mmap;vma;vma = vma->vm_next_share) {
+ if (!(vma->vm_flags & VM_MAYSHARE))
+ continue;
+ spin_unlock(&inode->i_shared_lock);
+ error = -EAGAIN;
+ goto out_putf;
+ }
+ spin_unlock(&inode->i_shared_lock);
}
error = -EINVAL;
@@ -546,47 +553,23 @@
return (cfl);
}
-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 (IS_MANDLOCK(inode) &&
- (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
- return (locks_mandatory_locked(inode));
- return (0);
-}
-
-int locks_verify_area(int read_write, struct inode *inode, struct file *filp,
- loff_t offset, size_t count)
-{
- /* Candidates for mandatory locking have the setgid bit set
- * but no group execute bit - an otherwise meaningless combination.
- */
- if (IS_MANDLOCK(inode) && (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) {
- int retval;
- lock_kernel();
- retval = locks_mandatory_area(read_write, inode, filp, offset, count);
- unlock_kernel();
- return retval;
- }
- return 0;
-}
-
int locks_mandatory_locked(struct inode *inode)
{
fl_owner_t owner = current->files;
struct file_lock *fl;
- /* Search the lock list for this inode for any POSIX locks.
+ /*
+ * Search the lock list for this inode for any POSIX locks.
*/
+ lock_kernel();
for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
if (!(fl->fl_flags & FL_POSIX))
continue;
if (fl->fl_owner != owner)
- return (-EAGAIN);
+ break;
}
- return (0);
+ unlock_kernel();
+ return fl ? -EAGAIN : 0;
}
int locks_mandatory_area(int read_write, struct inode *inode,
@@ -595,6 +578,7 @@
{
struct file_lock *fl;
struct file_lock tfl;
+ int error;
memset(&tfl, 0, sizeof(tfl));
@@ -607,31 +591,39 @@
tfl.fl_start = offset;
tfl.fl_end = offset + count - 1;
+ error = 0;
+ lock_kernel();
+
repeat:
/* Search the lock list for this inode for locks that conflict with
* the proposed read/write.
*/
- for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
+ for (fl = inode->i_flock; ; fl = fl->fl_next) {
+ error = 0;
+ if (!fl)
+ break;
if (!(fl->fl_flags & FL_POSIX))
continue;
/* Block for writes against a "read" lock,
* and both reads and writes against a "write" lock.
*/
if (posix_locks_conflict(fl, &tfl)) {
+ error = -EAGAIN;
if (filp && (filp->f_flags & O_NONBLOCK))
- return (-EAGAIN);
+ break;
+ error = -ERESTARTSYS;
if (signal_pending(current))
- return (-ERESTARTSYS);
+ break;
+ error = -EDEADLK;
if (posix_locks_deadlock(&tfl, fl))
- return (-EDEADLK);
+ break;
locks_insert_block(fl, &tfl);
interruptible_sleep_on(&tfl.fl_wait);
locks_delete_block(fl, &tfl);
- if (signal_pending(current))
- return (-ERESTARTSYS);
- /* If we've been sleeping someone might have
+ /*
+ * If we've been sleeping someone might have
* changed the permissions behind our back.
*/
if ((inode->i_mode & (S_ISGID | S_IXGRP)) != S_ISGID)
@@ -639,7 +631,8 @@
goto repeat;
}
}
- return (0);
+ unlock_kernel();
+ return error;
}
/* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)