diff options
Diffstat (limited to 'fs/locks.c')
-rw-r--r-- | fs/locks.c | 61 |
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 | ||
1614 | static 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 | ||
1635 | static 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; |