aboutsummaryrefslogtreecommitdiffstats
path: root/fs/locks.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/locks.c')
-rw-r--r--fs/locks.c61
1 files changed, 36 insertions, 25 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 1a00b8bc65ed..957775ba6468 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1611,6 +1611,38 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
1611 return error; 1611 return error;
1612} 1612}
1613 1613
1614static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
1615{
1616 flock->l_pid = fl->fl_pid;
1617#if BITS_PER_LONG == 32
1618 /*
1619 * Make sure we can represent the posix lock via
1620 * legacy 32bit flock.
1621 */
1622 if (fl->fl_start > OFFT_OFFSET_MAX)
1623 return -EOVERFLOW;
1624 if (fl->fl_end != OFFSET_MAX && fl->fl_end > OFFT_OFFSET_MAX)
1625 return -EOVERFLOW;
1626#endif
1627 flock->l_start = fl->fl_start;
1628 flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
1629 fl->fl_end - fl->fl_start + 1;
1630 flock->l_whence = 0;
1631 return 0;
1632}
1633
1634#if BITS_PER_LONG == 32
1635static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
1636{
1637 flock->l_pid = fl->fl_pid;
1638 flock->l_start = fl->fl_start;
1639 flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
1640 fl->fl_end - fl->fl_start + 1;
1641 flock->l_whence = 0;
1642 flock->l_type = fl->fl_type;
1643}
1644#endif
1645
1614/* Report the first existing lock that would conflict with l. 1646/* Report the first existing lock that would conflict with l.
1615 * This implements the F_GETLK command of fcntl(). 1647 * This implements the F_GETLK command of fcntl().
1616 */ 1648 */
@@ -1645,24 +1677,9 @@ int fcntl_getlk(struct file *filp, struct flock __user *l)
1645 1677
1646 flock.l_type = F_UNLCK; 1678 flock.l_type = F_UNLCK;
1647 if (fl != NULL) { 1679 if (fl != NULL) {
1648 flock.l_pid = fl->fl_pid; 1680 error = posix_lock_to_flock(&flock, fl);
1649#if BITS_PER_LONG == 32 1681 if (error)
1650 /*
1651 * Make sure we can represent the posix lock via
1652 * legacy 32bit flock.
1653 */
1654 error = -EOVERFLOW;
1655 if (fl->fl_start > OFFT_OFFSET_MAX)
1656 goto out;
1657 if ((fl->fl_end != OFFSET_MAX)
1658 && (fl->fl_end > OFFT_OFFSET_MAX))
1659 goto out; 1682 goto out;
1660#endif
1661 flock.l_start = fl->fl_start;
1662 flock.l_len = fl->fl_end == OFFSET_MAX ? 0 :
1663 fl->fl_end - fl->fl_start + 1;
1664 flock.l_whence = 0;
1665 flock.l_type = fl->fl_type;
1666 } 1683 }
1667 error = -EFAULT; 1684 error = -EFAULT;
1668 if (!copy_to_user(l, &flock, sizeof(flock))) 1685 if (!copy_to_user(l, &flock, sizeof(flock)))
@@ -1798,14 +1815,8 @@ int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
1798 } 1815 }
1799 1816
1800 flock.l_type = F_UNLCK; 1817 flock.l_type = F_UNLCK;
1801 if (fl != NULL) { 1818 if (fl != NULL)
1802 flock.l_pid = fl->fl_pid; 1819 posix_lock_to_flock64(&flock, fl);
1803 flock.l_start = fl->fl_start;
1804 flock.l_len = fl->fl_end == OFFSET_MAX ? 0 :
1805 fl->fl_end - fl->fl_start + 1;
1806 flock.l_whence = 0;
1807 flock.l_type = fl->fl_type;
1808 }
1809 error = -EFAULT; 1820 error = -EFAULT;
1810 if (!copy_to_user(l, &flock, sizeof(flock))) 1821 if (!copy_to_user(l, &flock, sizeof(flock)))
1811 error = 0; 1822 error = 0;