Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Kernel v2.6.26-rc9 /fs/locks.c

Filename:/fs/locks.c
Lines Added:35
Lines Deleted:25
Also changed in: (Previous) 2.6.26-rc8-git5  2.6.26-rc8-git4  2.6.26-rc8-git3  2.6.26-rc8-git2  2.6.26-rc8-git1  2.6.26-rc8 
(Following) 2.6.26  2.6.26-git13  2.6.26-git14  2.6.26-git15  2.6.26-git16  2.6.26-git17 

Location
[  2.6.26-rc9
  [  fs
     o  locks.c

Patch

diff --git a/fs/locks.c b/fs/locks.c
index 43c0af2..dce8c74 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -116,6 +116,7 @@
 
 #include <linux/capability.h>
 #include <linux/file.h>
+#include <linux/fdtable.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -127,7 +128,6 @@
 #include <linux/rcupdate.h>
 #include <linux/pid_namespace.h>
 
-#include <asm/semaphore.h>
 #include <asm/uaccess.h>
 
 #define IS_POSIX(fl)   (fl->fl_flags & FL_POSIX)
@@ -225,7 +225,7 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)
 /*
  * Initialize a new lock from an existing file_lock structure.
  */
-static void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl)
+void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl)
 {
    new->fl_owner = fl->fl_owner;
    new->fl_pid = fl->fl_pid;
@@ -237,6 +237,7 @@ static void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl)
    new->fl_ops = NULL;
    new->fl_lmops = NULL;
 }
+EXPORT_SYMBOL(__locks_copy_lock);
 
 void locks_copy_lock(struct file_lock *new, struct file_lock *fl)
 {
@@ -560,9 +561,6 @@ static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl)
    /* insert into file's list */
    fl->fl_next = *pos;
    *pos = fl;
-
-   if (fl->fl_ops && fl->fl_ops->fl_insert)
-      fl->fl_ops->fl_insert(fl);
 }
 
 /*
@@ -585,9 +583,6 @@ static void locks_delete_lock(struct file_lock **thisfl_p)
       fl->fl_fasync = NULL;
    }
 
-   if (fl->fl_ops && fl->fl_ops->fl_remove)
-      fl->fl_ops->fl_remove(fl);
-
    if (fl->fl_nspid) {
       put_pid(fl->fl_nspid);
       fl->fl_nspid = NULL;
@@ -772,7 +767,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
     * give it the opportunity to lock the file.
     */
    if (found)
-      cond_resched();
+      cond_resched_bkl();
 
 find_conflict:
    for_each_lock(inode, before) {
@@ -834,7 +829,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
          if (!posix_locks_conflict(request, fl))
             continue;
          if (conflock)
-            locks_copy_lock(conflock, fl);
+            __locks_copy_lock(conflock, fl);
          error = -EAGAIN;
          if (!(request->fl_flags & FL_SLEEP))
             goto out;
@@ -1368,18 +1363,20 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
 
    lease = *flp;
 
-   error = -EAGAIN;
-   if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
-      goto out;
-   if ((arg == F_WRLCK)
-       && ((atomic_read(&dentry->d_count) > 1)
-      || (atomic_read(&inode->i_count) > 1)))
-      goto out;
+   if (arg != F_UNLCK) {
+      error = -ENOMEM;
+      new_fl = locks_alloc_lock();
+      if (new_fl == NULL)
+         goto out;
 
-   error = -ENOMEM;
-   new_fl = locks_alloc_lock();
-   if (new_fl == NULL)
-      goto out;
+      error = -EAGAIN;
+      if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
+         goto out;
+      if ((arg == F_WRLCK)
+          && ((atomic_read(&dentry->d_count) > 1)
+         || (atomic_read(&inode->i_count) > 1)))
+         goto out;
+   }
 
    /*
     * At this point, we know that if there is an exclusive
@@ -1405,6 +1402,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
          rdlease_count++;
    }
 
+   error = -EAGAIN;
    if ((arg == F_RDLCK && (wrlease_count > 0)) ||
        (arg == F_WRLCK && ((rdlease_count + wrlease_count) > 0)))
       goto out;
@@ -1491,8 +1489,7 @@ EXPORT_SYMBOL_GPL(vfs_setlease);
 int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
 {
    struct file_lock fl, *flp = &fl;
-   struct dentry *dentry = filp->f_path.dentry;
-   struct inode *inode = dentry->d_inode;
+   struct inode *inode = filp->f_path.dentry->d_inode;
    int error;
 
    locks_init_lock(&fl);
@@ -1750,6 +1747,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
    struct file_lock *file_lock = locks_alloc_lock();
    struct flock flock;
    struct inode *inode;
+   struct file *f;
    int error;
 
    if (file_lock == NULL)
@@ -1822,7 +1820,15 @@ again:
     * Attempt to detect a close/fcntl race and recover by
     * releasing the lock that was just acquired.
     */
-   if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) {
+   /*
+    * we need that spin_lock here - it prevents reordering between
+    * update of inode->i_flock and check for it done in close().
+    * rcu_read_lock() wouldn't do.
+    */
+   spin_lock(¤t->files->file_lock);
+   f = fcheck(fd);
+   spin_unlock(¤t->files->file_lock);
+   if (!error && f != filp && flock.l_type != F_UNLCK) {
       flock.l_type = F_UNLCK;
       goto again;
    }
@@ -1878,6 +1884,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
    struct file_lock *file_lock = locks_alloc_lock();
    struct flock64 flock;
    struct inode *inode;
+   struct file *f;
    int error;
 
    if (file_lock == NULL)
@@ -1950,7 +1957,10 @@ again:
     * Attempt to detect a close/fcntl race and recover by
     * releasing the lock that was just acquired.
     */
-   if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) {
+   spin_lock(¤t->files->file_lock);
+   f = fcheck(fd);
+   spin_unlock(¤t->files->file_lock);
+   if (!error && f != filp && flock.l_type != F_UNLCK) {
       flock.l_type = F_UNLCK;
       goto again;
    }


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.