@@ -293,9 +293,33 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call,
293
293
case 0 :
294
294
call -> offset = 0 ;
295
295
call -> unmarshall ++ ;
296
+ if (call -> operation_ID != FSFETCHDATA64 ) {
297
+ call -> unmarshall ++ ;
298
+ goto no_msw ;
299
+ }
296
300
297
- /* extract the returned data length */
301
+ /* extract the upper part of the returned data length of an
302
+ * FSFETCHDATA64 op (which should always be 0 using this
303
+ * client) */
298
304
case 1 :
305
+ _debug ("extract data length (MSW)" );
306
+ ret = afs_extract_data (call , skb , last , & call -> tmp , 4 );
307
+ switch (ret ) {
308
+ case 0 : break ;
309
+ case - EAGAIN : return 0 ;
310
+ default : return ret ;
311
+ }
312
+
313
+ call -> count = ntohl (call -> tmp );
314
+ _debug ("DATA length MSW: %u" , call -> count );
315
+ if (call -> count > 0 )
316
+ return - EBADMSG ;
317
+ call -> offset = 0 ;
318
+ call -> unmarshall ++ ;
319
+
320
+ no_msw :
321
+ /* extract the returned data length */
322
+ case 2 :
299
323
_debug ("extract data length" );
300
324
ret = afs_extract_data (call , skb , last , & call -> tmp , 4 );
301
325
switch (ret ) {
@@ -312,7 +336,7 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call,
312
336
call -> unmarshall ++ ;
313
337
314
338
/* extract the returned data */
315
- case 2 :
339
+ case 3 :
316
340
_debug ("extract data" );
317
341
if (call -> count > 0 ) {
318
342
page = call -> reply3 ;
@@ -331,7 +355,7 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call,
331
355
call -> unmarshall ++ ;
332
356
333
357
/* extract the metadata */
334
- case 3 :
358
+ case 4 :
335
359
ret = afs_extract_data (call , skb , last , call -> buffer ,
336
360
(21 + 3 + 6 ) * 4 );
337
361
switch (ret ) {
@@ -349,7 +373,7 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call,
349
373
call -> offset = 0 ;
350
374
call -> unmarshall ++ ;
351
375
352
- case 4 :
376
+ case 5 :
353
377
_debug ("trailer" );
354
378
if (skb -> len != 0 )
355
379
return - EBADMSG ;
@@ -381,6 +405,56 @@ static const struct afs_call_type afs_RXFSFetchData = {
381
405
.destructor = afs_flat_call_destructor ,
382
406
};
383
407
408
+ static const struct afs_call_type afs_RXFSFetchData64 = {
409
+ .name = "FS.FetchData64" ,
410
+ .deliver = afs_deliver_fs_fetch_data ,
411
+ .abort_to_error = afs_abort_to_error ,
412
+ .destructor = afs_flat_call_destructor ,
413
+ };
414
+
415
+ /*
416
+ * fetch data from a very large file
417
+ */
418
+ static int afs_fs_fetch_data64 (struct afs_server * server ,
419
+ struct key * key ,
420
+ struct afs_vnode * vnode ,
421
+ off_t offset , size_t length ,
422
+ struct page * buffer ,
423
+ const struct afs_wait_mode * wait_mode )
424
+ {
425
+ struct afs_call * call ;
426
+ __be32 * bp ;
427
+
428
+ _enter ("" );
429
+
430
+ ASSERTCMP (length , < , ULONG_MAX );
431
+
432
+ call = afs_alloc_flat_call (& afs_RXFSFetchData64 , 32 , (21 + 3 + 6 ) * 4 );
433
+ if (!call )
434
+ return - ENOMEM ;
435
+
436
+ call -> key = key ;
437
+ call -> reply = vnode ;
438
+ call -> reply2 = NULL ; /* volsync */
439
+ call -> reply3 = buffer ;
440
+ call -> service_id = FS_SERVICE ;
441
+ call -> port = htons (AFS_FS_PORT );
442
+ call -> operation_ID = FSFETCHDATA64 ;
443
+
444
+ /* marshall the parameters */
445
+ bp = call -> request ;
446
+ bp [0 ] = htonl (FSFETCHDATA64 );
447
+ bp [1 ] = htonl (vnode -> fid .vid );
448
+ bp [2 ] = htonl (vnode -> fid .vnode );
449
+ bp [3 ] = htonl (vnode -> fid .unique );
450
+ bp [4 ] = htonl (upper_32_bits (offset ));
451
+ bp [5 ] = htonl ((u32 ) offset );
452
+ bp [6 ] = 0 ;
453
+ bp [7 ] = htonl ((u32 ) length );
454
+
455
+ return afs_make_call (& server -> addr , call , GFP_NOFS , wait_mode );
456
+ }
457
+
384
458
/*
385
459
* fetch data from a file
386
460
*/
@@ -394,6 +468,10 @@ int afs_fs_fetch_data(struct afs_server *server,
394
468
struct afs_call * call ;
395
469
__be32 * bp ;
396
470
471
+ if (upper_32_bits (offset ) || upper_32_bits (offset + length ))
472
+ return afs_fs_fetch_data64 (server , key , vnode , offset , length ,
473
+ buffer , wait_mode );
474
+
397
475
_enter ("" );
398
476
399
477
call = afs_alloc_flat_call (& afs_RXFSFetchData , 24 , (21 + 3 + 6 ) * 4 );
@@ -406,6 +484,7 @@ int afs_fs_fetch_data(struct afs_server *server,
406
484
call -> reply3 = buffer ;
407
485
call -> service_id = FS_SERVICE ;
408
486
call -> port = htons (AFS_FS_PORT );
487
+ call -> operation_ID = FSFETCHDATA ;
409
488
410
489
/* marshall the parameters */
411
490
bp = call -> request ;
@@ -1032,6 +1111,73 @@ static const struct afs_call_type afs_RXFSStoreData = {
1032
1111
.destructor = afs_flat_call_destructor ,
1033
1112
};
1034
1113
1114
+ static const struct afs_call_type afs_RXFSStoreData64 = {
1115
+ .name = "FS.StoreData64" ,
1116
+ .deliver = afs_deliver_fs_store_data ,
1117
+ .abort_to_error = afs_abort_to_error ,
1118
+ .destructor = afs_flat_call_destructor ,
1119
+ };
1120
+
1121
+ /*
1122
+ * store a set of pages to a very large file
1123
+ */
1124
+ static int afs_fs_store_data64 (struct afs_server * server ,
1125
+ struct afs_writeback * wb ,
1126
+ pgoff_t first , pgoff_t last ,
1127
+ unsigned offset , unsigned to ,
1128
+ loff_t size , loff_t pos , loff_t i_size ,
1129
+ const struct afs_wait_mode * wait_mode )
1130
+ {
1131
+ struct afs_vnode * vnode = wb -> vnode ;
1132
+ struct afs_call * call ;
1133
+ __be32 * bp ;
1134
+
1135
+ _enter (",%x,{%x:%u},," ,
1136
+ key_serial (wb -> key ), vnode -> fid .vid , vnode -> fid .vnode );
1137
+
1138
+ call = afs_alloc_flat_call (& afs_RXFSStoreData64 ,
1139
+ (4 + 6 + 3 * 2 ) * 4 ,
1140
+ (21 + 6 ) * 4 );
1141
+ if (!call )
1142
+ return - ENOMEM ;
1143
+
1144
+ call -> wb = wb ;
1145
+ call -> key = wb -> key ;
1146
+ call -> reply = vnode ;
1147
+ call -> service_id = FS_SERVICE ;
1148
+ call -> port = htons (AFS_FS_PORT );
1149
+ call -> mapping = vnode -> vfs_inode .i_mapping ;
1150
+ call -> first = first ;
1151
+ call -> last = last ;
1152
+ call -> first_offset = offset ;
1153
+ call -> last_to = to ;
1154
+ call -> send_pages = true;
1155
+ call -> store_version = vnode -> status .data_version + 1 ;
1156
+
1157
+ /* marshall the parameters */
1158
+ bp = call -> request ;
1159
+ * bp ++ = htonl (FSSTOREDATA64 );
1160
+ * bp ++ = htonl (vnode -> fid .vid );
1161
+ * bp ++ = htonl (vnode -> fid .vnode );
1162
+ * bp ++ = htonl (vnode -> fid .unique );
1163
+
1164
+ * bp ++ = 0 ; /* mask */
1165
+ * bp ++ = 0 ; /* mtime */
1166
+ * bp ++ = 0 ; /* owner */
1167
+ * bp ++ = 0 ; /* group */
1168
+ * bp ++ = 0 ; /* unix mode */
1169
+ * bp ++ = 0 ; /* segment size */
1170
+
1171
+ * bp ++ = htonl (pos >> 32 );
1172
+ * bp ++ = htonl ((u32 ) pos );
1173
+ * bp ++ = htonl (size >> 32 );
1174
+ * bp ++ = htonl ((u32 ) size );
1175
+ * bp ++ = htonl (i_size >> 32 );
1176
+ * bp ++ = htonl ((u32 ) i_size );
1177
+
1178
+ return afs_make_call (& server -> addr , call , GFP_NOFS , wait_mode );
1179
+ }
1180
+
1035
1181
/*
1036
1182
* store a set of pages
1037
1183
*/
@@ -1062,7 +1208,9 @@ int afs_fs_store_data(struct afs_server *server, struct afs_writeback *wb,
1062
1208
(unsigned long long ) size , (unsigned long long ) pos ,
1063
1209
(unsigned long long ) i_size );
1064
1210
1065
- BUG_ON (i_size > 0xffffffff ); // TODO: use 64-bit store
1211
+ if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size ) >> 32 )
1212
+ return afs_fs_store_data64 (server , wb , first , last , offset , to ,
1213
+ size , pos , i_size , wait_mode );
1066
1214
1067
1215
call = afs_alloc_flat_call (& afs_RXFSStoreData ,
1068
1216
(4 + 6 + 3 ) * 4 ,
@@ -1158,6 +1306,61 @@ static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1158
1306
.destructor = afs_flat_call_destructor ,
1159
1307
};
1160
1308
1309
+ static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1310
+ .name = "FS.StoreData64" ,
1311
+ .deliver = afs_deliver_fs_store_status ,
1312
+ .abort_to_error = afs_abort_to_error ,
1313
+ .destructor = afs_flat_call_destructor ,
1314
+ };
1315
+
1316
+ /*
1317
+ * set the attributes on a very large file, using FS.StoreData rather than
1318
+ * FS.StoreStatus so as to alter the file size also
1319
+ */
1320
+ static int afs_fs_setattr_size64 (struct afs_server * server , struct key * key ,
1321
+ struct afs_vnode * vnode , struct iattr * attr ,
1322
+ const struct afs_wait_mode * wait_mode )
1323
+ {
1324
+ struct afs_call * call ;
1325
+ __be32 * bp ;
1326
+
1327
+ _enter (",%x,{%x:%u},," ,
1328
+ key_serial (key ), vnode -> fid .vid , vnode -> fid .vnode );
1329
+
1330
+ ASSERT (attr -> ia_valid & ATTR_SIZE );
1331
+
1332
+ call = afs_alloc_flat_call (& afs_RXFSStoreData64_as_Status ,
1333
+ (4 + 6 + 3 * 2 ) * 4 ,
1334
+ (21 + 6 ) * 4 );
1335
+ if (!call )
1336
+ return - ENOMEM ;
1337
+
1338
+ call -> key = key ;
1339
+ call -> reply = vnode ;
1340
+ call -> service_id = FS_SERVICE ;
1341
+ call -> port = htons (AFS_FS_PORT );
1342
+ call -> store_version = vnode -> status .data_version + 1 ;
1343
+ call -> operation_ID = FSSTOREDATA ;
1344
+
1345
+ /* marshall the parameters */
1346
+ bp = call -> request ;
1347
+ * bp ++ = htonl (FSSTOREDATA64 );
1348
+ * bp ++ = htonl (vnode -> fid .vid );
1349
+ * bp ++ = htonl (vnode -> fid .vnode );
1350
+ * bp ++ = htonl (vnode -> fid .unique );
1351
+
1352
+ xdr_encode_AFS_StoreStatus (& bp , attr );
1353
+
1354
+ * bp ++ = 0 ; /* position of start of write */
1355
+ * bp ++ = 0 ;
1356
+ * bp ++ = 0 ; /* size of write */
1357
+ * bp ++ = 0 ;
1358
+ * bp ++ = htonl (attr -> ia_size >> 32 ); /* new file length */
1359
+ * bp ++ = htonl ((u32 ) attr -> ia_size );
1360
+
1361
+ return afs_make_call (& server -> addr , call , GFP_NOFS , wait_mode );
1362
+ }
1363
+
1161
1364
/*
1162
1365
* set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1163
1366
* so as to alter the file size also
@@ -1173,7 +1376,9 @@ static int afs_fs_setattr_size(struct afs_server *server, struct key *key,
1173
1376
key_serial (key ), vnode -> fid .vid , vnode -> fid .vnode );
1174
1377
1175
1378
ASSERT (attr -> ia_valid & ATTR_SIZE );
1176
- ASSERTCMP (attr -> ia_size , <=, 0xffffffff ); // TODO: use 64-bit store
1379
+ if (attr -> ia_size >> 32 )
1380
+ return afs_fs_setattr_size64 (server , key , vnode , attr ,
1381
+ wait_mode );
1177
1382
1178
1383
call = afs_alloc_flat_call (& afs_RXFSStoreData_as_Status ,
1179
1384
(4 + 6 + 3 ) * 4 ,
0 commit comments