]> err.no Git - linux-2.6/blobdiff - fs/locks.c
locks: give posix_test_lock same interface as ->lock
[linux-2.6] / fs / locks.c
index 52a81005dab4b8878bba2a3f1586bc346890cc5b..749a0dc7cd4b674cdd974ec8ee02e271923d5401 100644 (file)
@@ -666,11 +666,11 @@ static int locks_block_on_timeout(struct file_lock *blocker, struct file_lock *w
 }
 
 int
-posix_test_lock(struct file *filp, struct file_lock *fl,
-               struct file_lock *conflock)
+posix_test_lock(struct file *filp, struct file_lock *fl)
 {
        struct file_lock *cfl;
 
+       fl->fl_type = F_UNLCK;
        lock_kernel();
        for (cfl = filp->f_path.dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) {
                if (!IS_POSIX(cfl))
@@ -679,7 +679,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl,
                        break;
        }
        if (cfl) {
-               __locks_copy_lock(conflock, cfl);
+               __locks_copy_lock(fl, cfl);
                unlock_kernel();
                return 1;
        }
@@ -1611,12 +1611,44 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
        return error;
 }
 
+static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
+{
+       flock->l_pid = fl->fl_pid;
+#if BITS_PER_LONG == 32
+       /*
+        * Make sure we can represent the posix lock via
+        * legacy 32bit flock.
+        */
+       if (fl->fl_start > OFFT_OFFSET_MAX)
+               return -EOVERFLOW;
+       if (fl->fl_end != OFFSET_MAX && fl->fl_end > OFFT_OFFSET_MAX)
+               return -EOVERFLOW;
+#endif
+       flock->l_start = fl->fl_start;
+       flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
+               fl->fl_end - fl->fl_start + 1;
+       flock->l_whence = 0;
+       return 0;
+}
+
+#if BITS_PER_LONG == 32
+static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
+{
+       flock->l_pid = fl->fl_pid;
+       flock->l_start = fl->fl_start;
+       flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
+               fl->fl_end - fl->fl_start + 1;
+       flock->l_whence = 0;
+       flock->l_type = fl->fl_type;
+}
+#endif
+
 /* Report the first existing lock that would conflict with l.
  * This implements the F_GETLK command of fcntl().
  */
 int fcntl_getlk(struct file *filp, struct flock __user *l)
 {
-       struct file_lock *fl, cfl, file_lock;
+       struct file_lock file_lock;
        struct flock flock;
        int error;
 
@@ -1633,36 +1665,16 @@ int fcntl_getlk(struct file *filp, struct flock __user *l)
 
        if (filp->f_op && filp->f_op->lock) {
                error = filp->f_op->lock(filp, F_GETLK, &file_lock);
-               if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
-                       file_lock.fl_ops->fl_release_private(&file_lock);
                if (error < 0)
                        goto out;
-               else
-                 fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
-       } else {
-               fl = (posix_test_lock(filp, &file_lock, &cfl) ? &cfl : NULL);
-       }
+       } else
+               posix_test_lock(filp, &file_lock);
  
-       flock.l_type = F_UNLCK;
-       if (fl != NULL) {
-               flock.l_pid = fl->fl_pid;
-#if BITS_PER_LONG == 32
-               /*
-                * Make sure we can represent the posix lock via
-                * legacy 32bit flock.
-                */
-               error = -EOVERFLOW;
-               if (fl->fl_start > OFFT_OFFSET_MAX)
-                       goto out;
-               if ((fl->fl_end != OFFSET_MAX)
-                   && (fl->fl_end > OFFT_OFFSET_MAX))
+       flock.l_type = file_lock.fl_type;
+       if (file_lock.fl_type != F_UNLCK) {
+               error = posix_lock_to_flock(&flock, &file_lock);
+               if (error)
                        goto out;
-#endif
-               flock.l_start = fl->fl_start;
-               flock.l_len = fl->fl_end == OFFSET_MAX ? 0 :
-                       fl->fl_end - fl->fl_start + 1;
-               flock.l_whence = 0;
-               flock.l_type = fl->fl_type;
        }
        error = -EFAULT;
        if (!copy_to_user(l, &flock, sizeof(flock)))
@@ -1738,7 +1750,7 @@ again:
        else {
                for (;;) {
                        error = posix_lock_file(filp, file_lock);
-                       if ((error != -EAGAIN) || (cmd == F_SETLK))
+                       if (error != -EAGAIN || cmd == F_SETLK)
                                break;
                        error = wait_event_interruptible(file_lock->fl_wait,
                                        !file_lock->fl_next);
@@ -1770,7 +1782,7 @@ out:
  */
 int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
 {
-       struct file_lock *fl, cfl, file_lock;
+       struct file_lock file_lock;
        struct flock64 flock;
        int error;
 
@@ -1787,25 +1799,15 @@ int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
 
        if (filp->f_op && filp->f_op->lock) {
                error = filp->f_op->lock(filp, F_GETLK, &file_lock);
-               if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
-                       file_lock.fl_ops->fl_release_private(&file_lock);
                if (error < 0)
                        goto out;
-               else
-                 fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
-       } else {
-               fl = (posix_test_lock(filp, &file_lock, &cfl) ? &cfl : NULL);
-       }
+       } else
+               posix_test_lock(filp, &file_lock);
  
-       flock.l_type = F_UNLCK;
-       if (fl != NULL) {
-               flock.l_pid = fl->fl_pid;
-               flock.l_start = fl->fl_start;
-               flock.l_len = fl->fl_end == OFFSET_MAX ? 0 :
-                       fl->fl_end - fl->fl_start + 1;
-               flock.l_whence = 0;
-               flock.l_type = fl->fl_type;
-       }
+       flock.l_type = file_lock.fl_type;
+       if (file_lock.fl_type != F_UNLCK)
+               posix_lock_to_flock64(&flock, &file_lock);
+
        error = -EFAULT;
        if (!copy_to_user(l, &flock, sizeof(flock)))
                error = 0;
@@ -1881,7 +1883,7 @@ again:
        else {
                for (;;) {
                        error = posix_lock_file(filp, file_lock);
-                       if ((error != -EAGAIN) || (cmd == F_SETLK64))
+                       if (error != -EAGAIN || cmd == F_SETLK64)
                                break;
                        error = wait_event_interruptible(file_lock->fl_wait,
                                        !file_lock->fl_next);