mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-08 14:23:19 +00:00
afs: Detect cell aliases 3 - YFS Cells with a canonical cell name op
YFS Volume Location servers have an operation by which the cell name may be queried. Use this to find out what a YFS server thinks the canonical cell name should be. Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
parent
6ef350b184
commit
6dfdf5369c
@ -268,12 +268,70 @@ static int afs_query_for_alias(struct afs_cell *cell, struct key *key)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up a VLDB record for a volume.
|
||||
*/
|
||||
static char *afs_vl_get_cell_name(struct afs_cell *cell, struct key *key)
|
||||
{
|
||||
struct afs_vl_cursor vc;
|
||||
char *cell_name = ERR_PTR(-EDESTADDRREQ);
|
||||
bool skipped = false, not_skipped = false;
|
||||
int ret;
|
||||
|
||||
if (!afs_begin_vlserver_operation(&vc, cell, key))
|
||||
return ERR_PTR(-ERESTARTSYS);
|
||||
|
||||
while (afs_select_vlserver(&vc)) {
|
||||
if (!test_bit(AFS_VLSERVER_FL_IS_YFS, &vc.server->flags)) {
|
||||
vc.ac.error = -EOPNOTSUPP;
|
||||
skipped = true;
|
||||
continue;
|
||||
}
|
||||
not_skipped = true;
|
||||
cell_name = afs_yfsvl_get_cell_name(&vc);
|
||||
}
|
||||
|
||||
ret = afs_end_vlserver_operation(&vc);
|
||||
if (skipped && !not_skipped)
|
||||
ret = -EOPNOTSUPP;
|
||||
return ret < 0 ? ERR_PTR(ret) : cell_name;
|
||||
}
|
||||
|
||||
static int yfs_check_canonical_cell_name(struct afs_cell *cell, struct key *key)
|
||||
{
|
||||
struct afs_cell *master;
|
||||
char *cell_name;
|
||||
|
||||
cell_name = afs_vl_get_cell_name(cell, key);
|
||||
if (IS_ERR(cell_name))
|
||||
return PTR_ERR(cell_name);
|
||||
|
||||
if (strcmp(cell_name, cell->name) == 0) {
|
||||
kfree(cell_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
master = afs_lookup_cell(cell->net, cell_name, strlen(cell_name),
|
||||
NULL, false);
|
||||
kfree(cell_name);
|
||||
if (IS_ERR(master))
|
||||
return PTR_ERR(master);
|
||||
|
||||
cell->alias_of = master; /* Transfer our ref */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int afs_do_cell_detect_alias(struct afs_cell *cell, struct key *key)
|
||||
{
|
||||
struct afs_volume *root_volume;
|
||||
int ret;
|
||||
|
||||
_enter("%s", cell->name);
|
||||
|
||||
ret = yfs_check_canonical_cell_name(cell, key);
|
||||
if (ret != -EOPNOTSUPP)
|
||||
return ret;
|
||||
|
||||
/* Try and get the root.cell volume for comparison with other cells */
|
||||
root_volume = afs_sample_volume(cell, key, "root.cell", 9);
|
||||
if (!IS_ERR(root_volume)) {
|
||||
|
@ -151,6 +151,10 @@ bool afs_select_vlserver(struct afs_vl_cursor *vc)
|
||||
vc->error = error;
|
||||
vc->flags |= AFS_VL_CURSOR_RETRY;
|
||||
goto next_server;
|
||||
|
||||
case -EOPNOTSUPP:
|
||||
_debug("notsupp");
|
||||
goto next_server;
|
||||
}
|
||||
|
||||
restart_from_beginning:
|
||||
|
Loading…
Reference in New Issue
Block a user