hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/fs/afs/inode.c
....@@ -23,47 +23,89 @@
2323 #include <linux/namei.h>
2424 #include <linux/iversion.h>
2525 #include "internal.h"
26
+#include "afs_fs.h"
2627
2728 static const struct inode_operations afs_symlink_inode_operations = {
2829 .get_link = page_get_link,
29
- .listxattr = afs_listxattr,
3030 };
31
+
32
+static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *parent_vnode)
33
+{
34
+ static unsigned long once_only;
35
+
36
+ pr_warn("kAFS: AFS vnode with undefined type %u\n", vnode->status.type);
37
+ pr_warn("kAFS: A=%d m=%o s=%llx v=%llx\n",
38
+ vnode->status.abort_code,
39
+ vnode->status.mode,
40
+ vnode->status.size,
41
+ vnode->status.data_version);
42
+ pr_warn("kAFS: vnode %llx:%llx:%x\n",
43
+ vnode->fid.vid,
44
+ vnode->fid.vnode,
45
+ vnode->fid.unique);
46
+ if (parent_vnode)
47
+ pr_warn("kAFS: dir %llx:%llx:%x\n",
48
+ parent_vnode->fid.vid,
49
+ parent_vnode->fid.vnode,
50
+ parent_vnode->fid.unique);
51
+
52
+ if (!test_and_set_bit(0, &once_only))
53
+ dump_stack();
54
+}
3155
3256 /*
3357 * Initialise an inode from the vnode status.
3458 */
35
-static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key)
59
+static int afs_inode_init_from_status(struct afs_operation *op,
60
+ struct afs_vnode_param *vp,
61
+ struct afs_vnode *vnode)
3662 {
63
+ struct afs_file_status *status = &vp->scb.status;
3764 struct inode *inode = AFS_VNODE_TO_I(vnode);
65
+ struct timespec64 t;
66
+
67
+ _enter("{%llx:%llu.%u} %s",
68
+ vp->fid.vid, vp->fid.vnode, vp->fid.unique,
69
+ op->type ? op->type->name : "???");
3870
3971 _debug("FS: ft=%d lk=%d sz=%llu ver=%Lu mod=%hu",
40
- vnode->status.type,
41
- vnode->status.nlink,
42
- (unsigned long long) vnode->status.size,
43
- vnode->status.data_version,
44
- vnode->status.mode);
72
+ status->type,
73
+ status->nlink,
74
+ (unsigned long long) status->size,
75
+ status->data_version,
76
+ status->mode);
4577
46
- read_seqlock_excl(&vnode->cb_lock);
78
+ write_seqlock(&vnode->cb_lock);
4779
48
- afs_update_inode_from_status(vnode, &vnode->status, NULL,
49
- AFS_VNODE_NOT_YET_SET);
80
+ vnode->cb_v_break = op->cb_v_break;
81
+ vnode->cb_s_break = op->cb_s_break;
82
+ vnode->status = *status;
5083
51
- switch (vnode->status.type) {
84
+ t = status->mtime_client;
85
+ inode->i_ctime = t;
86
+ inode->i_mtime = t;
87
+ inode->i_atime = t;
88
+ inode->i_flags |= S_NOATIME;
89
+ inode->i_uid = make_kuid(&init_user_ns, status->owner);
90
+ inode->i_gid = make_kgid(&init_user_ns, status->group);
91
+ set_nlink(&vnode->vfs_inode, status->nlink);
92
+
93
+ switch (status->type) {
5294 case AFS_FTYPE_FILE:
53
- inode->i_mode = S_IFREG | vnode->status.mode;
95
+ inode->i_mode = S_IFREG | (status->mode & S_IALLUGO);
5496 inode->i_op = &afs_file_inode_operations;
5597 inode->i_fop = &afs_file_operations;
5698 inode->i_mapping->a_ops = &afs_fs_aops;
5799 break;
58100 case AFS_FTYPE_DIR:
59
- inode->i_mode = S_IFDIR | vnode->status.mode;
101
+ inode->i_mode = S_IFDIR | (status->mode & S_IALLUGO);
60102 inode->i_op = &afs_dir_inode_operations;
61103 inode->i_fop = &afs_dir_file_operations;
62104 inode->i_mapping->a_ops = &afs_dir_aops;
63105 break;
64106 case AFS_FTYPE_SYMLINK:
65107 /* Symlinks with a mode of 0644 are actually mountpoints. */
66
- if ((vnode->status.mode & 0777) == 0644) {
108
+ if ((status->mode & 0777) == 0644) {
67109 inode->i_flags |= S_AUTOMOUNT;
68110
69111 set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags);
....@@ -73,73 +115,275 @@
73115 inode->i_fop = &afs_mntpt_file_operations;
74116 inode->i_mapping->a_ops = &afs_fs_aops;
75117 } else {
76
- inode->i_mode = S_IFLNK | vnode->status.mode;
118
+ inode->i_mode = S_IFLNK | status->mode;
77119 inode->i_op = &afs_symlink_inode_operations;
78120 inode->i_mapping->a_ops = &afs_fs_aops;
79121 }
80122 inode_nohighmem(inode);
81123 break;
82124 default:
83
- printk("kAFS: AFS vnode with undefined type\n");
84
- read_sequnlock_excl(&vnode->cb_lock);
85
- return afs_protocol_error(NULL, -EBADMSG);
125
+ dump_vnode(vnode, op->file[0].vnode != vnode ? op->file[0].vnode : NULL);
126
+ write_sequnlock(&vnode->cb_lock);
127
+ return afs_protocol_error(NULL, afs_eproto_file_type);
86128 }
87129
88
- inode->i_blocks = 0;
89
- vnode->invalid_before = vnode->status.data_version;
130
+ afs_set_i_size(vnode, status->size);
90131
91
- read_sequnlock_excl(&vnode->cb_lock);
132
+ vnode->invalid_before = status->data_version;
133
+ inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);
134
+
135
+ if (!vp->scb.have_cb) {
136
+ /* it's a symlink we just created (the fileserver
137
+ * didn't give us a callback) */
138
+ vnode->cb_expires_at = ktime_get_real_seconds();
139
+ } else {
140
+ vnode->cb_expires_at = vp->scb.callback.expires_at;
141
+ vnode->cb_server = op->server;
142
+ set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
143
+ }
144
+
145
+ write_sequnlock(&vnode->cb_lock);
92146 return 0;
93147 }
94148
95149 /*
96
- * Fetch file status from the volume.
150
+ * Update the core inode struct from a returned status record.
97151 */
98
-int afs_fetch_status(struct afs_vnode *vnode, struct key *key, bool new_inode)
152
+static void afs_apply_status(struct afs_operation *op,
153
+ struct afs_vnode_param *vp)
99154 {
100
- struct afs_fs_cursor fc;
155
+ struct afs_file_status *status = &vp->scb.status;
156
+ struct afs_vnode *vnode = vp->vnode;
157
+ struct inode *inode = &vnode->vfs_inode;
158
+ struct timespec64 t;
159
+ umode_t mode;
160
+ bool data_changed = false;
161
+ bool change_size = vp->set_size;
162
+
163
+ _enter("{%llx:%llu.%u} %s",
164
+ vp->fid.vid, vp->fid.vnode, vp->fid.unique,
165
+ op->type ? op->type->name : "???");
166
+
167
+ BUG_ON(test_bit(AFS_VNODE_UNSET, &vnode->flags));
168
+
169
+ if (status->type != vnode->status.type) {
170
+ pr_warn("Vnode %llx:%llx:%x changed type %u to %u\n",
171
+ vnode->fid.vid,
172
+ vnode->fid.vnode,
173
+ vnode->fid.unique,
174
+ status->type, vnode->status.type);
175
+ afs_protocol_error(NULL, afs_eproto_bad_status);
176
+ return;
177
+ }
178
+
179
+ if (status->nlink != vnode->status.nlink)
180
+ set_nlink(inode, status->nlink);
181
+
182
+ if (status->owner != vnode->status.owner)
183
+ inode->i_uid = make_kuid(&init_user_ns, status->owner);
184
+
185
+ if (status->group != vnode->status.group)
186
+ inode->i_gid = make_kgid(&init_user_ns, status->group);
187
+
188
+ if (status->mode != vnode->status.mode) {
189
+ mode = inode->i_mode;
190
+ mode &= ~S_IALLUGO;
191
+ mode |= status->mode & S_IALLUGO;
192
+ WRITE_ONCE(inode->i_mode, mode);
193
+ }
194
+
195
+ t = status->mtime_client;
196
+ inode->i_mtime = t;
197
+ if (vp->update_ctime)
198
+ inode->i_ctime = op->ctime;
199
+
200
+ if (vnode->status.data_version != status->data_version)
201
+ data_changed = true;
202
+
203
+ vnode->status = *status;
204
+
205
+ if (vp->dv_before + vp->dv_delta != status->data_version) {
206
+ if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags))
207
+ pr_warn("kAFS: vnode modified {%llx:%llu} %llx->%llx %s\n",
208
+ vnode->fid.vid, vnode->fid.vnode,
209
+ (unsigned long long)vp->dv_before + vp->dv_delta,
210
+ (unsigned long long)status->data_version,
211
+ op->type ? op->type->name : "???");
212
+
213
+ vnode->invalid_before = status->data_version;
214
+ if (vnode->status.type == AFS_FTYPE_DIR) {
215
+ if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
216
+ afs_stat_v(vnode, n_inval);
217
+ } else {
218
+ set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
219
+ }
220
+ change_size = true;
221
+ data_changed = true;
222
+ } else if (vnode->status.type == AFS_FTYPE_DIR) {
223
+ /* Expected directory change is handled elsewhere so
224
+ * that we can locally edit the directory and save on a
225
+ * download.
226
+ */
227
+ if (test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
228
+ data_changed = false;
229
+ change_size = true;
230
+ }
231
+
232
+ if (data_changed) {
233
+ inode_set_iversion_raw(inode, status->data_version);
234
+
235
+ /* Only update the size if the data version jumped. If the
236
+ * file is being modified locally, then we might have our own
237
+ * idea of what the size should be that's not the same as
238
+ * what's on the server.
239
+ */
240
+ if (change_size) {
241
+ afs_set_i_size(vnode, status->size);
242
+ inode->i_ctime = t;
243
+ inode->i_atime = t;
244
+ }
245
+ }
246
+}
247
+
248
+/*
249
+ * Apply a callback to a vnode.
250
+ */
251
+static void afs_apply_callback(struct afs_operation *op,
252
+ struct afs_vnode_param *vp)
253
+{
254
+ struct afs_callback *cb = &vp->scb.callback;
255
+ struct afs_vnode *vnode = vp->vnode;
256
+
257
+ if (!afs_cb_is_broken(vp->cb_break_before, vnode)) {
258
+ vnode->cb_expires_at = cb->expires_at;
259
+ vnode->cb_server = op->server;
260
+ set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
261
+ }
262
+}
263
+
264
+/*
265
+ * Apply the received status and callback to an inode all in the same critical
266
+ * section to avoid races with afs_validate().
267
+ */
268
+void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *vp)
269
+{
270
+ struct afs_vnode *vnode = vp->vnode;
271
+
272
+ _enter("");
273
+
274
+ write_seqlock(&vnode->cb_lock);
275
+
276
+ if (vp->scb.have_error) {
277
+ /* A YFS server will return this from RemoveFile2 and AFS and
278
+ * YFS will return this from InlineBulkStatus.
279
+ */
280
+ if (vp->scb.status.abort_code == VNOVNODE) {
281
+ set_bit(AFS_VNODE_DELETED, &vnode->flags);
282
+ clear_nlink(&vnode->vfs_inode);
283
+ __afs_break_callback(vnode, afs_cb_break_for_deleted);
284
+ op->flags &= ~AFS_OPERATION_DIR_CONFLICT;
285
+ }
286
+ } else if (vp->scb.have_status) {
287
+ if (vp->speculative &&
288
+ (test_bit(AFS_VNODE_MODIFYING, &vnode->flags) ||
289
+ vp->dv_before != vnode->status.data_version))
290
+ /* Ignore the result of a speculative bulk status fetch
291
+ * if it splits around a modification op, thereby
292
+ * appearing to regress the data version.
293
+ */
294
+ goto out;
295
+ afs_apply_status(op, vp);
296
+ if (vp->scb.have_cb)
297
+ afs_apply_callback(op, vp);
298
+ } else if (vp->op_unlinked && !(op->flags & AFS_OPERATION_DIR_CONFLICT)) {
299
+ drop_nlink(&vnode->vfs_inode);
300
+ if (vnode->vfs_inode.i_nlink == 0) {
301
+ set_bit(AFS_VNODE_DELETED, &vnode->flags);
302
+ __afs_break_callback(vnode, afs_cb_break_for_deleted);
303
+ }
304
+ }
305
+
306
+out:
307
+ write_sequnlock(&vnode->cb_lock);
308
+
309
+ if (vp->scb.have_status)
310
+ afs_cache_permit(vnode, op->key, vp->cb_break_before, &vp->scb);
311
+}
312
+
313
+static void afs_fetch_status_success(struct afs_operation *op)
314
+{
315
+ struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
316
+ struct afs_vnode *vnode = vp->vnode;
101317 int ret;
102318
103
- _enter("%s,{%x:%u.%u,S=%lx}",
319
+ if (vnode->vfs_inode.i_state & I_NEW) {
320
+ ret = afs_inode_init_from_status(op, vp, vnode);
321
+ op->error = ret;
322
+ if (ret == 0)
323
+ afs_cache_permit(vnode, op->key, vp->cb_break_before, &vp->scb);
324
+ } else {
325
+ afs_vnode_commit_status(op, vp);
326
+ }
327
+}
328
+
329
+const struct afs_operation_ops afs_fetch_status_operation = {
330
+ .issue_afs_rpc = afs_fs_fetch_status,
331
+ .issue_yfs_rpc = yfs_fs_fetch_status,
332
+ .success = afs_fetch_status_success,
333
+ .aborted = afs_check_for_remote_deletion,
334
+};
335
+
336
+/*
337
+ * Fetch file status from the volume.
338
+ */
339
+int afs_fetch_status(struct afs_vnode *vnode, struct key *key, bool is_new,
340
+ afs_access_t *_caller_access)
341
+{
342
+ struct afs_operation *op;
343
+
344
+ _enter("%s,{%llx:%llu.%u,S=%lx}",
104345 vnode->volume->name,
105346 vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique,
106347 vnode->flags);
107348
108
- ret = -ERESTARTSYS;
109
- if (afs_begin_vnode_operation(&fc, vnode, key)) {
110
- while (afs_select_fileserver(&fc)) {
111
- fc.cb_break = afs_calc_vnode_cb_break(vnode);
112
- afs_fs_fetch_file_status(&fc, NULL, new_inode);
113
- }
349
+ op = afs_alloc_operation(key, vnode->volume);
350
+ if (IS_ERR(op))
351
+ return PTR_ERR(op);
114352
115
- afs_check_for_remote_deletion(&fc, fc.vnode);
116
- afs_vnode_commit_status(&fc, vnode, fc.cb_break);
117
- ret = afs_end_vnode_operation(&fc);
118
- }
353
+ afs_op_set_vnode(op, 0, vnode);
119354
120
- _leave(" = %d", ret);
121
- return ret;
355
+ op->nr_files = 1;
356
+ op->ops = &afs_fetch_status_operation;
357
+ afs_begin_vnode_operation(op);
358
+ afs_wait_for_operation(op);
359
+
360
+ if (_caller_access)
361
+ *_caller_access = op->file[0].scb.status.caller_access;
362
+ return afs_put_operation(op);
363
+}
364
+
365
+/*
366
+ * ilookup() comparator
367
+ */
368
+int afs_ilookup5_test_by_fid(struct inode *inode, void *opaque)
369
+{
370
+ struct afs_vnode *vnode = AFS_FS_I(inode);
371
+ struct afs_fid *fid = opaque;
372
+
373
+ return (fid->vnode == vnode->fid.vnode &&
374
+ fid->vnode_hi == vnode->fid.vnode_hi &&
375
+ fid->unique == vnode->fid.unique);
122376 }
123377
124378 /*
125379 * iget5() comparator
126380 */
127
-int afs_iget5_test(struct inode *inode, void *opaque)
381
+static int afs_iget5_test(struct inode *inode, void *opaque)
128382 {
129
- struct afs_iget_data *data = opaque;
383
+ struct afs_vnode_param *vp = opaque;
384
+ //struct afs_vnode *vnode = AFS_FS_I(inode);
130385
131
- return inode->i_ino == data->fid.vnode &&
132
- inode->i_generation == data->fid.unique;
133
-}
134
-
135
-/*
136
- * iget5() comparator for inode created by autocell operations
137
- *
138
- * These pseudo inodes don't match anything.
139
- */
140
-static int afs_iget5_pseudo_dir_test(struct inode *inode, void *opaque)
141
-{
142
- return 0;
386
+ return afs_ilookup5_test_by_fid(inode, &vp->fid);
143387 }
144388
145389 /*
....@@ -147,89 +391,19 @@
147391 */
148392 static int afs_iget5_set(struct inode *inode, void *opaque)
149393 {
150
- struct afs_iget_data *data = opaque;
394
+ struct afs_vnode_param *vp = opaque;
395
+ struct afs_super_info *as = AFS_FS_S(inode->i_sb);
151396 struct afs_vnode *vnode = AFS_FS_I(inode);
152397
153
- inode->i_ino = data->fid.vnode;
154
- inode->i_generation = data->fid.unique;
155
- vnode->fid = data->fid;
156
- vnode->volume = data->volume;
398
+ vnode->volume = as->volume;
399
+ vnode->fid = vp->fid;
157400
401
+ /* YFS supports 96-bit vnode IDs, but Linux only supports
402
+ * 64-bit inode numbers.
403
+ */
404
+ inode->i_ino = vnode->fid.vnode;
405
+ inode->i_generation = vnode->fid.unique;
158406 return 0;
159
-}
160
-
161
-/*
162
- * Create an inode for a dynamic root directory or an autocell dynamic
163
- * automount dir.
164
- */
165
-struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root)
166
-{
167
- struct afs_iget_data data;
168
- struct afs_super_info *as;
169
- struct afs_vnode *vnode;
170
- struct inode *inode;
171
- static atomic_t afs_autocell_ino;
172
-
173
- _enter("");
174
-
175
- as = sb->s_fs_info;
176
- if (as->volume) {
177
- data.volume = as->volume;
178
- data.fid.vid = as->volume->vid;
179
- }
180
- if (root) {
181
- data.fid.vnode = 1;
182
- data.fid.unique = 1;
183
- } else {
184
- data.fid.vnode = atomic_inc_return(&afs_autocell_ino);
185
- data.fid.unique = 0;
186
- }
187
-
188
- inode = iget5_locked(sb, data.fid.vnode,
189
- afs_iget5_pseudo_dir_test, afs_iget5_set,
190
- &data);
191
- if (!inode) {
192
- _leave(" = -ENOMEM");
193
- return ERR_PTR(-ENOMEM);
194
- }
195
-
196
- _debug("GOT INODE %p { ino=%lu, vl=%x, vn=%x, u=%x }",
197
- inode, inode->i_ino, data.fid.vid, data.fid.vnode,
198
- data.fid.unique);
199
-
200
- vnode = AFS_FS_I(inode);
201
-
202
- /* there shouldn't be an existing inode */
203
- BUG_ON(!(inode->i_state & I_NEW));
204
-
205
- inode->i_size = 0;
206
- inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
207
- if (root) {
208
- inode->i_op = &afs_dynroot_inode_operations;
209
- inode->i_fop = &afs_dynroot_file_operations;
210
- } else {
211
- inode->i_op = &afs_autocell_inode_operations;
212
- }
213
- set_nlink(inode, 2);
214
- inode->i_uid = GLOBAL_ROOT_UID;
215
- inode->i_gid = GLOBAL_ROOT_GID;
216
- inode->i_ctime.tv_sec = get_seconds();
217
- inode->i_ctime.tv_nsec = 0;
218
- inode->i_atime = inode->i_mtime = inode->i_ctime;
219
- inode->i_blocks = 0;
220
- inode_set_iversion_raw(inode, 0);
221
- inode->i_generation = 0;
222
-
223
- set_bit(AFS_VNODE_PSEUDODIR, &vnode->flags);
224
- if (!root) {
225
- set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags);
226
- inode->i_flags |= S_AUTOMOUNT;
227
- }
228
-
229
- inode->i_flags |= S_NOATIME;
230
- unlock_new_inode(inode);
231
- _leave(" = %p", inode);
232
- return inode;
233407 }
234408
235409 /*
....@@ -252,8 +426,8 @@
252426
253427 key.vnode_id = vnode->fid.vnode;
254428 key.unique = vnode->fid.unique;
255
- key.vnode_id_ext[0] = 0;
256
- key.vnode_id_ext[1] = 0;
429
+ key.vnode_id_ext[0] = vnode->fid.vnode >> 32;
430
+ key.vnode_id_ext[1] = vnode->fid.vnode_hi;
257431 aux.data_version = vnode->status.data_version;
258432
259433 vnode->cache = fscache_acquire_cookie(vnode->volume->cache,
....@@ -267,32 +441,26 @@
267441 /*
268442 * inode retrieval
269443 */
270
-struct inode *afs_iget(struct super_block *sb, struct key *key,
271
- struct afs_fid *fid, struct afs_file_status *status,
272
- struct afs_callback *cb, struct afs_cb_interest *cbi)
444
+struct inode *afs_iget(struct afs_operation *op, struct afs_vnode_param *vp)
273445 {
274
- struct afs_iget_data data = { .fid = *fid };
275
- struct afs_super_info *as;
446
+ struct afs_vnode_param *dvp = &op->file[0];
447
+ struct super_block *sb = dvp->vnode->vfs_inode.i_sb;
276448 struct afs_vnode *vnode;
277449 struct inode *inode;
278450 int ret;
279451
280
- _enter(",{%x:%u.%u},,", fid->vid, fid->vnode, fid->unique);
452
+ _enter(",{%llx:%llu.%u},,", vp->fid.vid, vp->fid.vnode, vp->fid.unique);
281453
282
- as = sb->s_fs_info;
283
- data.volume = as->volume;
284
-
285
- inode = iget5_locked(sb, fid->vnode, afs_iget5_test, afs_iget5_set,
286
- &data);
454
+ inode = iget5_locked(sb, vp->fid.vnode, afs_iget5_test, afs_iget5_set, vp);
287455 if (!inode) {
288456 _leave(" = -ENOMEM");
289457 return ERR_PTR(-ENOMEM);
290458 }
291459
292
- _debug("GOT INODE %p { vl=%x vn=%x, u=%x }",
293
- inode, fid->vid, fid->vnode, fid->unique);
294
-
295460 vnode = AFS_FS_I(inode);
461
+
462
+ _debug("GOT INODE %p { vl=%llx vn=%llx, u=%x }",
463
+ inode, vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);
296464
297465 /* deal with an existing inode */
298466 if (!(inode->i_state & I_NEW)) {
....@@ -300,33 +468,7 @@
300468 return inode;
301469 }
302470
303
- if (!status) {
304
- /* it's a remotely extant inode */
305
- ret = afs_fetch_status(vnode, key, true);
306
- if (ret < 0)
307
- goto bad_inode;
308
- } else {
309
- /* it's an inode we just created */
310
- memcpy(&vnode->status, status, sizeof(vnode->status));
311
-
312
- if (!cb) {
313
- /* it's a symlink we just created (the fileserver
314
- * didn't give us a callback) */
315
- vnode->cb_version = 0;
316
- vnode->cb_type = 0;
317
- vnode->cb_expires_at = 0;
318
- } else {
319
- vnode->cb_version = cb->version;
320
- vnode->cb_type = cb->type;
321
- vnode->cb_expires_at = cb->expiry;
322
- vnode->cb_interest = afs_get_cb_interest(cbi);
323
- set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
324
- }
325
-
326
- vnode->cb_expires_at += ktime_get_real_seconds();
327
- }
328
-
329
- ret = afs_inode_init_from_status(vnode, key);
471
+ ret = afs_inode_init_from_status(op, vp, vnode);
330472 if (ret < 0)
331473 goto bad_inode;
332474
....@@ -334,9 +476,8 @@
334476
335477 /* success */
336478 clear_bit(AFS_VNODE_UNSET, &vnode->flags);
337
- inode->i_flags |= S_NOATIME;
338479 unlock_new_inode(inode);
339
- _leave(" = %p [CB { v=%u t=%u }]", inode, vnode->cb_version, vnode->cb_type);
480
+ _leave(" = %p", inode);
340481 return inode;
341482
342483 /* failure */
....@@ -346,13 +487,81 @@
346487 return ERR_PTR(ret);
347488 }
348489
490
+static int afs_iget5_set_root(struct inode *inode, void *opaque)
491
+{
492
+ struct afs_super_info *as = AFS_FS_S(inode->i_sb);
493
+ struct afs_vnode *vnode = AFS_FS_I(inode);
494
+
495
+ vnode->volume = as->volume;
496
+ vnode->fid.vid = as->volume->vid,
497
+ vnode->fid.vnode = 1;
498
+ vnode->fid.unique = 1;
499
+ inode->i_ino = 1;
500
+ inode->i_generation = 1;
501
+ return 0;
502
+}
503
+
504
+/*
505
+ * Set up the root inode for a volume. This is always vnode 1, unique 1 within
506
+ * the volume.
507
+ */
508
+struct inode *afs_root_iget(struct super_block *sb, struct key *key)
509
+{
510
+ struct afs_super_info *as = AFS_FS_S(sb);
511
+ struct afs_operation *op;
512
+ struct afs_vnode *vnode;
513
+ struct inode *inode;
514
+ int ret;
515
+
516
+ _enter(",{%llx},,", as->volume->vid);
517
+
518
+ inode = iget5_locked(sb, 1, NULL, afs_iget5_set_root, NULL);
519
+ if (!inode) {
520
+ _leave(" = -ENOMEM");
521
+ return ERR_PTR(-ENOMEM);
522
+ }
523
+
524
+ _debug("GOT ROOT INODE %p { vl=%llx }", inode, as->volume->vid);
525
+
526
+ BUG_ON(!(inode->i_state & I_NEW));
527
+
528
+ vnode = AFS_FS_I(inode);
529
+ vnode->cb_v_break = as->volume->cb_v_break,
530
+
531
+ op = afs_alloc_operation(key, as->volume);
532
+ if (IS_ERR(op)) {
533
+ ret = PTR_ERR(op);
534
+ goto error;
535
+ }
536
+
537
+ afs_op_set_vnode(op, 0, vnode);
538
+
539
+ op->nr_files = 1;
540
+ op->ops = &afs_fetch_status_operation;
541
+ ret = afs_do_sync_operation(op);
542
+ if (ret < 0)
543
+ goto error;
544
+
545
+ afs_get_inode_cache(vnode);
546
+
547
+ clear_bit(AFS_VNODE_UNSET, &vnode->flags);
548
+ unlock_new_inode(inode);
549
+ _leave(" = %p", inode);
550
+ return inode;
551
+
552
+error:
553
+ iget_failed(inode);
554
+ _leave(" = %d [bad]", ret);
555
+ return ERR_PTR(ret);
556
+}
557
+
349558 /*
350559 * mark the data attached to an inode as obsolete due to a write on the server
351560 * - might also want to ditch all the outstanding writes and dirty pages
352561 */
353
-void afs_zap_data(struct afs_vnode *vnode)
562
+static void afs_zap_data(struct afs_vnode *vnode)
354563 {
355
- _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
564
+ _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
356565
357566 #ifdef CONFIG_AFS_FSCACHE
358567 fscache_invalidate(vnode->cache);
....@@ -368,6 +577,84 @@
368577 }
369578
370579 /*
580
+ * Get the server reinit counter for a vnode's current server.
581
+ */
582
+static bool afs_get_s_break_rcu(struct afs_vnode *vnode, unsigned int *_s_break)
583
+{
584
+ struct afs_server_list *slist = rcu_dereference(vnode->volume->servers);
585
+ struct afs_server *server;
586
+ int i;
587
+
588
+ for (i = 0; i < slist->nr_servers; i++) {
589
+ server = slist->servers[i].server;
590
+ if (server == vnode->cb_server) {
591
+ *_s_break = READ_ONCE(server->cb_s_break);
592
+ return true;
593
+ }
594
+ }
595
+
596
+ return false;
597
+}
598
+
599
+/*
600
+ * Check the validity of a vnode/inode.
601
+ */
602
+bool afs_check_validity(struct afs_vnode *vnode)
603
+{
604
+ struct afs_volume *volume = vnode->volume;
605
+ enum afs_cb_break_reason need_clear = afs_cb_break_no_break;
606
+ time64_t now = ktime_get_real_seconds();
607
+ bool valid;
608
+ unsigned int cb_break, cb_s_break, cb_v_break;
609
+ int seq = 0;
610
+
611
+ do {
612
+ read_seqbegin_or_lock(&vnode->cb_lock, &seq);
613
+ cb_v_break = READ_ONCE(volume->cb_v_break);
614
+ cb_break = vnode->cb_break;
615
+
616
+ if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags) &&
617
+ afs_get_s_break_rcu(vnode, &cb_s_break)) {
618
+ if (vnode->cb_s_break != cb_s_break ||
619
+ vnode->cb_v_break != cb_v_break) {
620
+ vnode->cb_s_break = cb_s_break;
621
+ vnode->cb_v_break = cb_v_break;
622
+ need_clear = afs_cb_break_for_vsbreak;
623
+ valid = false;
624
+ } else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) {
625
+ need_clear = afs_cb_break_for_zap;
626
+ valid = false;
627
+ } else if (vnode->cb_expires_at - 10 <= now) {
628
+ need_clear = afs_cb_break_for_lapsed;
629
+ valid = false;
630
+ } else {
631
+ valid = true;
632
+ }
633
+ } else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
634
+ valid = true;
635
+ } else {
636
+ vnode->cb_v_break = cb_v_break;
637
+ valid = false;
638
+ }
639
+
640
+ } while (need_seqretry(&vnode->cb_lock, seq));
641
+
642
+ done_seqretry(&vnode->cb_lock, seq);
643
+
644
+ if (need_clear != afs_cb_break_no_break) {
645
+ write_seqlock(&vnode->cb_lock);
646
+ if (cb_break == vnode->cb_break)
647
+ __afs_break_callback(vnode, need_clear);
648
+ else
649
+ trace_afs_cb_miss(&vnode->fid, need_clear);
650
+ write_sequnlock(&vnode->cb_lock);
651
+ valid = false;
652
+ }
653
+
654
+ return valid;
655
+}
656
+
657
+/*
371658 * validate a vnode/inode
372659 * - there are several things we need to check
373660 * - parent dir data changes (rm, rmdir, rename, mkdir, create, link,
....@@ -378,41 +665,16 @@
378665 */
379666 int afs_validate(struct afs_vnode *vnode, struct key *key)
380667 {
381
- time64_t now = ktime_get_real_seconds();
382668 bool valid;
383669 int ret;
384670
385
- _enter("{v={%x:%u} fl=%lx},%x",
671
+ _enter("{v={%llx:%llu} fl=%lx},%x",
386672 vnode->fid.vid, vnode->fid.vnode, vnode->flags,
387673 key_serial(key));
388674
389
- /* Quickly check the callback state. Ideally, we'd use read_seqbegin
390
- * here, but we have no way to pass the net namespace to the RCU
391
- * cleanup for the server record.
392
- */
393
- read_seqlock_excl(&vnode->cb_lock);
394
-
395
- if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
396
- if (vnode->cb_s_break != vnode->cb_interest->server->cb_s_break ||
397
- vnode->cb_v_break != vnode->volume->cb_v_break) {
398
- vnode->cb_s_break = vnode->cb_interest->server->cb_s_break;
399
- vnode->cb_v_break = vnode->volume->cb_v_break;
400
- valid = false;
401
- } else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) {
402
- valid = false;
403
- } else if (vnode->cb_expires_at - 10 <= now) {
404
- valid = false;
405
- } else {
406
- valid = true;
407
- }
408
- } else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
409
- valid = true;
410
- } else {
411
- vnode->cb_v_break = vnode->volume->cb_v_break;
412
- valid = false;
413
- }
414
-
415
- read_sequnlock_excl(&vnode->cb_lock);
675
+ rcu_read_lock();
676
+ valid = afs_check_validity(vnode);
677
+ rcu_read_unlock();
416678
417679 if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
418680 clear_nlink(&vnode->vfs_inode);
....@@ -428,7 +690,7 @@
428690 * access */
429691 if (!test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
430692 _debug("not promised");
431
- ret = afs_fetch_status(vnode, key, false);
693
+ ret = afs_fetch_status(vnode, key, false, NULL);
432694 if (ret < 0) {
433695 if (ret == -ENOENT) {
434696 set_bit(AFS_VNODE_DELETED, &vnode->flags);
....@@ -468,13 +730,29 @@
468730 {
469731 struct inode *inode = d_inode(path->dentry);
470732 struct afs_vnode *vnode = AFS_FS_I(inode);
471
- int seq = 0;
733
+ struct key *key;
734
+ int ret, seq = 0;
472735
473736 _enter("{ ino=%lu v=%u }", inode->i_ino, inode->i_generation);
737
+
738
+ if (vnode->volume &&
739
+ !(query_flags & AT_STATX_DONT_SYNC) &&
740
+ !test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
741
+ key = afs_request_key(vnode->volume->cell);
742
+ if (IS_ERR(key))
743
+ return PTR_ERR(key);
744
+ ret = afs_validate(vnode, key);
745
+ key_put(key);
746
+ if (ret < 0)
747
+ return ret;
748
+ }
474749
475750 do {
476751 read_seqbegin_or_lock(&vnode->cb_lock, &seq);
477752 generic_fillattr(inode, stat);
753
+ if (test_bit(AFS_VNODE_SILLY_DELETED, &vnode->flags) &&
754
+ stat->nlink > 0)
755
+ stat->nlink -= 1;
478756 } while (need_seqretry(&vnode->cb_lock, seq));
479757
480758 done_seqretry(&vnode->cb_lock, seq);
....@@ -503,7 +781,7 @@
503781
504782 vnode = AFS_FS_I(inode);
505783
506
- _enter("{%x:%u.%d}",
784
+ _enter("{%llx:%llu.%d}",
507785 vnode->fid.vid,
508786 vnode->fid.vnode,
509787 vnode->fid.unique);
....@@ -514,11 +792,6 @@
514792
515793 truncate_inode_pages_final(&inode->i_data);
516794 clear_inode(inode);
517
-
518
- if (vnode->cb_interest) {
519
- afs_put_cb_interest(afs_i2net(inode), vnode->cb_interest);
520
- vnode->cb_interest = NULL;
521
- }
522795
523796 while (!list_empty(&vnode->wb_keys)) {
524797 struct afs_wb_key *wbk = list_entry(vnode->wb_keys.next,
....@@ -540,61 +813,114 @@
540813
541814 afs_prune_wb_keys(vnode);
542815 afs_put_permits(rcu_access_pointer(vnode->permit_cache));
816
+ key_put(vnode->silly_key);
817
+ vnode->silly_key = NULL;
543818 key_put(vnode->lock_key);
544819 vnode->lock_key = NULL;
545820 _leave("");
546821 }
822
+
823
+static void afs_setattr_success(struct afs_operation *op)
824
+{
825
+ struct afs_vnode_param *vp = &op->file[0];
826
+ struct inode *inode = &vp->vnode->vfs_inode;
827
+ loff_t old_i_size = i_size_read(inode);
828
+
829
+ op->setattr.old_i_size = old_i_size;
830
+ afs_vnode_commit_status(op, vp);
831
+ /* inode->i_size has now been changed. */
832
+
833
+ if (op->setattr.attr->ia_valid & ATTR_SIZE) {
834
+ loff_t size = op->setattr.attr->ia_size;
835
+ if (size > old_i_size)
836
+ pagecache_isize_extended(inode, old_i_size, size);
837
+ }
838
+}
839
+
840
+static void afs_setattr_edit_file(struct afs_operation *op)
841
+{
842
+ struct afs_vnode_param *vp = &op->file[0];
843
+ struct inode *inode = &vp->vnode->vfs_inode;
844
+
845
+ if (op->setattr.attr->ia_valid & ATTR_SIZE) {
846
+ loff_t size = op->setattr.attr->ia_size;
847
+ loff_t i_size = op->setattr.old_i_size;
848
+
849
+ if (size < i_size)
850
+ truncate_pagecache(inode, size);
851
+ }
852
+}
853
+
854
+static const struct afs_operation_ops afs_setattr_operation = {
855
+ .issue_afs_rpc = afs_fs_setattr,
856
+ .issue_yfs_rpc = yfs_fs_setattr,
857
+ .success = afs_setattr_success,
858
+ .edit_dir = afs_setattr_edit_file,
859
+};
547860
548861 /*
549862 * set the attributes of an inode
550863 */
551864 int afs_setattr(struct dentry *dentry, struct iattr *attr)
552865 {
553
- struct afs_fs_cursor fc;
866
+ struct afs_operation *op;
554867 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
555
- struct key *key;
556868 int ret;
557869
558
- _enter("{%x:%u},{n=%pd},%x",
870
+ _enter("{%llx:%llu},{n=%pd},%x",
559871 vnode->fid.vid, vnode->fid.vnode, dentry,
560872 attr->ia_valid);
561873
562874 if (!(attr->ia_valid & (ATTR_SIZE | ATTR_MODE | ATTR_UID | ATTR_GID |
563
- ATTR_MTIME))) {
875
+ ATTR_MTIME | ATTR_MTIME_SET | ATTR_TIMES_SET |
876
+ ATTR_TOUCH))) {
564877 _leave(" = 0 [unsupported]");
565878 return 0;
879
+ }
880
+
881
+ if (attr->ia_valid & ATTR_SIZE) {
882
+ if (!S_ISREG(vnode->vfs_inode.i_mode))
883
+ return -EISDIR;
884
+
885
+ ret = inode_newsize_ok(&vnode->vfs_inode, attr->ia_size);
886
+ if (ret)
887
+ return ret;
888
+
889
+ if (attr->ia_size == i_size_read(&vnode->vfs_inode))
890
+ attr->ia_valid &= ~ATTR_SIZE;
566891 }
567892
568893 /* flush any dirty data outstanding on a regular file */
569894 if (S_ISREG(vnode->vfs_inode.i_mode))
570895 filemap_write_and_wait(vnode->vfs_inode.i_mapping);
571896
572
- if (attr->ia_valid & ATTR_FILE) {
573
- key = afs_file_key(attr->ia_file);
574
- } else {
575
- key = afs_request_key(vnode->volume->cell);
576
- if (IS_ERR(key)) {
577
- ret = PTR_ERR(key);
578
- goto error;
579
- }
897
+ /* Prevent any new writebacks from starting whilst we do this. */
898
+ down_write(&vnode->validate_lock);
899
+
900
+ op = afs_alloc_operation(((attr->ia_valid & ATTR_FILE) ?
901
+ afs_file_key(attr->ia_file) : NULL),
902
+ vnode->volume);
903
+ if (IS_ERR(op)) {
904
+ ret = PTR_ERR(op);
905
+ goto out_unlock;
580906 }
581907
582
- ret = -ERESTARTSYS;
583
- if (afs_begin_vnode_operation(&fc, vnode, key)) {
584
- while (afs_select_fileserver(&fc)) {
585
- fc.cb_break = afs_calc_vnode_cb_break(vnode);
586
- afs_fs_setattr(&fc, attr);
587
- }
908
+ afs_op_set_vnode(op, 0, vnode);
909
+ op->setattr.attr = attr;
588910
589
- afs_check_for_remote_deletion(&fc, fc.vnode);
590
- afs_vnode_commit_status(&fc, vnode, fc.cb_break);
591
- ret = afs_end_vnode_operation(&fc);
911
+ if (attr->ia_valid & ATTR_SIZE) {
912
+ op->file[0].dv_delta = 1;
913
+ op->file[0].set_size = true;
592914 }
915
+ op->ctime = attr->ia_ctime;
916
+ op->file[0].update_ctime = 1;
917
+ op->file[0].modification = true;
593918
594
- if (!(attr->ia_valid & ATTR_FILE))
595
- key_put(key);
919
+ op->ops = &afs_setattr_operation;
920
+ ret = afs_do_sync_operation(op);
596921
597
-error:
922
+out_unlock:
923
+ up_write(&vnode->validate_lock);
598924 _leave(" = %d", ret);
599925 return ret;
600926 }