mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 20:54:10 +08:00
afs: Allow dumping of server cursor on operation failure
Provide an option to allow the file or volume location server cursor to be dumped if the rotation routine falls off the end without managing to contact a server. Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
parent
30062bd13e
commit
744bcd713a
@ -27,3 +27,15 @@ config AFS_FSCACHE
|
||||
help
|
||||
Say Y here if you want AFS data to be cached locally on disk through
|
||||
the generic filesystem cache manager
|
||||
|
||||
config AFS_DEBUG_CURSOR
|
||||
bool "AFS server cursor debugging"
|
||||
depends on AFS_FS
|
||||
help
|
||||
Say Y here to cause the contents of a server cursor to be dumped to
|
||||
the dmesg log if the server rotation algorithm fails to successfully
|
||||
contact a server.
|
||||
|
||||
See <file:Documentation/filesystems/afs.txt> for more information.
|
||||
|
||||
If unsure, say N.
|
||||
|
@ -358,6 +358,8 @@ bool afs_iterate_addresses(struct afs_addr_cursor *ac)
|
||||
if (!ac->alist)
|
||||
return false;
|
||||
|
||||
ac->nr_iterations++;
|
||||
|
||||
if (ac->begun) {
|
||||
ac->index++;
|
||||
if (ac->index == ac->alist->nr_addrs)
|
||||
|
@ -660,6 +660,7 @@ struct afs_addr_cursor {
|
||||
short error;
|
||||
bool begun; /* T if we've begun iteration */
|
||||
bool responded; /* T if the current address responded */
|
||||
unsigned short nr_iterations; /* Number of address iterations */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -677,6 +678,7 @@ struct afs_vl_cursor {
|
||||
#define AFS_VL_CURSOR_STOP 0x0001 /* Set to cease iteration */
|
||||
#define AFS_VL_CURSOR_RETRY 0x0002 /* Set to do a retry */
|
||||
#define AFS_VL_CURSOR_RETRIED 0x0004 /* Set if started a retry */
|
||||
unsigned short nr_iterations; /* Number of server iterations */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -700,6 +702,7 @@ struct afs_fs_cursor {
|
||||
#define AFS_FS_CURSOR_VNOVOL 0x0008 /* Set if seen VNOVOL */
|
||||
#define AFS_FS_CURSOR_CUR_ONLY 0x0010 /* Set if current server only (file lock held) */
|
||||
#define AFS_FS_CURSOR_NO_VSLEEP 0x0020 /* Set to prevent sleep on VBUSY, VOFFLINE, ... */
|
||||
unsigned short nr_iterations; /* Number of server iterations */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -156,6 +156,8 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
|
||||
return false;
|
||||
}
|
||||
|
||||
fc->nr_iterations++;
|
||||
|
||||
/* Evaluate the result of the previous operation, if there was one. */
|
||||
switch (error) {
|
||||
case SHRT_MAX:
|
||||
@ -519,6 +521,56 @@ iterate_address:
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump cursor state in the case of the error being EDESTADDRREQ.
|
||||
*/
|
||||
static void afs_dump_edestaddrreq(const struct afs_fs_cursor *fc)
|
||||
{
|
||||
static int count;
|
||||
int i;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_AFS_DEBUG_CURSOR) || count > 3)
|
||||
return;
|
||||
count++;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
pr_notice("EDESTADDR occurred\n");
|
||||
pr_notice("FC: cbb=%x cbb2=%x fl=%hx err=%hd\n",
|
||||
fc->cb_break, fc->cb_break_2, fc->flags, fc->error);
|
||||
pr_notice("FC: st=%u ix=%u ni=%u\n",
|
||||
fc->start, fc->index, fc->nr_iterations);
|
||||
|
||||
if (fc->server_list) {
|
||||
const struct afs_server_list *sl = fc->server_list;
|
||||
pr_notice("FC: SL nr=%u ix=%u vnov=%hx\n",
|
||||
sl->nr_servers, sl->index, sl->vnovol_mask);
|
||||
for (i = 0; i < sl->nr_servers; i++) {
|
||||
const struct afs_server *s = sl->servers[i].server;
|
||||
pr_notice("FC: server fl=%lx av=%u %pU\n",
|
||||
s->flags, s->addr_version, &s->uuid);
|
||||
if (s->addresses) {
|
||||
const struct afs_addr_list *a =
|
||||
rcu_dereference(s->addresses);
|
||||
pr_notice("FC: - av=%u nr=%u/%u/%u ax=%u\n",
|
||||
a->version,
|
||||
a->nr_ipv4, a->nr_addrs, a->max_addrs,
|
||||
a->index);
|
||||
pr_notice("FC: - pr=%lx yf=%lx\n",
|
||||
a->probed, a->yfs);
|
||||
if (a == fc->ac.alist)
|
||||
pr_notice("FC: - current\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pr_notice("AC: as=%u ax=%u ac=%d er=%d b=%u r=%u ni=%u\n",
|
||||
fc->ac.start, fc->ac.index, fc->ac.abort_code, fc->ac.error,
|
||||
fc->ac.begun, fc->ac.responded, fc->ac.nr_iterations);
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
* Tidy up a filesystem cursor and unlock the vnode.
|
||||
*/
|
||||
@ -526,6 +578,11 @@ int afs_end_vnode_operation(struct afs_fs_cursor *fc)
|
||||
{
|
||||
struct afs_net *net = afs_v2net(fc->vnode);
|
||||
|
||||
if (fc->error == -EDESTADDRREQ ||
|
||||
fc->error == -ENETUNREACH ||
|
||||
fc->error == -EHOSTUNREACH)
|
||||
afs_dump_edestaddrreq(fc);
|
||||
|
||||
mutex_unlock(&fc->vnode->io_lock);
|
||||
|
||||
afs_end_cursor(&fc->ac);
|
||||
|
@ -83,6 +83,8 @@ bool afs_select_vlserver(struct afs_vl_cursor *vc)
|
||||
return false;
|
||||
}
|
||||
|
||||
vc->nr_iterations++;
|
||||
|
||||
/* Evaluate the result of the previous operation, if there was one. */
|
||||
switch (error) {
|
||||
case SHRT_MAX:
|
||||
@ -234,6 +236,52 @@ failed:
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump cursor state in the case of the error being EDESTADDRREQ.
|
||||
*/
|
||||
static void afs_vl_dump_edestaddrreq(const struct afs_vl_cursor *vc)
|
||||
{
|
||||
static int count;
|
||||
int i;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_AFS_DEBUG_CURSOR) || count > 3)
|
||||
return;
|
||||
count++;
|
||||
|
||||
rcu_read_lock();
|
||||
pr_notice("EDESTADDR occurred\n");
|
||||
pr_notice("VC: st=%u ix=%u ni=%hu fl=%hx err=%hd\n",
|
||||
vc->start, vc->index, vc->nr_iterations, vc->flags, vc->error);
|
||||
|
||||
if (vc->server_list) {
|
||||
const struct afs_vlserver_list *sl = vc->server_list;
|
||||
pr_notice("VC: SL nr=%u ix=%u\n",
|
||||
sl->nr_servers, sl->index);
|
||||
for (i = 0; i < sl->nr_servers; i++) {
|
||||
const struct afs_vlserver *s = sl->servers[i].server;
|
||||
pr_notice("VC: server fl=%lx %s+%hu\n",
|
||||
s->flags, s->name, s->port);
|
||||
if (s->addresses) {
|
||||
const struct afs_addr_list *a =
|
||||
rcu_dereference(s->addresses);
|
||||
pr_notice("VC: - av=%u nr=%u/%u/%u ax=%u\n",
|
||||
a->version,
|
||||
a->nr_ipv4, a->nr_addrs, a->max_addrs,
|
||||
a->index);
|
||||
pr_notice("VC: - pr=%lx yf=%lx\n",
|
||||
a->probed, a->yfs);
|
||||
if (a == vc->ac.alist)
|
||||
pr_notice("VC: - current\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pr_notice("AC: as=%u ax=%u ac=%d er=%d b=%u r=%u ni=%hu\n",
|
||||
vc->ac.start, vc->ac.index, vc->ac.abort_code, vc->ac.error,
|
||||
vc->ac.begun, vc->ac.responded, vc->ac.nr_iterations);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
* Tidy up a volume location server cursor and unlock the vnode.
|
||||
*/
|
||||
@ -241,6 +289,11 @@ int afs_end_vlserver_operation(struct afs_vl_cursor *vc)
|
||||
{
|
||||
struct afs_net *net = vc->cell->net;
|
||||
|
||||
if (vc->error == -EDESTADDRREQ ||
|
||||
vc->error == -ENETUNREACH ||
|
||||
vc->error == -EHOSTUNREACH)
|
||||
afs_vl_dump_edestaddrreq(vc);
|
||||
|
||||
afs_end_cursor(&vc->ac);
|
||||
afs_put_vlserverlist(net, vc->server_list);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user