Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro: "Assorted fixes all over the place. The iov_iter one is this cycle regression (splice from UDP triggering WARN_ON()), the rest is older" * 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: afs: Use d_instantiate() rather than d_add() and don't d_drop() afs: Fix missing net error handling afs: Fix validation/callback interaction iov_iter: teach csum_and_copy_to_iter() to handle pipe-backed ones exportfs: do not read dentry after free exportfs: fix 'passing zero to ERR_PTR()' warning aio: fix failure to put the file pointer sysv: return 'err' instead of 0 in __sysv_write_inode
This commit is contained in:
commit
5f1ca5c619
|
@ -1075,8 +1075,6 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc,
|
||||||
if (fc->ac.error < 0)
|
if (fc->ac.error < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
d_drop(new_dentry);
|
|
||||||
|
|
||||||
inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key,
|
inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key,
|
||||||
newfid, newstatus, newcb, fc->cbi);
|
newfid, newstatus, newcb, fc->cbi);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
|
@ -1090,7 +1088,7 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc,
|
||||||
vnode = AFS_FS_I(inode);
|
vnode = AFS_FS_I(inode);
|
||||||
set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
|
set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
|
||||||
afs_vnode_commit_status(fc, vnode, 0);
|
afs_vnode_commit_status(fc, vnode, 0);
|
||||||
d_add(new_dentry, inode);
|
d_instantiate(new_dentry, inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -61,8 +61,11 @@ void afs_fileserver_probe_result(struct afs_call *call)
|
||||||
afs_io_error(call, afs_io_error_fs_probe_fail);
|
afs_io_error(call, afs_io_error_fs_probe_fail);
|
||||||
goto out;
|
goto out;
|
||||||
case -ECONNRESET: /* Responded, but call expired. */
|
case -ECONNRESET: /* Responded, but call expired. */
|
||||||
|
case -ERFKILL:
|
||||||
|
case -EADDRNOTAVAIL:
|
||||||
case -ENETUNREACH:
|
case -ENETUNREACH:
|
||||||
case -EHOSTUNREACH:
|
case -EHOSTUNREACH:
|
||||||
|
case -EHOSTDOWN:
|
||||||
case -ECONNREFUSED:
|
case -ECONNREFUSED:
|
||||||
case -ETIMEDOUT:
|
case -ETIMEDOUT:
|
||||||
case -ETIME:
|
case -ETIME:
|
||||||
|
@ -132,12 +135,14 @@ out:
|
||||||
static int afs_do_probe_fileserver(struct afs_net *net,
|
static int afs_do_probe_fileserver(struct afs_net *net,
|
||||||
struct afs_server *server,
|
struct afs_server *server,
|
||||||
struct key *key,
|
struct key *key,
|
||||||
unsigned int server_index)
|
unsigned int server_index,
|
||||||
|
struct afs_error *_e)
|
||||||
{
|
{
|
||||||
struct afs_addr_cursor ac = {
|
struct afs_addr_cursor ac = {
|
||||||
.index = 0,
|
.index = 0,
|
||||||
};
|
};
|
||||||
int ret;
|
bool in_progress = false;
|
||||||
|
int err;
|
||||||
|
|
||||||
_enter("%pU", &server->uuid);
|
_enter("%pU", &server->uuid);
|
||||||
|
|
||||||
|
@ -151,15 +156,17 @@ static int afs_do_probe_fileserver(struct afs_net *net,
|
||||||
server->probe.rtt = UINT_MAX;
|
server->probe.rtt = UINT_MAX;
|
||||||
|
|
||||||
for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) {
|
for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) {
|
||||||
ret = afs_fs_get_capabilities(net, server, &ac, key, server_index,
|
err = afs_fs_get_capabilities(net, server, &ac, key, server_index,
|
||||||
true);
|
true);
|
||||||
if (ret != -EINPROGRESS) {
|
if (err == -EINPROGRESS)
|
||||||
afs_fs_probe_done(server);
|
in_progress = true;
|
||||||
return ret;
|
else
|
||||||
}
|
afs_prioritise_error(_e, err, ac.abort_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
if (!in_progress)
|
||||||
|
afs_fs_probe_done(server);
|
||||||
|
return in_progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -169,21 +176,23 @@ int afs_probe_fileservers(struct afs_net *net, struct key *key,
|
||||||
struct afs_server_list *list)
|
struct afs_server_list *list)
|
||||||
{
|
{
|
||||||
struct afs_server *server;
|
struct afs_server *server;
|
||||||
int i, ret;
|
struct afs_error e;
|
||||||
|
bool in_progress = false;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
e.error = 0;
|
||||||
|
e.responded = false;
|
||||||
for (i = 0; i < list->nr_servers; i++) {
|
for (i = 0; i < list->nr_servers; i++) {
|
||||||
server = list->servers[i].server;
|
server = list->servers[i].server;
|
||||||
if (test_bit(AFS_SERVER_FL_PROBED, &server->flags))
|
if (test_bit(AFS_SERVER_FL_PROBED, &server->flags))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!test_and_set_bit_lock(AFS_SERVER_FL_PROBING, &server->flags)) {
|
if (!test_and_set_bit_lock(AFS_SERVER_FL_PROBING, &server->flags) &&
|
||||||
ret = afs_do_probe_fileserver(net, server, key, i);
|
afs_do_probe_fileserver(net, server, key, i, &e))
|
||||||
if (ret)
|
in_progress = true;
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return in_progress ? 0 : e.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -382,7 +382,7 @@ void afs_zap_data(struct afs_vnode *vnode)
|
||||||
int afs_validate(struct afs_vnode *vnode, struct key *key)
|
int afs_validate(struct afs_vnode *vnode, struct key *key)
|
||||||
{
|
{
|
||||||
time64_t now = ktime_get_real_seconds();
|
time64_t now = ktime_get_real_seconds();
|
||||||
bool valid = false;
|
bool valid;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
_enter("{v={%llx:%llu} fl=%lx},%x",
|
_enter("{v={%llx:%llu} fl=%lx},%x",
|
||||||
|
@ -402,15 +402,21 @@ int afs_validate(struct afs_vnode *vnode, struct key *key)
|
||||||
vnode->cb_v_break = vnode->volume->cb_v_break;
|
vnode->cb_v_break = vnode->volume->cb_v_break;
|
||||||
valid = false;
|
valid = false;
|
||||||
} else if (vnode->status.type == AFS_FTYPE_DIR &&
|
} else if (vnode->status.type == AFS_FTYPE_DIR &&
|
||||||
test_bit(AFS_VNODE_DIR_VALID, &vnode->flags) &&
|
(!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags) ||
|
||||||
vnode->cb_expires_at - 10 > now) {
|
vnode->cb_expires_at - 10 <= now)) {
|
||||||
valid = true;
|
valid = false;
|
||||||
} else if (!test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) &&
|
} else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) ||
|
||||||
vnode->cb_expires_at - 10 > now) {
|
vnode->cb_expires_at - 10 <= now) {
|
||||||
|
valid = false;
|
||||||
|
} else {
|
||||||
valid = true;
|
valid = true;
|
||||||
}
|
}
|
||||||
} else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
|
} else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
|
||||||
valid = true;
|
valid = true;
|
||||||
|
} else {
|
||||||
|
vnode->cb_s_break = vnode->cb_interest->server->cb_s_break;
|
||||||
|
vnode->cb_v_break = vnode->volume->cb_v_break;
|
||||||
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_sequnlock_excl(&vnode->cb_lock);
|
read_sequnlock_excl(&vnode->cb_lock);
|
||||||
|
|
|
@ -695,6 +695,14 @@ struct afs_interface {
|
||||||
unsigned mtu; /* MTU of interface */
|
unsigned mtu; /* MTU of interface */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error prioritisation and accumulation.
|
||||||
|
*/
|
||||||
|
struct afs_error {
|
||||||
|
short error; /* Accumulated error */
|
||||||
|
bool responded; /* T if server responded */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cursor for iterating over a server's address list.
|
* Cursor for iterating over a server's address list.
|
||||||
*/
|
*/
|
||||||
|
@ -1015,6 +1023,7 @@ static inline void __afs_stat(atomic_t *s)
|
||||||
* misc.c
|
* misc.c
|
||||||
*/
|
*/
|
||||||
extern int afs_abort_to_error(u32);
|
extern int afs_abort_to_error(u32);
|
||||||
|
extern void afs_prioritise_error(struct afs_error *, int, u32);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mntpt.c
|
* mntpt.c
|
||||||
|
|
|
@ -118,3 +118,55 @@ int afs_abort_to_error(u32 abort_code)
|
||||||
default: return -EREMOTEIO;
|
default: return -EREMOTEIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Select the error to report from a set of errors.
|
||||||
|
*/
|
||||||
|
void afs_prioritise_error(struct afs_error *e, int error, u32 abort_code)
|
||||||
|
{
|
||||||
|
switch (error) {
|
||||||
|
case 0:
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
if (e->error == -ETIMEDOUT ||
|
||||||
|
e->error == -ETIME)
|
||||||
|
return;
|
||||||
|
case -ETIMEDOUT:
|
||||||
|
case -ETIME:
|
||||||
|
if (e->error == -ENOMEM ||
|
||||||
|
e->error == -ENONET)
|
||||||
|
return;
|
||||||
|
case -ENOMEM:
|
||||||
|
case -ENONET:
|
||||||
|
if (e->error == -ERFKILL)
|
||||||
|
return;
|
||||||
|
case -ERFKILL:
|
||||||
|
if (e->error == -EADDRNOTAVAIL)
|
||||||
|
return;
|
||||||
|
case -EADDRNOTAVAIL:
|
||||||
|
if (e->error == -ENETUNREACH)
|
||||||
|
return;
|
||||||
|
case -ENETUNREACH:
|
||||||
|
if (e->error == -EHOSTUNREACH)
|
||||||
|
return;
|
||||||
|
case -EHOSTUNREACH:
|
||||||
|
if (e->error == -EHOSTDOWN)
|
||||||
|
return;
|
||||||
|
case -EHOSTDOWN:
|
||||||
|
if (e->error == -ECONNREFUSED)
|
||||||
|
return;
|
||||||
|
case -ECONNREFUSED:
|
||||||
|
if (e->error == -ECONNRESET)
|
||||||
|
return;
|
||||||
|
case -ECONNRESET: /* Responded, but call expired. */
|
||||||
|
if (e->responded)
|
||||||
|
return;
|
||||||
|
e->error = error;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case -ECONNABORTED:
|
||||||
|
e->responded = true;
|
||||||
|
e->error = afs_abort_to_error(abort_code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -136,7 +136,8 @@ 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;
|
||||||
u32 rtt, abort_code;
|
struct afs_error e;
|
||||||
|
u32 rtt;
|
||||||
int error = fc->ac.error, i;
|
int error = fc->ac.error, i;
|
||||||
|
|
||||||
_enter("%lx[%d],%lx[%d],%d,%d",
|
_enter("%lx[%d],%lx[%d],%d,%d",
|
||||||
|
@ -306,8 +307,11 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
|
||||||
if (fc->error != -EDESTADDRREQ)
|
if (fc->error != -EDESTADDRREQ)
|
||||||
goto iterate_address;
|
goto iterate_address;
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
case -ERFKILL:
|
||||||
|
case -EADDRNOTAVAIL:
|
||||||
case -ENETUNREACH:
|
case -ENETUNREACH:
|
||||||
case -EHOSTUNREACH:
|
case -EHOSTUNREACH:
|
||||||
|
case -EHOSTDOWN:
|
||||||
case -ECONNREFUSED:
|
case -ECONNREFUSED:
|
||||||
_debug("no conn");
|
_debug("no conn");
|
||||||
fc->error = error;
|
fc->error = error;
|
||||||
|
@ -446,50 +450,15 @@ no_more_servers:
|
||||||
if (fc->flags & AFS_FS_CURSOR_VBUSY)
|
if (fc->flags & AFS_FS_CURSOR_VBUSY)
|
||||||
goto restart_from_beginning;
|
goto restart_from_beginning;
|
||||||
|
|
||||||
abort_code = 0;
|
e.error = -EDESTADDRREQ;
|
||||||
error = -EDESTADDRREQ;
|
e.responded = false;
|
||||||
for (i = 0; i < fc->server_list->nr_servers; i++) {
|
for (i = 0; i < fc->server_list->nr_servers; i++) {
|
||||||
struct afs_server *s = fc->server_list->servers[i].server;
|
struct afs_server *s = fc->server_list->servers[i].server;
|
||||||
int probe_error = READ_ONCE(s->probe.error);
|
|
||||||
|
|
||||||
switch (probe_error) {
|
afs_prioritise_error(&e, READ_ONCE(s->probe.error),
|
||||||
case 0:
|
s->probe.abort_code);
|
||||||
continue;
|
|
||||||
default:
|
|
||||||
if (error == -ETIMEDOUT ||
|
|
||||||
error == -ETIME)
|
|
||||||
continue;
|
|
||||||
case -ETIMEDOUT:
|
|
||||||
case -ETIME:
|
|
||||||
if (error == -ENOMEM ||
|
|
||||||
error == -ENONET)
|
|
||||||
continue;
|
|
||||||
case -ENOMEM:
|
|
||||||
case -ENONET:
|
|
||||||
if (error == -ENETUNREACH)
|
|
||||||
continue;
|
|
||||||
case -ENETUNREACH:
|
|
||||||
if (error == -EHOSTUNREACH)
|
|
||||||
continue;
|
|
||||||
case -EHOSTUNREACH:
|
|
||||||
if (error == -ECONNREFUSED)
|
|
||||||
continue;
|
|
||||||
case -ECONNREFUSED:
|
|
||||||
if (error == -ECONNRESET)
|
|
||||||
continue;
|
|
||||||
case -ECONNRESET: /* Responded, but call expired. */
|
|
||||||
if (error == -ECONNABORTED)
|
|
||||||
continue;
|
|
||||||
case -ECONNABORTED:
|
|
||||||
abort_code = s->probe.abort_code;
|
|
||||||
error = probe_error;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error == -ECONNABORTED)
|
|
||||||
error = afs_abort_to_error(abort_code);
|
|
||||||
|
|
||||||
failed_set_error:
|
failed_set_error:
|
||||||
fc->error = error;
|
fc->error = error;
|
||||||
failed:
|
failed:
|
||||||
|
@ -553,8 +522,11 @@ bool afs_select_current_fileserver(struct afs_fs_cursor *fc)
|
||||||
_leave(" = f [abort]");
|
_leave(" = f [abort]");
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
case -ERFKILL:
|
||||||
|
case -EADDRNOTAVAIL:
|
||||||
case -ENETUNREACH:
|
case -ENETUNREACH:
|
||||||
case -EHOSTUNREACH:
|
case -EHOSTUNREACH:
|
||||||
|
case -EHOSTDOWN:
|
||||||
case -ECONNREFUSED:
|
case -ECONNREFUSED:
|
||||||
case -ETIMEDOUT:
|
case -ETIMEDOUT:
|
||||||
case -ETIME:
|
case -ETIME:
|
||||||
|
@ -633,6 +605,7 @@ 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);
|
||||||
|
|
||||||
if (fc->error == -EDESTADDRREQ ||
|
if (fc->error == -EDESTADDRREQ ||
|
||||||
|
fc->error == -EADDRNOTAVAIL ||
|
||||||
fc->error == -ENETUNREACH ||
|
fc->error == -ENETUNREACH ||
|
||||||
fc->error == -EHOSTUNREACH)
|
fc->error == -EHOSTUNREACH)
|
||||||
afs_dump_edestaddrreq(fc);
|
afs_dump_edestaddrreq(fc);
|
||||||
|
|
|
@ -61,8 +61,11 @@ void afs_vlserver_probe_result(struct afs_call *call)
|
||||||
afs_io_error(call, afs_io_error_vl_probe_fail);
|
afs_io_error(call, afs_io_error_vl_probe_fail);
|
||||||
goto out;
|
goto out;
|
||||||
case -ECONNRESET: /* Responded, but call expired. */
|
case -ECONNRESET: /* Responded, but call expired. */
|
||||||
|
case -ERFKILL:
|
||||||
|
case -EADDRNOTAVAIL:
|
||||||
case -ENETUNREACH:
|
case -ENETUNREACH:
|
||||||
case -EHOSTUNREACH:
|
case -EHOSTUNREACH:
|
||||||
|
case -EHOSTDOWN:
|
||||||
case -ECONNREFUSED:
|
case -ECONNREFUSED:
|
||||||
case -ETIMEDOUT:
|
case -ETIMEDOUT:
|
||||||
case -ETIME:
|
case -ETIME:
|
||||||
|
@ -129,15 +132,17 @@ out:
|
||||||
* Probe all of a vlserver's addresses to find out the best route and to
|
* Probe all of a vlserver's addresses to find out the best route and to
|
||||||
* query its capabilities.
|
* query its capabilities.
|
||||||
*/
|
*/
|
||||||
static int afs_do_probe_vlserver(struct afs_net *net,
|
static bool afs_do_probe_vlserver(struct afs_net *net,
|
||||||
struct afs_vlserver *server,
|
struct afs_vlserver *server,
|
||||||
struct key *key,
|
struct key *key,
|
||||||
unsigned int server_index)
|
unsigned int server_index,
|
||||||
|
struct afs_error *_e)
|
||||||
{
|
{
|
||||||
struct afs_addr_cursor ac = {
|
struct afs_addr_cursor ac = {
|
||||||
.index = 0,
|
.index = 0,
|
||||||
};
|
};
|
||||||
int ret;
|
bool in_progress = false;
|
||||||
|
int err;
|
||||||
|
|
||||||
_enter("%s", server->name);
|
_enter("%s", server->name);
|
||||||
|
|
||||||
|
@ -151,15 +156,17 @@ static int afs_do_probe_vlserver(struct afs_net *net,
|
||||||
server->probe.rtt = UINT_MAX;
|
server->probe.rtt = UINT_MAX;
|
||||||
|
|
||||||
for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) {
|
for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) {
|
||||||
ret = afs_vl_get_capabilities(net, &ac, key, server,
|
err = afs_vl_get_capabilities(net, &ac, key, server,
|
||||||
server_index, true);
|
server_index, true);
|
||||||
if (ret != -EINPROGRESS) {
|
if (err == -EINPROGRESS)
|
||||||
afs_vl_probe_done(server);
|
in_progress = true;
|
||||||
return ret;
|
else
|
||||||
}
|
afs_prioritise_error(_e, err, ac.abort_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
if (!in_progress)
|
||||||
|
afs_vl_probe_done(server);
|
||||||
|
return in_progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -169,21 +176,23 @@ int afs_send_vl_probes(struct afs_net *net, struct key *key,
|
||||||
struct afs_vlserver_list *vllist)
|
struct afs_vlserver_list *vllist)
|
||||||
{
|
{
|
||||||
struct afs_vlserver *server;
|
struct afs_vlserver *server;
|
||||||
int i, ret;
|
struct afs_error e;
|
||||||
|
bool in_progress = false;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
e.error = 0;
|
||||||
|
e.responded = false;
|
||||||
for (i = 0; i < vllist->nr_servers; i++) {
|
for (i = 0; i < vllist->nr_servers; i++) {
|
||||||
server = vllist->servers[i].server;
|
server = vllist->servers[i].server;
|
||||||
if (test_bit(AFS_VLSERVER_FL_PROBED, &server->flags))
|
if (test_bit(AFS_VLSERVER_FL_PROBED, &server->flags))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!test_and_set_bit_lock(AFS_VLSERVER_FL_PROBING, &server->flags)) {
|
if (!test_and_set_bit_lock(AFS_VLSERVER_FL_PROBING, &server->flags) &&
|
||||||
ret = afs_do_probe_vlserver(net, server, key, i);
|
afs_do_probe_vlserver(net, server, key, i, &e))
|
||||||
if (ret)
|
in_progress = true;
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return in_progress ? 0 : e.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -71,8 +71,9 @@ bool afs_select_vlserver(struct afs_vl_cursor *vc)
|
||||||
{
|
{
|
||||||
struct afs_addr_list *alist;
|
struct afs_addr_list *alist;
|
||||||
struct afs_vlserver *vlserver;
|
struct afs_vlserver *vlserver;
|
||||||
|
struct afs_error e;
|
||||||
u32 rtt;
|
u32 rtt;
|
||||||
int error = vc->ac.error, abort_code, i;
|
int error = vc->ac.error, i;
|
||||||
|
|
||||||
_enter("%lx[%d],%lx[%d],%d,%d",
|
_enter("%lx[%d],%lx[%d],%d,%d",
|
||||||
vc->untried, vc->index,
|
vc->untried, vc->index,
|
||||||
|
@ -119,8 +120,11 @@ bool afs_select_vlserver(struct afs_vl_cursor *vc)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case -ERFKILL:
|
||||||
|
case -EADDRNOTAVAIL:
|
||||||
case -ENETUNREACH:
|
case -ENETUNREACH:
|
||||||
case -EHOSTUNREACH:
|
case -EHOSTUNREACH:
|
||||||
|
case -EHOSTDOWN:
|
||||||
case -ECONNREFUSED:
|
case -ECONNREFUSED:
|
||||||
case -ETIMEDOUT:
|
case -ETIMEDOUT:
|
||||||
case -ETIME:
|
case -ETIME:
|
||||||
|
@ -235,50 +239,15 @@ no_more_servers:
|
||||||
if (vc->flags & AFS_VL_CURSOR_RETRY)
|
if (vc->flags & AFS_VL_CURSOR_RETRY)
|
||||||
goto restart_from_beginning;
|
goto restart_from_beginning;
|
||||||
|
|
||||||
abort_code = 0;
|
e.error = -EDESTADDRREQ;
|
||||||
error = -EDESTADDRREQ;
|
e.responded = false;
|
||||||
for (i = 0; i < vc->server_list->nr_servers; i++) {
|
for (i = 0; i < vc->server_list->nr_servers; i++) {
|
||||||
struct afs_vlserver *s = vc->server_list->servers[i].server;
|
struct afs_vlserver *s = vc->server_list->servers[i].server;
|
||||||
int probe_error = READ_ONCE(s->probe.error);
|
|
||||||
|
|
||||||
switch (probe_error) {
|
afs_prioritise_error(&e, READ_ONCE(s->probe.error),
|
||||||
case 0:
|
s->probe.abort_code);
|
||||||
continue;
|
|
||||||
default:
|
|
||||||
if (error == -ETIMEDOUT ||
|
|
||||||
error == -ETIME)
|
|
||||||
continue;
|
|
||||||
case -ETIMEDOUT:
|
|
||||||
case -ETIME:
|
|
||||||
if (error == -ENOMEM ||
|
|
||||||
error == -ENONET)
|
|
||||||
continue;
|
|
||||||
case -ENOMEM:
|
|
||||||
case -ENONET:
|
|
||||||
if (error == -ENETUNREACH)
|
|
||||||
continue;
|
|
||||||
case -ENETUNREACH:
|
|
||||||
if (error == -EHOSTUNREACH)
|
|
||||||
continue;
|
|
||||||
case -EHOSTUNREACH:
|
|
||||||
if (error == -ECONNREFUSED)
|
|
||||||
continue;
|
|
||||||
case -ECONNREFUSED:
|
|
||||||
if (error == -ECONNRESET)
|
|
||||||
continue;
|
|
||||||
case -ECONNRESET: /* Responded, but call expired. */
|
|
||||||
if (error == -ECONNABORTED)
|
|
||||||
continue;
|
|
||||||
case -ECONNABORTED:
|
|
||||||
abort_code = s->probe.abort_code;
|
|
||||||
error = probe_error;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error == -ECONNABORTED)
|
|
||||||
error = afs_abort_to_error(abort_code);
|
|
||||||
|
|
||||||
failed_set_error:
|
failed_set_error:
|
||||||
vc->error = error;
|
vc->error = error;
|
||||||
failed:
|
failed:
|
||||||
|
@ -341,6 +310,7 @@ int afs_end_vlserver_operation(struct afs_vl_cursor *vc)
|
||||||
struct afs_net *net = vc->cell->net;
|
struct afs_net *net = vc->cell->net;
|
||||||
|
|
||||||
if (vc->error == -EDESTADDRREQ ||
|
if (vc->error == -EDESTADDRREQ ||
|
||||||
|
vc->error == -EADDRNOTAVAIL ||
|
||||||
vc->error == -ENETUNREACH ||
|
vc->error == -ENETUNREACH ||
|
||||||
vc->error == -EHOSTUNREACH)
|
vc->error == -EHOSTUNREACH)
|
||||||
afs_vl_dump_edestaddrreq(vc);
|
afs_vl_dump_edestaddrreq(vc);
|
||||||
|
|
1
fs/aio.c
1
fs/aio.c
|
@ -1436,6 +1436,7 @@ static int aio_prep_rw(struct kiocb *req, struct iocb *iocb)
|
||||||
ret = ioprio_check_cap(iocb->aio_reqprio);
|
ret = ioprio_check_cap(iocb->aio_reqprio);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_debug("aio ioprio check cap error: %d\n", ret);
|
pr_debug("aio ioprio check cap error: %d\n", ret);
|
||||||
|
fput(req->ki_filp);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ static bool dentry_connected(struct dentry *dentry)
|
||||||
struct dentry *parent = dget_parent(dentry);
|
struct dentry *parent = dget_parent(dentry);
|
||||||
|
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
if (IS_ROOT(dentry)) {
|
if (dentry == parent) {
|
||||||
dput(parent);
|
dput(parent);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,7 @@ static struct dentry *reconnect_one(struct vfsmount *mnt,
|
||||||
tmp = lookup_one_len_unlocked(nbuf, parent, strlen(nbuf));
|
tmp = lookup_one_len_unlocked(nbuf, parent, strlen(nbuf));
|
||||||
if (IS_ERR(tmp)) {
|
if (IS_ERR(tmp)) {
|
||||||
dprintk("%s: lookup failed: %d\n", __func__, PTR_ERR(tmp));
|
dprintk("%s: lookup failed: %d\n", __func__, PTR_ERR(tmp));
|
||||||
|
err = PTR_ERR(tmp);
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
if (tmp != dentry) {
|
if (tmp != dentry) {
|
||||||
|
|
|
@ -275,7 +275,7 @@ static int __sysv_write_inode(struct inode *inode, int wait)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sysv_write_inode(struct inode *inode, struct writeback_control *wbc)
|
int sysv_write_inode(struct inode *inode, struct writeback_control *wbc)
|
||||||
|
|
|
@ -560,6 +560,38 @@ static size_t copy_pipe_to_iter(const void *addr, size_t bytes,
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t csum_and_copy_to_pipe_iter(const void *addr, size_t bytes,
|
||||||
|
__wsum *csum, struct iov_iter *i)
|
||||||
|
{
|
||||||
|
struct pipe_inode_info *pipe = i->pipe;
|
||||||
|
size_t n, r;
|
||||||
|
size_t off = 0;
|
||||||
|
__wsum sum = *csum, next;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
if (!sanity(i))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bytes = n = push_pipe(i, bytes, &idx, &r);
|
||||||
|
if (unlikely(!n))
|
||||||
|
return 0;
|
||||||
|
for ( ; n; idx = next_idx(idx, pipe), r = 0) {
|
||||||
|
size_t chunk = min_t(size_t, n, PAGE_SIZE - r);
|
||||||
|
char *p = kmap_atomic(pipe->bufs[idx].page);
|
||||||
|
next = csum_partial_copy_nocheck(addr, p + r, chunk, 0);
|
||||||
|
sum = csum_block_add(sum, next, off);
|
||||||
|
kunmap_atomic(p);
|
||||||
|
i->idx = idx;
|
||||||
|
i->iov_offset = r + chunk;
|
||||||
|
n -= chunk;
|
||||||
|
off += chunk;
|
||||||
|
addr += chunk;
|
||||||
|
}
|
||||||
|
i->count -= bytes;
|
||||||
|
*csum = sum;
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
size_t _copy_to_iter(const void *addr, size_t bytes, struct iov_iter *i)
|
size_t _copy_to_iter(const void *addr, size_t bytes, struct iov_iter *i)
|
||||||
{
|
{
|
||||||
const char *from = addr;
|
const char *from = addr;
|
||||||
|
@ -1438,8 +1470,12 @@ size_t csum_and_copy_to_iter(const void *addr, size_t bytes, __wsum *csum,
|
||||||
const char *from = addr;
|
const char *from = addr;
|
||||||
__wsum sum, next;
|
__wsum sum, next;
|
||||||
size_t off = 0;
|
size_t off = 0;
|
||||||
|
|
||||||
|
if (unlikely(iov_iter_is_pipe(i)))
|
||||||
|
return csum_and_copy_to_pipe_iter(addr, bytes, csum, i);
|
||||||
|
|
||||||
sum = *csum;
|
sum = *csum;
|
||||||
if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) {
|
if (unlikely(iov_iter_is_discard(i))) {
|
||||||
WARN_ON(1); /* for now */
|
WARN_ON(1); /* for now */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue