|
@@ -39,9 +39,10 @@ bool afs_begin_vnode_operation(struct afs_fs_cursor *fc, struct afs_vnode *vnode
|
|
fc->vnode = vnode;
|
|
fc->vnode = vnode;
|
|
fc->key = key;
|
|
fc->key = key;
|
|
fc->ac.error = SHRT_MAX;
|
|
fc->ac.error = SHRT_MAX;
|
|
|
|
+ fc->error = -EDESTADDRREQ;
|
|
|
|
|
|
if (mutex_lock_interruptible(&vnode->io_lock) < 0) {
|
|
if (mutex_lock_interruptible(&vnode->io_lock) < 0) {
|
|
- fc->ac.error = -EINTR;
|
|
|
|
|
|
+ fc->error = -EINTR;
|
|
fc->flags |= AFS_FS_CURSOR_STOP;
|
|
fc->flags |= AFS_FS_CURSOR_STOP;
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
@@ -80,7 +81,7 @@ static bool afs_start_fs_iteration(struct afs_fs_cursor *fc,
|
|
* and have to return an error.
|
|
* and have to return an error.
|
|
*/
|
|
*/
|
|
if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) {
|
|
if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) {
|
|
- fc->ac.error = -ESTALE;
|
|
|
|
|
|
+ fc->error = -ESTALE;
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -127,7 +128,7 @@ static bool afs_sleep_and_retry(struct afs_fs_cursor *fc)
|
|
{
|
|
{
|
|
msleep_interruptible(1000);
|
|
msleep_interruptible(1000);
|
|
if (signal_pending(current)) {
|
|
if (signal_pending(current)) {
|
|
- fc->ac.error = -ERESTARTSYS;
|
|
|
|
|
|
+ fc->error = -ERESTARTSYS;
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -143,11 +144,12 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
|
|
struct afs_addr_list *alist;
|
|
struct afs_addr_list *alist;
|
|
struct afs_server *server;
|
|
struct afs_server *server;
|
|
struct afs_vnode *vnode = fc->vnode;
|
|
struct afs_vnode *vnode = fc->vnode;
|
|
|
|
+ int error = fc->ac.error;
|
|
|
|
|
|
_enter("%u/%u,%u/%u,%d,%d",
|
|
_enter("%u/%u,%u/%u,%d,%d",
|
|
fc->index, fc->start,
|
|
fc->index, fc->start,
|
|
fc->ac.index, fc->ac.start,
|
|
fc->ac.index, fc->ac.start,
|
|
- fc->ac.error, fc->ac.abort_code);
|
|
|
|
|
|
+ error, fc->ac.abort_code);
|
|
|
|
|
|
if (fc->flags & AFS_FS_CURSOR_STOP) {
|
|
if (fc->flags & AFS_FS_CURSOR_STOP) {
|
|
_leave(" = f [stopped]");
|
|
_leave(" = f [stopped]");
|
|
@@ -155,15 +157,16 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
|
|
}
|
|
}
|
|
|
|
|
|
/* Evaluate the result of the previous operation, if there was one. */
|
|
/* Evaluate the result of the previous operation, if there was one. */
|
|
- switch (fc->ac.error) {
|
|
|
|
|
|
+ switch (error) {
|
|
case SHRT_MAX:
|
|
case SHRT_MAX:
|
|
goto start;
|
|
goto start;
|
|
|
|
|
|
case 0:
|
|
case 0:
|
|
default:
|
|
default:
|
|
/* Success or local failure. Stop. */
|
|
/* Success or local failure. Stop. */
|
|
|
|
+ fc->error = error;
|
|
fc->flags |= AFS_FS_CURSOR_STOP;
|
|
fc->flags |= AFS_FS_CURSOR_STOP;
|
|
- _leave(" = f [okay/local %d]", fc->ac.error);
|
|
|
|
|
|
+ _leave(" = f [okay/local %d]", error);
|
|
return false;
|
|
return false;
|
|
|
|
|
|
case -ECONNABORTED:
|
|
case -ECONNABORTED:
|
|
@@ -178,7 +181,7 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
|
|
* - May indicate that the fileserver couldn't attach to the vol.
|
|
* - May indicate that the fileserver couldn't attach to the vol.
|
|
*/
|
|
*/
|
|
if (fc->flags & AFS_FS_CURSOR_VNOVOL) {
|
|
if (fc->flags & AFS_FS_CURSOR_VNOVOL) {
|
|
- fc->ac.error = -EREMOTEIO;
|
|
|
|
|
|
+ fc->error = -EREMOTEIO;
|
|
goto next_server;
|
|
goto next_server;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -187,12 +190,12 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
|
|
write_unlock(&vnode->volume->servers_lock);
|
|
write_unlock(&vnode->volume->servers_lock);
|
|
|
|
|
|
set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags);
|
|
set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags);
|
|
- fc->ac.error = afs_check_volume_status(vnode->volume, fc->key);
|
|
|
|
- if (fc->ac.error < 0)
|
|
|
|
- goto failed;
|
|
|
|
|
|
+ error = afs_check_volume_status(vnode->volume, fc->key);
|
|
|
|
+ if (error < 0)
|
|
|
|
+ goto failed_set_error;
|
|
|
|
|
|
if (test_bit(AFS_VOLUME_DELETED, &vnode->volume->flags)) {
|
|
if (test_bit(AFS_VOLUME_DELETED, &vnode->volume->flags)) {
|
|
- fc->ac.error = -ENOMEDIUM;
|
|
|
|
|
|
+ fc->error = -ENOMEDIUM;
|
|
goto failed;
|
|
goto failed;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -200,7 +203,7 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
|
|
* it's the fileserver having trouble.
|
|
* it's the fileserver having trouble.
|
|
*/
|
|
*/
|
|
if (vnode->volume->servers == fc->server_list) {
|
|
if (vnode->volume->servers == fc->server_list) {
|
|
- fc->ac.error = -EREMOTEIO;
|
|
|
|
|
|
+ fc->error = -EREMOTEIO;
|
|
goto next_server;
|
|
goto next_server;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -215,7 +218,7 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
|
|
case VONLINE:
|
|
case VONLINE:
|
|
case VDISKFULL:
|
|
case VDISKFULL:
|
|
case VOVERQUOTA:
|
|
case VOVERQUOTA:
|
|
- fc->ac.error = afs_abort_to_error(fc->ac.abort_code);
|
|
|
|
|
|
+ fc->error = afs_abort_to_error(fc->ac.abort_code);
|
|
goto next_server;
|
|
goto next_server;
|
|
|
|
|
|
case VOFFLINE:
|
|
case VOFFLINE:
|
|
@@ -224,11 +227,11 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
|
|
clear_bit(AFS_VOLUME_BUSY, &vnode->volume->flags);
|
|
clear_bit(AFS_VOLUME_BUSY, &vnode->volume->flags);
|
|
}
|
|
}
|
|
if (fc->flags & AFS_FS_CURSOR_NO_VSLEEP) {
|
|
if (fc->flags & AFS_FS_CURSOR_NO_VSLEEP) {
|
|
- fc->ac.error = -EADV;
|
|
|
|
|
|
+ fc->error = -EADV;
|
|
goto failed;
|
|
goto failed;
|
|
}
|
|
}
|
|
if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) {
|
|
if (fc->flags & AFS_FS_CURSOR_CUR_ONLY) {
|
|
- fc->ac.error = -ESTALE;
|
|
|
|
|
|
+ fc->error = -ESTALE;
|
|
goto failed;
|
|
goto failed;
|
|
}
|
|
}
|
|
goto busy;
|
|
goto busy;
|
|
@@ -240,7 +243,7 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
|
|
* have a file lock we need to maintain.
|
|
* have a file lock we need to maintain.
|
|
*/
|
|
*/
|
|
if (fc->flags & AFS_FS_CURSOR_NO_VSLEEP) {
|
|
if (fc->flags & AFS_FS_CURSOR_NO_VSLEEP) {
|
|
- fc->ac.error = -EBUSY;
|
|
|
|
|
|
+ fc->error = -EBUSY;
|
|
goto failed;
|
|
goto failed;
|
|
}
|
|
}
|
|
if (!test_and_set_bit(AFS_VOLUME_BUSY, &vnode->volume->flags)) {
|
|
if (!test_and_set_bit(AFS_VOLUME_BUSY, &vnode->volume->flags)) {
|
|
@@ -269,16 +272,16 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
|
|
* honour, just in case someone sets up a loop.
|
|
* honour, just in case someone sets up a loop.
|
|
*/
|
|
*/
|
|
if (fc->flags & AFS_FS_CURSOR_VMOVED) {
|
|
if (fc->flags & AFS_FS_CURSOR_VMOVED) {
|
|
- fc->ac.error = -EREMOTEIO;
|
|
|
|
|
|
+ fc->error = -EREMOTEIO;
|
|
goto failed;
|
|
goto failed;
|
|
}
|
|
}
|
|
fc->flags |= AFS_FS_CURSOR_VMOVED;
|
|
fc->flags |= AFS_FS_CURSOR_VMOVED;
|
|
|
|
|
|
set_bit(AFS_VOLUME_WAIT, &vnode->volume->flags);
|
|
set_bit(AFS_VOLUME_WAIT, &vnode->volume->flags);
|
|
set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags);
|
|
set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags);
|
|
- fc->ac.error = afs_check_volume_status(vnode->volume, fc->key);
|
|
|
|
- if (fc->ac.error < 0)
|
|
|
|
- goto failed;
|
|
|
|
|
|
+ error = afs_check_volume_status(vnode->volume, fc->key);
|
|
|
|
+ if (error < 0)
|
|
|
|
+ goto failed_set_error;
|
|
|
|
|
|
/* If the server list didn't change, then the VLDB is
|
|
/* If the server list didn't change, then the VLDB is
|
|
* out of sync with the fileservers. This is hopefully
|
|
* out of sync with the fileservers. This is hopefully
|
|
@@ -290,7 +293,7 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
|
|
* TODO: Retry a few times with sleeps.
|
|
* TODO: Retry a few times with sleeps.
|
|
*/
|
|
*/
|
|
if (vnode->volume->servers == fc->server_list) {
|
|
if (vnode->volume->servers == fc->server_list) {
|
|
- fc->ac.error = -ENOMEDIUM;
|
|
|
|
|
|
+ fc->error = -ENOMEDIUM;
|
|
goto failed;
|
|
goto failed;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -299,20 +302,25 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
|
|
default:
|
|
default:
|
|
clear_bit(AFS_VOLUME_OFFLINE, &vnode->volume->flags);
|
|
clear_bit(AFS_VOLUME_OFFLINE, &vnode->volume->flags);
|
|
clear_bit(AFS_VOLUME_BUSY, &vnode->volume->flags);
|
|
clear_bit(AFS_VOLUME_BUSY, &vnode->volume->flags);
|
|
- fc->ac.error = afs_abort_to_error(fc->ac.abort_code);
|
|
|
|
|
|
+ fc->error = afs_abort_to_error(fc->ac.abort_code);
|
|
goto failed;
|
|
goto failed;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ case -ETIMEDOUT:
|
|
|
|
+ case -ETIME:
|
|
|
|
+ if (fc->error != -EDESTADDRREQ)
|
|
|
|
+ goto iterate_address;
|
|
|
|
+ /* Fall through */
|
|
case -ENETUNREACH:
|
|
case -ENETUNREACH:
|
|
case -EHOSTUNREACH:
|
|
case -EHOSTUNREACH:
|
|
case -ECONNREFUSED:
|
|
case -ECONNREFUSED:
|
|
- case -ETIMEDOUT:
|
|
|
|
- case -ETIME:
|
|
|
|
_debug("no conn");
|
|
_debug("no conn");
|
|
|
|
+ fc->error = error;
|
|
goto iterate_address;
|
|
goto iterate_address;
|
|
|
|
|
|
case -ECONNRESET:
|
|
case -ECONNRESET:
|
|
_debug("call reset");
|
|
_debug("call reset");
|
|
|
|
+ fc->error = error;
|
|
goto failed;
|
|
goto failed;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -328,9 +336,9 @@ start:
|
|
/* See if we need to do an update of the volume record. Note that the
|
|
/* See if we need to do an update of the volume record. Note that the
|
|
* volume may have moved or even have been deleted.
|
|
* volume may have moved or even have been deleted.
|
|
*/
|
|
*/
|
|
- fc->ac.error = afs_check_volume_status(vnode->volume, fc->key);
|
|
|
|
- if (fc->ac.error < 0)
|
|
|
|
- goto failed;
|
|
|
|
|
|
+ error = afs_check_volume_status(vnode->volume, fc->key);
|
|
|
|
+ if (error < 0)
|
|
|
|
+ goto failed_set_error;
|
|
|
|
|
|
if (!afs_start_fs_iteration(fc, vnode))
|
|
if (!afs_start_fs_iteration(fc, vnode))
|
|
goto failed;
|
|
goto failed;
|
|
@@ -354,10 +362,10 @@ use_server:
|
|
* break request before we've finished decoding the reply and
|
|
* break request before we've finished decoding the reply and
|
|
* installing the vnode.
|
|
* installing the vnode.
|
|
*/
|
|
*/
|
|
- fc->ac.error = afs_register_server_cb_interest(vnode, fc->server_list,
|
|
|
|
- fc->index);
|
|
|
|
- if (fc->ac.error < 0)
|
|
|
|
- goto failed;
|
|
|
|
|
|
+ error = afs_register_server_cb_interest(vnode, fc->server_list,
|
|
|
|
+ fc->index);
|
|
|
|
+ if (error < 0)
|
|
|
|
+ goto failed_set_error;
|
|
|
|
|
|
fc->cbi = afs_get_cb_interest(vnode->cb_interest);
|
|
fc->cbi = afs_get_cb_interest(vnode->cb_interest);
|
|
|
|
|
|
@@ -422,13 +430,14 @@ next_server:
|
|
if (fc->flags & AFS_FS_CURSOR_VBUSY)
|
|
if (fc->flags & AFS_FS_CURSOR_VBUSY)
|
|
goto restart_from_beginning;
|
|
goto restart_from_beginning;
|
|
|
|
|
|
- fc->ac.error = -EDESTADDRREQ;
|
|
|
|
goto failed;
|
|
goto failed;
|
|
|
|
|
|
|
|
+failed_set_error:
|
|
|
|
+ fc->error = error;
|
|
failed:
|
|
failed:
|
|
fc->flags |= AFS_FS_CURSOR_STOP;
|
|
fc->flags |= AFS_FS_CURSOR_STOP;
|
|
afs_end_cursor(&fc->ac);
|
|
afs_end_cursor(&fc->ac);
|
|
- _leave(" = f [failed %d]", fc->ac.error);
|
|
|
|
|
|
+ _leave(" = f [failed %d]", fc->error);
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -442,13 +451,14 @@ bool afs_select_current_fileserver(struct afs_fs_cursor *fc)
|
|
struct afs_vnode *vnode = fc->vnode;
|
|
struct afs_vnode *vnode = fc->vnode;
|
|
struct afs_cb_interest *cbi = vnode->cb_interest;
|
|
struct afs_cb_interest *cbi = vnode->cb_interest;
|
|
struct afs_addr_list *alist;
|
|
struct afs_addr_list *alist;
|
|
|
|
+ int error = fc->ac.error;
|
|
|
|
|
|
_enter("");
|
|
_enter("");
|
|
|
|
|
|
- switch (fc->ac.error) {
|
|
|
|
|
|
+ switch (error) {
|
|
case SHRT_MAX:
|
|
case SHRT_MAX:
|
|
if (!cbi) {
|
|
if (!cbi) {
|
|
- fc->ac.error = -ESTALE;
|
|
|
|
|
|
+ fc->error = -ESTALE;
|
|
fc->flags |= AFS_FS_CURSOR_STOP;
|
|
fc->flags |= AFS_FS_CURSOR_STOP;
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
@@ -461,7 +471,7 @@ bool afs_select_current_fileserver(struct afs_fs_cursor *fc)
|
|
afs_get_addrlist(alist);
|
|
afs_get_addrlist(alist);
|
|
read_unlock(&cbi->server->fs_lock);
|
|
read_unlock(&cbi->server->fs_lock);
|
|
if (!alist) {
|
|
if (!alist) {
|
|
- fc->ac.error = -ESTALE;
|
|
|
|
|
|
+ fc->error = -ESTALE;
|
|
fc->flags |= AFS_FS_CURSOR_STOP;
|
|
fc->flags |= AFS_FS_CURSOR_STOP;
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
@@ -475,11 +485,13 @@ bool afs_select_current_fileserver(struct afs_fs_cursor *fc)
|
|
case 0:
|
|
case 0:
|
|
default:
|
|
default:
|
|
/* Success or local failure. Stop. */
|
|
/* Success or local failure. Stop. */
|
|
|
|
+ fc->error = error;
|
|
fc->flags |= AFS_FS_CURSOR_STOP;
|
|
fc->flags |= AFS_FS_CURSOR_STOP;
|
|
- _leave(" = f [okay/local %d]", fc->ac.error);
|
|
|
|
|
|
+ _leave(" = f [okay/local %d]", error);
|
|
return false;
|
|
return false;
|
|
|
|
|
|
case -ECONNABORTED:
|
|
case -ECONNABORTED:
|
|
|
|
+ fc->error = afs_abort_to_error(fc->ac.abort_code);
|
|
fc->flags |= AFS_FS_CURSOR_STOP;
|
|
fc->flags |= AFS_FS_CURSOR_STOP;
|
|
_leave(" = f [abort]");
|
|
_leave(" = f [abort]");
|
|
return false;
|
|
return false;
|
|
@@ -490,6 +502,7 @@ bool afs_select_current_fileserver(struct afs_fs_cursor *fc)
|
|
case -ETIMEDOUT:
|
|
case -ETIMEDOUT:
|
|
case -ETIME:
|
|
case -ETIME:
|
|
_debug("no conn");
|
|
_debug("no conn");
|
|
|
|
+ fc->error = error;
|
|
goto iterate_address;
|
|
goto iterate_address;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -512,7 +525,6 @@ iterate_address:
|
|
int afs_end_vnode_operation(struct afs_fs_cursor *fc)
|
|
int afs_end_vnode_operation(struct afs_fs_cursor *fc)
|
|
{
|
|
{
|
|
struct afs_net *net = afs_v2net(fc->vnode);
|
|
struct afs_net *net = afs_v2net(fc->vnode);
|
|
- int ret;
|
|
|
|
|
|
|
|
mutex_unlock(&fc->vnode->io_lock);
|
|
mutex_unlock(&fc->vnode->io_lock);
|
|
|
|
|
|
@@ -520,9 +532,8 @@ int afs_end_vnode_operation(struct afs_fs_cursor *fc)
|
|
afs_put_cb_interest(net, fc->cbi);
|
|
afs_put_cb_interest(net, fc->cbi);
|
|
afs_put_serverlist(net, fc->server_list);
|
|
afs_put_serverlist(net, fc->server_list);
|
|
|
|
|
|
- ret = fc->ac.error;
|
|
|
|
- if (ret == -ECONNABORTED)
|
|
|
|
- afs_abort_to_error(fc->ac.abort_code);
|
|
|
|
|
|
+ if (fc->error == -ECONNABORTED)
|
|
|
|
+ fc->error = afs_abort_to_error(fc->ac.abort_code);
|
|
|
|
|
|
- return fc->ac.error;
|
|
|
|
|
|
+ return fc->error;
|
|
}
|
|
}
|