]> err.no Git - linux-2.6/blobdiff - fs/locks.c
[PATCH] RTC subsystem: RS5C372 driver
[linux-2.6] / fs / locks.c
index 231b23c12c3d685b861697bb2cd1720ec631bc51..4d9e71d43e7e2068eeef0859e20c8909d026ccc8 100644 (file)
@@ -139,13 +139,10 @@ int lease_break_time = 45;
 #define for_each_lock(inode, lockp) \
        for (lockp = &inode->i_flock; *lockp != NULL; lockp = &(*lockp)->fl_next)
 
-LIST_HEAD(file_lock_list);
-
-EXPORT_SYMBOL(file_lock_list);
-
+static LIST_HEAD(file_lock_list);
 static LIST_HEAD(blocked_list);
 
-static kmem_cache_t *filelock_cache;
+static kmem_cache_t *filelock_cache __read_mostly;
 
 /* Allocate an empty lock structure. */
 static struct file_lock *locks_alloc_lock(void)
@@ -239,17 +236,25 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)
 /*
  * Initialize a new lock from an existing file_lock structure.
  */
-void locks_copy_lock(struct file_lock *new, struct file_lock *fl)
+static void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl)
 {
-       locks_release_private(new);
-
        new->fl_owner = fl->fl_owner;
        new->fl_pid = fl->fl_pid;
-       new->fl_file = fl->fl_file;
+       new->fl_file = NULL;
        new->fl_flags = fl->fl_flags;
        new->fl_type = fl->fl_type;
        new->fl_start = fl->fl_start;
        new->fl_end = fl->fl_end;
+       new->fl_ops = NULL;
+       new->fl_lmops = NULL;
+}
+
+void locks_copy_lock(struct file_lock *new, struct file_lock *fl)
+{
+       locks_release_private(new);
+
+       __locks_copy_lock(new, fl);
+       new->fl_file = fl->fl_file;
        new->fl_ops = fl->fl_ops;
        new->fl_lmops = fl->fl_lmops;
 
@@ -528,12 +533,7 @@ static void locks_delete_block(struct file_lock *waiter)
 static void locks_insert_block(struct file_lock *blocker, 
                               struct file_lock *waiter)
 {
-       if (!list_empty(&waiter->fl_block)) {
-               printk(KERN_ERR "locks_insert_block: removing duplicated lock "
-                       "(pid=%d %Ld-%Ld type=%d)\n", waiter->fl_pid,
-                       waiter->fl_start, waiter->fl_end, waiter->fl_type);
-               __locks_delete_block(waiter);
-       }
+       BUG_ON(!list_empty(&waiter->fl_block));
        list_add_tail(&waiter->fl_block, &blocker->fl_block);
        waiter->fl_next = blocker;
        if (IS_POSIX(blocker))
@@ -686,7 +686,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl,
                        break;
        }
        if (cfl) {
-               locks_copy_lock(conflock, cfl);
+               __locks_copy_lock(conflock, cfl);
                unlock_kernel();
                return 1;
        }
@@ -792,9 +792,7 @@ out:
        return error;
 }
 
-EXPORT_SYMBOL(posix_lock_file);
-
-static int __posix_lock_file(struct inode *inode, struct file_lock *request)
+static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request, struct file_lock *conflock)
 {
        struct file_lock *fl;
        struct file_lock *new_fl, *new_fl2;
@@ -818,6 +816,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request)
                                continue;
                        if (!posix_locks_conflict(request, fl))
                                continue;
+                       if (conflock)
+                               locks_copy_lock(conflock, fl);
                        error = -EAGAIN;
                        if (!(request->fl_flags & FL_SLEEP))
                                goto out;
@@ -987,8 +987,24 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request)
  */
 int posix_lock_file(struct file *filp, struct file_lock *fl)
 {
-       return __posix_lock_file(filp->f_dentry->d_inode, fl);
+       return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, NULL);
+}
+EXPORT_SYMBOL(posix_lock_file);
+
+/**
+ * posix_lock_file_conf - Apply a POSIX-style lock to a file
+ * @filp: The file to apply the lock to
+ * @fl: The lock to be applied
+ * @conflock: Place to return a copy of the conflicting lock, if found.
+ *
+ * Except for the conflock parameter, acts just like posix_lock_file.
+ */
+int posix_lock_file_conf(struct file *filp, struct file_lock *fl,
+                       struct file_lock *conflock)
+{
+       return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, conflock);
 }
+EXPORT_SYMBOL(posix_lock_file_conf);
 
 /**
  * posix_lock_file_wait - Apply a POSIX-style lock to a file
@@ -1004,7 +1020,7 @@ int posix_lock_file_wait(struct file *filp, struct file_lock *fl)
        int error;
        might_sleep ();
        for (;;) {
-               error = __posix_lock_file(filp->f_dentry->d_inode, fl);
+               error = posix_lock_file(filp, fl);
                if ((error != -EAGAIN) || !(fl->fl_flags & FL_SLEEP))
                        break;
                error = wait_event_interruptible(fl->fl_wait, !fl->fl_next);
@@ -1076,7 +1092,7 @@ int locks_mandatory_area(int read_write, struct inode *inode,
        fl.fl_end = offset + count - 1;
 
        for (;;) {
-               error = __posix_lock_file(inode, &fl);
+               error = __posix_lock_file_conf(inode, &fl, NULL);
                if (error != -EAGAIN)
                        break;
                if (!(fl.fl_flags & FL_SLEEP))
@@ -1689,7 +1705,7 @@ again:
                error = filp->f_op->lock(filp, cmd, file_lock);
        else {
                for (;;) {
-                       error = __posix_lock_file(inode, file_lock);
+                       error = posix_lock_file(filp, file_lock);
                        if ((error != -EAGAIN) || (cmd == F_SETLK))
                                break;
                        error = wait_event_interruptible(file_lock->fl_wait,
@@ -1832,7 +1848,7 @@ again:
                error = filp->f_op->lock(filp, cmd, file_lock);
        else {
                for (;;) {
-                       error = __posix_lock_file(inode, file_lock);
+                       error = posix_lock_file(filp, file_lock);
                        if ((error != -EAGAIN) || (cmd == F_SETLK64))
                                break;
                        error = wait_event_interruptible(file_lock->fl_wait,