Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 20b8391f authored by David Howells's avatar David Howells
Browse files

afs: Make some RPC operations non-interruptible



Make certain RPC operations non-interruptible, including:

 (*) Set attributes
 (*) Store data

     We don't want to get interrupted during a flush on close, flush on
     unlock, writeback or an inode update, leaving us in a state where we
     still need to do the writeback or update.

 (*) Extend lock
 (*) Release lock

     We don't want to get lock extension interrupted as the file locks on
     the server are time-limited.  Interruption during lock release is less
     of an issue since the lock is time-limited, but it's better to
     complete the release to avoid a several-minute wait to recover it.

     *Setting* the lock isn't a problem if it's interrupted since we can
      just return to the user and tell them they were interrupted - at
      which point they can elect to retry.

 (*) Silly unlink

     We want to remove silly unlink files if we can, rather than leaving
     them for the salvager to clear up.

Note that whilst these calls are no longer interruptible, they do have
timeouts on them, so if the server stops responding the call will fail with
something like ETIME or ECONNRESET.

Without this, the following:

	kAFS: Unexpected error from FS.StoreData -512

appears in dmesg when a pending store data gets interrupted and some
processes may just hang.

Additionally, make the code that checks/updates the server record ignore
failure due to interruption if the main call is uninterruptible and if the
server has an address list.  The next op will check it again since the
expiration time on the old list has past.

Fixes: d2ddc776 ("afs: Overhaul volume and server record caching and fileserver rotation")
Reported-by: default avatarJonathan Billings <jsbillings@jsbillings.org>
Reported-by: default avatarMarc Dionne <marc.dionne@auristor.com>
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent b960a34b
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -704,7 +704,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
		goto no_inline_bulk_status;

	inode = ERR_PTR(-ERESTARTSYS);
	if (afs_begin_vnode_operation(&fc, dvnode, key)) {
	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
		while (afs_select_fileserver(&fc)) {
			if (test_bit(AFS_SERVER_FL_NO_IBULK,
				      &fc.cbi->server->flags)) {
@@ -739,7 +739,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
	 */
	cookie->nr_fids = 1;
	inode = ERR_PTR(-ERESTARTSYS);
	if (afs_begin_vnode_operation(&fc, dvnode, key)) {
	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
		while (afs_select_fileserver(&fc)) {
			afs_fs_fetch_status(&fc,
					    afs_v2net(dvnode),
@@ -1166,7 +1166,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
	}

	ret = -ERESTARTSYS;
	if (afs_begin_vnode_operation(&fc, dvnode, key)) {
	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
		while (afs_select_fileserver(&fc)) {
			fc.cb_break = afs_calc_vnode_cb_break(dvnode);
			afs_fs_create(&fc, dentry->d_name.name, mode, data_version,
@@ -1250,7 +1250,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
	}

	ret = -ERESTARTSYS;
	if (afs_begin_vnode_operation(&fc, dvnode, key)) {
	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
		while (afs_select_fileserver(&fc)) {
			fc.cb_break = afs_calc_vnode_cb_break(dvnode);
			afs_fs_remove(&fc, vnode, dentry->d_name.name, true,
@@ -1374,7 +1374,7 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
	spin_unlock(&dentry->d_lock);

	ret = -ERESTARTSYS;
	if (afs_begin_vnode_operation(&fc, dvnode, key)) {
	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
		while (afs_select_fileserver(&fc)) {
			fc.cb_break = afs_calc_vnode_cb_break(dvnode);

@@ -1445,7 +1445,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
	}

	ret = -ERESTARTSYS;
	if (afs_begin_vnode_operation(&fc, dvnode, key)) {
	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
		while (afs_select_fileserver(&fc)) {
			fc.cb_break = afs_calc_vnode_cb_break(dvnode);
			afs_fs_create(&fc, dentry->d_name.name, mode, data_version,
@@ -1510,7 +1510,7 @@ static int afs_link(struct dentry *from, struct inode *dir,
	}

	ret = -ERESTARTSYS;
	if (afs_begin_vnode_operation(&fc, dvnode, key)) {
	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
		if (mutex_lock_interruptible_nested(&vnode->io_lock, 1) < 0) {
			afs_end_vnode_operation(&fc);
			goto error_key;
@@ -1584,7 +1584,7 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
	}

	ret = -ERESTARTSYS;
	if (afs_begin_vnode_operation(&fc, dvnode, key)) {
	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
		while (afs_select_fileserver(&fc)) {
			fc.cb_break = afs_calc_vnode_cb_break(dvnode);
			afs_fs_symlink(&fc, dentry->d_name.name,
@@ -1696,7 +1696,7 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
	}

	ret = -ERESTARTSYS;
	if (afs_begin_vnode_operation(&fc, orig_dvnode, key)) {
	if (afs_begin_vnode_operation(&fc, orig_dvnode, key, true)) {
		if (orig_dvnode != new_dvnode) {
			if (mutex_lock_interruptible_nested(&new_dvnode->io_lock, 1) < 0) {
				afs_end_vnode_operation(&fc);
+2 −2
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ static int afs_do_silly_rename(struct afs_vnode *dvnode, struct afs_vnode *vnode
	_enter("%pd,%pd", old, new);

	trace_afs_silly_rename(vnode, false);
	if (afs_begin_vnode_operation(&fc, dvnode, key)) {
	if (afs_begin_vnode_operation(&fc, dvnode, key, true)) {
		while (afs_select_fileserver(&fc)) {
			fc.cb_break = afs_calc_vnode_cb_break(dvnode);
			afs_fs_rename(&fc, old->d_name.name,
@@ -149,7 +149,7 @@ static int afs_do_silly_unlink(struct afs_vnode *dvnode, struct afs_vnode *vnode
	_enter("");

	trace_afs_silly_rename(vnode, true);
	if (afs_begin_vnode_operation(&fc, dvnode, key)) {
	if (afs_begin_vnode_operation(&fc, dvnode, key, false)) {
		while (afs_select_fileserver(&fc)) {
			fc.cb_break = afs_calc_vnode_cb_break(dvnode);

+1 −1
Original line number Diff line number Diff line
@@ -238,7 +238,7 @@ int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *de
	       key_serial(key));

	ret = -ERESTARTSYS;
	if (afs_begin_vnode_operation(&fc, vnode, key)) {
	if (afs_begin_vnode_operation(&fc, vnode, key, true)) {
		while (afs_select_fileserver(&fc)) {
			fc.cb_break = afs_calc_vnode_cb_break(vnode);
			afs_fs_fetch_data(&fc, desc);
+3 −3
Original line number Diff line number Diff line
@@ -196,7 +196,7 @@ static int afs_set_lock(struct afs_vnode *vnode, struct key *key,
	       key_serial(key), type);

	ret = -ERESTARTSYS;
	if (afs_begin_vnode_operation(&fc, vnode, key)) {
	if (afs_begin_vnode_operation(&fc, vnode, key, true)) {
		while (afs_select_fileserver(&fc)) {
			fc.cb_break = afs_calc_vnode_cb_break(vnode);
			afs_fs_set_lock(&fc, type);
@@ -227,7 +227,7 @@ static int afs_extend_lock(struct afs_vnode *vnode, struct key *key)
	       key_serial(key));

	ret = -ERESTARTSYS;
	if (afs_begin_vnode_operation(&fc, vnode, key)) {
	if (afs_begin_vnode_operation(&fc, vnode, key, false)) {
		while (afs_select_current_fileserver(&fc)) {
			fc.cb_break = afs_calc_vnode_cb_break(vnode);
			afs_fs_extend_lock(&fc);
@@ -258,7 +258,7 @@ static int afs_release_lock(struct afs_vnode *vnode, struct key *key)
	       key_serial(key));

	ret = -ERESTARTSYS;
	if (afs_begin_vnode_operation(&fc, vnode, key)) {
	if (afs_begin_vnode_operation(&fc, vnode, key, false)) {
		while (afs_select_current_fileserver(&fc)) {
			fc.cb_break = afs_calc_vnode_cb_break(vnode);
			afs_fs_release_lock(&fc);
+19 −0
Original line number Diff line number Diff line
@@ -469,6 +469,7 @@ int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsy
	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call(call, &vnode->fid);

	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -664,6 +665,7 @@ static int afs_fs_fetch_data64(struct afs_fs_cursor *fc, struct afs_read *req)
	call->cb_break = fc->cb_break;
	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call(call, &vnode->fid);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -712,6 +714,7 @@ int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
	call->cb_break = fc->cb_break;
	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call(call, &vnode->fid);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -833,6 +836,7 @@ int afs_fs_create(struct afs_fs_cursor *fc,

	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call1(call, &vnode->fid, name);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -930,6 +934,7 @@ int afs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,

	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call1(call, &dvnode->fid, name);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -1023,6 +1028,7 @@ int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,

	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call1(call, &vnode->fid, name);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -1138,6 +1144,7 @@ int afs_fs_symlink(struct afs_fs_cursor *fc,

	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call1(call, &vnode->fid, name);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -1257,6 +1264,7 @@ int afs_fs_rename(struct afs_fs_cursor *fc,

	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call2(call, &orig_dvnode->fid, orig_name, new_name);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -1362,6 +1370,7 @@ static int afs_fs_store_data64(struct afs_fs_cursor *fc,
	*bp++ = htonl((u32) i_size);

	trace_afs_make_fs_call(call, &vnode->fid);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -1439,6 +1448,7 @@ int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,

	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call(call, &vnode->fid);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -1538,6 +1548,7 @@ static int afs_fs_setattr_size64(struct afs_fs_cursor *fc, struct iattr *attr)

	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call(call, &vnode->fid);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -1585,6 +1596,7 @@ static int afs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr)

	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call(call, &vnode->fid);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -1630,6 +1642,7 @@ int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)

	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call(call, &vnode->fid);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -1815,6 +1828,7 @@ int afs_fs_get_volume_status(struct afs_fs_cursor *fc,

	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call(call, &vnode->fid);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -1906,6 +1920,7 @@ int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)

	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_calli(call, &vnode->fid, type);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -1942,6 +1957,7 @@ int afs_fs_extend_lock(struct afs_fs_cursor *fc)

	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call(call, &vnode->fid);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -1977,6 +1993,7 @@ int afs_fs_release_lock(struct afs_fs_cursor *fc)

	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call(call, &vnode->fid);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -2211,6 +2228,7 @@ int afs_fs_fetch_status(struct afs_fs_cursor *fc,
	call->cb_break = fc->cb_break;
	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call(call, fid);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
@@ -2397,6 +2415,7 @@ int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
	call->cb_break = fc->cb_break;
	afs_use_fs_server(call, fc->cbi);
	trace_afs_make_fs_call(call, &fids[0]);
	afs_set_fc_call(call, fc);
	afs_make_call(&fc->ac, call, GFP_NOFS);
	return afs_wait_for_call_to_complete(call, &fc->ac);
}
Loading