]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/locks.c
[SCSI] lpfc 8.1.2: Change version number to 8.1.2
[linux-2.6-omap-h63xx.git] / fs / locks.c
index 7eb1d77b9204deccce359d4b2f9f1e9ffcb954ab..909eab8fb1d09ba157f578a4817fefb7d0937c36 100644 (file)
@@ -154,7 +154,7 @@ static struct file_lock *locks_alloc_lock(void)
 }
 
 /* Free a lock which is not in use. */
-static inline void locks_free_lock(struct file_lock *fl)
+static void locks_free_lock(struct file_lock *fl)
 {
        if (fl == NULL) {
                BUG();
@@ -316,21 +316,22 @@ static int flock_to_posix_lock(struct file *filp, struct file_lock *fl,
        /* POSIX-1996 leaves the case l->l_len < 0 undefined;
           POSIX-2001 defines it. */
        start += l->l_start;
-       end = start + l->l_len - 1;
-       if (l->l_len < 0) {
+       if (start < 0)
+               return -EINVAL;
+       fl->fl_end = OFFSET_MAX;
+       if (l->l_len > 0) {
+               end = start + l->l_len - 1;
+               fl->fl_end = end;
+       } else if (l->l_len < 0) {
                end = start - 1;
+               fl->fl_end = end;
                start += l->l_len;
+               if (start < 0)
+                       return -EINVAL;
        }
-
-       if (start < 0)
-               return -EINVAL;
-       if (l->l_len > 0 && end < 0)
-               return -EOVERFLOW;
-
        fl->fl_start = start;   /* we record the absolute position */
-       fl->fl_end = end;
-       if (l->l_len == 0)
-               fl->fl_end = OFFSET_MAX;
+       if (fl->fl_end < fl->fl_start)
+               return -EOVERFLOW;
        
        fl->fl_owner = current->files;
        fl->fl_pid = current->tgid;
@@ -362,14 +363,21 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
                return -EINVAL;
        }
 
-       if (((start += l->l_start) < 0) || (l->l_len < 0))
+       start += l->l_start;
+       if (start < 0)
                return -EINVAL;
-       fl->fl_end = start + l->l_len - 1;
-       if (l->l_len > 0 && fl->fl_end < 0)
-               return -EOVERFLOW;
+       fl->fl_end = OFFSET_MAX;
+       if (l->l_len > 0) {
+               fl->fl_end = start + l->l_len - 1;
+       } else if (l->l_len < 0) {
+               fl->fl_end = start - 1;
+               start += l->l_len;
+               if (start < 0)
+                       return -EINVAL;
+       }
        fl->fl_start = start;   /* we record the absolute position */
-       if (l->l_len == 0)
-               fl->fl_end = OFFSET_MAX;
+       if (fl->fl_end < fl->fl_start)
+               return -EOVERFLOW;
        
        fl->fl_owner = current->files;
        fl->fl_pid = current->tgid;
@@ -467,8 +475,7 @@ static inline int locks_overlap(struct file_lock *fl1, struct file_lock *fl2)
 /*
  * Check whether two locks have the same owner.
  */
-static inline int
-posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
+static int posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
 {
        if (fl1->fl_lmops && fl1->fl_lmops->fl_compare_owner)
                return fl2->fl_lmops == fl1->fl_lmops &&
@@ -479,7 +486,7 @@ posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
 /* Remove waiter from blocker's block list.
  * When blocker ends up pointing to itself then the list is empty.
  */
-static inline void __locks_delete_block(struct file_lock *waiter)
+static void __locks_delete_block(struct file_lock *waiter)
 {
        list_del_init(&waiter->fl_block);
        list_del_init(&waiter->fl_link);
@@ -1097,7 +1104,6 @@ static void time_out_leases(struct inode *inode)
                        before = &fl->fl_next;
                        continue;
                }
-               printk(KERN_INFO "lease broken - owner pid = %d\n", fl->fl_pid);
                lease_modify(before, fl->fl_type & ~F_INPROGRESS);
                if (fl == *before)      /* lease_modify may have freed fl */
                        before = &fl->fl_next;
@@ -1422,7 +1428,7 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
        lock_kernel();
 
        error = __setlease(filp, arg, &flp);
-       if (error)
+       if (error || arg == F_UNLCK)
                goto out_unlock;
 
        error = fasync_helper(fd, filp, 1, &flp->fl_fasync);
@@ -1951,22 +1957,18 @@ EXPORT_SYMBOL(posix_block_lock);
  *
  *     lockd needs to block waiting for locks.
  */
-void
+int
 posix_unblock_lock(struct file *filp, struct file_lock *waiter)
 {
-       /* 
-        * A remote machine may cancel the lock request after it's been
-        * granted locally.  If that happens, we need to delete the lock.
-        */
+       int status = 0;
+
        lock_kernel();
-       if (waiter->fl_next) {
+       if (waiter->fl_next)
                __locks_delete_block(waiter);
-               unlock_kernel();
-       } else {
-               unlock_kernel();
-               waiter->fl_type = F_UNLCK;
-               posix_lock_file(filp, waiter);
-       }
+       else
+               status = -ENOENT;
+       unlock_kernel();
+       return status;
 }
 
 EXPORT_SYMBOL(posix_unblock_lock);