Skip to content

Commit 30062bd

Browse files
committed
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 <[email protected]>
1 parent d493680 commit 30062bd

File tree

9 files changed

+2500
-28
lines changed

9 files changed

+2500
-28
lines changed

fs/afs/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ kafs-y := \
3333
vl_list.o \
3434
volume.o \
3535
write.o \
36-
xattr.o
36+
xattr.o \
37+
yfsclient.o
3738

3839
kafs-$(CONFIG_PROC_FS) += proc.o
3940
obj-$(CONFIG_AFS_FS) := kafs.o

fs/afs/callback.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,10 @@ void afs_init_callback_state(struct afs_server *server)
210210
/*
211211
* actually break a callback
212212
*/
213-
void afs_break_callback(struct afs_vnode *vnode)
213+
void __afs_break_callback(struct afs_vnode *vnode)
214214
{
215215
_enter("");
216216

217-
write_seqlock(&vnode->cb_lock);
218-
219217
clear_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
220218
if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
221219
vnode->cb_break++;
@@ -230,7 +228,12 @@ void afs_break_callback(struct afs_vnode *vnode)
230228
afs_lock_may_be_available(vnode);
231229
spin_unlock(&vnode->lock);
232230
}
231+
}
233232

233+
void afs_break_callback(struct afs_vnode *vnode)
234+
{
235+
write_seqlock(&vnode->cb_lock);
236+
__afs_break_callback(vnode);
234237
write_sequnlock(&vnode->cb_lock);
235238
}
236239

fs/afs/dir.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,7 +1200,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
12001200
if (afs_begin_vnode_operation(&fc, dvnode, key)) {
12011201
while (afs_select_fileserver(&fc)) {
12021202
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,
12041204
data_version);
12051205
}
12061206

@@ -1245,7 +1245,9 @@ static int afs_dir_remove_link(struct dentry *dentry, struct key *key,
12451245
if (d_really_is_positive(dentry)) {
12461246
struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
12471247

1248-
if (dir_valid) {
1248+
if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
1249+
/* Already done */
1250+
} else if (dir_valid) {
12491251
drop_nlink(&vnode->vfs_inode);
12501252
if (vnode->vfs_inode.i_nlink == 0) {
12511253
set_bit(AFS_VNODE_DELETED, &vnode->flags);
@@ -1274,7 +1276,7 @@ static int afs_dir_remove_link(struct dentry *dentry, struct key *key,
12741276
static int afs_unlink(struct inode *dir, struct dentry *dentry)
12751277
{
12761278
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;
12781280
struct key *key;
12791281
unsigned long d_version = (unsigned long)dentry->d_fsdata;
12801282
u64 data_version = dvnode->status.data_version;
@@ -1304,7 +1306,18 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
13041306
if (afs_begin_vnode_operation(&fc, dvnode, key)) {
13051307
while (afs_select_fileserver(&fc)) {
13061308
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,
13081321
data_version);
13091322
}
13101323

fs/afs/fsclient.c

Lines changed: 86 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "internal.h"
1818
#include "afs_fs.h"
1919
#include "xdr_fs.h"
20+
#include "protocol_yfs.h"
2021

2122
static const struct afs_fid afs_zero_fid;
2223

@@ -312,14 +313,18 @@ static void xdr_decode_AFSVolSync(const __be32 **_bp,
312313
struct afs_volsync *volsync)
313314
{
314315
const __be32 *bp = *_bp;
316+
u32 creation;
315317

316-
volsync->creation = ntohl(*bp++);
318+
creation = ntohl(*bp++);
317319
bp++; /* spare2 */
318320
bp++; /* spare3 */
319321
bp++; /* spare4 */
320322
bp++; /* spare5 */
321323
bp++; /* spare6 */
322324
*_bp = bp;
325+
326+
if (volsync)
327+
volsync->creation = creation;
323328
}
324329

325330
/*
@@ -380,6 +385,8 @@ static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
380385
vs->blocks_in_use = ntohl(*bp++);
381386
vs->part_blocks_avail = ntohl(*bp++);
382387
vs->part_max_blocks = ntohl(*bp++);
388+
vs->vol_copy_date = 0;
389+
vs->vol_backup_date = 0;
383390
*_bp = bp;
384391
}
385392

@@ -405,8 +412,7 @@ static int afs_deliver_fs_fetch_status_vnode(struct afs_call *call)
405412
if (ret < 0)
406413
return ret;
407414
xdr_decode_AFSCallBack(call, vnode, &bp);
408-
if (call->reply[1])
409-
xdr_decode_AFSVolSync(&bp, call->reply[1]);
415+
xdr_decode_AFSVolSync(&bp, call->reply[1]);
410416

411417
_leave(" = 0 [done]");
412418
return 0;
@@ -433,6 +439,9 @@ int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsy
433439
struct afs_net *net = afs_v2net(vnode);
434440
__be32 *bp;
435441

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+
436445
_enter(",%x,{%llx:%llu},,",
437446
key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
438447

@@ -567,8 +576,7 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
567576
if (ret < 0)
568577
return ret;
569578
xdr_decode_AFSCallBack(call, vnode, &bp);
570-
if (call->reply[1])
571-
xdr_decode_AFSVolSync(&bp, call->reply[1]);
579+
xdr_decode_AFSVolSync(&bp, call->reply[1]);
572580

573581
call->unmarshall++;
574582

@@ -665,6 +673,9 @@ int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
665673
struct afs_net *net = afs_v2net(vnode);
666674
__be32 *bp;
667675

676+
if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
677+
return yfs_fs_fetch_data(fc, req);
678+
668679
if (upper_32_bits(req->pos) ||
669680
upper_32_bits(req->len) ||
670681
upper_32_bits(req->pos + req->len))
@@ -765,6 +776,15 @@ int afs_fs_create(struct afs_fs_cursor *fc,
765776
size_t namesz, reqsz, padsz;
766777
__be32 *bp;
767778

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+
768788
_enter("");
769789

770790
namesz = strlen(name);
@@ -857,15 +877,18 @@ static const struct afs_call_type afs_RXFSRemoveDir = {
857877
/*
858878
* remove a file or directory
859879
*/
860-
int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir,
861-
u64 current_data_version)
880+
int afs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
881+
const char *name, bool isdir, u64 current_data_version)
862882
{
863-
struct afs_vnode *vnode = fc->vnode;
883+
struct afs_vnode *dvnode = fc->vnode;
864884
struct afs_call *call;
865-
struct afs_net *net = afs_v2net(vnode);
885+
struct afs_net *net = afs_v2net(dvnode);
866886
size_t namesz, reqsz, padsz;
867887
__be32 *bp;
868888

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+
869892
_enter("");
870893

871894
namesz = strlen(name);
@@ -879,15 +902,16 @@ int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir,
879902
return -ENOMEM;
880903

881904
call->key = fc->key;
882-
call->reply[0] = vnode;
905+
call->reply[0] = dvnode;
906+
call->reply[1] = vnode;
883907
call->expected_version = current_data_version + 1;
884908

885909
/* marshall the parameters */
886910
bp = call->request;
887911
*bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
888-
*bp++ = htonl(vnode->fid.vid);
889-
*bp++ = htonl(vnode->fid.vnode);
890-
*bp++ = htonl(vnode->fid.unique);
912+
*bp++ = htonl(dvnode->fid.vid);
913+
*bp++ = htonl(dvnode->fid.vnode);
914+
*bp++ = htonl(dvnode->fid.unique);
891915
*bp++ = htonl(namesz);
892916
memcpy(bp, name, namesz);
893917
bp = (void *) bp + namesz;
@@ -897,7 +921,7 @@ int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir,
897921
}
898922

899923
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);
901925
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
902926
}
903927

@@ -953,6 +977,9 @@ int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
953977
size_t namesz, reqsz, padsz;
954978
__be32 *bp;
955979

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+
956983
_enter("");
957984

958985
namesz = strlen(name);
@@ -1047,6 +1074,10 @@ int afs_fs_symlink(struct afs_fs_cursor *fc,
10471074
size_t namesz, reqsz, padsz, c_namesz, c_padsz;
10481075
__be32 *bp;
10491076

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+
10501081
_enter("");
10511082

10521083
namesz = strlen(name);
@@ -1159,6 +1190,12 @@ int afs_fs_rename(struct afs_fs_cursor *fc,
11591190
size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
11601191
__be32 *bp;
11611192

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+
11621199
_enter("");
11631200

11641201
o_namesz = strlen(orig_name);
@@ -1329,6 +1366,9 @@ int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
13291366
loff_t size, pos, i_size;
13301367
__be32 *bp;
13311368

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+
13321372
_enter(",%x,{%llx:%llu},,",
13331373
key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
13341374

@@ -1544,6 +1584,9 @@ int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
15441584
struct afs_net *net = afs_v2net(vnode);
15451585
__be32 *bp;
15461586

1587+
if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1588+
return yfs_fs_setattr(fc, attr);
1589+
15471590
if (attr->ia_valid & ATTR_SIZE)
15481591
return afs_fs_setattr_size(fc, attr);
15491592

@@ -1728,6 +1771,9 @@ int afs_fs_get_volume_status(struct afs_fs_cursor *fc,
17281771
__be32 *bp;
17291772
void *tmpbuf;
17301773

1774+
if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1775+
return yfs_fs_get_volume_status(fc, vs);
1776+
17311777
_enter("");
17321778

17331779
tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
@@ -1817,6 +1863,9 @@ int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
18171863
struct afs_net *net = afs_v2net(vnode);
18181864
__be32 *bp;
18191865

1866+
if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1867+
return yfs_fs_set_lock(fc, type);
1868+
18201869
_enter("");
18211870

18221871
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)
18491898
struct afs_net *net = afs_v2net(vnode);
18501899
__be32 *bp;
18511900

1901+
if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1902+
return yfs_fs_extend_lock(fc);
1903+
18521904
_enter("");
18531905

18541906
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)
18801932
struct afs_net *net = afs_v2net(vnode);
18811933
__be32 *bp;
18821934

1935+
if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1936+
return yfs_fs_release_lock(fc);
1937+
18831938
_enter("");
18841939

18851940
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,
19512006
*/
19522007
static int afs_deliver_fs_get_capabilities(struct afs_call *call)
19532008
{
2009+
struct afs_server *server = call->reply[0];
19542010
u32 count;
19552011
int ret;
19562012

@@ -1986,6 +2042,11 @@ static int afs_deliver_fs_get_capabilities(struct afs_call *call)
19862042
break;
19872043
}
19882044

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+
19892050
_leave(" = 0 [done]");
19902051
return 0;
19912052
}
@@ -2019,6 +2080,8 @@ int afs_fs_get_capabilities(struct afs_net *net,
20192080
return -ENOMEM;
20202081

20212082
call->key = key;
2083+
call->reply[0] = server;
2084+
call->upgrade = true;
20222085

20232086
/* marshall the parameters */
20242087
bp = call->request;
@@ -2054,8 +2117,7 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call)
20542117
if (ret < 0)
20552118
return ret;
20562119
xdr_decode_AFSCallBack_raw(call, &bp, callback);
2057-
if (volsync)
2058-
xdr_decode_AFSVolSync(&bp, volsync);
2120+
xdr_decode_AFSVolSync(&bp, volsync);
20592121

20602122
_leave(" = 0 [done]");
20612123
return 0;
@@ -2084,6 +2146,9 @@ int afs_fs_fetch_status(struct afs_fs_cursor *fc,
20842146
struct afs_call *call;
20852147
__be32 *bp;
20862148

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+
20872152
_enter(",%x,{%llx:%llu},,",
20882153
key_serial(fc->key), fid->vid, fid->vnode);
20892154

@@ -2218,8 +2283,7 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)
22182283
return ret;
22192284

22202285
bp = call->buffer;
2221-
if (call->reply[3])
2222-
xdr_decode_AFSVolSync(&bp, call->reply[3]);
2286+
xdr_decode_AFSVolSync(&bp, call->reply[3]);
22232287

22242288
call->unmarshall++;
22252289

@@ -2256,6 +2320,10 @@ int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
22562320
__be32 *bp;
22572321
int i;
22582322

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+
22592327
_enter(",%x,{%llx:%llu},%u",
22602328
key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
22612329

0 commit comments

Comments
 (0)