0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/kernel.h>
0009 #include <linux/slab.h>
0010 #include <linux/fs.h>
0011 #include "internal.h"
0012
0013 static atomic_t afs_operation_debug_counter;
0014
0015
0016
0017
0018 struct afs_operation *afs_alloc_operation(struct key *key, struct afs_volume *volume)
0019 {
0020 struct afs_operation *op;
0021
0022 _enter("");
0023
0024 op = kzalloc(sizeof(*op), GFP_KERNEL);
0025 if (!op)
0026 return ERR_PTR(-ENOMEM);
0027
0028 if (!key) {
0029 key = afs_request_key(volume->cell);
0030 if (IS_ERR(key)) {
0031 kfree(op);
0032 return ERR_CAST(key);
0033 }
0034 } else {
0035 key_get(key);
0036 }
0037
0038 op->key = key;
0039 op->volume = afs_get_volume(volume, afs_volume_trace_get_new_op);
0040 op->net = volume->cell->net;
0041 op->cb_v_break = volume->cb_v_break;
0042 op->debug_id = atomic_inc_return(&afs_operation_debug_counter);
0043 op->error = -EDESTADDRREQ;
0044 op->ac.error = SHRT_MAX;
0045
0046 _leave(" = [op=%08x]", op->debug_id);
0047 return op;
0048 }
0049
0050
0051
0052
0053 static bool afs_get_io_locks(struct afs_operation *op)
0054 {
0055 struct afs_vnode *vnode = op->file[0].vnode;
0056 struct afs_vnode *vnode2 = op->file[1].vnode;
0057
0058 _enter("");
0059
0060 if (op->flags & AFS_OPERATION_UNINTR) {
0061 mutex_lock(&vnode->io_lock);
0062 op->flags |= AFS_OPERATION_LOCK_0;
0063 _leave(" = t [1]");
0064 return true;
0065 }
0066
0067 if (!vnode2 || !op->file[1].need_io_lock || vnode == vnode2)
0068 vnode2 = NULL;
0069
0070 if (vnode2 > vnode)
0071 swap(vnode, vnode2);
0072
0073 if (mutex_lock_interruptible(&vnode->io_lock) < 0) {
0074 op->error = -ERESTARTSYS;
0075 op->flags |= AFS_OPERATION_STOP;
0076 _leave(" = f [I 0]");
0077 return false;
0078 }
0079 op->flags |= AFS_OPERATION_LOCK_0;
0080
0081 if (vnode2) {
0082 if (mutex_lock_interruptible_nested(&vnode2->io_lock, 1) < 0) {
0083 op->error = -ERESTARTSYS;
0084 op->flags |= AFS_OPERATION_STOP;
0085 mutex_unlock(&vnode->io_lock);
0086 op->flags &= ~AFS_OPERATION_LOCK_0;
0087 _leave(" = f [I 1]");
0088 return false;
0089 }
0090 op->flags |= AFS_OPERATION_LOCK_1;
0091 }
0092
0093 _leave(" = t [2]");
0094 return true;
0095 }
0096
0097 static void afs_drop_io_locks(struct afs_operation *op)
0098 {
0099 struct afs_vnode *vnode = op->file[0].vnode;
0100 struct afs_vnode *vnode2 = op->file[1].vnode;
0101
0102 _enter("");
0103
0104 if (op->flags & AFS_OPERATION_LOCK_1)
0105 mutex_unlock(&vnode2->io_lock);
0106 if (op->flags & AFS_OPERATION_LOCK_0)
0107 mutex_unlock(&vnode->io_lock);
0108 }
0109
0110 static void afs_prepare_vnode(struct afs_operation *op, struct afs_vnode_param *vp,
0111 unsigned int index)
0112 {
0113 struct afs_vnode *vnode = vp->vnode;
0114
0115 if (vnode) {
0116 vp->fid = vnode->fid;
0117 vp->dv_before = vnode->status.data_version;
0118 vp->cb_break_before = afs_calc_vnode_cb_break(vnode);
0119 if (vnode->lock_state != AFS_VNODE_LOCK_NONE)
0120 op->flags |= AFS_OPERATION_CUR_ONLY;
0121 if (vp->modification)
0122 set_bit(AFS_VNODE_MODIFYING, &vnode->flags);
0123 }
0124
0125 if (vp->fid.vnode)
0126 _debug("PREP[%u] {%llx:%llu.%u}",
0127 index, vp->fid.vid, vp->fid.vnode, vp->fid.unique);
0128 }
0129
0130
0131
0132
0133
0134
0135
0136 bool afs_begin_vnode_operation(struct afs_operation *op)
0137 {
0138 struct afs_vnode *vnode = op->file[0].vnode;
0139
0140 ASSERT(vnode);
0141
0142 _enter("");
0143
0144 if (op->file[0].need_io_lock)
0145 if (!afs_get_io_locks(op))
0146 return false;
0147
0148 afs_prepare_vnode(op, &op->file[0], 0);
0149 afs_prepare_vnode(op, &op->file[1], 1);
0150 op->cb_v_break = op->volume->cb_v_break;
0151 _leave(" = true");
0152 return true;
0153 }
0154
0155
0156
0157
0158 static void afs_end_vnode_operation(struct afs_operation *op)
0159 {
0160 _enter("");
0161
0162 if (op->error == -EDESTADDRREQ ||
0163 op->error == -EADDRNOTAVAIL ||
0164 op->error == -ENETUNREACH ||
0165 op->error == -EHOSTUNREACH)
0166 afs_dump_edestaddrreq(op);
0167
0168 afs_drop_io_locks(op);
0169
0170 if (op->error == -ECONNABORTED)
0171 op->error = afs_abort_to_error(op->ac.abort_code);
0172 }
0173
0174
0175
0176
0177 void afs_wait_for_operation(struct afs_operation *op)
0178 {
0179 _enter("");
0180
0181 while (afs_select_fileserver(op)) {
0182 op->cb_s_break = op->server->cb_s_break;
0183 if (test_bit(AFS_SERVER_FL_IS_YFS, &op->server->flags) &&
0184 op->ops->issue_yfs_rpc)
0185 op->ops->issue_yfs_rpc(op);
0186 else if (op->ops->issue_afs_rpc)
0187 op->ops->issue_afs_rpc(op);
0188 else
0189 op->ac.error = -ENOTSUPP;
0190
0191 if (op->call)
0192 op->error = afs_wait_for_call_to_complete(op->call, &op->ac);
0193 }
0194
0195 switch (op->error) {
0196 case 0:
0197 _debug("success");
0198 op->ops->success(op);
0199 break;
0200 case -ECONNABORTED:
0201 if (op->ops->aborted)
0202 op->ops->aborted(op);
0203 fallthrough;
0204 default:
0205 if (op->ops->failed)
0206 op->ops->failed(op);
0207 break;
0208 }
0209
0210 afs_end_vnode_operation(op);
0211
0212 if (op->error == 0 && op->ops->edit_dir) {
0213 _debug("edit_dir");
0214 op->ops->edit_dir(op);
0215 }
0216 _leave("");
0217 }
0218
0219
0220
0221
0222 int afs_put_operation(struct afs_operation *op)
0223 {
0224 int i, ret = op->error;
0225
0226 _enter("op=%08x,%d", op->debug_id, ret);
0227
0228 if (op->ops && op->ops->put)
0229 op->ops->put(op);
0230 if (op->file[0].modification)
0231 clear_bit(AFS_VNODE_MODIFYING, &op->file[0].vnode->flags);
0232 if (op->file[1].modification && op->file[1].vnode != op->file[0].vnode)
0233 clear_bit(AFS_VNODE_MODIFYING, &op->file[1].vnode->flags);
0234 if (op->file[0].put_vnode)
0235 iput(&op->file[0].vnode->netfs.inode);
0236 if (op->file[1].put_vnode)
0237 iput(&op->file[1].vnode->netfs.inode);
0238
0239 if (op->more_files) {
0240 for (i = 0; i < op->nr_files - 2; i++)
0241 if (op->more_files[i].put_vnode)
0242 iput(&op->more_files[i].vnode->netfs.inode);
0243 kfree(op->more_files);
0244 }
0245
0246 afs_end_cursor(&op->ac);
0247 afs_put_serverlist(op->net, op->server_list);
0248 afs_put_volume(op->net, op->volume, afs_volume_trace_put_put_op);
0249 key_put(op->key);
0250 kfree(op);
0251 return ret;
0252 }
0253
0254 int afs_do_sync_operation(struct afs_operation *op)
0255 {
0256 afs_begin_vnode_operation(op);
0257 afs_wait_for_operation(op);
0258 return afs_put_operation(op);
0259 }