Skip to content

Commit

Permalink
afs: Implement YFS support in the fs client
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
dhowells committed Oct 23, 2018
1 parent d493680 commit 30062bd
Show file tree
Hide file tree
Showing 9 changed files with 2,500 additions and 28 deletions.
3 changes: 2 additions & 1 deletion fs/afs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ kafs-y := \
vl_list.o \
volume.o \
write.o \
xattr.o
xattr.o \
yfsclient.o

kafs-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_AFS_FS) := kafs.o
9 changes: 6 additions & 3 deletions fs/afs/callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,10 @@ void afs_init_callback_state(struct afs_server *server)
/*
* actually break a callback
*/
void afs_break_callback(struct afs_vnode *vnode)
void __afs_break_callback(struct afs_vnode *vnode)
{
_enter("");

write_seqlock(&vnode->cb_lock);

clear_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
vnode->cb_break++;
Expand All @@ -230,7 +228,12 @@ void afs_break_callback(struct afs_vnode *vnode)
afs_lock_may_be_available(vnode);
spin_unlock(&vnode->lock);
}
}

void afs_break_callback(struct afs_vnode *vnode)
{
write_seqlock(&vnode->cb_lock);
__afs_break_callback(vnode);
write_sequnlock(&vnode->cb_lock);
}

Expand Down
21 changes: 17 additions & 4 deletions fs/afs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1200,7 +1200,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
if (afs_begin_vnode_operation(&fc, dvnode, key)) {
while (afs_select_fileserver(&fc)) {
fc.cb_break = afs_calc_vnode_cb_break(dvnode);
afs_fs_remove(&fc, dentry->d_name.name, true,
afs_fs_remove(&fc, vnode, dentry->d_name.name, true,
data_version);
}

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

if (dir_valid) {
if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
/* Already done */
} else if (dir_valid) {
drop_nlink(&vnode->vfs_inode);
if (vnode->vfs_inode.i_nlink == 0) {
set_bit(AFS_VNODE_DELETED, &vnode->flags);
Expand Down Expand Up @@ -1274,7 +1276,7 @@ static int afs_dir_remove_link(struct dentry *dentry, struct key *key,
static int afs_unlink(struct inode *dir, struct dentry *dentry)
{
struct afs_fs_cursor fc;
struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode;
struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL;
struct key *key;
unsigned long d_version = (unsigned long)dentry->d_fsdata;
u64 data_version = dvnode->status.data_version;
Expand Down Expand Up @@ -1304,7 +1306,18 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
if (afs_begin_vnode_operation(&fc, dvnode, key)) {
while (afs_select_fileserver(&fc)) {
fc.cb_break = afs_calc_vnode_cb_break(dvnode);
afs_fs_remove(&fc, dentry->d_name.name, false,

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc.cbi->server->flags) &&
!test_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags)) {
yfs_fs_remove_file2(&fc, vnode, dentry->d_name.name,
data_version);
if (fc.ac.error != -ECONNABORTED ||
fc.ac.abort_code != RXGEN_OPCODE)
continue;
set_bit(AFS_SERVER_FL_NO_RM2, &fc.cbi->server->flags);
}

afs_fs_remove(&fc, vnode, dentry->d_name.name, false,
data_version);
}

Expand Down
104 changes: 86 additions & 18 deletions fs/afs/fsclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "internal.h"
#include "afs_fs.h"
#include "xdr_fs.h"
#include "protocol_yfs.h"

static const struct afs_fid afs_zero_fid;

Expand Down Expand Up @@ -312,14 +313,18 @@ static void xdr_decode_AFSVolSync(const __be32 **_bp,
struct afs_volsync *volsync)
{
const __be32 *bp = *_bp;
u32 creation;

volsync->creation = ntohl(*bp++);
creation = ntohl(*bp++);
bp++; /* spare2 */
bp++; /* spare3 */
bp++; /* spare4 */
bp++; /* spare5 */
bp++; /* spare6 */
*_bp = bp;

if (volsync)
volsync->creation = creation;
}

/*
Expand Down Expand Up @@ -380,6 +385,8 @@ static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
vs->blocks_in_use = ntohl(*bp++);
vs->part_blocks_avail = ntohl(*bp++);
vs->part_max_blocks = ntohl(*bp++);
vs->vol_copy_date = 0;
vs->vol_backup_date = 0;
*_bp = bp;
}

Expand All @@ -405,8 +412,7 @@ static int afs_deliver_fs_fetch_status_vnode(struct afs_call *call)
if (ret < 0)
return ret;
xdr_decode_AFSCallBack(call, vnode, &bp);
if (call->reply[1])
xdr_decode_AFSVolSync(&bp, call->reply[1]);
xdr_decode_AFSVolSync(&bp, call->reply[1]);

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

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
return yfs_fs_fetch_file_status(fc, volsync, new_inode);

_enter(",%x,{%llx:%llu},,",
key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);

Expand Down Expand Up @@ -567,8 +576,7 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
if (ret < 0)
return ret;
xdr_decode_AFSCallBack(call, vnode, &bp);
if (call->reply[1])
xdr_decode_AFSVolSync(&bp, call->reply[1]);
xdr_decode_AFSVolSync(&bp, call->reply[1]);

call->unmarshall++;

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

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
return yfs_fs_fetch_data(fc, req);

if (upper_32_bits(req->pos) ||
upper_32_bits(req->len) ||
upper_32_bits(req->pos + req->len))
Expand Down Expand Up @@ -765,6 +776,15 @@ int afs_fs_create(struct afs_fs_cursor *fc,
size_t namesz, reqsz, padsz;
__be32 *bp;

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)){
if (S_ISDIR(mode))
return yfs_fs_make_dir(fc, name, mode, current_data_version,
newfid, newstatus, newcb);
else
return yfs_fs_create_file(fc, name, mode, current_data_version,
newfid, newstatus, newcb);
}

_enter("");

namesz = strlen(name);
Expand Down Expand Up @@ -857,15 +877,18 @@ static const struct afs_call_type afs_RXFSRemoveDir = {
/*
* remove a file or directory
*/
int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir,
u64 current_data_version)
int afs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
const char *name, bool isdir, u64 current_data_version)
{
struct afs_vnode *vnode = fc->vnode;
struct afs_vnode *dvnode = fc->vnode;
struct afs_call *call;
struct afs_net *net = afs_v2net(vnode);
struct afs_net *net = afs_v2net(dvnode);
size_t namesz, reqsz, padsz;
__be32 *bp;

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
return yfs_fs_remove(fc, vnode, name, isdir, current_data_version);

_enter("");

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

call->key = fc->key;
call->reply[0] = vnode;
call->reply[0] = dvnode;
call->reply[1] = vnode;
call->expected_version = current_data_version + 1;

/* marshall the parameters */
bp = call->request;
*bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
*bp++ = htonl(vnode->fid.vid);
*bp++ = htonl(vnode->fid.vnode);
*bp++ = htonl(vnode->fid.unique);
*bp++ = htonl(dvnode->fid.vid);
*bp++ = htonl(dvnode->fid.vnode);
*bp++ = htonl(dvnode->fid.unique);
*bp++ = htonl(namesz);
memcpy(bp, name, namesz);
bp = (void *) bp + namesz;
Expand All @@ -897,7 +921,7 @@ int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir,
}

afs_use_fs_server(call, fc->cbi);
trace_afs_make_fs_call(call, &vnode->fid);
trace_afs_make_fs_call(call, &dvnode->fid);
return afs_make_call(&fc->ac, call, GFP_NOFS, false);
}

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

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
return yfs_fs_link(fc, vnode, name, current_data_version);

_enter("");

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

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
return yfs_fs_symlink(fc, name, contents, current_data_version,
newfid, newstatus);

_enter("");

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

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
return yfs_fs_rename(fc, orig_name,
new_dvnode, new_name,
current_orig_data_version,
current_new_data_version);

_enter("");

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

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
return yfs_fs_store_data(fc, mapping, first, last, offset, to);

_enter(",%x,{%llx:%llu},,",
key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);

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

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
return yfs_fs_setattr(fc, attr);

if (attr->ia_valid & ATTR_SIZE)
return afs_fs_setattr_size(fc, attr);

Expand Down Expand Up @@ -1728,6 +1771,9 @@ int afs_fs_get_volume_status(struct afs_fs_cursor *fc,
__be32 *bp;
void *tmpbuf;

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
return yfs_fs_get_volume_status(fc, vs);

_enter("");

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

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
return yfs_fs_set_lock(fc, type);

_enter("");

call = afs_alloc_flat_call(net, &afs_RXFSSetLock, 5 * 4, 6 * 4);
Expand Down Expand Up @@ -1849,6 +1898,9 @@ int afs_fs_extend_lock(struct afs_fs_cursor *fc)
struct afs_net *net = afs_v2net(vnode);
__be32 *bp;

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
return yfs_fs_extend_lock(fc);

_enter("");

call = afs_alloc_flat_call(net, &afs_RXFSExtendLock, 4 * 4, 6 * 4);
Expand Down Expand Up @@ -1880,6 +1932,9 @@ int afs_fs_release_lock(struct afs_fs_cursor *fc)
struct afs_net *net = afs_v2net(vnode);
__be32 *bp;

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
return yfs_fs_release_lock(fc);

_enter("");

call = afs_alloc_flat_call(net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4);
Expand Down Expand Up @@ -1951,6 +2006,7 @@ int afs_fs_give_up_all_callbacks(struct afs_net *net,
*/
static int afs_deliver_fs_get_capabilities(struct afs_call *call)
{
struct afs_server *server = call->reply[0];
u32 count;
int ret;

Expand Down Expand Up @@ -1986,6 +2042,11 @@ static int afs_deliver_fs_get_capabilities(struct afs_call *call)
break;
}

if (call->service_id == YFS_FS_SERVICE)
set_bit(AFS_SERVER_FL_IS_YFS, &server->flags);
else
clear_bit(AFS_SERVER_FL_IS_YFS, &server->flags);

_leave(" = 0 [done]");
return 0;
}
Expand Down Expand Up @@ -2019,6 +2080,8 @@ int afs_fs_get_capabilities(struct afs_net *net,
return -ENOMEM;

call->key = key;
call->reply[0] = server;
call->upgrade = true;

/* marshall the parameters */
bp = call->request;
Expand Down Expand Up @@ -2054,8 +2117,7 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call)
if (ret < 0)
return ret;
xdr_decode_AFSCallBack_raw(call, &bp, callback);
if (volsync)
xdr_decode_AFSVolSync(&bp, volsync);
xdr_decode_AFSVolSync(&bp, volsync);

_leave(" = 0 [done]");
return 0;
Expand Down Expand Up @@ -2084,6 +2146,9 @@ int afs_fs_fetch_status(struct afs_fs_cursor *fc,
struct afs_call *call;
__be32 *bp;

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
return yfs_fs_fetch_status(fc, net, fid, status, callback, volsync);

_enter(",%x,{%llx:%llu},,",
key_serial(fc->key), fid->vid, fid->vnode);

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

bp = call->buffer;
if (call->reply[3])
xdr_decode_AFSVolSync(&bp, call->reply[3]);
xdr_decode_AFSVolSync(&bp, call->reply[3]);

call->unmarshall++;

Expand Down Expand Up @@ -2256,6 +2320,10 @@ int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
__be32 *bp;
int i;

if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
return yfs_fs_inline_bulk_status(fc, net, fids, statuses, callbacks,
nr_fids, volsync);

_enter(",%x,{%llx:%llu},%u",
key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);

Expand Down
Loading

0 comments on commit 30062bd

Please sign in to comment.