diff options
author | David Howells <dhowells@redhat.com> | 2007-07-16 02:40:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-16 12:05:43 -0400 |
commit | e8d6c554126b830217c5e9f549e0e21f865a0a8a (patch) | |
tree | c43219c6ef4e6a9b4f0ac46d6bd8b675dc249a8b /fs/afs/fsclient.c | |
parent | b0fed3140f57c435d2783b698c5090f325c22bad (diff) |
AFS: implement file locking
Implement file locking for AFS.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/afs/fsclient.c')
-rw-r--r-- | fs/afs/fsclient.c | 155 |
1 files changed, 154 insertions, 1 deletions
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index 5dff1308b6f0..023b95b0d9d7 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c | |||
@@ -67,7 +67,7 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp, | |||
67 | EXTRACT(status->group); | 67 | EXTRACT(status->group); |
68 | bp++; /* sync counter */ | 68 | bp++; /* sync counter */ |
69 | data_version |= (u64) ntohl(*bp++) << 32; | 69 | data_version |= (u64) ntohl(*bp++) << 32; |
70 | bp++; /* lock count */ | 70 | EXTRACT(status->lock_count); |
71 | size |= (u64) ntohl(*bp++) << 32; | 71 | size |= (u64) ntohl(*bp++) << 32; |
72 | bp++; /* spare 4 */ | 72 | bp++; /* spare 4 */ |
73 | *_bp = bp; | 73 | *_bp = bp; |
@@ -1748,3 +1748,156 @@ int afs_fs_get_volume_status(struct afs_server *server, | |||
1748 | 1748 | ||
1749 | return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode); | 1749 | return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode); |
1750 | } | 1750 | } |
1751 | |||
1752 | /* | ||
1753 | * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock | ||
1754 | */ | ||
1755 | static int afs_deliver_fs_xxxx_lock(struct afs_call *call, | ||
1756 | struct sk_buff *skb, bool last) | ||
1757 | { | ||
1758 | const __be32 *bp; | ||
1759 | |||
1760 | _enter("{%u},{%u},%d", call->unmarshall, skb->len, last); | ||
1761 | |||
1762 | afs_transfer_reply(call, skb); | ||
1763 | if (!last) | ||
1764 | return 0; | ||
1765 | |||
1766 | if (call->reply_size != call->reply_max) | ||
1767 | return -EBADMSG; | ||
1768 | |||
1769 | /* unmarshall the reply once we've received all of it */ | ||
1770 | bp = call->buffer; | ||
1771 | /* xdr_decode_AFSVolSync(&bp, call->replyX); */ | ||
1772 | |||
1773 | _leave(" = 0 [done]"); | ||
1774 | return 0; | ||
1775 | } | ||
1776 | |||
1777 | /* | ||
1778 | * FS.SetLock operation type | ||
1779 | */ | ||
1780 | static const struct afs_call_type afs_RXFSSetLock = { | ||
1781 | .name = "FS.SetLock", | ||
1782 | .deliver = afs_deliver_fs_xxxx_lock, | ||
1783 | .abort_to_error = afs_abort_to_error, | ||
1784 | .destructor = afs_flat_call_destructor, | ||
1785 | }; | ||
1786 | |||
1787 | /* | ||
1788 | * FS.ExtendLock operation type | ||
1789 | */ | ||
1790 | static const struct afs_call_type afs_RXFSExtendLock = { | ||
1791 | .name = "FS.ExtendLock", | ||
1792 | .deliver = afs_deliver_fs_xxxx_lock, | ||
1793 | .abort_to_error = afs_abort_to_error, | ||
1794 | .destructor = afs_flat_call_destructor, | ||
1795 | }; | ||
1796 | |||
1797 | /* | ||
1798 | * FS.ReleaseLock operation type | ||
1799 | */ | ||
1800 | static const struct afs_call_type afs_RXFSReleaseLock = { | ||
1801 | .name = "FS.ReleaseLock", | ||
1802 | .deliver = afs_deliver_fs_xxxx_lock, | ||
1803 | .abort_to_error = afs_abort_to_error, | ||
1804 | .destructor = afs_flat_call_destructor, | ||
1805 | }; | ||
1806 | |||
1807 | /* | ||
1808 | * get a lock on a file | ||
1809 | */ | ||
1810 | int afs_fs_set_lock(struct afs_server *server, | ||
1811 | struct key *key, | ||
1812 | struct afs_vnode *vnode, | ||
1813 | afs_lock_type_t type, | ||
1814 | const struct afs_wait_mode *wait_mode) | ||
1815 | { | ||
1816 | struct afs_call *call; | ||
1817 | __be32 *bp; | ||
1818 | |||
1819 | _enter(""); | ||
1820 | |||
1821 | call = afs_alloc_flat_call(&afs_RXFSSetLock, 5 * 4, 6 * 4); | ||
1822 | if (!call) | ||
1823 | return -ENOMEM; | ||
1824 | |||
1825 | call->key = key; | ||
1826 | call->reply = vnode; | ||
1827 | call->service_id = FS_SERVICE; | ||
1828 | call->port = htons(AFS_FS_PORT); | ||
1829 | |||
1830 | /* marshall the parameters */ | ||
1831 | bp = call->request; | ||
1832 | *bp++ = htonl(FSSETLOCK); | ||
1833 | *bp++ = htonl(vnode->fid.vid); | ||
1834 | *bp++ = htonl(vnode->fid.vnode); | ||
1835 | *bp++ = htonl(vnode->fid.unique); | ||
1836 | *bp++ = htonl(type); | ||
1837 | |||
1838 | return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode); | ||
1839 | } | ||
1840 | |||
1841 | /* | ||
1842 | * extend a lock on a file | ||
1843 | */ | ||
1844 | int afs_fs_extend_lock(struct afs_server *server, | ||
1845 | struct key *key, | ||
1846 | struct afs_vnode *vnode, | ||
1847 | const struct afs_wait_mode *wait_mode) | ||
1848 | { | ||
1849 | struct afs_call *call; | ||
1850 | __be32 *bp; | ||
1851 | |||
1852 | _enter(""); | ||
1853 | |||
1854 | call = afs_alloc_flat_call(&afs_RXFSExtendLock, 4 * 4, 6 * 4); | ||
1855 | if (!call) | ||
1856 | return -ENOMEM; | ||
1857 | |||
1858 | call->key = key; | ||
1859 | call->reply = vnode; | ||
1860 | call->service_id = FS_SERVICE; | ||
1861 | call->port = htons(AFS_FS_PORT); | ||
1862 | |||
1863 | /* marshall the parameters */ | ||
1864 | bp = call->request; | ||
1865 | *bp++ = htonl(FSEXTENDLOCK); | ||
1866 | *bp++ = htonl(vnode->fid.vid); | ||
1867 | *bp++ = htonl(vnode->fid.vnode); | ||
1868 | *bp++ = htonl(vnode->fid.unique); | ||
1869 | |||
1870 | return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode); | ||
1871 | } | ||
1872 | |||
1873 | /* | ||
1874 | * release a lock on a file | ||
1875 | */ | ||
1876 | int afs_fs_release_lock(struct afs_server *server, | ||
1877 | struct key *key, | ||
1878 | struct afs_vnode *vnode, | ||
1879 | const struct afs_wait_mode *wait_mode) | ||
1880 | { | ||
1881 | struct afs_call *call; | ||
1882 | __be32 *bp; | ||
1883 | |||
1884 | _enter(""); | ||
1885 | |||
1886 | call = afs_alloc_flat_call(&afs_RXFSReleaseLock, 4 * 4, 6 * 4); | ||
1887 | if (!call) | ||
1888 | return -ENOMEM; | ||
1889 | |||
1890 | call->key = key; | ||
1891 | call->reply = vnode; | ||
1892 | call->service_id = FS_SERVICE; | ||
1893 | call->port = htons(AFS_FS_PORT); | ||
1894 | |||
1895 | /* marshall the parameters */ | ||
1896 | bp = call->request; | ||
1897 | *bp++ = htonl(FSRELEASELOCK); | ||
1898 | *bp++ = htonl(vnode->fid.vid); | ||
1899 | *bp++ = htonl(vnode->fid.vnode); | ||
1900 | *bp++ = htonl(vnode->fid.unique); | ||
1901 | |||
1902 | return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode); | ||
1903 | } | ||