afs: Fix offline and busy message emission

The current code assumes that offline and busy volume states apply to all
instances of a volume, not just the one on the server that returned
VOFFLINE or VBUSY and will emit a notice to dmesg suggesting that the
entire volume is unavailable.

Fix that by moving the flags recording this to the afs_server_entry struct
that is used to represent a particular instance of a volume on a specific
server.  The notice is altered to include the server UUID also.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
This commit is contained in:
David Howells 2023-11-09 12:06:49 +00:00
parent 495f2ae9e3
commit 28f4c58045
2 changed files with 25 additions and 14 deletions

View File

@ -612,6 +612,8 @@ struct afs_server_entry {
time64_t cb_expires_at; /* Time at which volume-level callback expires */
unsigned long flags;
#define AFS_SE_EXCLUDED 0 /* Set if server is to be excluded in rotation */
#define AFS_SE_VOLUME_OFFLINE 1 /* Set if volume offline notice given */
#define AFS_SE_VOLUME_BUSY 2 /* Set if volume busy notice given */
};
struct afs_server_list {
@ -645,10 +647,8 @@ struct afs_volume {
#define AFS_VOLUME_UPDATING 1 /* - T if an update is in progress */
#define AFS_VOLUME_WAIT 2 /* - T if users must wait for update */
#define AFS_VOLUME_DELETED 3 /* - T if volume appears deleted */
#define AFS_VOLUME_OFFLINE 4 /* - T if volume offline notice given */
#define AFS_VOLUME_BUSY 5 /* - T if volume busy notice given */
#define AFS_VOLUME_MAYBE_NO_IBULK 6 /* - T if some servers don't have InlineBulkStatus */
#define AFS_VOLUME_RM_TREE 7 /* - Set if volume removed from cell->volumes */
#define AFS_VOLUME_MAYBE_NO_IBULK 4 /* - T if some servers don't have InlineBulkStatus */
#define AFS_VOLUME_RM_TREE 5 /* - Set if volume removed from cell->volumes */
#ifdef CONFIG_AFS_FSCACHE
struct fscache_volume *cache; /* Caching cookie */
#endif

View File

@ -111,7 +111,7 @@ found_interest:
/*
* Post volume busy note.
*/
static void afs_busy(struct afs_volume *volume, u32 abort_code)
static void afs_busy(struct afs_operation *op, u32 abort_code)
{
const char *m;
@ -122,7 +122,8 @@ static void afs_busy(struct afs_volume *volume, u32 abort_code)
default: m = "busy"; break;
}
pr_notice("kAFS: Volume %llu '%s' is %s\n", volume->vid, volume->name, m);
pr_notice("kAFS: Volume %llu '%s' on server %pU is %s\n",
op->volume->vid, op->volume->name, &op->server->uuid, m);
}
/*
@ -181,6 +182,10 @@ bool afs_select_fileserver(struct afs_operation *op)
/* Evaluate the result of the previous operation, if there was one. */
switch (op->call_error) {
case 0:
clear_bit(AFS_SE_VOLUME_OFFLINE,
&op->server_list->servers[op->server_index].flags);
clear_bit(AFS_SE_VOLUME_BUSY,
&op->server_list->servers[op->server_index].flags);
op->cumul_error.responded = true;
/* We succeeded, but we may need to redo the op from another
@ -314,9 +319,11 @@ bool afs_select_fileserver(struct afs_operation *op)
* expected to come back but it might take a long time (could be
* days).
*/
if (!test_and_set_bit(AFS_VOLUME_OFFLINE, &op->volume->flags)) {
afs_busy(op->volume, abort_code);
clear_bit(AFS_VOLUME_BUSY, &op->volume->flags);
if (!test_and_set_bit(AFS_SE_VOLUME_OFFLINE,
&op->server_list->servers[op->server_index].flags)) {
afs_busy(op, abort_code);
clear_bit(AFS_SE_VOLUME_BUSY,
&op->server_list->servers[op->server_index].flags);
}
if (op->flags & AFS_OPERATION_NO_VSLEEP) {
afs_op_set_error(op, -EADV);
@ -343,9 +350,11 @@ bool afs_select_fileserver(struct afs_operation *op)
afs_op_set_error(op, -EBUSY);
goto failed;
}
if (!test_and_set_bit(AFS_VOLUME_BUSY, &op->volume->flags)) {
afs_busy(op->volume, abort_code);
clear_bit(AFS_VOLUME_OFFLINE, &op->volume->flags);
if (!test_and_set_bit(AFS_SE_VOLUME_BUSY,
&op->server_list->servers[op->server_index].flags)) {
afs_busy(op, abort_code);
clear_bit(AFS_SE_VOLUME_OFFLINE,
&op->server_list->servers[op->server_index].flags);
}
busy:
if (op->flags & AFS_OPERATION_CUR_ONLY) {
@ -426,8 +435,10 @@ bool afs_select_fileserver(struct afs_operation *op)
default:
afs_op_accumulate_error(op, error, abort_code);
failed_but_online:
clear_bit(AFS_VOLUME_OFFLINE, &op->volume->flags);
clear_bit(AFS_VOLUME_BUSY, &op->volume->flags);
clear_bit(AFS_SE_VOLUME_OFFLINE,
&op->server_list->servers[op->server_index].flags);
clear_bit(AFS_SE_VOLUME_BUSY,
&op->server_list->servers[op->server_index].flags);
goto failed;
}