locks: make ->lock release private data before returning in GETLK case
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / locks.c
index d7c53392cac12cf5b907d0122e1e504ca7a26f0e..b07e6e6f819b62e2d944f800046591cd00acd928 100644 (file)
@@ -142,12 +142,12 @@ int lease_break_time = 45;
 static LIST_HEAD(file_lock_list);
 static LIST_HEAD(blocked_list);
 
-static kmem_cache_t *filelock_cache __read_mostly;
+static struct kmem_cache *filelock_cache __read_mostly;
 
 /* Allocate an empty lock structure. */
 static struct file_lock *locks_alloc_lock(void)
 {
-       return kmem_cache_alloc(filelock_cache, SLAB_KERNEL);
+       return kmem_cache_alloc(filelock_cache, GFP_KERNEL);
 }
 
 static void locks_release_private(struct file_lock *fl)
@@ -199,7 +199,7 @@ EXPORT_SYMBOL(locks_init_lock);
  * Initialises the fields of the file lock which are invariant for
  * free file_locks.
  */
-static void init_once(void *foo, kmem_cache_t *cache, unsigned long flags)
+static void init_once(void *foo, struct kmem_cache *cache, unsigned long flags)
 {
        struct file_lock *lock = (struct file_lock *) foo;
 
@@ -314,14 +314,14 @@ static int flock_to_posix_lock(struct file *filp, struct file_lock *fl,
        off_t start, end;
 
        switch (l->l_whence) {
-       case 0: /*SEEK_SET*/
+       case SEEK_SET:
                start = 0;
                break;
-       case 1: /*SEEK_CUR*/
+       case SEEK_CUR:
                start = filp->f_pos;
                break;
-       case 2: /*SEEK_END*/
-               start = i_size_read(filp->f_dentry->d_inode);
+       case SEEK_END:
+               start = i_size_read(filp->f_path.dentry->d_inode);
                break;
        default:
                return -EINVAL;
@@ -364,14 +364,14 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
        loff_t start;
 
        switch (l->l_whence) {
-       case 0: /*SEEK_SET*/
+       case SEEK_SET:
                start = 0;
                break;
-       case 1: /*SEEK_CUR*/
+       case SEEK_CUR:
                start = filp->f_pos;
                break;
-       case 2: /*SEEK_END*/
-               start = i_size_read(filp->f_dentry->d_inode);
+       case SEEK_END:
+               start = i_size_read(filp->f_path.dentry->d_inode);
                break;
        default:
                return -EINVAL;
@@ -672,7 +672,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl,
        struct file_lock *cfl;
 
        lock_kernel();
-       for (cfl = filp->f_dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) {
+       for (cfl = filp->f_path.dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) {
                if (!IS_POSIX(cfl))
                        continue;
                if (posix_locks_conflict(cfl, fl))
@@ -734,7 +734,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
 {
        struct file_lock *new_fl = NULL;
        struct file_lock **before;
-       struct inode * inode = filp->f_dentry->d_inode;
+       struct inode * inode = filp->f_path.dentry->d_inode;
        int error = 0;
        int found = 0;
 
@@ -1018,7 +1018,7 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
  */
 int posix_lock_file(struct file *filp, struct file_lock *fl)
 {
-       return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, NULL);
+       return __posix_lock_file_conf(filp->f_path.dentry->d_inode, fl, NULL);
 }
 EXPORT_SYMBOL(posix_lock_file);
 
@@ -1033,7 +1033,7 @@ EXPORT_SYMBOL(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);
+       return __posix_lock_file_conf(filp->f_path.dentry->d_inode, fl, conflock);
 }
 EXPORT_SYMBOL(posix_lock_file_conf);
 
@@ -1333,8 +1333,8 @@ int fcntl_getlease(struct file *filp)
        int type = F_UNLCK;
 
        lock_kernel();
-       time_out_leases(filp->f_dentry->d_inode);
-       for (fl = filp->f_dentry->d_inode->i_flock; fl && IS_LEASE(fl);
+       time_out_leases(filp->f_path.dentry->d_inode);
+       for (fl = filp->f_path.dentry->d_inode->i_flock; fl && IS_LEASE(fl);
                        fl = fl->fl_next) {
                if (fl->fl_file == filp) {
                        type = fl->fl_type & ~F_INPROGRESS;
@@ -1359,7 +1359,7 @@ int fcntl_getlease(struct file *filp)
 static int __setlease(struct file *filp, long arg, struct file_lock **flp)
 {
        struct file_lock *fl, **before, **my_before = NULL, *lease;
-       struct dentry *dentry = filp->f_dentry;
+       struct dentry *dentry = filp->f_path.dentry;
        struct inode *inode = dentry->d_inode;
        int error, rdlease_count = 0, wrlease_count = 0;
 
@@ -1448,7 +1448,7 @@ out:
 
 int setlease(struct file *filp, long arg, struct file_lock **lease)
 {
-       struct dentry *dentry = filp->f_dentry;
+       struct dentry *dentry = filp->f_path.dentry;
        struct inode *inode = dentry->d_inode;
        int error;
 
@@ -1482,7 +1482,7 @@ EXPORT_SYMBOL(setlease);
 int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
 {
        struct file_lock fl, *flp = &fl;
-       struct dentry *dentry = filp->f_dentry;
+       struct dentry *dentry = filp->f_path.dentry;
        struct inode *inode = dentry->d_inode;
        int error;
 
@@ -1514,7 +1514,7 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
                goto out_unlock;
        }
 
-       error = f_setown(filp, current->pid, 0);
+       error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
 out_unlock:
        unlock_kernel();
        return error;
@@ -1611,6 +1611,38 @@ 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().
  */
@@ -1633,8 +1665,6 @@ 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
@@ -1645,24 +1675,9 @@ int fcntl_getlk(struct file *filp, struct flock __user *l)
  
        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))
+               error = posix_lock_to_flock(&flock, fl);
+               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)))
@@ -1692,7 +1707,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
        if (copy_from_user(&flock, l, sizeof(flock)))
                goto out;
 
-       inode = filp->f_dentry->d_inode;
+       inode = filp->f_path.dentry->d_inode;
 
        /* Don't allow mandatory locks on files that may be memory mapped
         * and shared.
@@ -1738,7 +1753,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);
@@ -1787,8 +1802,6 @@ 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
@@ -1798,14 +1811,8 @@ int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
        }
  
        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;
-       }
+       if (fl != NULL)
+               posix_lock_to_flock64(&flock, fl);
        error = -EFAULT;
        if (!copy_to_user(l, &flock, sizeof(flock)))
                error = 0;
@@ -1835,7 +1842,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
        if (copy_from_user(&flock, l, sizeof(flock)))
                goto out;
 
-       inode = filp->f_dentry->d_inode;
+       inode = filp->f_path.dentry->d_inode;
 
        /* Don't allow mandatory locks on files that may be memory mapped
         * and shared.
@@ -1881,7 +1888,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);
@@ -1922,7 +1929,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
         * posix_lock_file().  Another process could be setting a lock on this
         * file at the same time, but we wouldn't remove that lock anyway.
         */
-       if (!filp->f_dentry->d_inode->i_flock)
+       if (!filp->f_path.dentry->d_inode->i_flock)
                return;
 
        lock.fl_type = F_UNLCK;
@@ -1951,7 +1958,7 @@ EXPORT_SYMBOL(locks_remove_posix);
  */
 void locks_remove_flock(struct file *filp)
 {
-       struct inode * inode = filp->f_dentry->d_inode; 
+       struct inode * inode = filp->f_path.dentry->d_inode;
        struct file_lock *fl;
        struct file_lock **before;
 
@@ -2020,7 +2027,7 @@ static void lock_get_status(char* out, struct file_lock *fl, int id, char *pfx)
        struct inode *inode = NULL;
 
        if (fl->fl_file != NULL)
-               inode = fl->fl_file->f_dentry->d_inode;
+               inode = fl->fl_file->f_path.dentry->d_inode;
 
        out += sprintf(out, "%d:%s ", id, pfx);
        if (IS_POSIX(fl)) {