Commit 728279a5 authored by David Howells's avatar David Howells
Browse files

afs: Fix use of afs_check_for_remote_deletion()



afs_check_for_remote_deletion() checks to see if error ENOENT is returned
by the server in response to an operation and, if so, marks the primary
vnode as having been deleted as the FID is no longer valid.

However, it's being called from the operation success functions, where no
abort has happened - and if an inline abort is recorded, it's handled by
afs_vnode_commit_status().

Fix this by actually calling the operation aborted method if provided and
having that point to afs_check_for_remote_deletion().

Fixes: e49c7b2f ("afs: Build an abstraction around an "operation" concept")
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent 44767c35
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -700,6 +700,7 @@ static const struct afs_operation_ops afs_fetch_status_operation = {
	.issue_afs_rpc	= afs_fs_fetch_status,
	.issue_yfs_rpc	= yfs_fs_fetch_status,
	.success	= afs_do_lookup_success,
	.aborted	= afs_check_for_remote_deletion,
};

/*
@@ -1236,6 +1237,17 @@ void afs_d_release(struct dentry *dentry)
	_enter("%pd", dentry);
}

void afs_check_for_remote_deletion(struct afs_operation *op)
{
	struct afs_vnode *vnode = op->file[0].vnode;

	switch (op->ac.abort_code) {
	case VNOVNODE:
		set_bit(AFS_VNODE_DELETED, &vnode->flags);
		afs_break_callback(vnode, afs_cb_break_for_deleted);
	}
}

/*
 * Create a new inode for create/mkdir/symlink
 */
@@ -1269,7 +1281,6 @@ static void afs_create_success(struct afs_operation *op)
{
	_enter("op=%08x", op->debug_id);
	op->ctime = op->file[0].scb.status.mtime_client;
	afs_check_for_remote_deletion(op, op->file[0].vnode);
	afs_vnode_commit_status(op, &op->file[0]);
	afs_update_dentry_version(op, &op->file[0], op->dentry);
	afs_vnode_new_inode(op);
@@ -1303,6 +1314,7 @@ static const struct afs_operation_ops afs_mkdir_operation = {
	.issue_afs_rpc	= afs_fs_make_dir,
	.issue_yfs_rpc	= yfs_fs_make_dir,
	.success	= afs_create_success,
	.aborted	= afs_check_for_remote_deletion,
	.edit_dir	= afs_create_edit_dir,
	.put		= afs_create_put,
};
@@ -1353,7 +1365,6 @@ static void afs_rmdir_success(struct afs_operation *op)
{
	_enter("op=%08x", op->debug_id);
	op->ctime = op->file[0].scb.status.mtime_client;
	afs_check_for_remote_deletion(op, op->file[0].vnode);
	afs_vnode_commit_status(op, &op->file[0]);
	afs_update_dentry_version(op, &op->file[0], op->dentry);
}
@@ -1385,6 +1396,7 @@ static const struct afs_operation_ops afs_rmdir_operation = {
	.issue_afs_rpc	= afs_fs_remove_dir,
	.issue_yfs_rpc	= yfs_fs_remove_dir,
	.success	= afs_rmdir_success,
	.aborted	= afs_check_for_remote_deletion,
	.edit_dir	= afs_rmdir_edit_dir,
	.put		= afs_rmdir_put,
};
@@ -1484,7 +1496,6 @@ static void afs_unlink_success(struct afs_operation *op)
{
	_enter("op=%08x", op->debug_id);
	op->ctime = op->file[0].scb.status.mtime_client;
	afs_check_for_remote_deletion(op, op->file[0].vnode);
	afs_vnode_commit_status(op, &op->file[0]);
	afs_vnode_commit_status(op, &op->file[1]);
	afs_update_dentry_version(op, &op->file[0], op->dentry);
@@ -1516,6 +1527,7 @@ static const struct afs_operation_ops afs_unlink_operation = {
	.issue_afs_rpc	= afs_fs_remove_file,
	.issue_yfs_rpc	= yfs_fs_remove_file,
	.success	= afs_unlink_success,
	.aborted	= afs_check_for_remote_deletion,
	.edit_dir	= afs_unlink_edit_dir,
	.put		= afs_unlink_put,
};
@@ -1580,6 +1592,7 @@ static const struct afs_operation_ops afs_create_operation = {
	.issue_afs_rpc	= afs_fs_create_file,
	.issue_yfs_rpc	= yfs_fs_create_file,
	.success	= afs_create_success,
	.aborted	= afs_check_for_remote_deletion,
	.edit_dir	= afs_create_edit_dir,
	.put		= afs_create_put,
};
@@ -1649,6 +1662,7 @@ static const struct afs_operation_ops afs_link_operation = {
	.issue_afs_rpc	= afs_fs_link,
	.issue_yfs_rpc	= yfs_fs_link,
	.success	= afs_link_success,
	.aborted	= afs_check_for_remote_deletion,
	.edit_dir	= afs_create_edit_dir,
	.put		= afs_link_put,
};
@@ -1700,6 +1714,7 @@ static const struct afs_operation_ops afs_symlink_operation = {
	.issue_afs_rpc	= afs_fs_symlink,
	.issue_yfs_rpc	= yfs_fs_symlink,
	.success	= afs_create_success,
	.aborted	= afs_check_for_remote_deletion,
	.edit_dir	= afs_create_edit_dir,
	.put		= afs_create_put,
};
+1 −1
Original line number Diff line number Diff line
@@ -151,7 +151,6 @@ static void afs_silly_unlink_success(struct afs_operation *op)
	struct afs_vnode *vnode = op->file[1].vnode;

	_enter("op=%08x", op->debug_id);
	afs_check_for_remote_deletion(op, op->file[0].vnode);
	afs_vnode_commit_status(op, &op->file[0]);
	afs_vnode_commit_status(op, &op->file[1]);
	afs_update_dentry_version(op, &op->file[0], op->dentry);
@@ -181,6 +180,7 @@ static const struct afs_operation_ops afs_silly_unlink_operation = {
	.issue_afs_rpc	= afs_fs_remove_file,
	.issue_yfs_rpc	= yfs_fs_remove_file,
	.success	= afs_silly_unlink_success,
	.aborted	= afs_check_for_remote_deletion,
	.edit_dir	= afs_silly_unlink_edit_dir,
};

+1 −1
Original line number Diff line number Diff line
@@ -225,7 +225,6 @@ static void afs_fetch_data_success(struct afs_operation *op)
	struct afs_vnode *vnode = op->file[0].vnode;

	_enter("op=%08x", op->debug_id);
	afs_check_for_remote_deletion(op, vnode);
	afs_vnode_commit_status(op, &op->file[0]);
	afs_stat_v(vnode, n_fetches);
	atomic_long_add(op->fetch.req->actual_len, &op->net->n_fetch_bytes);
@@ -240,6 +239,7 @@ static const struct afs_operation_ops afs_fetch_data_operation = {
	.issue_afs_rpc	= afs_fs_fetch_data,
	.issue_yfs_rpc	= yfs_fs_fetch_data,
	.success	= afs_fetch_data_success,
	.aborted	= afs_check_for_remote_deletion,
	.put		= afs_fetch_data_put,
};

+1 −3
Original line number Diff line number Diff line
@@ -175,10 +175,7 @@ static void afs_kill_lockers_enoent(struct afs_vnode *vnode)

static void afs_lock_success(struct afs_operation *op)
{
	struct afs_vnode *vnode = op->file[0].vnode;

	_enter("op=%08x", op->debug_id);
	afs_check_for_remote_deletion(op, vnode);
	afs_vnode_commit_status(op, &op->file[0]);
}

@@ -186,6 +183,7 @@ static const struct afs_operation_ops afs_set_lock_operation = {
	.issue_afs_rpc	= afs_fs_set_lock,
	.issue_yfs_rpc	= yfs_fs_set_lock,
	.success	= afs_lock_success,
	.aborted	= afs_check_for_remote_deletion,
};

/*
+9 −1
Original line number Diff line number Diff line
@@ -187,9 +187,17 @@ void afs_wait_for_operation(struct afs_operation *op)
		op->error = afs_wait_for_call_to_complete(op->call, &op->ac);
	}

	if (op->error == 0) {
	switch (op->error) {
	case 0:
		_debug("success");
		op->ops->success(op);
		break;
	case -ECONNABORTED:
		if (op->ops->aborted)
			op->ops->aborted(op);
		break;
	default:
		break;
	}

	afs_end_vnode_operation(op);
Loading