aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-10-19 19:57:58 -0400
committerDavid Howells <dhowells@redhat.com>2018-10-23 19:41:08 -0400
commit30062bd13e3659a309d249a06d5f4ebb4a5c5251 (patch)
tree151b4925fbf78d25f098fe54a1d2422a434ee780 /fs/afs
parentd4936803a92b7d088086b1d7b8ecb5739d52c03b (diff)
afs: Implement YFS support in the fs client
Implement support for talking to YFS-variant fileservers in the cache manager and the filesystem client. These implement upgraded services on the same port as their AFS services. YFS fileservers provide expanded capabilities over AFS. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs')
-rw-r--r--fs/afs/Makefile3
-rw-r--r--fs/afs/callback.c9
-rw-r--r--fs/afs/dir.c21
-rw-r--r--fs/afs/fsclient.c104
-rw-r--r--fs/afs/internal.h35
-rw-r--r--fs/afs/protocol_yfs.h106
-rw-r--r--fs/afs/server.c8
-rw-r--r--fs/afs/yfsclient.c2184
8 files changed, 2443 insertions, 27 deletions
diff --git a/fs/afs/Makefile b/fs/afs/Makefile
index 03e9f7afea1b..cc942b790cff 100644
--- a/fs/afs/Makefile
+++ b/fs/afs/Makefile
@@ -33,7 +33,8 @@ kafs-y := \
33 vl_list.o \ 33 vl_list.o \
34 volume.o \ 34 volume.o \
35 write.o \ 35 write.o \
36 xattr.o 36 xattr.o \
37 yfsclient.o
37 38
38kafs-$(CONFIG_PROC_FS) += proc.o 39kafs-$(CONFIG_PROC_FS) += proc.o
39obj-$(CONFIG_AFS_FS) := kafs.o 40obj-$(CONFIG_AFS_FS) := kafs.o
diff --git a/fs/afs/callback.c b/fs/afs/callback.c
index df9bfee698ad..1c7955f5cdaf 100644
--- a/fs/afs/callback.c
+++ b/fs/afs/callback.c
@@ -210,12 +210,10 @@ void afs_init_callback_state(struct afs_server *server)
210/* 210/*
211 * actually break a callback 211 * actually break a callback
212 */ 212 */
213void afs_break_callback(struct afs_vnode *vnode) 213void __afs_break_callback(struct afs_vnode *vnode)
214{ 214{
215 _enter(""); 215 _enter("");
216 216
217 write_seqlock(&vnode->cb_lock);
218
219 clear_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags); 217 clear_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
220 if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) { 218 if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
221 vnode->cb_break++; 219 vnode->cb_break++;
@@ -230,7 +228,12 @@ void afs_break_callback(struct afs_vnode *vnode)
230 afs_lock_may_be_available(vnode); 228 afs_lock_may_be_available(vnode);
231 spin_unlock(&vnode->lock); 229 spin_unlock(&vnode->lock);
232 } 230 }
231}
233 232
233void afs_break_callback(struct afs_vnode *vnode)
234{
235 write_seqlock(&vnode->cb_lock);
236 __afs_break_callback(vnode);
234 write_sequnlock(&vnode->cb_lock); 237 write_sequnlock(&vnode->cb_lock);
235} 238}
236 239
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index f2dd48d4363f..43dea3b00c29 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -1200,7 +1200,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
1200 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1200 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
1201 while (afs_select_fileserver(&fc)) { 1201 while (afs_select_fileserver(&fc)) {
1202 fc.cb_break = afs_calc_vnode_cb_break(dvnode); 1202 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
1203 afs_fs_remove(&fc, dentry->d_name.name, true, 1203 afs_fs_remove(&fc, vnode, dentry->d_name.name, true,
1204 data_version); 1204 data_version);
1205 } 1205 }
1206 1206
@@ -1245,7 +1245,9 @@ static int afs_dir_remove_link(struct dentry *dentry, struct key *key,
1245 if (d_really_is_positive(dentry)) { 1245 if (d_really_is_positive(dentry)) {
1246 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry)); 1246 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
1247 1247
1248 if (dir_valid) { 1248 if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
1249 /* Already done */
1250 } else if (dir_valid) {
1249 drop_nlink(&vnode->vfs_inode); 1251 drop_nlink(&vnode->vfs_inode);
1250 if (vnode->vfs_inode.i_nlink == 0) { 1252 if (vnode->vfs_inode.i_nlink == 0) {
1251 set_bit(AFS_VNODE_DELETED, &vnode->flags); 1253 set_bit(AFS_VNODE_DELETED, &vnode->flags);
@@ -1274,7 +1276,7 @@ static int afs_dir_remove_link(struct dentry *dentry, struct key *key,
1274static int afs_unlink(struct inode *dir, struct dentry *dentry) 1276static int afs_unlink(struct inode *dir, struct dentry *dentry)
1275{ 1277{
1276 struct afs_fs_cursor fc; 1278 struct afs_fs_cursor fc;
1277 struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode; 1279 struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL;
1278 struct key *key; 1280 struct key *key;
1279 unsigned long d_version = (unsigned long)dentry->d_fsdata; 1281 unsigned long d_version = (unsigned long)dentry->d_fsdata;
1280 u64 data_version = dvnode->status.data_version; 1282 u64 data_version = dvnode->status.data_version;
@@ -1304,7 +1306,18 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
1304 if (afs_begin_vnode_operation(&fc, dvnode, key)) { 1306 if (afs_begin_vnode_operation(&fc, dvnode, key)) {
1305 while (afs_select_fileserver(&fc)) { 1307 while (afs_select_fileserver(&fc)) {
1306 fc.cb_break = afs_calc_vnode_cb_break(dvnode); 1308 fc.cb_break = afs_calc_vnode_cb_break(dvnode);
1307 afs_fs_remove(&fc, dentry->d_name.name, false, 1309
1310 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc.cbi->server->flags) &&
1311 !test_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags)) {
1312 yfs_fs_remove_file2(&fc, vnode, dentry->d_name.name,
1313 data_version);
1314 if (fc.ac.error != -ECONNABORTED ||
1315 fc.ac.abort_code != RXGEN_OPCODE)
1316 continue;
1317 set_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags);
1318 }
1319
1320 afs_fs_remove(&fc, vnode, dentry->d_name.name, false,
1308 data_version); 1321 data_version);
1309 } 1322 }
1310 1323
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index 2da65309e0de..3975969719de 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -17,6 +17,7 @@
17#include "internal.h" 17#include "internal.h"
18#include "afs_fs.h" 18#include "afs_fs.h"
19#include "xdr_fs.h" 19#include "xdr_fs.h"
20#include "protocol_yfs.h"
20 21
21static const struct afs_fid afs_zero_fid; 22static const struct afs_fid afs_zero_fid;
22 23
@@ -312,14 +313,18 @@ static void xdr_decode_AFSVolSync(const __be32 **_bp,
312 struct afs_volsync *volsync) 313 struct afs_volsync *volsync)
313{ 314{
314 const __be32 *bp = *_bp; 315 const __be32 *bp = *_bp;
316 u32 creation;
315 317
316 volsync->creation = ntohl(*bp++); 318 creation = ntohl(*bp++);
317 bp++; /* spare2 */ 319 bp++; /* spare2 */
318 bp++; /* spare3 */ 320 bp++; /* spare3 */
319 bp++; /* spare4 */ 321 bp++; /* spare4 */
320 bp++; /* spare5 */ 322 bp++; /* spare5 */
321 bp++; /* spare6 */ 323 bp++; /* spare6 */
322 *_bp = bp; 324 *_bp = bp;
325
326 if (volsync)
327 volsync->creation = creation;
323} 328}
324 329
325/* 330/*
@@ -380,6 +385,8 @@ static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
380 vs->blocks_in_use = ntohl(*bp++); 385 vs->blocks_in_use = ntohl(*bp++);
381 vs->part_blocks_avail = ntohl(*bp++); 386 vs->part_blocks_avail = ntohl(*bp++);
382 vs->part_max_blocks = ntohl(*bp++); 387 vs->part_max_blocks = ntohl(*bp++);
388 vs->vol_copy_date = 0;
389 vs->vol_backup_date = 0;
383 *_bp = bp; 390 *_bp = bp;
384} 391}
385 392
@@ -405,8 +412,7 @@ static int afs_deliver_fs_fetch_status_vnode(struct afs_call *call)
405 if (ret < 0) 412 if (ret < 0)
406 return ret; 413 return ret;
407 xdr_decode_AFSCallBack(call, vnode, &bp); 414 xdr_decode_AFSCallBack(call, vnode, &bp);
408 if (call->reply[1]) 415 xdr_decode_AFSVolSync(&bp, call->reply[1]);
409 xdr_decode_AFSVolSync(&bp, call->reply[1]);
410 416
411 _leave(" = 0 [done]"); 417 _leave(" = 0 [done]");
412 return 0; 418 return 0;
@@ -433,6 +439,9 @@ int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsy
433 struct afs_net *net = afs_v2net(vnode); 439 struct afs_net *net = afs_v2net(vnode);
434 __be32 *bp; 440 __be32 *bp;
435 441
442 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
443 return yfs_fs_fetch_file_status(fc, volsync, new_inode);
444
436 _enter(",%x,{%llx:%llu},,", 445 _enter(",%x,{%llx:%llu},,",
437 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 446 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
438 447
@@ -567,8 +576,7 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
567 if (ret < 0) 576 if (ret < 0)
568 return ret; 577 return ret;
569 xdr_decode_AFSCallBack(call, vnode, &bp); 578 xdr_decode_AFSCallBack(call, vnode, &bp);
570 if (call->reply[1]) 579 xdr_decode_AFSVolSync(&bp, call->reply[1]);
571 xdr_decode_AFSVolSync(&bp, call->reply[1]);
572 580
573 call->unmarshall++; 581 call->unmarshall++;
574 582
@@ -665,6 +673,9 @@ int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
665 struct afs_net *net = afs_v2net(vnode); 673 struct afs_net *net = afs_v2net(vnode);
666 __be32 *bp; 674 __be32 *bp;
667 675
676 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
677 return yfs_fs_fetch_data(fc, req);
678
668 if (upper_32_bits(req->pos) || 679 if (upper_32_bits(req->pos) ||
669 upper_32_bits(req->len) || 680 upper_32_bits(req->len) ||
670 upper_32_bits(req->pos + req->len)) 681 upper_32_bits(req->pos + req->len))
@@ -765,6 +776,15 @@ int afs_fs_create(struct afs_fs_cursor *fc,
765 size_t namesz, reqsz, padsz; 776 size_t namesz, reqsz, padsz;
766 __be32 *bp; 777 __be32 *bp;
767 778
779 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)){
780 if (S_ISDIR(mode))
781 return yfs_fs_make_dir(fc, name, mode, current_data_version,
782 newfid, newstatus, newcb);
783 else
784 return yfs_fs_create_file(fc, name, mode, current_data_version,
785 newfid, newstatus, newcb);
786 }
787
768 _enter(""); 788 _enter("");
769 789
770 namesz = strlen(name); 790 namesz = strlen(name);
@@ -857,15 +877,18 @@ static const struct afs_call_type afs_RXFSRemoveDir = {
857/* 877/*
858 * remove a file or directory 878 * remove a file or directory
859 */ 879 */
860int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir, 880int afs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
861 u64 current_data_version) 881 const char *name, bool isdir, u64 current_data_version)
862{ 882{
863 struct afs_vnode *vnode = fc->vnode; 883 struct afs_vnode *dvnode = fc->vnode;
864 struct afs_call *call; 884 struct afs_call *call;
865 struct afs_net *net = afs_v2net(vnode); 885 struct afs_net *net = afs_v2net(dvnode);
866 size_t namesz, reqsz, padsz; 886 size_t namesz, reqsz, padsz;
867 __be32 *bp; 887 __be32 *bp;
868 888
889 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
890 return yfs_fs_remove(fc, vnode, name, isdir, current_data_version);
891
869 _enter(""); 892 _enter("");
870 893
871 namesz = strlen(name); 894 namesz = strlen(name);
@@ -879,15 +902,16 @@ int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir,
879 return -ENOMEM; 902 return -ENOMEM;
880 903
881 call->key = fc->key; 904 call->key = fc->key;
882 call->reply[0] = vnode; 905 call->reply[0] = dvnode;
906 call->reply[1] = vnode;
883 call->expected_version = current_data_version + 1; 907 call->expected_version = current_data_version + 1;
884 908
885 /* marshall the parameters */ 909 /* marshall the parameters */
886 bp = call->request; 910 bp = call->request;
887 *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE); 911 *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
888 *bp++ = htonl(vnode->fid.vid); 912 *bp++ = htonl(dvnode->fid.vid);
889 *bp++ = htonl(vnode->fid.vnode); 913 *bp++ = htonl(dvnode->fid.vnode);
890 *bp++ = htonl(vnode->fid.unique); 914 *bp++ = htonl(dvnode->fid.unique);
891 *bp++ = htonl(namesz); 915 *bp++ = htonl(namesz);
892 memcpy(bp, name, namesz); 916 memcpy(bp, name, namesz);
893 bp = (void *) bp + namesz; 917 bp = (void *) bp + namesz;
@@ -897,7 +921,7 @@ int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir,
897 } 921 }
898 922
899 afs_use_fs_server(call, fc->cbi); 923 afs_use_fs_server(call, fc->cbi);
900 trace_afs_make_fs_call(call, &vnode->fid); 924 trace_afs_make_fs_call(call, &dvnode->fid);
901 return afs_make_call(&fc->ac, call, GFP_NOFS, false); 925 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
902} 926}
903 927
@@ -953,6 +977,9 @@ int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
953 size_t namesz, reqsz, padsz; 977 size_t namesz, reqsz, padsz;
954 __be32 *bp; 978 __be32 *bp;
955 979
980 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
981 return yfs_fs_link(fc, vnode, name, current_data_version);
982
956 _enter(""); 983 _enter("");
957 984
958 namesz = strlen(name); 985 namesz = strlen(name);
@@ -1047,6 +1074,10 @@ int afs_fs_symlink(struct afs_fs_cursor *fc,
1047 size_t namesz, reqsz, padsz, c_namesz, c_padsz; 1074 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
1048 __be32 *bp; 1075 __be32 *bp;
1049 1076
1077 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1078 return yfs_fs_symlink(fc, name, contents, current_data_version,
1079 newfid, newstatus);
1080
1050 _enter(""); 1081 _enter("");
1051 1082
1052 namesz = strlen(name); 1083 namesz = strlen(name);
@@ -1159,6 +1190,12 @@ int afs_fs_rename(struct afs_fs_cursor *fc,
1159 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz; 1190 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1160 __be32 *bp; 1191 __be32 *bp;
1161 1192
1193 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1194 return yfs_fs_rename(fc, orig_name,
1195 new_dvnode, new_name,
1196 current_orig_data_version,
1197 current_new_data_version);
1198
1162 _enter(""); 1199 _enter("");
1163 1200
1164 o_namesz = strlen(orig_name); 1201 o_namesz = strlen(orig_name);
@@ -1329,6 +1366,9 @@ int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1329 loff_t size, pos, i_size; 1366 loff_t size, pos, i_size;
1330 __be32 *bp; 1367 __be32 *bp;
1331 1368
1369 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1370 return yfs_fs_store_data(fc, mapping, first, last, offset, to);
1371
1332 _enter(",%x,{%llx:%llu},,", 1372 _enter(",%x,{%llx:%llu},,",
1333 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode); 1373 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1334 1374
@@ -1544,6 +1584,9 @@ int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
1544 struct afs_net *net = afs_v2net(vnode); 1584 struct afs_net *net = afs_v2net(vnode);
1545 __be32 *bp; 1585 __be32 *bp;
1546 1586
1587 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1588 return yfs_fs_setattr(fc, attr);
1589
1547 if (attr->ia_valid & ATTR_SIZE) 1590 if (attr->ia_valid & ATTR_SIZE)
1548 return afs_fs_setattr_size(fc, attr); 1591 return afs_fs_setattr_size(fc, attr);
1549 1592
@@ -1728,6 +1771,9 @@ int afs_fs_get_volume_status(struct afs_fs_cursor *fc,
1728 __be32 *bp; 1771 __be32 *bp;
1729 void *tmpbuf; 1772 void *tmpbuf;
1730 1773
1774 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1775 return yfs_fs_get_volume_status(fc, vs);
1776
1731 _enter(""); 1777 _enter("");
1732 1778
1733 tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL); 1779 tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
@@ -1817,6 +1863,9 @@ int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
1817 struct afs_net *net = afs_v2net(vnode); 1863 struct afs_net *net = afs_v2net(vnode);
1818 __be32 *bp; 1864 __be32 *bp;
1819 1865
1866 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1867 return yfs_fs_set_lock(fc, type);
1868
1820 _enter(""); 1869 _enter("");
1821 1870
1822 call = afs_alloc_flat_call(net, &afs_RXFSSetLock, 5 * 4, 6 * 4); 1871 call = afs_alloc_flat_call(net, &afs_RXFSSetLock, 5 * 4, 6 * 4);
@@ -1849,6 +1898,9 @@ int afs_fs_extend_lock(struct afs_fs_cursor *fc)
1849 struct afs_net *net = afs_v2net(vnode); 1898 struct afs_net *net = afs_v2net(vnode);
1850 __be32 *bp; 1899 __be32 *bp;
1851 1900
1901 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1902 return yfs_fs_extend_lock(fc);
1903
1852 _enter(""); 1904 _enter("");
1853 1905
1854 call = afs_alloc_flat_call(net, &afs_RXFSExtendLock, 4 * 4, 6 * 4); 1906 call = afs_alloc_flat_call(net, &afs_RXFSExtendLock, 4 * 4, 6 * 4);
@@ -1880,6 +1932,9 @@ int afs_fs_release_lock(struct afs_fs_cursor *fc)
1880 struct afs_net *net = afs_v2net(vnode); 1932 struct afs_net *net = afs_v2net(vnode);
1881 __be32 *bp; 1933 __be32 *bp;
1882 1934
1935 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1936 return yfs_fs_release_lock(fc);
1937
1883 _enter(""); 1938 _enter("");
1884 1939
1885 call = afs_alloc_flat_call(net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4); 1940 call = afs_alloc_flat_call(net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4);
@@ -1951,6 +2006,7 @@ int afs_fs_give_up_all_callbacks(struct afs_net *net,
1951 */ 2006 */
1952static int afs_deliver_fs_get_capabilities(struct afs_call *call) 2007static int afs_deliver_fs_get_capabilities(struct afs_call *call)
1953{ 2008{
2009 struct afs_server *server = call->reply[0];
1954 u32 count; 2010 u32 count;
1955 int ret; 2011 int ret;
1956 2012
@@ -1986,6 +2042,11 @@ static int afs_deliver_fs_get_capabilities(struct afs_call *call)
1986 break; 2042 break;
1987 } 2043 }
1988 2044
2045 if (call->service_id == YFS_FS_SERVICE)
2046 set_bit(AFS_SERVER_FL_IS_YFS, &server->flags);
2047 else
2048 clear_bit(AFS_SERVER_FL_IS_YFS, &server->flags);
2049
1989 _leave(" = 0 [done]"); 2050 _leave(" = 0 [done]");
1990 return 0; 2051 return 0;
1991} 2052}
@@ -2019,6 +2080,8 @@ int afs_fs_get_capabilities(struct afs_net *net,
2019 return -ENOMEM; 2080 return -ENOMEM;
2020 2081
2021 call->key = key; 2082 call->key = key;
2083 call->reply[0] = server;
2084 call->upgrade = true;
2022 2085
2023 /* marshall the parameters */ 2086 /* marshall the parameters */
2024 bp = call->request; 2087 bp = call->request;
@@ -2054,8 +2117,7 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call)
2054 if (ret < 0) 2117 if (ret < 0)
2055 return ret; 2118 return ret;
2056 xdr_decode_AFSCallBack_raw(call, &bp, callback); 2119 xdr_decode_AFSCallBack_raw(call, &bp, callback);
2057 if (volsync) 2120 xdr_decode_AFSVolSync(&bp, volsync);
2058 xdr_decode_AFSVolSync(&bp, volsync);
2059 2121
2060 _leave(" = 0 [done]"); 2122 _leave(" = 0 [done]");
2061 return 0; 2123 return 0;
@@ -2084,6 +2146,9 @@ int afs_fs_fetch_status(struct afs_fs_cursor *fc,
2084 struct afs_call *call; 2146 struct afs_call *call;
2085 __be32 *bp; 2147 __be32 *bp;
2086 2148
2149 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
2150 return yfs_fs_fetch_status(fc, net, fid, status, callback, volsync);
2151
2087 _enter(",%x,{%llx:%llu},,", 2152 _enter(",%x,{%llx:%llu},,",
2088 key_serial(fc->key), fid->vid, fid->vnode); 2153 key_serial(fc->key), fid->vid, fid->vnode);
2089 2154
@@ -2218,8 +2283,7 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)
2218 return ret; 2283 return ret;
2219 2284
2220 bp = call->buffer; 2285 bp = call->buffer;
2221 if (call->reply[3]) 2286 xdr_decode_AFSVolSync(&bp, call->reply[3]);
2222 xdr_decode_AFSVolSync(&bp, call->reply[3]);
2223 2287
2224 call->unmarshall++; 2288 call->unmarshall++;
2225 2289
@@ -2256,6 +2320,10 @@ int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
2256 __be32 *bp; 2320 __be32 *bp;
2257 int i; 2321 int i;
2258 2322
2323 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
2324 return yfs_fs_inline_bulk_status(fc, net, fids, statuses, callbacks,
2325 nr_fids, volsync);
2326
2259 _enter(",%x,{%llx:%llu},%u", 2327 _enter(",%x,{%llx:%llu},%u",
2260 key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids); 2328 key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
2261 2329
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 78065af05153..ce79bd514331 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -459,6 +459,8 @@ struct afs_server {
459#define AFS_SERVER_FL_PROBING 6 /* Fileserver is being probed */ 459#define AFS_SERVER_FL_PROBING 6 /* Fileserver is being probed */
460#define AFS_SERVER_FL_NO_IBULK 7 /* Fileserver doesn't support FS.InlineBulkStatus */ 460#define AFS_SERVER_FL_NO_IBULK 7 /* Fileserver doesn't support FS.InlineBulkStatus */
461#define AFS_SERVER_FL_MAY_HAVE_CB 8 /* May have callbacks on this fileserver */ 461#define AFS_SERVER_FL_MAY_HAVE_CB 8 /* May have callbacks on this fileserver */
462#define AFS_SERVER_FL_IS_YFS 9 /* Server is YFS not AFS */
463#define AFS_SERVER_FL_NO_RM2 10 /* Fileserver doesn't support YFS.RemoveFile2 */
462 atomic_t usage; 464 atomic_t usage;
463 u32 addr_version; /* Address list version */ 465 u32 addr_version; /* Address list version */
464 466
@@ -751,6 +753,7 @@ extern struct fscache_cookie_def afs_vnode_cache_index_def;
751 * callback.c 753 * callback.c
752 */ 754 */
753extern void afs_init_callback_state(struct afs_server *); 755extern void afs_init_callback_state(struct afs_server *);
756extern void __afs_break_callback(struct afs_vnode *);
754extern void afs_break_callback(struct afs_vnode *); 757extern void afs_break_callback(struct afs_vnode *);
755extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break*); 758extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break*);
756 759
@@ -864,7 +867,7 @@ extern int afs_fs_give_up_callbacks(struct afs_net *, struct afs_server *);
864extern int afs_fs_fetch_data(struct afs_fs_cursor *, struct afs_read *); 867extern int afs_fs_fetch_data(struct afs_fs_cursor *, struct afs_read *);
865extern int afs_fs_create(struct afs_fs_cursor *, const char *, umode_t, u64, 868extern int afs_fs_create(struct afs_fs_cursor *, const char *, umode_t, u64,
866 struct afs_fid *, struct afs_file_status *, struct afs_callback *); 869 struct afs_fid *, struct afs_file_status *, struct afs_callback *);
867extern int afs_fs_remove(struct afs_fs_cursor *, const char *, bool, u64); 870extern int afs_fs_remove(struct afs_fs_cursor *, struct afs_vnode *, const char *, bool, u64);
868extern int afs_fs_link(struct afs_fs_cursor *, struct afs_vnode *, const char *, u64); 871extern int afs_fs_link(struct afs_fs_cursor *, struct afs_vnode *, const char *, u64);
869extern int afs_fs_symlink(struct afs_fs_cursor *, const char *, const char *, u64, 872extern int afs_fs_symlink(struct afs_fs_cursor *, const char *, const char *, u64,
870 struct afs_fid *, struct afs_file_status *); 873 struct afs_fid *, struct afs_file_status *);
@@ -1228,6 +1231,36 @@ extern int afs_launder_page(struct page *);
1228extern const struct xattr_handler *afs_xattr_handlers[]; 1231extern const struct xattr_handler *afs_xattr_handlers[];
1229extern ssize_t afs_listxattr(struct dentry *, char *, size_t); 1232extern ssize_t afs_listxattr(struct dentry *, char *, size_t);
1230 1233
1234/*
1235 * yfsclient.c
1236 */
1237extern int yfs_fs_fetch_file_status(struct afs_fs_cursor *, struct afs_volsync *, bool);
1238extern int yfs_fs_fetch_data(struct afs_fs_cursor *, struct afs_read *);
1239extern int yfs_fs_create_file(struct afs_fs_cursor *, const char *, umode_t, u64,
1240 struct afs_fid *, struct afs_file_status *, struct afs_callback *);
1241extern int yfs_fs_make_dir(struct afs_fs_cursor *, const char *, umode_t, u64,
1242 struct afs_fid *, struct afs_file_status *, struct afs_callback *);
1243extern int yfs_fs_remove_file2(struct afs_fs_cursor *, struct afs_vnode *, const char *, u64);
1244extern int yfs_fs_remove(struct afs_fs_cursor *, struct afs_vnode *, const char *, bool, u64);
1245extern int yfs_fs_link(struct afs_fs_cursor *, struct afs_vnode *, const char *, u64);
1246extern int yfs_fs_symlink(struct afs_fs_cursor *, const char *, const char *, u64,
1247 struct afs_fid *, struct afs_file_status *);
1248extern int yfs_fs_rename(struct afs_fs_cursor *, const char *,
1249 struct afs_vnode *, const char *, u64, u64);
1250extern int yfs_fs_store_data(struct afs_fs_cursor *, struct address_space *,
1251 pgoff_t, pgoff_t, unsigned, unsigned);
1252extern int yfs_fs_setattr(struct afs_fs_cursor *, struct iattr *);
1253extern int yfs_fs_get_volume_status(struct afs_fs_cursor *, struct afs_volume_status *);
1254extern int yfs_fs_set_lock(struct afs_fs_cursor *, afs_lock_type_t);
1255extern int yfs_fs_extend_lock(struct afs_fs_cursor *);
1256extern int yfs_fs_release_lock(struct afs_fs_cursor *);
1257extern int yfs_fs_fetch_status(struct afs_fs_cursor *, struct afs_net *,
1258 struct afs_fid *, struct afs_file_status *,
1259 struct afs_callback *, struct afs_volsync *);
1260extern int yfs_fs_inline_bulk_status(struct afs_fs_cursor *, struct afs_net *,
1261 struct afs_fid *, struct afs_file_status *,
1262 struct afs_callback *, unsigned int,
1263 struct afs_volsync *);
1231 1264
1232/* 1265/*
1233 * Miscellaneous inline functions. 1266 * Miscellaneous inline functions.
diff --git a/fs/afs/protocol_yfs.h b/fs/afs/protocol_yfs.h
index b7b211dd9857..07bc10f076aa 100644
--- a/fs/afs/protocol_yfs.h
+++ b/fs/afs/protocol_yfs.h
@@ -30,6 +30,36 @@ enum YFS_CM_Operations {
30 YFSCBCallBack = 64204, 30 YFSCBCallBack = 64204,
31}; 31};
32 32
33enum YFS_FS_Operations {
34 YFSFETCHACL = 64131, /* YFS Fetch file ACL */
35 YFSFETCHSTATUS = 64132, /* YFS Fetch file status */
36 YFSSTOREACL = 64134, /* YFS Store file ACL */
37 YFSSTORESTATUS = 64135, /* YFS Store file status */
38 YFSREMOVEFILE = 64136, /* YFS Remove a file */
39 YFSCREATEFILE = 64137, /* YFS Create a file */
40 YFSRENAME = 64138, /* YFS Rename or move a file or directory */
41 YFSSYMLINK = 64139, /* YFS Create a symbolic link */
42 YFSLINK = 64140, /* YFS Create a hard link */
43 YFSMAKEDIR = 64141, /* YFS Create a directory */
44 YFSREMOVEDIR = 64142, /* YFS Remove a directory */
45 YFSGETVOLUMESTATUS = 64149, /* YFS Get volume status information */
46 YFSSETVOLUMESTATUS = 64150, /* YFS Set volume status information */
47 YFSSETLOCK = 64156, /* YFS Request a file lock */
48 YFSEXTENDLOCK = 64157, /* YFS Extend a file lock */
49 YFSRELEASELOCK = 64158, /* YFS Release a file lock */
50 YFSLOOKUP = 64161, /* YFS lookup file in directory */
51 YFSFLUSHCPS = 64165,
52 YFSFETCHOPAQUEACL = 64168,
53 YFSWHOAMI = 64170,
54 YFSREMOVEACL = 64171,
55 YFSREMOVEFILE2 = 64173,
56 YFSSTOREOPAQUEACL2 = 64174,
57 YFSINLINEBULKSTATUS = 64536, /* YFS Fetch multiple file statuses with errors */
58 YFSFETCHDATA64 = 64537, /* YFS Fetch file data */
59 YFSSTOREDATA64 = 64538, /* YFS Store file data */
60 YFSUPDATESYMLINK = 64540,
61};
62
33struct yfs_xdr_u64 { 63struct yfs_xdr_u64 {
34 __be32 msw; 64 __be32 msw;
35 __be32 lsw; 65 __be32 lsw;
@@ -55,3 +85,79 @@ struct yfs_xdr_YFSFid {
55 struct yfs_xdr_u64 volume; 85 struct yfs_xdr_u64 volume;
56 struct yfs_xdr_vnode vnode; 86 struct yfs_xdr_vnode vnode;
57} __packed; 87} __packed;
88
89
90struct yfs_xdr_YFSFetchStatus {
91 __be32 type;
92 __be32 nlink;
93 struct yfs_xdr_u64 size;
94 struct yfs_xdr_u64 data_version;
95 struct yfs_xdr_u64 author;
96 struct yfs_xdr_u64 owner;
97 struct yfs_xdr_u64 group;
98 __be32 mode;
99 __be32 caller_access;
100 __be32 anon_access;
101 struct yfs_xdr_vnode parent;
102 __be32 data_access_protocol;
103 struct yfs_xdr_u64 mtime_client;
104 struct yfs_xdr_u64 mtime_server;
105 __be32 lock_count;
106 __be32 abort_code;
107} __packed;
108
109struct yfs_xdr_YFSCallBack {
110 __be32 version;
111 struct yfs_xdr_u64 expiration_time;
112 __be32 type;
113} __packed;
114
115struct yfs_xdr_YFSStoreStatus {
116 __be32 mask;
117 __be32 mode;
118 struct yfs_xdr_u64 mtime_client;
119 struct yfs_xdr_u64 owner;
120 struct yfs_xdr_u64 group;
121} __packed;
122
123struct yfs_xdr_RPCFlags {
124 __be32 rpc_flags;
125} __packed;
126
127struct yfs_xdr_YFSVolSync {
128 struct yfs_xdr_u64 vol_creation_date;
129 struct yfs_xdr_u64 vol_update_date;
130 struct yfs_xdr_u64 max_quota;
131 struct yfs_xdr_u64 blocks_in_use;
132 struct yfs_xdr_u64 blocks_avail;
133} __packed;
134
135enum yfs_volume_type {
136 yfs_volume_type_ro = 0,
137 yfs_volume_type_rw = 1,
138};
139
140#define yfs_FVSOnline 0x1
141#define yfs_FVSInservice 0x2
142#define yfs_FVSBlessed 0x4
143#define yfs_FVSNeedsSalvage 0x8
144
145struct yfs_xdr_YFSFetchVolumeStatus {
146 struct yfs_xdr_u64 vid;
147 struct yfs_xdr_u64 parent_id;
148 __be32 flags;
149 __be32 type;
150 struct yfs_xdr_u64 max_quota;
151 struct yfs_xdr_u64 blocks_in_use;
152 struct yfs_xdr_u64 part_blocks_avail;
153 struct yfs_xdr_u64 part_max_blocks;
154 struct yfs_xdr_u64 vol_copy_date;
155 struct yfs_xdr_u64 vol_backup_date;
156} __packed;
157
158struct yfs_xdr_YFSStoreVolumeStatus {
159 __be32 mask;
160 struct yfs_xdr_u64 min_quota;
161 struct yfs_xdr_u64 max_quota;
162 struct yfs_xdr_u64 file_quota;
163} __packed;
diff --git a/fs/afs/server.c b/fs/afs/server.c
index 1a087eb8f2d7..aa35cfae5440 100644
--- a/fs/afs/server.c
+++ b/fs/afs/server.c
@@ -13,6 +13,7 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include "afs_fs.h" 14#include "afs_fs.h"
15#include "internal.h" 15#include "internal.h"
16#include "protocol_yfs.h"
16 17
17static unsigned afs_server_gc_delay = 10; /* Server record timeout in seconds */ 18static unsigned afs_server_gc_delay = 10; /* Server record timeout in seconds */
18static unsigned afs_server_update_delay = 30; /* Time till VLDB recheck in secs */ 19static unsigned afs_server_update_delay = 30; /* Time till VLDB recheck in secs */
@@ -513,6 +514,8 @@ void afs_purge_servers(struct afs_net *net)
513 */ 514 */
514static bool afs_do_probe_fileserver(struct afs_fs_cursor *fc) 515static bool afs_do_probe_fileserver(struct afs_fs_cursor *fc)
515{ 516{
517 int i;
518
516 _enter(""); 519 _enter("");
517 520
518 fc->ac.addr = NULL; 521 fc->ac.addr = NULL;
@@ -526,6 +529,11 @@ static bool afs_do_probe_fileserver(struct afs_fs_cursor *fc)
526 &fc->ac, fc->key); 529 &fc->ac, fc->key);
527 switch (fc->ac.error) { 530 switch (fc->ac.error) {
528 case 0: 531 case 0:
532 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)) {
533 for (i = 0; i < fc->ac.alist->nr_addrs; i++)
534 fc->ac.alist->addrs[i].srx_service =
535 YFS_FS_SERVICE;
536 }
529 afs_end_cursor(&fc->ac); 537 afs_end_cursor(&fc->ac);
530 set_bit(AFS_SERVER_FL_PROBED, &fc->cbi->server->flags); 538 set_bit(AFS_SERVER_FL_PROBED, &fc->cbi->server->flags);
531 return true; 539 return true;
diff --git a/fs/afs/yfsclient.c b/fs/afs/yfsclient.c
new file mode 100644
index 000000000000..d5e3f0095040
--- /dev/null
+++ b/fs/afs/yfsclient.c
@@ -0,0 +1,2184 @@
1/* YFS File Server client stubs
2 *
3 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#include <linux/init.h>
13#include <linux/slab.h>
14#include <linux/sched.h>
15#include <linux/circ_buf.h>
16#include <linux/iversion.h>
17#include "internal.h"
18#include "afs_fs.h"
19#include "xdr_fs.h"
20#include "protocol_yfs.h"
21
22static const struct afs_fid afs_zero_fid;
23
24static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi)
25{
26 call->cbi = afs_get_cb_interest(cbi);
27}
28
29#define xdr_size(x) (sizeof(*x) / sizeof(__be32))
30
31static void xdr_decode_YFSFid(const __be32 **_bp, struct afs_fid *fid)
32{
33 const struct yfs_xdr_YFSFid *x = (const void *)*_bp;
34
35 fid->vid = xdr_to_u64(x->volume);
36 fid->vnode = xdr_to_u64(x->vnode.lo);
37 fid->vnode_hi = ntohl(x->vnode.hi);
38 fid->unique = ntohl(x->vnode.unique);
39 *_bp += xdr_size(x);
40}
41
42static __be32 *xdr_encode_u32(__be32 *bp, u32 n)
43{
44 *bp++ = htonl(n);
45 return bp;
46}
47
48static __be32 *xdr_encode_u64(__be32 *bp, u64 n)
49{
50 struct yfs_xdr_u64 *x = (void *)bp;
51
52 *x = u64_to_xdr(n);
53 return bp + xdr_size(x);
54}
55
56static __be32 *xdr_encode_YFSFid(__be32 *bp, struct afs_fid *fid)
57{
58 struct yfs_xdr_YFSFid *x = (void *)bp;
59
60 x->volume = u64_to_xdr(fid->vid);
61 x->vnode.lo = u64_to_xdr(fid->vnode);
62 x->vnode.hi = htonl(fid->vnode_hi);
63 x->vnode.unique = htonl(fid->unique);
64 return bp + xdr_size(x);
65}
66
67static size_t xdr_strlen(unsigned int len)
68{
69 return sizeof(__be32) + round_up(len, sizeof(__be32));
70}
71
72static __be32 *xdr_encode_string(__be32 *bp, const char *p, unsigned int len)
73{
74 bp = xdr_encode_u32(bp, len);
75 bp = memcpy(bp, p, len);
76 if (len & 3) {
77 unsigned int pad = 4 - (len & 3);
78
79 memset((u8 *)bp + len, 0, pad);
80 len += pad;
81 }
82
83 return bp + len / sizeof(__be32);
84}
85
86static s64 linux_to_yfs_time(const struct timespec64 *t)
87{
88 /* Convert to 100ns intervals. */
89 return (u64)t->tv_sec * 10000000 + t->tv_nsec/100;
90}
91
92static __be32 *xdr_encode_YFSStoreStatus_mode(__be32 *bp, mode_t mode)
93{
94 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
95
96 x->mask = htonl(AFS_SET_MODE);
97 x->mode = htonl(mode & S_IALLUGO);
98 x->mtime_client = u64_to_xdr(0);
99 x->owner = u64_to_xdr(0);
100 x->group = u64_to_xdr(0);
101 return bp + xdr_size(x);
102}
103
104static __be32 *xdr_encode_YFSStoreStatus_mtime(__be32 *bp, const struct timespec64 *t)
105{
106 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
107 s64 mtime = linux_to_yfs_time(t);
108
109 x->mask = htonl(AFS_SET_MTIME);
110 x->mode = htonl(0);
111 x->mtime_client = u64_to_xdr(mtime);
112 x->owner = u64_to_xdr(0);
113 x->group = u64_to_xdr(0);
114 return bp + xdr_size(x);
115}
116
117/*
118 * Convert a signed 100ns-resolution 64-bit time into a timespec.
119 */
120static struct timespec64 yfs_time_to_linux(s64 t)
121{
122 struct timespec64 ts;
123 u64 abs_t;
124
125 /*
126 * Unfortunately can not use normal 64 bit division on 32 bit arch, but
127 * the alternative, do_div, does not work with negative numbers so have
128 * to special case them
129 */
130 if (t < 0) {
131 abs_t = -t;
132 ts.tv_nsec = (time64_t)(do_div(abs_t, 10000000) * 100);
133 ts.tv_nsec = -ts.tv_nsec;
134 ts.tv_sec = -abs_t;
135 } else {
136 abs_t = t;
137 ts.tv_nsec = (time64_t)do_div(abs_t, 10000000) * 100;
138 ts.tv_sec = abs_t;
139 }
140
141 return ts;
142}
143
144static struct timespec64 xdr_to_time(const struct yfs_xdr_u64 xdr)
145{
146 s64 t = xdr_to_u64(xdr);
147
148 return yfs_time_to_linux(t);
149}
150
151static void yfs_check_req(struct afs_call *call, __be32 *bp)
152{
153 size_t len = (void *)bp - call->request;
154
155 if (len > call->request_size)
156 pr_err("kAFS: %s: Request buffer overflow (%zu>%u)\n",
157 call->type->name, len, call->request_size);
158 else if (len < call->request_size)
159 pr_warning("kAFS: %s: Request buffer underflow (%zu<%u)\n",
160 call->type->name, len, call->request_size);
161}
162
163/*
164 * Dump a bad file status record.
165 */
166static void xdr_dump_bad(const __be32 *bp)
167{
168 __be32 x[4];
169 int i;
170
171 pr_notice("YFS XDR: Bad status record\n");
172 for (i = 0; i < 5 * 4 * 4; i += 16) {
173 memcpy(x, bp, 16);
174 bp += 4;
175 pr_notice("%03x: %08x %08x %08x %08x\n",
176 i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
177 }
178
179 memcpy(x, bp, 4);
180 pr_notice("0x50: %08x\n", ntohl(x[0]));
181}
182
183/*
184 * Decode a YFSFetchStatus block
185 */
186static int xdr_decode_YFSFetchStatus(struct afs_call *call,
187 const __be32 **_bp,
188 struct afs_file_status *status,
189 struct afs_vnode *vnode,
190 const afs_dataversion_t *expected_version,
191 struct afs_read *read_req)
192{
193 const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp;
194 u32 type;
195 u8 flags = 0;
196
197 status->abort_code = ntohl(xdr->abort_code);
198 if (status->abort_code != 0) {
199 if (vnode && status->abort_code == VNOVNODE) {
200 set_bit(AFS_VNODE_DELETED, &vnode->flags);
201 status->nlink = 0;
202 __afs_break_callback(vnode);
203 }
204 return 0;
205 }
206
207 type = ntohl(xdr->type);
208 switch (type) {
209 case AFS_FTYPE_FILE:
210 case AFS_FTYPE_DIR:
211 case AFS_FTYPE_SYMLINK:
212 if (type != status->type &&
213 vnode &&
214 !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
215 pr_warning("Vnode %llx:%llx:%x changed type %u to %u\n",
216 vnode->fid.vid,
217 vnode->fid.vnode,
218 vnode->fid.unique,
219 status->type, type);
220 goto bad;
221 }
222 status->type = type;
223 break;
224 default:
225 goto bad;
226 }
227
228#define EXTRACT_M4(FIELD) \
229 do { \
230 u32 x = ntohl(xdr->FIELD); \
231 if (status->FIELD != x) { \
232 flags |= AFS_VNODE_META_CHANGED; \
233 status->FIELD = x; \
234 } \
235 } while (0)
236
237#define EXTRACT_M8(FIELD) \
238 do { \
239 u64 x = xdr_to_u64(xdr->FIELD); \
240 if (status->FIELD != x) { \
241 flags |= AFS_VNODE_META_CHANGED; \
242 status->FIELD = x; \
243 } \
244 } while (0)
245
246#define EXTRACT_D8(FIELD) \
247 do { \
248 u64 x = xdr_to_u64(xdr->FIELD); \
249 if (status->FIELD != x) { \
250 flags |= AFS_VNODE_DATA_CHANGED; \
251 status->FIELD = x; \
252 } \
253 } while (0)
254
255 EXTRACT_M4(nlink);
256 EXTRACT_D8(size);
257 EXTRACT_D8(data_version);
258 EXTRACT_M8(author);
259 EXTRACT_M8(owner);
260 EXTRACT_M8(group);
261 EXTRACT_M4(mode);
262 EXTRACT_M4(caller_access); /* call ticket dependent */
263 EXTRACT_M4(anon_access);
264
265 status->mtime_client = xdr_to_time(xdr->mtime_client);
266 status->mtime_server = xdr_to_time(xdr->mtime_server);
267 status->lock_count = ntohl(xdr->lock_count);
268
269 if (read_req) {
270 read_req->data_version = status->data_version;
271 read_req->file_size = status->size;
272 }
273
274 *_bp += xdr_size(xdr);
275
276 if (vnode) {
277 if (test_bit(AFS_VNODE_UNSET, &vnode->flags))
278 flags |= AFS_VNODE_NOT_YET_SET;
279 afs_update_inode_from_status(vnode, status, expected_version,
280 flags);
281 }
282
283 return 0;
284
285bad:
286 xdr_dump_bad(*_bp);
287 return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
288}
289
290/*
291 * Decode the file status. We need to lock the target vnode if we're going to
292 * update its status so that stat() sees the attributes update atomically.
293 */
294static int yfs_decode_status(struct afs_call *call,
295 const __be32 **_bp,
296 struct afs_file_status *status,
297 struct afs_vnode *vnode,
298 const afs_dataversion_t *expected_version,
299 struct afs_read *read_req)
300{
301 int ret;
302
303 if (!vnode)
304 return xdr_decode_YFSFetchStatus(call, _bp, status, vnode,
305 expected_version, read_req);
306
307 write_seqlock(&vnode->cb_lock);
308 ret = xdr_decode_YFSFetchStatus(call, _bp, status, vnode,
309 expected_version, read_req);
310 write_sequnlock(&vnode->cb_lock);
311 return ret;
312}
313
314/*
315 * Decode a YFSCallBack block
316 */
317static void xdr_decode_YFSCallBack(struct afs_call *call,
318 struct afs_vnode *vnode,
319 const __be32 **_bp)
320{
321 struct yfs_xdr_YFSCallBack *xdr = (void *)*_bp;
322 struct afs_cb_interest *old, *cbi = call->cbi;
323 u64 cb_expiry;
324
325 write_seqlock(&vnode->cb_lock);
326
327 if (call->cb_break == afs_cb_break_sum(vnode, cbi)) {
328 cb_expiry = xdr_to_u64(xdr->expiration_time);
329 do_div(cb_expiry, 10 * 1000 * 1000);
330 vnode->cb_version = ntohl(xdr->version);
331 vnode->cb_type = ntohl(xdr->type);
332 vnode->cb_expires_at = cb_expiry + ktime_get_real_seconds();
333 old = vnode->cb_interest;
334 if (old != call->cbi) {
335 vnode->cb_interest = cbi;
336 cbi = old;
337 }
338 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
339 }
340
341 write_sequnlock(&vnode->cb_lock);
342 call->cbi = cbi;
343 *_bp += xdr_size(xdr);
344}
345
346static void xdr_decode_YFSCallBack_raw(const __be32 **_bp,
347 struct afs_callback *cb)
348{
349 struct yfs_xdr_YFSCallBack *x = (void *)*_bp;
350 u64 cb_expiry;
351
352 cb_expiry = xdr_to_u64(x->expiration_time);
353 do_div(cb_expiry, 10 * 1000 * 1000);
354 cb->version = ntohl(x->version);
355 cb->type = ntohl(x->type);
356 cb->expires_at = cb_expiry + ktime_get_real_seconds();
357
358 *_bp += xdr_size(x);
359}
360
361/*
362 * Decode a YFSVolSync block
363 */
364static void xdr_decode_YFSVolSync(const __be32 **_bp,
365 struct afs_volsync *volsync)
366{
367 struct yfs_xdr_YFSVolSync *x = (void *)*_bp;
368 u64 creation;
369
370 if (volsync) {
371 creation = xdr_to_u64(x->vol_creation_date);
372 do_div(creation, 10 * 1000 * 1000);
373 volsync->creation = creation;
374 }
375
376 *_bp += xdr_size(x);
377}
378
379/*
380 * Encode the requested attributes into a YFSStoreStatus block
381 */
382static __be32 *xdr_encode_YFS_StoreStatus(__be32 *bp, struct iattr *attr)
383{
384 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
385 s64 mtime = 0, owner = 0, group = 0;
386 u32 mask = 0, mode = 0;
387
388 mask = 0;
389 if (attr->ia_valid & ATTR_MTIME) {
390 mask |= AFS_SET_MTIME;
391 mtime = linux_to_yfs_time(&attr->ia_mtime);
392 }
393
394 if (attr->ia_valid & ATTR_UID) {
395 mask |= AFS_SET_OWNER;
396 owner = from_kuid(&init_user_ns, attr->ia_uid);
397 }
398
399 if (attr->ia_valid & ATTR_GID) {
400 mask |= AFS_SET_GROUP;
401 group = from_kgid(&init_user_ns, attr->ia_gid);
402 }
403
404 if (attr->ia_valid & ATTR_MODE) {
405 mask |= AFS_SET_MODE;
406 mode = attr->ia_mode & S_IALLUGO;
407 }
408
409 x->mask = htonl(mask);
410 x->mode = htonl(mode);
411 x->mtime_client = u64_to_xdr(mtime);
412 x->owner = u64_to_xdr(owner);
413 x->group = u64_to_xdr(group);
414 return bp + xdr_size(x);
415}
416
417/*
418 * Decode a YFSFetchVolumeStatus block.
419 */
420static void xdr_decode_YFSFetchVolumeStatus(const __be32 **_bp,
421 struct afs_volume_status *vs)
422{
423 const struct yfs_xdr_YFSFetchVolumeStatus *x = (const void *)*_bp;
424 u32 flags;
425
426 vs->vid = xdr_to_u64(x->vid);
427 vs->parent_id = xdr_to_u64(x->parent_id);
428 flags = ntohl(x->flags);
429 vs->online = flags & yfs_FVSOnline;
430 vs->in_service = flags & yfs_FVSInservice;
431 vs->blessed = flags & yfs_FVSBlessed;
432 vs->needs_salvage = flags & yfs_FVSNeedsSalvage;
433 vs->type = ntohl(x->type);
434 vs->min_quota = 0;
435 vs->max_quota = xdr_to_u64(x->max_quota);
436 vs->blocks_in_use = xdr_to_u64(x->blocks_in_use);
437 vs->part_blocks_avail = xdr_to_u64(x->part_blocks_avail);
438 vs->part_max_blocks = xdr_to_u64(x->part_max_blocks);
439 vs->vol_copy_date = xdr_to_u64(x->vol_copy_date);
440 vs->vol_backup_date = xdr_to_u64(x->vol_backup_date);
441 *_bp += sizeof(*x) / sizeof(__be32);
442}
443
444/*
445 * deliver reply data to an FS.FetchStatus
446 */
447static int yfs_deliver_fs_fetch_status_vnode(struct afs_call *call)
448{
449 struct afs_vnode *vnode = call->reply[0];
450 const __be32 *bp;
451 int ret;
452
453 ret = afs_transfer_reply(call);
454 if (ret < 0)
455 return ret;
456
457 _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
458
459 /* unmarshall the reply once we've received all of it */
460 bp = call->buffer;
461 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
462 &call->expected_version, NULL);
463 if (ret < 0)
464 return ret;
465 xdr_decode_YFSCallBack(call, vnode, &bp);
466 xdr_decode_YFSVolSync(&bp, call->reply[1]);
467
468 _leave(" = 0 [done]");
469 return 0;
470}
471
472/*
473 * YFS.FetchStatus operation type
474 */
475static const struct afs_call_type yfs_RXYFSFetchStatus_vnode = {
476 .name = "YFS.FetchStatus(vnode)",
477 .op = yfs_FS_FetchStatus,
478 .deliver = yfs_deliver_fs_fetch_status_vnode,
479 .destructor = afs_flat_call_destructor,
480};
481
482/*
483 * Fetch the status information for a file.
484 */
485int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync,
486 bool new_inode)
487{
488 struct afs_vnode *vnode = fc->vnode;
489 struct afs_call *call;
490 struct afs_net *net = afs_v2net(vnode);
491 __be32 *bp;
492
493 _enter(",%x,{%llx:%llu},,",
494 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
495
496 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus_vnode,
497 sizeof(__be32) * 2 +
498 sizeof(struct yfs_xdr_YFSFid),
499 sizeof(struct yfs_xdr_YFSFetchStatus) +
500 sizeof(struct yfs_xdr_YFSCallBack) +
501 sizeof(struct yfs_xdr_YFSVolSync));
502 if (!call) {
503 fc->ac.error = -ENOMEM;
504 return -ENOMEM;
505 }
506
507 call->key = fc->key;
508 call->reply[0] = vnode;
509 call->reply[1] = volsync;
510 call->expected_version = new_inode ? 1 : vnode->status.data_version;
511
512 /* marshall the parameters */
513 bp = call->request;
514 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
515 bp = xdr_encode_u32(bp, 0); /* RPC flags */
516 bp = xdr_encode_YFSFid(bp, &vnode->fid);
517 yfs_check_req(call, bp);
518
519 call->cb_break = fc->cb_break;
520 afs_use_fs_server(call, fc->cbi);
521 trace_afs_make_fs_call(call, &vnode->fid);
522 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
523}
524
525/*
526 * Deliver reply data to an YFS.FetchData64.
527 */
528static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
529{
530 struct afs_vnode *vnode = call->reply[0];
531 struct afs_read *req = call->reply[2];
532 const __be32 *bp;
533 unsigned int size;
534 int ret;
535
536 _enter("{%u,%zu/%llu}",
537 call->unmarshall, iov_iter_count(&call->iter), req->actual_len);
538
539 switch (call->unmarshall) {
540 case 0:
541 req->actual_len = 0;
542 req->index = 0;
543 req->offset = req->pos & (PAGE_SIZE - 1);
544 afs_extract_to_tmp64(call);
545 call->unmarshall++;
546
547 /* extract the returned data length */
548 case 1:
549 _debug("extract data length");
550 ret = afs_extract_data(call, true);
551 if (ret < 0)
552 return ret;
553
554 req->actual_len = be64_to_cpu(call->tmp64);
555 _debug("DATA length: %llu", req->actual_len);
556 req->remain = min(req->len, req->actual_len);
557 if (req->remain == 0)
558 goto no_more_data;
559
560 call->unmarshall++;
561
562 begin_page:
563 ASSERTCMP(req->index, <, req->nr_pages);
564 if (req->remain > PAGE_SIZE - req->offset)
565 size = PAGE_SIZE - req->offset;
566 else
567 size = req->remain;
568 call->bvec[0].bv_len = size;
569 call->bvec[0].bv_offset = req->offset;
570 call->bvec[0].bv_page = req->pages[req->index];
571 iov_iter_bvec(&call->iter, READ, call->bvec, 1, size);
572 ASSERTCMP(size, <=, PAGE_SIZE);
573
574 /* extract the returned data */
575 case 2:
576 _debug("extract data %zu/%llu",
577 iov_iter_count(&call->iter), req->remain);
578
579 ret = afs_extract_data(call, true);
580 if (ret < 0)
581 return ret;
582 req->remain -= call->bvec[0].bv_len;
583 req->offset += call->bvec[0].bv_len;
584 ASSERTCMP(req->offset, <=, PAGE_SIZE);
585 if (req->offset == PAGE_SIZE) {
586 req->offset = 0;
587 if (req->page_done)
588 req->page_done(call, req);
589 req->index++;
590 if (req->remain > 0)
591 goto begin_page;
592 }
593
594 ASSERTCMP(req->remain, ==, 0);
595 if (req->actual_len <= req->len)
596 goto no_more_data;
597
598 /* Discard any excess data the server gave us */
599 iov_iter_discard(&call->iter, READ, req->actual_len - req->len);
600 call->unmarshall = 3;
601 case 3:
602 _debug("extract discard %zu/%llu",
603 iov_iter_count(&call->iter), req->actual_len - req->len);
604
605 ret = afs_extract_data(call, true);
606 if (ret < 0)
607 return ret;
608
609 no_more_data:
610 call->unmarshall = 4;
611 afs_extract_to_buf(call,
612 sizeof(struct yfs_xdr_YFSFetchStatus) +
613 sizeof(struct yfs_xdr_YFSCallBack) +
614 sizeof(struct yfs_xdr_YFSVolSync));
615
616 /* extract the metadata */
617 case 4:
618 ret = afs_extract_data(call, false);
619 if (ret < 0)
620 return ret;
621
622 bp = call->buffer;
623 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
624 &vnode->status.data_version, req);
625 if (ret < 0)
626 return ret;
627 xdr_decode_YFSCallBack(call, vnode, &bp);
628 xdr_decode_YFSVolSync(&bp, call->reply[1]);
629
630 call->unmarshall++;
631
632 case 5:
633 break;
634 }
635
636 for (; req->index < req->nr_pages; req->index++) {
637 if (req->offset < PAGE_SIZE)
638 zero_user_segment(req->pages[req->index],
639 req->offset, PAGE_SIZE);
640 if (req->page_done)
641 req->page_done(call, req);
642 req->offset = 0;
643 }
644
645 _leave(" = 0 [done]");
646 return 0;
647}
648
649static void yfs_fetch_data_destructor(struct afs_call *call)
650{
651 struct afs_read *req = call->reply[2];
652
653 afs_put_read(req);
654 afs_flat_call_destructor(call);
655}
656
657/*
658 * YFS.FetchData64 operation type
659 */
660static const struct afs_call_type yfs_RXYFSFetchData64 = {
661 .name = "YFS.FetchData64",
662 .op = yfs_FS_FetchData64,
663 .deliver = yfs_deliver_fs_fetch_data64,
664 .destructor = yfs_fetch_data_destructor,
665};
666
667/*
668 * Fetch data from a file.
669 */
670int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
671{
672 struct afs_vnode *vnode = fc->vnode;
673 struct afs_call *call;
674 struct afs_net *net = afs_v2net(vnode);
675 __be32 *bp;
676
677 _enter(",%x,{%llx:%llu},%llx,%llx",
678 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode,
679 req->pos, req->len);
680
681 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchData64,
682 sizeof(__be32) * 2 +
683 sizeof(struct yfs_xdr_YFSFid) +
684 sizeof(struct yfs_xdr_u64) * 2,
685 sizeof(struct yfs_xdr_YFSFetchStatus) +
686 sizeof(struct yfs_xdr_YFSCallBack) +
687 sizeof(struct yfs_xdr_YFSVolSync));
688 if (!call)
689 return -ENOMEM;
690
691 call->key = fc->key;
692 call->reply[0] = vnode;
693 call->reply[1] = NULL; /* volsync */
694 call->reply[2] = req;
695 call->expected_version = vnode->status.data_version;
696 call->want_reply_time = true;
697
698 /* marshall the parameters */
699 bp = call->request;
700 bp = xdr_encode_u32(bp, YFSFETCHDATA64);
701 bp = xdr_encode_u32(bp, 0); /* RPC flags */
702 bp = xdr_encode_YFSFid(bp, &vnode->fid);
703 bp = xdr_encode_u64(bp, req->pos);
704 bp = xdr_encode_u64(bp, req->len);
705 yfs_check_req(call, bp);
706
707 refcount_inc(&req->usage);
708 call->cb_break = fc->cb_break;
709 afs_use_fs_server(call, fc->cbi);
710 trace_afs_make_fs_call(call, &vnode->fid);
711 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
712}
713
714/*
715 * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
716 */
717static int yfs_deliver_fs_create_vnode(struct afs_call *call)
718{
719 struct afs_vnode *vnode = call->reply[0];
720 const __be32 *bp;
721 int ret;
722
723 _enter("{%u}", call->unmarshall);
724
725 ret = afs_transfer_reply(call);
726 if (ret < 0)
727 return ret;
728
729 /* unmarshall the reply once we've received all of it */
730 bp = call->buffer;
731 xdr_decode_YFSFid(&bp, call->reply[1]);
732 ret = yfs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL);
733 if (ret < 0)
734 return ret;
735 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
736 &call->expected_version, NULL);
737 if (ret < 0)
738 return ret;
739 xdr_decode_YFSCallBack_raw(&bp, call->reply[3]);
740 xdr_decode_YFSVolSync(&bp, NULL);
741
742 _leave(" = 0 [done]");
743 return 0;
744}
745
746/*
747 * FS.CreateFile and FS.MakeDir operation type
748 */
749static const struct afs_call_type afs_RXFSCreateFile = {
750 .name = "YFS.CreateFile",
751 .op = yfs_FS_CreateFile,
752 .deliver = yfs_deliver_fs_create_vnode,
753 .destructor = afs_flat_call_destructor,
754};
755
756/*
757 * Create a file.
758 */
759int yfs_fs_create_file(struct afs_fs_cursor *fc,
760 const char *name,
761 umode_t mode,
762 u64 current_data_version,
763 struct afs_fid *newfid,
764 struct afs_file_status *newstatus,
765 struct afs_callback *newcb)
766{
767 struct afs_vnode *vnode = fc->vnode;
768 struct afs_call *call;
769 struct afs_net *net = afs_v2net(vnode);
770 size_t namesz, reqsz, rplsz;
771 __be32 *bp;
772
773 _enter("");
774
775 namesz = strlen(name);
776 reqsz = (sizeof(__be32) +
777 sizeof(__be32) +
778 sizeof(struct yfs_xdr_YFSFid) +
779 xdr_strlen(namesz) +
780 sizeof(struct yfs_xdr_YFSStoreStatus) +
781 sizeof(__be32));
782 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
783 sizeof(struct yfs_xdr_YFSFetchStatus) +
784 sizeof(struct yfs_xdr_YFSFetchStatus) +
785 sizeof(struct yfs_xdr_YFSCallBack) +
786 sizeof(struct yfs_xdr_YFSVolSync));
787
788 call = afs_alloc_flat_call(net, &afs_RXFSCreateFile, reqsz, rplsz);
789 if (!call)
790 return -ENOMEM;
791
792 call->key = fc->key;
793 call->reply[0] = vnode;
794 call->reply[1] = newfid;
795 call->reply[2] = newstatus;
796 call->reply[3] = newcb;
797 call->expected_version = current_data_version + 1;
798
799 /* marshall the parameters */
800 bp = call->request;
801 bp = xdr_encode_u32(bp, YFSCREATEFILE);
802 bp = xdr_encode_u32(bp, 0); /* RPC flags */
803 bp = xdr_encode_YFSFid(bp, &vnode->fid);
804 bp = xdr_encode_string(bp, name, namesz);
805 bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
806 bp = xdr_encode_u32(bp, 0); /* ViceLockType */
807 yfs_check_req(call, bp);
808
809 afs_use_fs_server(call, fc->cbi);
810 trace_afs_make_fs_call(call, &vnode->fid);
811 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
812}
813
814static const struct afs_call_type yfs_RXFSMakeDir = {
815 .name = "YFS.MakeDir",
816 .op = yfs_FS_MakeDir,
817 .deliver = yfs_deliver_fs_create_vnode,
818 .destructor = afs_flat_call_destructor,
819};
820
821/*
822 * Make a directory.
823 */
824int yfs_fs_make_dir(struct afs_fs_cursor *fc,
825 const char *name,
826 umode_t mode,
827 u64 current_data_version,
828 struct afs_fid *newfid,
829 struct afs_file_status *newstatus,
830 struct afs_callback *newcb)
831{
832 struct afs_vnode *vnode = fc->vnode;
833 struct afs_call *call;
834 struct afs_net *net = afs_v2net(vnode);
835 size_t namesz, reqsz, rplsz;
836 __be32 *bp;
837
838 _enter("");
839
840 namesz = strlen(name);
841 reqsz = (sizeof(__be32) +
842 sizeof(struct yfs_xdr_RPCFlags) +
843 sizeof(struct yfs_xdr_YFSFid) +
844 xdr_strlen(namesz) +
845 sizeof(struct yfs_xdr_YFSStoreStatus));
846 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
847 sizeof(struct yfs_xdr_YFSFetchStatus) +
848 sizeof(struct yfs_xdr_YFSFetchStatus) +
849 sizeof(struct yfs_xdr_YFSCallBack) +
850 sizeof(struct yfs_xdr_YFSVolSync));
851
852 call = afs_alloc_flat_call(net, &yfs_RXFSMakeDir, reqsz, rplsz);
853 if (!call)
854 return -ENOMEM;
855
856 call->key = fc->key;
857 call->reply[0] = vnode;
858 call->reply[1] = newfid;
859 call->reply[2] = newstatus;
860 call->reply[3] = newcb;
861 call->expected_version = current_data_version + 1;
862
863 /* marshall the parameters */
864 bp = call->request;
865 bp = xdr_encode_u32(bp, YFSMAKEDIR);
866 bp = xdr_encode_u32(bp, 0); /* RPC flags */
867 bp = xdr_encode_YFSFid(bp, &vnode->fid);
868 bp = xdr_encode_string(bp, name, namesz);
869 bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
870 yfs_check_req(call, bp);
871
872 afs_use_fs_server(call, fc->cbi);
873 trace_afs_make_fs_call(call, &vnode->fid);
874 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
875}
876
877/*
878 * Deliver reply data to a YFS.RemoveFile2 operation.
879 */
880static int yfs_deliver_fs_remove_file2(struct afs_call *call)
881{
882 struct afs_vnode *dvnode = call->reply[0];
883 struct afs_vnode *vnode = call->reply[1];
884 struct afs_fid fid;
885 const __be32 *bp;
886 int ret;
887
888 _enter("{%u}", call->unmarshall);
889
890 ret = afs_transfer_reply(call);
891 if (ret < 0)
892 return ret;
893
894 /* unmarshall the reply once we've received all of it */
895 bp = call->buffer;
896 ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode,
897 &call->expected_version, NULL);
898 if (ret < 0)
899 return ret;
900
901 xdr_decode_YFSFid(&bp, &fid);
902 ret = yfs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL);
903 if (ret < 0)
904 return ret;
905 /* Was deleted if vnode->status.abort_code == VNOVNODE. */
906
907 xdr_decode_YFSVolSync(&bp, NULL);
908 return 0;
909}
910
911/*
912 * YFS.RemoveFile2 operation type.
913 */
914static const struct afs_call_type yfs_RXYFSRemoveFile2 = {
915 .name = "YFS.RemoveFile2",
916 .op = yfs_FS_RemoveFile2,
917 .deliver = yfs_deliver_fs_remove_file2,
918 .destructor = afs_flat_call_destructor,
919};
920
921/*
922 * Remove a file and retrieve new file status.
923 */
924int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
925 const char *name, u64 current_data_version)
926{
927 struct afs_vnode *dvnode = fc->vnode;
928 struct afs_call *call;
929 struct afs_net *net = afs_v2net(dvnode);
930 size_t namesz;
931 __be32 *bp;
932
933 _enter("");
934
935 namesz = strlen(name);
936
937 call = afs_alloc_flat_call(net, &yfs_RXYFSRemoveFile2,
938 sizeof(__be32) +
939 sizeof(struct yfs_xdr_RPCFlags) +
940 sizeof(struct yfs_xdr_YFSFid) +
941 xdr_strlen(namesz),
942 sizeof(struct yfs_xdr_YFSFetchStatus) +
943 sizeof(struct yfs_xdr_YFSFid) +
944 sizeof(struct yfs_xdr_YFSFetchStatus) +
945 sizeof(struct yfs_xdr_YFSVolSync));
946 if (!call)
947 return -ENOMEM;
948
949 call->key = fc->key;
950 call->reply[0] = dvnode;
951 call->reply[1] = vnode;
952 call->expected_version = current_data_version + 1;
953
954 /* marshall the parameters */
955 bp = call->request;
956 bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
957 bp = xdr_encode_u32(bp, 0); /* RPC flags */
958 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
959 bp = xdr_encode_string(bp, name, namesz);
960 yfs_check_req(call, bp);
961
962 afs_use_fs_server(call, fc->cbi);
963 trace_afs_make_fs_call(call, &dvnode->fid);
964 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
965}
966
967/*
968 * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
969 */
970static int yfs_deliver_fs_remove(struct afs_call *call)
971{
972 struct afs_vnode *dvnode = call->reply[0];
973 const __be32 *bp;
974 int ret;
975
976 _enter("{%u}", call->unmarshall);
977
978 ret = afs_transfer_reply(call);
979 if (ret < 0)
980 return ret;
981
982 /* unmarshall the reply once we've received all of it */
983 bp = call->buffer;
984 ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode,
985 &call->expected_version, NULL);
986 if (ret < 0)
987 return ret;
988
989 xdr_decode_YFSVolSync(&bp, NULL);
990 return 0;
991}
992
993/*
994 * FS.RemoveDir and FS.RemoveFile operation types.
995 */
996static const struct afs_call_type yfs_RXYFSRemoveFile = {
997 .name = "YFS.RemoveFile",
998 .op = yfs_FS_RemoveFile,
999 .deliver = yfs_deliver_fs_remove,
1000 .destructor = afs_flat_call_destructor,
1001};
1002
1003static const struct afs_call_type yfs_RXYFSRemoveDir = {
1004 .name = "YFS.RemoveDir",
1005 .op = yfs_FS_RemoveDir,
1006 .deliver = yfs_deliver_fs_remove,
1007 .destructor = afs_flat_call_destructor,
1008};
1009
1010/*
1011 * remove a file or directory
1012 */
1013int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
1014 const char *name, bool isdir, u64 current_data_version)
1015{
1016 struct afs_vnode *dvnode = fc->vnode;
1017 struct afs_call *call;
1018 struct afs_net *net = afs_v2net(dvnode);
1019 size_t namesz;
1020 __be32 *bp;
1021
1022 _enter("");
1023
1024 namesz = strlen(name);
1025 call = afs_alloc_flat_call(
1026 net, isdir ? &yfs_RXYFSRemoveDir : &yfs_RXYFSRemoveFile,
1027 sizeof(__be32) +
1028 sizeof(struct yfs_xdr_RPCFlags) +
1029 sizeof(struct yfs_xdr_YFSFid) +
1030 xdr_strlen(namesz),
1031 sizeof(struct yfs_xdr_YFSFetchStatus) +
1032 sizeof(struct yfs_xdr_YFSVolSync));
1033 if (!call)
1034 return -ENOMEM;
1035
1036 call->key = fc->key;
1037 call->reply[0] = dvnode;
1038 call->reply[1] = vnode;
1039 call->expected_version = current_data_version + 1;
1040
1041 /* marshall the parameters */
1042 bp = call->request;
1043 bp = xdr_encode_u32(bp, isdir ? YFSREMOVEDIR : YFSREMOVEFILE);
1044 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1045 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1046 bp = xdr_encode_string(bp, name, namesz);
1047 yfs_check_req(call, bp);
1048
1049 afs_use_fs_server(call, fc->cbi);
1050 trace_afs_make_fs_call(call, &dvnode->fid);
1051 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1052}
1053
1054/*
1055 * Deliver reply data to a YFS.Link operation.
1056 */
1057static int yfs_deliver_fs_link(struct afs_call *call)
1058{
1059 struct afs_vnode *dvnode = call->reply[0], *vnode = call->reply[1];
1060 const __be32 *bp;
1061 int ret;
1062
1063 _enter("{%u}", call->unmarshall);
1064
1065 ret = afs_transfer_reply(call);
1066 if (ret < 0)
1067 return ret;
1068
1069 /* unmarshall the reply once we've received all of it */
1070 bp = call->buffer;
1071 ret = yfs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL);
1072 if (ret < 0)
1073 return ret;
1074 ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode,
1075 &call->expected_version, NULL);
1076 if (ret < 0)
1077 return ret;
1078 xdr_decode_YFSVolSync(&bp, NULL);
1079 _leave(" = 0 [done]");
1080 return 0;
1081}
1082
1083/*
1084 * YFS.Link operation type.
1085 */
1086static const struct afs_call_type yfs_RXYFSLink = {
1087 .name = "YFS.Link",
1088 .op = yfs_FS_Link,
1089 .deliver = yfs_deliver_fs_link,
1090 .destructor = afs_flat_call_destructor,
1091};
1092
1093/*
1094 * Make a hard link.
1095 */
1096int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
1097 const char *name, u64 current_data_version)
1098{
1099 struct afs_vnode *dvnode = fc->vnode;
1100 struct afs_call *call;
1101 struct afs_net *net = afs_v2net(vnode);
1102 size_t namesz;
1103 __be32 *bp;
1104
1105 _enter("");
1106
1107 namesz = strlen(name);
1108 call = afs_alloc_flat_call(net, &yfs_RXYFSLink,
1109 sizeof(__be32) +
1110 sizeof(struct yfs_xdr_RPCFlags) +
1111 sizeof(struct yfs_xdr_YFSFid) +
1112 xdr_strlen(namesz) +
1113 sizeof(struct yfs_xdr_YFSFid),
1114 sizeof(struct yfs_xdr_YFSFetchStatus) +
1115 sizeof(struct yfs_xdr_YFSFetchStatus) +
1116 sizeof(struct yfs_xdr_YFSVolSync));
1117 if (!call)
1118 return -ENOMEM;
1119
1120 call->key = fc->key;
1121 call->reply[0] = dvnode;
1122 call->reply[1] = vnode;
1123 call->expected_version = current_data_version + 1;
1124
1125 /* marshall the parameters */
1126 bp = call->request;
1127 bp = xdr_encode_u32(bp, YFSLINK);
1128 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1129 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1130 bp = xdr_encode_string(bp, name, namesz);
1131 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1132 yfs_check_req(call, bp);
1133
1134 afs_use_fs_server(call, fc->cbi);
1135 trace_afs_make_fs_call(call, &vnode->fid);
1136 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1137}
1138
1139/*
1140 * Deliver reply data to a YFS.Symlink operation.
1141 */
1142static int yfs_deliver_fs_symlink(struct afs_call *call)
1143{
1144 struct afs_vnode *vnode = call->reply[0];
1145 const __be32 *bp;
1146 int ret;
1147
1148 _enter("{%u}", call->unmarshall);
1149
1150 ret = afs_transfer_reply(call);
1151 if (ret < 0)
1152 return ret;
1153
1154 /* unmarshall the reply once we've received all of it */
1155 bp = call->buffer;
1156 xdr_decode_YFSFid(&bp, call->reply[1]);
1157 ret = yfs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL);
1158 if (ret < 0)
1159 return ret;
1160 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1161 &call->expected_version, NULL);
1162 if (ret < 0)
1163 return ret;
1164 xdr_decode_YFSVolSync(&bp, NULL);
1165
1166 _leave(" = 0 [done]");
1167 return 0;
1168}
1169
1170/*
1171 * YFS.Symlink operation type
1172 */
1173static const struct afs_call_type yfs_RXYFSSymlink = {
1174 .name = "YFS.Symlink",
1175 .op = yfs_FS_Symlink,
1176 .deliver = yfs_deliver_fs_symlink,
1177 .destructor = afs_flat_call_destructor,
1178};
1179
1180/*
1181 * Create a symbolic link.
1182 */
1183int yfs_fs_symlink(struct afs_fs_cursor *fc,
1184 const char *name,
1185 const char *contents,
1186 u64 current_data_version,
1187 struct afs_fid *newfid,
1188 struct afs_file_status *newstatus)
1189{
1190 struct afs_vnode *dvnode = fc->vnode;
1191 struct afs_call *call;
1192 struct afs_net *net = afs_v2net(dvnode);
1193 size_t namesz, contents_sz;
1194 __be32 *bp;
1195
1196 _enter("");
1197
1198 namesz = strlen(name);
1199 contents_sz = strlen(contents);
1200 call = afs_alloc_flat_call(net, &yfs_RXYFSSymlink,
1201 sizeof(__be32) +
1202 sizeof(struct yfs_xdr_RPCFlags) +
1203 sizeof(struct yfs_xdr_YFSFid) +
1204 xdr_strlen(namesz) +
1205 xdr_strlen(contents_sz) +
1206 sizeof(struct yfs_xdr_YFSStoreStatus),
1207 sizeof(struct yfs_xdr_YFSFid) +
1208 sizeof(struct yfs_xdr_YFSFetchStatus) +
1209 sizeof(struct yfs_xdr_YFSFetchStatus) +
1210 sizeof(struct yfs_xdr_YFSVolSync));
1211 if (!call)
1212 return -ENOMEM;
1213
1214 call->key = fc->key;
1215 call->reply[0] = dvnode;
1216 call->reply[1] = newfid;
1217 call->reply[2] = newstatus;
1218 call->expected_version = current_data_version + 1;
1219
1220 /* marshall the parameters */
1221 bp = call->request;
1222 bp = xdr_encode_u32(bp, YFSSYMLINK);
1223 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1224 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1225 bp = xdr_encode_string(bp, name, namesz);
1226 bp = xdr_encode_string(bp, contents, contents_sz);
1227 bp = xdr_encode_YFSStoreStatus_mode(bp, S_IRWXUGO);
1228 yfs_check_req(call, bp);
1229
1230 afs_use_fs_server(call, fc->cbi);
1231 trace_afs_make_fs_call(call, &dvnode->fid);
1232 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1233}
1234
1235/*
1236 * Deliver reply data to a YFS.Rename operation.
1237 */
1238static int yfs_deliver_fs_rename(struct afs_call *call)
1239{
1240 struct afs_vnode *orig_dvnode = call->reply[0];
1241 struct afs_vnode *new_dvnode = call->reply[1];
1242 const __be32 *bp;
1243 int ret;
1244
1245 _enter("{%u}", call->unmarshall);
1246
1247 ret = afs_transfer_reply(call);
1248 if (ret < 0)
1249 return ret;
1250
1251 /* unmarshall the reply once we've received all of it */
1252 bp = call->buffer;
1253 ret = yfs_decode_status(call, &bp, &orig_dvnode->status, orig_dvnode,
1254 &call->expected_version, NULL);
1255 if (ret < 0)
1256 return ret;
1257 if (new_dvnode != orig_dvnode) {
1258 ret = yfs_decode_status(call, &bp, &new_dvnode->status, new_dvnode,
1259 &call->expected_version_2, NULL);
1260 if (ret < 0)
1261 return ret;
1262 }
1263
1264 xdr_decode_YFSVolSync(&bp, NULL);
1265 _leave(" = 0 [done]");
1266 return 0;
1267}
1268
1269/*
1270 * YFS.Rename operation type
1271 */
1272static const struct afs_call_type yfs_RXYFSRename = {
1273 .name = "FS.Rename",
1274 .op = yfs_FS_Rename,
1275 .deliver = yfs_deliver_fs_rename,
1276 .destructor = afs_flat_call_destructor,
1277};
1278
1279/*
1280 * Rename a file or directory.
1281 */
1282int yfs_fs_rename(struct afs_fs_cursor *fc,
1283 const char *orig_name,
1284 struct afs_vnode *new_dvnode,
1285 const char *new_name,
1286 u64 current_orig_data_version,
1287 u64 current_new_data_version)
1288{
1289 struct afs_vnode *orig_dvnode = fc->vnode;
1290 struct afs_call *call;
1291 struct afs_net *net = afs_v2net(orig_dvnode);
1292 size_t o_namesz, n_namesz;
1293 __be32 *bp;
1294
1295 _enter("");
1296
1297 o_namesz = strlen(orig_name);
1298 n_namesz = strlen(new_name);
1299 call = afs_alloc_flat_call(net, &yfs_RXYFSRename,
1300 sizeof(__be32) +
1301 sizeof(struct yfs_xdr_RPCFlags) +
1302 sizeof(struct yfs_xdr_YFSFid) +
1303 xdr_strlen(o_namesz) +
1304 sizeof(struct yfs_xdr_YFSFid) +
1305 xdr_strlen(n_namesz),
1306 sizeof(struct yfs_xdr_YFSFetchStatus) +
1307 sizeof(struct yfs_xdr_YFSFetchStatus) +
1308 sizeof(struct yfs_xdr_YFSVolSync));
1309 if (!call)
1310 return -ENOMEM;
1311
1312 call->key = fc->key;
1313 call->reply[0] = orig_dvnode;
1314 call->reply[1] = new_dvnode;
1315 call->expected_version = current_orig_data_version + 1;
1316 call->expected_version_2 = current_new_data_version + 1;
1317
1318 /* marshall the parameters */
1319 bp = call->request;
1320 bp = xdr_encode_u32(bp, YFSRENAME);
1321 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1322 bp = xdr_encode_YFSFid(bp, &orig_dvnode->fid);
1323 bp = xdr_encode_string(bp, orig_name, o_namesz);
1324 bp = xdr_encode_YFSFid(bp, &new_dvnode->fid);
1325 bp = xdr_encode_string(bp, new_name, n_namesz);
1326 yfs_check_req(call, bp);
1327
1328 afs_use_fs_server(call, fc->cbi);
1329 trace_afs_make_fs_call(call, &orig_dvnode->fid);
1330 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1331}
1332
1333/*
1334 * Deliver reply data to a YFS.StoreData64 operation.
1335 */
1336static int yfs_deliver_fs_store_data(struct afs_call *call)
1337{
1338 struct afs_vnode *vnode = call->reply[0];
1339 const __be32 *bp;
1340 int ret;
1341
1342 _enter("");
1343
1344 ret = afs_transfer_reply(call);
1345 if (ret < 0)
1346 return ret;
1347
1348 /* unmarshall the reply once we've received all of it */
1349 bp = call->buffer;
1350 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1351 &call->expected_version, NULL);
1352 if (ret < 0)
1353 return ret;
1354 xdr_decode_YFSVolSync(&bp, NULL);
1355
1356 afs_pages_written_back(vnode, call);
1357
1358 _leave(" = 0 [done]");
1359 return 0;
1360}
1361
1362/*
1363 * YFS.StoreData64 operation type.
1364 */
1365static const struct afs_call_type yfs_RXYFSStoreData64 = {
1366 .name = "YFS.StoreData64",
1367 .op = yfs_FS_StoreData64,
1368 .deliver = yfs_deliver_fs_store_data,
1369 .destructor = afs_flat_call_destructor,
1370};
1371
1372/*
1373 * Store a set of pages to a large file.
1374 */
1375int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1376 pgoff_t first, pgoff_t last,
1377 unsigned offset, unsigned to)
1378{
1379 struct afs_vnode *vnode = fc->vnode;
1380 struct afs_call *call;
1381 struct afs_net *net = afs_v2net(vnode);
1382 loff_t size, pos, i_size;
1383 __be32 *bp;
1384
1385 _enter(",%x,{%llx:%llu},,",
1386 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1387
1388 size = (loff_t)to - (loff_t)offset;
1389 if (first != last)
1390 size += (loff_t)(last - first) << PAGE_SHIFT;
1391 pos = (loff_t)first << PAGE_SHIFT;
1392 pos += offset;
1393
1394 i_size = i_size_read(&vnode->vfs_inode);
1395 if (pos + size > i_size)
1396 i_size = size + pos;
1397
1398 _debug("size %llx, at %llx, i_size %llx",
1399 (unsigned long long)size, (unsigned long long)pos,
1400 (unsigned long long)i_size);
1401
1402 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64,
1403 sizeof(__be32) +
1404 sizeof(__be32) +
1405 sizeof(struct yfs_xdr_YFSFid) +
1406 sizeof(struct yfs_xdr_YFSStoreStatus) +
1407 sizeof(struct yfs_xdr_u64) * 3,
1408 sizeof(struct yfs_xdr_YFSFetchStatus) +
1409 sizeof(struct yfs_xdr_YFSVolSync));
1410 if (!call)
1411 return -ENOMEM;
1412
1413 call->key = fc->key;
1414 call->mapping = mapping;
1415 call->reply[0] = vnode;
1416 call->first = first;
1417 call->last = last;
1418 call->first_offset = offset;
1419 call->last_to = to;
1420 call->send_pages = true;
1421 call->expected_version = vnode->status.data_version + 1;
1422
1423 /* marshall the parameters */
1424 bp = call->request;
1425 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1426 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1427 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1428 bp = xdr_encode_YFSStoreStatus_mtime(bp, &vnode->vfs_inode.i_mtime);
1429 bp = xdr_encode_u64(bp, pos);
1430 bp = xdr_encode_u64(bp, size);
1431 bp = xdr_encode_u64(bp, i_size);
1432 yfs_check_req(call, bp);
1433
1434 afs_use_fs_server(call, fc->cbi);
1435 trace_afs_make_fs_call(call, &vnode->fid);
1436 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1437}
1438
1439/*
1440 * deliver reply data to an FS.StoreStatus
1441 */
1442static int yfs_deliver_fs_store_status(struct afs_call *call)
1443{
1444 struct afs_vnode *vnode = call->reply[0];
1445 const __be32 *bp;
1446 int ret;
1447
1448 _enter("");
1449
1450 ret = afs_transfer_reply(call);
1451 if (ret < 0)
1452 return ret;
1453
1454 /* unmarshall the reply once we've received all of it */
1455 bp = call->buffer;
1456 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1457 &call->expected_version, NULL);
1458 if (ret < 0)
1459 return ret;
1460 xdr_decode_YFSVolSync(&bp, NULL);
1461
1462 _leave(" = 0 [done]");
1463 return 0;
1464}
1465
1466/*
1467 * YFS.StoreStatus operation type
1468 */
1469static const struct afs_call_type yfs_RXYFSStoreStatus = {
1470 .name = "YFS.StoreStatus",
1471 .op = yfs_FS_StoreStatus,
1472 .deliver = yfs_deliver_fs_store_status,
1473 .destructor = afs_flat_call_destructor,
1474};
1475
1476static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = {
1477 .name = "YFS.StoreData64",
1478 .op = yfs_FS_StoreData64,
1479 .deliver = yfs_deliver_fs_store_status,
1480 .destructor = afs_flat_call_destructor,
1481};
1482
1483/*
1484 * Set the attributes on a file, using YFS.StoreData64 rather than
1485 * YFS.StoreStatus so as to alter the file size also.
1486 */
1487static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr)
1488{
1489 struct afs_vnode *vnode = fc->vnode;
1490 struct afs_call *call;
1491 struct afs_net *net = afs_v2net(vnode);
1492 __be32 *bp;
1493
1494 _enter(",%x,{%llx:%llu},,",
1495 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1496
1497 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64_as_Status,
1498 sizeof(__be32) * 2 +
1499 sizeof(struct yfs_xdr_YFSFid) +
1500 sizeof(struct yfs_xdr_YFSStoreStatus) +
1501 sizeof(struct yfs_xdr_u64) * 3,
1502 sizeof(struct yfs_xdr_YFSFetchStatus) +
1503 sizeof(struct yfs_xdr_YFSVolSync));
1504 if (!call)
1505 return -ENOMEM;
1506
1507 call->key = fc->key;
1508 call->reply[0] = vnode;
1509 call->expected_version = vnode->status.data_version + 1;
1510
1511 /* marshall the parameters */
1512 bp = call->request;
1513 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1514 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1515 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1516 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1517 bp = xdr_encode_u64(bp, 0); /* position of start of write */
1518 bp = xdr_encode_u64(bp, 0); /* size of write */
1519 bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */
1520 yfs_check_req(call, bp);
1521
1522 afs_use_fs_server(call, fc->cbi);
1523 trace_afs_make_fs_call(call, &vnode->fid);
1524 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1525}
1526
1527/*
1528 * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1529 * file size, and YFS.StoreStatus otherwise.
1530 */
1531int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
1532{
1533 struct afs_vnode *vnode = fc->vnode;
1534 struct afs_call *call;
1535 struct afs_net *net = afs_v2net(vnode);
1536 __be32 *bp;
1537
1538 if (attr->ia_valid & ATTR_SIZE)
1539 return yfs_fs_setattr_size(fc, attr);
1540
1541 _enter(",%x,{%llx:%llu},,",
1542 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1543
1544 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus,
1545 sizeof(__be32) * 2 +
1546 sizeof(struct yfs_xdr_YFSFid) +
1547 sizeof(struct yfs_xdr_YFSStoreStatus),
1548 sizeof(struct yfs_xdr_YFSFetchStatus) +
1549 sizeof(struct yfs_xdr_YFSVolSync));
1550 if (!call)
1551 return -ENOMEM;
1552
1553 call->key = fc->key;
1554 call->reply[0] = vnode;
1555 call->expected_version = vnode->status.data_version;
1556
1557 /* marshall the parameters */
1558 bp = call->request;
1559 bp = xdr_encode_u32(bp, YFSSTORESTATUS);
1560 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1561 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1562 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1563 yfs_check_req(call, bp);
1564
1565 afs_use_fs_server(call, fc->cbi);
1566 trace_afs_make_fs_call(call, &vnode->fid);
1567 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1568}
1569
1570/*
1571 * Deliver reply data to a YFS.GetVolumeStatus operation.
1572 */
1573static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1574{
1575 const __be32 *bp;
1576 char *p;
1577 u32 size;
1578 int ret;
1579
1580 _enter("{%u}", call->unmarshall);
1581
1582 switch (call->unmarshall) {
1583 case 0:
1584 call->unmarshall++;
1585 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus));
1586
1587 /* extract the returned status record */
1588 case 1:
1589 _debug("extract status");
1590 ret = afs_extract_data(call, true);
1591 if (ret < 0)
1592 return ret;
1593
1594 bp = call->buffer;
1595 xdr_decode_YFSFetchVolumeStatus(&bp, call->reply[1]);
1596 call->unmarshall++;
1597 afs_extract_to_tmp(call);
1598
1599 /* extract the volume name length */
1600 case 2:
1601 ret = afs_extract_data(call, true);
1602 if (ret < 0)
1603 return ret;
1604
1605 call->count = ntohl(call->tmp);
1606 _debug("volname length: %u", call->count);
1607 if (call->count >= AFSNAMEMAX)
1608 return afs_protocol_error(call, -EBADMSG,
1609 afs_eproto_volname_len);
1610 size = (call->count + 3) & ~3; /* It's padded */
1611 afs_extract_begin(call, call->reply[2], size);
1612 call->unmarshall++;
1613
1614 /* extract the volume name */
1615 case 3:
1616 _debug("extract volname");
1617 ret = afs_extract_data(call, true);
1618 if (ret < 0)
1619 return ret;
1620
1621 p = call->reply[2];
1622 p[call->count] = 0;
1623 _debug("volname '%s'", p);
1624 afs_extract_to_tmp(call);
1625 call->unmarshall++;
1626
1627 /* extract the offline message length */
1628 case 4:
1629 ret = afs_extract_data(call, true);
1630 if (ret < 0)
1631 return ret;
1632
1633 call->count = ntohl(call->tmp);
1634 _debug("offline msg length: %u", call->count);
1635 if (call->count >= AFSNAMEMAX)
1636 return afs_protocol_error(call, -EBADMSG,
1637 afs_eproto_offline_msg_len);
1638 size = (call->count + 3) & ~3; /* It's padded */
1639 afs_extract_begin(call, call->reply[2], size);
1640 call->unmarshall++;
1641
1642 /* extract the offline message */
1643 case 5:
1644 _debug("extract offline");
1645 ret = afs_extract_data(call, true);
1646 if (ret < 0)
1647 return ret;
1648
1649 p = call->reply[2];
1650 p[call->count] = 0;
1651 _debug("offline '%s'", p);
1652
1653 afs_extract_to_tmp(call);
1654 call->unmarshall++;
1655
1656 /* extract the message of the day length */
1657 case 6:
1658 ret = afs_extract_data(call, true);
1659 if (ret < 0)
1660 return ret;
1661
1662 call->count = ntohl(call->tmp);
1663 _debug("motd length: %u", call->count);
1664 if (call->count >= AFSNAMEMAX)
1665 return afs_protocol_error(call, -EBADMSG,
1666 afs_eproto_motd_len);
1667 size = (call->count + 3) & ~3; /* It's padded */
1668 afs_extract_begin(call, call->reply[2], size);
1669 call->unmarshall++;
1670
1671 /* extract the message of the day */
1672 case 7:
1673 _debug("extract motd");
1674 ret = afs_extract_data(call, false);
1675 if (ret < 0)
1676 return ret;
1677
1678 p = call->reply[2];
1679 p[call->count] = 0;
1680 _debug("motd '%s'", p);
1681
1682 call->unmarshall++;
1683
1684 case 8:
1685 break;
1686 }
1687
1688 _leave(" = 0 [done]");
1689 return 0;
1690}
1691
1692/*
1693 * Destroy a YFS.GetVolumeStatus call.
1694 */
1695static void yfs_get_volume_status_call_destructor(struct afs_call *call)
1696{
1697 kfree(call->reply[2]);
1698 call->reply[2] = NULL;
1699 afs_flat_call_destructor(call);
1700}
1701
1702/*
1703 * YFS.GetVolumeStatus operation type
1704 */
1705static const struct afs_call_type yfs_RXYFSGetVolumeStatus = {
1706 .name = "YFS.GetVolumeStatus",
1707 .op = yfs_FS_GetVolumeStatus,
1708 .deliver = yfs_deliver_fs_get_volume_status,
1709 .destructor = yfs_get_volume_status_call_destructor,
1710};
1711
1712/*
1713 * fetch the status of a volume
1714 */
1715int yfs_fs_get_volume_status(struct afs_fs_cursor *fc,
1716 struct afs_volume_status *vs)
1717{
1718 struct afs_vnode *vnode = fc->vnode;
1719 struct afs_call *call;
1720 struct afs_net *net = afs_v2net(vnode);
1721 __be32 *bp;
1722 void *tmpbuf;
1723
1724 _enter("");
1725
1726 tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1727 if (!tmpbuf)
1728 return -ENOMEM;
1729
1730 call = afs_alloc_flat_call(net, &yfs_RXYFSGetVolumeStatus,
1731 sizeof(__be32) * 2 +
1732 sizeof(struct yfs_xdr_u64),
1733 sizeof(struct yfs_xdr_YFSFetchVolumeStatus) +
1734 sizeof(__be32));
1735 if (!call) {
1736 kfree(tmpbuf);
1737 return -ENOMEM;
1738 }
1739
1740 call->key = fc->key;
1741 call->reply[0] = vnode;
1742 call->reply[1] = vs;
1743 call->reply[2] = tmpbuf;
1744
1745 /* marshall the parameters */
1746 bp = call->request;
1747 bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1748 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1749 bp = xdr_encode_u64(bp, vnode->fid.vid);
1750 yfs_check_req(call, bp);
1751
1752 afs_use_fs_server(call, fc->cbi);
1753 trace_afs_make_fs_call(call, &vnode->fid);
1754 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1755}
1756
1757/*
1758 * Deliver reply data to an YFS.SetLock, YFS.ExtendLock or YFS.ReleaseLock
1759 */
1760static int yfs_deliver_fs_xxxx_lock(struct afs_call *call)
1761{
1762 struct afs_vnode *vnode = call->reply[0];
1763 const __be32 *bp;
1764 int ret;
1765
1766 _enter("{%u}", call->unmarshall);
1767
1768 ret = afs_transfer_reply(call);
1769 if (ret < 0)
1770 return ret;
1771
1772 /* unmarshall the reply once we've received all of it */
1773 bp = call->buffer;
1774 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1775 &call->expected_version, NULL);
1776 if (ret < 0)
1777 return ret;
1778 xdr_decode_YFSVolSync(&bp, NULL);
1779
1780 _leave(" = 0 [done]");
1781 return 0;
1782}
1783
1784/*
1785 * YFS.SetLock operation type
1786 */
1787static const struct afs_call_type yfs_RXYFSSetLock = {
1788 .name = "YFS.SetLock",
1789 .op = yfs_FS_SetLock,
1790 .deliver = yfs_deliver_fs_xxxx_lock,
1791 .destructor = afs_flat_call_destructor,
1792};
1793
1794/*
1795 * YFS.ExtendLock operation type
1796 */
1797static const struct afs_call_type yfs_RXYFSExtendLock = {
1798 .name = "YFS.ExtendLock",
1799 .op = yfs_FS_ExtendLock,
1800 .deliver = yfs_deliver_fs_xxxx_lock,
1801 .destructor = afs_flat_call_destructor,
1802};
1803
1804/*
1805 * YFS.ReleaseLock operation type
1806 */
1807static const struct afs_call_type yfs_RXYFSReleaseLock = {
1808 .name = "YFS.ReleaseLock",
1809 .op = yfs_FS_ReleaseLock,
1810 .deliver = yfs_deliver_fs_xxxx_lock,
1811 .destructor = afs_flat_call_destructor,
1812};
1813
1814/*
1815 * Set a lock on a file
1816 */
1817int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
1818{
1819 struct afs_vnode *vnode = fc->vnode;
1820 struct afs_call *call;
1821 struct afs_net *net = afs_v2net(vnode);
1822 __be32 *bp;
1823
1824 _enter("");
1825
1826 call = afs_alloc_flat_call(net, &yfs_RXYFSSetLock,
1827 sizeof(__be32) * 2 +
1828 sizeof(struct yfs_xdr_YFSFid) +
1829 sizeof(__be32),
1830 sizeof(struct yfs_xdr_YFSFetchStatus) +
1831 sizeof(struct yfs_xdr_YFSVolSync));
1832 if (!call)
1833 return -ENOMEM;
1834
1835 call->key = fc->key;
1836 call->reply[0] = vnode;
1837
1838 /* marshall the parameters */
1839 bp = call->request;
1840 bp = xdr_encode_u32(bp, YFSSETLOCK);
1841 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1842 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1843 bp = xdr_encode_u32(bp, type);
1844 yfs_check_req(call, bp);
1845
1846 afs_use_fs_server(call, fc->cbi);
1847 trace_afs_make_fs_call(call, &vnode->fid);
1848 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1849}
1850
1851/*
1852 * extend a lock on a file
1853 */
1854int yfs_fs_extend_lock(struct afs_fs_cursor *fc)
1855{
1856 struct afs_vnode *vnode = fc->vnode;
1857 struct afs_call *call;
1858 struct afs_net *net = afs_v2net(vnode);
1859 __be32 *bp;
1860
1861 _enter("");
1862
1863 call = afs_alloc_flat_call(net, &yfs_RXYFSExtendLock,
1864 sizeof(__be32) * 2 +
1865 sizeof(struct yfs_xdr_YFSFid),
1866 sizeof(struct yfs_xdr_YFSFetchStatus) +
1867 sizeof(struct yfs_xdr_YFSVolSync));
1868 if (!call)
1869 return -ENOMEM;
1870
1871 call->key = fc->key;
1872 call->reply[0] = vnode;
1873
1874 /* marshall the parameters */
1875 bp = call->request;
1876 bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1877 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1878 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1879 yfs_check_req(call, bp);
1880
1881 afs_use_fs_server(call, fc->cbi);
1882 trace_afs_make_fs_call(call, &vnode->fid);
1883 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1884}
1885
1886/*
1887 * release a lock on a file
1888 */
1889int yfs_fs_release_lock(struct afs_fs_cursor *fc)
1890{
1891 struct afs_vnode *vnode = fc->vnode;
1892 struct afs_call *call;
1893 struct afs_net *net = afs_v2net(vnode);
1894 __be32 *bp;
1895
1896 _enter("");
1897
1898 call = afs_alloc_flat_call(net, &yfs_RXYFSReleaseLock,
1899 sizeof(__be32) * 2 +
1900 sizeof(struct yfs_xdr_YFSFid),
1901 sizeof(struct yfs_xdr_YFSFetchStatus) +
1902 sizeof(struct yfs_xdr_YFSVolSync));
1903 if (!call)
1904 return -ENOMEM;
1905
1906 call->key = fc->key;
1907 call->reply[0] = vnode;
1908
1909 /* marshall the parameters */
1910 bp = call->request;
1911 bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1912 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1913 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1914 yfs_check_req(call, bp);
1915
1916 afs_use_fs_server(call, fc->cbi);
1917 trace_afs_make_fs_call(call, &vnode->fid);
1918 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1919}
1920
1921/*
1922 * Deliver reply data to an FS.FetchStatus with no vnode.
1923 */
1924static int yfs_deliver_fs_fetch_status(struct afs_call *call)
1925{
1926 struct afs_file_status *status = call->reply[1];
1927 struct afs_callback *callback = call->reply[2];
1928 struct afs_volsync *volsync = call->reply[3];
1929 struct afs_vnode *vnode = call->reply[0];
1930 const __be32 *bp;
1931 int ret;
1932
1933 ret = afs_transfer_reply(call);
1934 if (ret < 0)
1935 return ret;
1936
1937 _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
1938
1939 /* unmarshall the reply once we've received all of it */
1940 bp = call->buffer;
1941 ret = yfs_decode_status(call, &bp, status, vnode,
1942 &call->expected_version, NULL);
1943 if (ret < 0)
1944 return ret;
1945 xdr_decode_YFSCallBack_raw(&bp, callback);
1946 xdr_decode_YFSVolSync(&bp, volsync);
1947
1948 _leave(" = 0 [done]");
1949 return 0;
1950}
1951
1952/*
1953 * YFS.FetchStatus operation type
1954 */
1955static const struct afs_call_type yfs_RXYFSFetchStatus = {
1956 .name = "YFS.FetchStatus",
1957 .op = yfs_FS_FetchStatus,
1958 .deliver = yfs_deliver_fs_fetch_status,
1959 .destructor = afs_flat_call_destructor,
1960};
1961
1962/*
1963 * Fetch the status information for a fid without needing a vnode handle.
1964 */
1965int yfs_fs_fetch_status(struct afs_fs_cursor *fc,
1966 struct afs_net *net,
1967 struct afs_fid *fid,
1968 struct afs_file_status *status,
1969 struct afs_callback *callback,
1970 struct afs_volsync *volsync)
1971{
1972 struct afs_call *call;
1973 __be32 *bp;
1974
1975 _enter(",%x,{%llx:%llu},,",
1976 key_serial(fc->key), fid->vid, fid->vnode);
1977
1978 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus,
1979 sizeof(__be32) * 2 +
1980 sizeof(struct yfs_xdr_YFSFid),
1981 sizeof(struct yfs_xdr_YFSFetchStatus) +
1982 sizeof(struct yfs_xdr_YFSCallBack) +
1983 sizeof(struct yfs_xdr_YFSVolSync));
1984 if (!call) {
1985 fc->ac.error = -ENOMEM;
1986 return -ENOMEM;
1987 }
1988
1989 call->key = fc->key;
1990 call->reply[0] = NULL; /* vnode for fid[0] */
1991 call->reply[1] = status;
1992 call->reply[2] = callback;
1993 call->reply[3] = volsync;
1994 call->expected_version = 1; /* vnode->status.data_version */
1995
1996 /* marshall the parameters */
1997 bp = call->request;
1998 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
1999 bp = xdr_encode_u32(bp, 0); /* RPC flags */
2000 bp = xdr_encode_YFSFid(bp, fid);
2001 yfs_check_req(call, bp);
2002
2003 call->cb_break = fc->cb_break;
2004 afs_use_fs_server(call, fc->cbi);
2005 trace_afs_make_fs_call(call, fid);
2006 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
2007}
2008
2009/*
2010 * Deliver reply data to an YFS.InlineBulkStatus call
2011 */
2012static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
2013{
2014 struct afs_file_status *statuses;
2015 struct afs_callback *callbacks;
2016 struct afs_vnode *vnode = call->reply[0];
2017 const __be32 *bp;
2018 u32 tmp;
2019 int ret;
2020
2021 _enter("{%u}", call->unmarshall);
2022
2023 switch (call->unmarshall) {
2024 case 0:
2025 afs_extract_to_tmp(call);
2026 call->unmarshall++;
2027
2028 /* Extract the file status count and array in two steps */
2029 case 1:
2030 _debug("extract status count");
2031 ret = afs_extract_data(call, true);
2032 if (ret < 0)
2033 return ret;
2034
2035 tmp = ntohl(call->tmp);
2036 _debug("status count: %u/%u", tmp, call->count2);
2037 if (tmp != call->count2)
2038 return afs_protocol_error(call, -EBADMSG,
2039 afs_eproto_ibulkst_count);
2040
2041 call->count = 0;
2042 call->unmarshall++;
2043 more_counts:
2044 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
2045
2046 case 2:
2047 _debug("extract status array %u", call->count);
2048 ret = afs_extract_data(call, true);
2049 if (ret < 0)
2050 return ret;
2051
2052 bp = call->buffer;
2053 statuses = call->reply[1];
2054 ret = yfs_decode_status(call, &bp, &statuses[call->count],
2055 call->count == 0 ? vnode : NULL,
2056 NULL, NULL);
2057 if (ret < 0)
2058 return ret;
2059
2060 call->count++;
2061 if (call->count < call->count2)
2062 goto more_counts;
2063
2064 call->count = 0;
2065 call->unmarshall++;
2066 afs_extract_to_tmp(call);
2067
2068 /* Extract the callback count and array in two steps */
2069 case 3:
2070 _debug("extract CB count");
2071 ret = afs_extract_data(call, true);
2072 if (ret < 0)
2073 return ret;
2074
2075 tmp = ntohl(call->tmp);
2076 _debug("CB count: %u", tmp);
2077 if (tmp != call->count2)
2078 return afs_protocol_error(call, -EBADMSG,
2079 afs_eproto_ibulkst_cb_count);
2080 call->count = 0;
2081 call->unmarshall++;
2082 more_cbs:
2083 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack));
2084
2085 case 4:
2086 _debug("extract CB array");
2087 ret = afs_extract_data(call, true);
2088 if (ret < 0)
2089 return ret;
2090
2091 _debug("unmarshall CB array");
2092 bp = call->buffer;
2093 callbacks = call->reply[2];
2094 xdr_decode_YFSCallBack_raw(&bp, &callbacks[call->count]);
2095 statuses = call->reply[1];
2096 if (call->count == 0 && vnode && statuses[0].abort_code == 0) {
2097 bp = call->buffer;
2098 xdr_decode_YFSCallBack(call, vnode, &bp);
2099 }
2100 call->count++;
2101 if (call->count < call->count2)
2102 goto more_cbs;
2103
2104 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
2105 call->unmarshall++;
2106
2107 case 5:
2108 ret = afs_extract_data(call, false);
2109 if (ret < 0)
2110 return ret;
2111
2112 bp = call->buffer;
2113 xdr_decode_YFSVolSync(&bp, call->reply[3]);
2114
2115 call->unmarshall++;
2116
2117 case 6:
2118 break;
2119 }
2120
2121 _leave(" = 0 [done]");
2122 return 0;
2123}
2124
2125/*
2126 * FS.InlineBulkStatus operation type
2127 */
2128static const struct afs_call_type yfs_RXYFSInlineBulkStatus = {
2129 .name = "YFS.InlineBulkStatus",
2130 .op = yfs_FS_InlineBulkStatus,
2131 .deliver = yfs_deliver_fs_inline_bulk_status,
2132 .destructor = afs_flat_call_destructor,
2133};
2134
2135/*
2136 * Fetch the status information for up to 1024 files
2137 */
2138int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
2139 struct afs_net *net,
2140 struct afs_fid *fids,
2141 struct afs_file_status *statuses,
2142 struct afs_callback *callbacks,
2143 unsigned int nr_fids,
2144 struct afs_volsync *volsync)
2145{
2146 struct afs_call *call;
2147 __be32 *bp;
2148 int i;
2149
2150 _enter(",%x,{%llx:%llu},%u",
2151 key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
2152
2153 call = afs_alloc_flat_call(net, &yfs_RXYFSInlineBulkStatus,
2154 sizeof(__be32) +
2155 sizeof(__be32) +
2156 sizeof(__be32) +
2157 sizeof(struct yfs_xdr_YFSFid) * nr_fids,
2158 sizeof(struct yfs_xdr_YFSFetchStatus));
2159 if (!call) {
2160 fc->ac.error = -ENOMEM;
2161 return -ENOMEM;
2162 }
2163
2164 call->key = fc->key;
2165 call->reply[0] = NULL; /* vnode for fid[0] */
2166 call->reply[1] = statuses;
2167 call->reply[2] = callbacks;
2168 call->reply[3] = volsync;
2169 call->count2 = nr_fids;
2170
2171 /* marshall the parameters */
2172 bp = call->request;
2173 bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
2174 bp = xdr_encode_u32(bp, 0); /* RPCFlags */
2175 bp = xdr_encode_u32(bp, nr_fids);
2176 for (i = 0; i < nr_fids; i++)
2177 bp = xdr_encode_YFSFid(bp, &fids[i]);
2178 yfs_check_req(call, bp);
2179
2180 call->cb_break = fc->cb_break;
2181 afs_use_fs_server(call, fc->cbi);
2182 trace_afs_make_fs_call(call, &fids[0]);
2183 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
2184}