forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
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,274 @@
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
+ } else if (vnode->status.type == AFS_FTYPE_DIR) {
222
+ /* Expected directory change is handled elsewhere so
223
+ * that we can locally edit the directory and save on a
224
+ * download.
225
+ */
226
+ if (test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
227
+ data_changed = false;
228
+ change_size = true;
229
+ }
230
+
231
+ if (data_changed) {
232
+ inode_set_iversion_raw(inode, status->data_version);
233
+
234
+ /* Only update the size if the data version jumped. If the
235
+ * file is being modified locally, then we might have our own
236
+ * idea of what the size should be that's not the same as
237
+ * what's on the server.
238
+ */
239
+ if (change_size) {
240
+ afs_set_i_size(vnode, status->size);
241
+ inode->i_ctime = t;
242
+ inode->i_atime = t;
243
+ }
244
+ }
245
+}
246
+
247
+/*
248
+ * Apply a callback to a vnode.
249
+ */
250
+static void afs_apply_callback(struct afs_operation *op,
251
+ struct afs_vnode_param *vp)
252
+{
253
+ struct afs_callback *cb = &vp->scb.callback;
254
+ struct afs_vnode *vnode = vp->vnode;
255
+
256
+ if (!afs_cb_is_broken(vp->cb_break_before, vnode)) {
257
+ vnode->cb_expires_at = cb->expires_at;
258
+ vnode->cb_server = op->server;
259
+ set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
260
+ }
261
+}
262
+
263
+/*
264
+ * Apply the received status and callback to an inode all in the same critical
265
+ * section to avoid races with afs_validate().
266
+ */
267
+void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *vp)
268
+{
269
+ struct afs_vnode *vnode = vp->vnode;
270
+
271
+ _enter("");
272
+
273
+ write_seqlock(&vnode->cb_lock);
274
+
275
+ if (vp->scb.have_error) {
276
+ /* A YFS server will return this from RemoveFile2 and AFS and
277
+ * YFS will return this from InlineBulkStatus.
278
+ */
279
+ if (vp->scb.status.abort_code == VNOVNODE) {
280
+ set_bit(AFS_VNODE_DELETED, &vnode->flags);
281
+ clear_nlink(&vnode->vfs_inode);
282
+ __afs_break_callback(vnode, afs_cb_break_for_deleted);
283
+ op->flags &= ~AFS_OPERATION_DIR_CONFLICT;
284
+ }
285
+ } else if (vp->scb.have_status) {
286
+ if (vp->speculative &&
287
+ (test_bit(AFS_VNODE_MODIFYING, &vnode->flags) ||
288
+ vp->dv_before != vnode->status.data_version))
289
+ /* Ignore the result of a speculative bulk status fetch
290
+ * if it splits around a modification op, thereby
291
+ * appearing to regress the data version.
292
+ */
293
+ goto out;
294
+ afs_apply_status(op, vp);
295
+ if (vp->scb.have_cb)
296
+ afs_apply_callback(op, vp);
297
+ } else if (vp->op_unlinked && !(op->flags & AFS_OPERATION_DIR_CONFLICT)) {
298
+ drop_nlink(&vnode->vfs_inode);
299
+ if (vnode->vfs_inode.i_nlink == 0) {
300
+ set_bit(AFS_VNODE_DELETED, &vnode->flags);
301
+ __afs_break_callback(vnode, afs_cb_break_for_deleted);
302
+ }
303
+ }
304
+
305
+out:
306
+ write_sequnlock(&vnode->cb_lock);
307
+
308
+ if (vp->scb.have_status)
309
+ afs_cache_permit(vnode, op->key, vp->cb_break_before, &vp->scb);
310
+}
311
+
312
+static void afs_fetch_status_success(struct afs_operation *op)
313
+{
314
+ struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
315
+ struct afs_vnode *vnode = vp->vnode;
101316 int ret;
102317
103
- _enter("%s,{%x:%u.%u,S=%lx}",
318
+ if (vnode->vfs_inode.i_state & I_NEW) {
319
+ ret = afs_inode_init_from_status(op, vp, vnode);
320
+ op->error = ret;
321
+ if (ret == 0)
322
+ afs_cache_permit(vnode, op->key, vp->cb_break_before, &vp->scb);
323
+ } else {
324
+ afs_vnode_commit_status(op, vp);
325
+ }
326
+}
327
+
328
+const struct afs_operation_ops afs_fetch_status_operation = {
329
+ .issue_afs_rpc = afs_fs_fetch_status,
330
+ .issue_yfs_rpc = yfs_fs_fetch_status,
331
+ .success = afs_fetch_status_success,
332
+ .aborted = afs_check_for_remote_deletion,
333
+};
334
+
335
+/*
336
+ * Fetch file status from the volume.
337
+ */
338
+int afs_fetch_status(struct afs_vnode *vnode, struct key *key, bool is_new,
339
+ afs_access_t *_caller_access)
340
+{
341
+ struct afs_operation *op;
342
+
343
+ _enter("%s,{%llx:%llu.%u,S=%lx}",
104344 vnode->volume->name,
105345 vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique,
106346 vnode->flags);
107347
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
- }
348
+ op = afs_alloc_operation(key, vnode->volume);
349
+ if (IS_ERR(op))
350
+ return PTR_ERR(op);
114351
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
- }
352
+ afs_op_set_vnode(op, 0, vnode);
119353
120
- _leave(" = %d", ret);
121
- return ret;
354
+ op->nr_files = 1;
355
+ op->ops = &afs_fetch_status_operation;
356
+ afs_begin_vnode_operation(op);
357
+ afs_wait_for_operation(op);
358
+
359
+ if (_caller_access)
360
+ *_caller_access = op->file[0].scb.status.caller_access;
361
+ return afs_put_operation(op);
362
+}
363
+
364
+/*
365
+ * ilookup() comparator
366
+ */
367
+int afs_ilookup5_test_by_fid(struct inode *inode, void *opaque)
368
+{
369
+ struct afs_vnode *vnode = AFS_FS_I(inode);
370
+ struct afs_fid *fid = opaque;
371
+
372
+ return (fid->vnode == vnode->fid.vnode &&
373
+ fid->vnode_hi == vnode->fid.vnode_hi &&
374
+ fid->unique == vnode->fid.unique);
122375 }
123376
124377 /*
125378 * iget5() comparator
126379 */
127
-int afs_iget5_test(struct inode *inode, void *opaque)
380
+static int afs_iget5_test(struct inode *inode, void *opaque)
128381 {
129
- struct afs_iget_data *data = opaque;
382
+ struct afs_vnode_param *vp = opaque;
383
+ //struct afs_vnode *vnode = AFS_FS_I(inode);
130384
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;
385
+ return afs_ilookup5_test_by_fid(inode, &vp->fid);
143386 }
144387
145388 /*
....@@ -147,89 +390,19 @@
147390 */
148391 static int afs_iget5_set(struct inode *inode, void *opaque)
149392 {
150
- struct afs_iget_data *data = opaque;
393
+ struct afs_vnode_param *vp = opaque;
394
+ struct afs_super_info *as = AFS_FS_S(inode->i_sb);
151395 struct afs_vnode *vnode = AFS_FS_I(inode);
152396
153
- inode->i_ino = data->fid.vnode;
154
- inode->i_generation = data->fid.unique;
155
- vnode->fid = data->fid;
156
- vnode->volume = data->volume;
397
+ vnode->volume = as->volume;
398
+ vnode->fid = vp->fid;
157399
400
+ /* YFS supports 96-bit vnode IDs, but Linux only supports
401
+ * 64-bit inode numbers.
402
+ */
403
+ inode->i_ino = vnode->fid.vnode;
404
+ inode->i_generation = vnode->fid.unique;
158405 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;
233406 }
234407
235408 /*
....@@ -252,8 +425,8 @@
252425
253426 key.vnode_id = vnode->fid.vnode;
254427 key.unique = vnode->fid.unique;
255
- key.vnode_id_ext[0] = 0;
256
- key.vnode_id_ext[1] = 0;
428
+ key.vnode_id_ext[0] = vnode->fid.vnode >> 32;
429
+ key.vnode_id_ext[1] = vnode->fid.vnode_hi;
257430 aux.data_version = vnode->status.data_version;
258431
259432 vnode->cache = fscache_acquire_cookie(vnode->volume->cache,
....@@ -267,32 +440,26 @@
267440 /*
268441 * inode retrieval
269442 */
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)
443
+struct inode *afs_iget(struct afs_operation *op, struct afs_vnode_param *vp)
273444 {
274
- struct afs_iget_data data = { .fid = *fid };
275
- struct afs_super_info *as;
445
+ struct afs_vnode_param *dvp = &op->file[0];
446
+ struct super_block *sb = dvp->vnode->vfs_inode.i_sb;
276447 struct afs_vnode *vnode;
277448 struct inode *inode;
278449 int ret;
279450
280
- _enter(",{%x:%u.%u},,", fid->vid, fid->vnode, fid->unique);
451
+ _enter(",{%llx:%llu.%u},,", vp->fid.vid, vp->fid.vnode, vp->fid.unique);
281452
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);
453
+ inode = iget5_locked(sb, vp->fid.vnode, afs_iget5_test, afs_iget5_set, vp);
287454 if (!inode) {
288455 _leave(" = -ENOMEM");
289456 return ERR_PTR(-ENOMEM);
290457 }
291458
292
- _debug("GOT INODE %p { vl=%x vn=%x, u=%x }",
293
- inode, fid->vid, fid->vnode, fid->unique);
294
-
295459 vnode = AFS_FS_I(inode);
460
+
461
+ _debug("GOT INODE %p { vl=%llx vn=%llx, u=%x }",
462
+ inode, vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);
296463
297464 /* deal with an existing inode */
298465 if (!(inode->i_state & I_NEW)) {
....@@ -300,33 +467,7 @@
300467 return inode;
301468 }
302469
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);
470
+ ret = afs_inode_init_from_status(op, vp, vnode);
330471 if (ret < 0)
331472 goto bad_inode;
332473
....@@ -334,9 +475,8 @@
334475
335476 /* success */
336477 clear_bit(AFS_VNODE_UNSET, &vnode->flags);
337
- inode->i_flags |= S_NOATIME;
338478 unlock_new_inode(inode);
339
- _leave(" = %p [CB { v=%u t=%u }]", inode, vnode->cb_version, vnode->cb_type);
479
+ _leave(" = %p", inode);
340480 return inode;
341481
342482 /* failure */
....@@ -346,13 +486,81 @@
346486 return ERR_PTR(ret);
347487 }
348488
489
+static int afs_iget5_set_root(struct inode *inode, void *opaque)
490
+{
491
+ struct afs_super_info *as = AFS_FS_S(inode->i_sb);
492
+ struct afs_vnode *vnode = AFS_FS_I(inode);
493
+
494
+ vnode->volume = as->volume;
495
+ vnode->fid.vid = as->volume->vid,
496
+ vnode->fid.vnode = 1;
497
+ vnode->fid.unique = 1;
498
+ inode->i_ino = 1;
499
+ inode->i_generation = 1;
500
+ return 0;
501
+}
502
+
503
+/*
504
+ * Set up the root inode for a volume. This is always vnode 1, unique 1 within
505
+ * the volume.
506
+ */
507
+struct inode *afs_root_iget(struct super_block *sb, struct key *key)
508
+{
509
+ struct afs_super_info *as = AFS_FS_S(sb);
510
+ struct afs_operation *op;
511
+ struct afs_vnode *vnode;
512
+ struct inode *inode;
513
+ int ret;
514
+
515
+ _enter(",{%llx},,", as->volume->vid);
516
+
517
+ inode = iget5_locked(sb, 1, NULL, afs_iget5_set_root, NULL);
518
+ if (!inode) {
519
+ _leave(" = -ENOMEM");
520
+ return ERR_PTR(-ENOMEM);
521
+ }
522
+
523
+ _debug("GOT ROOT INODE %p { vl=%llx }", inode, as->volume->vid);
524
+
525
+ BUG_ON(!(inode->i_state & I_NEW));
526
+
527
+ vnode = AFS_FS_I(inode);
528
+ vnode->cb_v_break = as->volume->cb_v_break,
529
+
530
+ op = afs_alloc_operation(key, as->volume);
531
+ if (IS_ERR(op)) {
532
+ ret = PTR_ERR(op);
533
+ goto error;
534
+ }
535
+
536
+ afs_op_set_vnode(op, 0, vnode);
537
+
538
+ op->nr_files = 1;
539
+ op->ops = &afs_fetch_status_operation;
540
+ ret = afs_do_sync_operation(op);
541
+ if (ret < 0)
542
+ goto error;
543
+
544
+ afs_get_inode_cache(vnode);
545
+
546
+ clear_bit(AFS_VNODE_UNSET, &vnode->flags);
547
+ unlock_new_inode(inode);
548
+ _leave(" = %p", inode);
549
+ return inode;
550
+
551
+error:
552
+ iget_failed(inode);
553
+ _leave(" = %d [bad]", ret);
554
+ return ERR_PTR(ret);
555
+}
556
+
349557 /*
350558 * mark the data attached to an inode as obsolete due to a write on the server
351559 * - might also want to ditch all the outstanding writes and dirty pages
352560 */
353
-void afs_zap_data(struct afs_vnode *vnode)
561
+static void afs_zap_data(struct afs_vnode *vnode)
354562 {
355
- _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
563
+ _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
356564
357565 #ifdef CONFIG_AFS_FSCACHE
358566 fscache_invalidate(vnode->cache);
....@@ -368,6 +576,84 @@
368576 }
369577
370578 /*
579
+ * Get the server reinit counter for a vnode's current server.
580
+ */
581
+static bool afs_get_s_break_rcu(struct afs_vnode *vnode, unsigned int *_s_break)
582
+{
583
+ struct afs_server_list *slist = rcu_dereference(vnode->volume->servers);
584
+ struct afs_server *server;
585
+ int i;
586
+
587
+ for (i = 0; i < slist->nr_servers; i++) {
588
+ server = slist->servers[i].server;
589
+ if (server == vnode->cb_server) {
590
+ *_s_break = READ_ONCE(server->cb_s_break);
591
+ return true;
592
+ }
593
+ }
594
+
595
+ return false;
596
+}
597
+
598
+/*
599
+ * Check the validity of a vnode/inode.
600
+ */
601
+bool afs_check_validity(struct afs_vnode *vnode)
602
+{
603
+ struct afs_volume *volume = vnode->volume;
604
+ enum afs_cb_break_reason need_clear = afs_cb_break_no_break;
605
+ time64_t now = ktime_get_real_seconds();
606
+ bool valid;
607
+ unsigned int cb_break, cb_s_break, cb_v_break;
608
+ int seq = 0;
609
+
610
+ do {
611
+ read_seqbegin_or_lock(&vnode->cb_lock, &seq);
612
+ cb_v_break = READ_ONCE(volume->cb_v_break);
613
+ cb_break = vnode->cb_break;
614
+
615
+ if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags) &&
616
+ afs_get_s_break_rcu(vnode, &cb_s_break)) {
617
+ if (vnode->cb_s_break != cb_s_break ||
618
+ vnode->cb_v_break != cb_v_break) {
619
+ vnode->cb_s_break = cb_s_break;
620
+ vnode->cb_v_break = cb_v_break;
621
+ need_clear = afs_cb_break_for_vsbreak;
622
+ valid = false;
623
+ } else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) {
624
+ need_clear = afs_cb_break_for_zap;
625
+ valid = false;
626
+ } else if (vnode->cb_expires_at - 10 <= now) {
627
+ need_clear = afs_cb_break_for_lapsed;
628
+ valid = false;
629
+ } else {
630
+ valid = true;
631
+ }
632
+ } else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
633
+ valid = true;
634
+ } else {
635
+ vnode->cb_v_break = cb_v_break;
636
+ valid = false;
637
+ }
638
+
639
+ } while (need_seqretry(&vnode->cb_lock, seq));
640
+
641
+ done_seqretry(&vnode->cb_lock, seq);
642
+
643
+ if (need_clear != afs_cb_break_no_break) {
644
+ write_seqlock(&vnode->cb_lock);
645
+ if (cb_break == vnode->cb_break)
646
+ __afs_break_callback(vnode, need_clear);
647
+ else
648
+ trace_afs_cb_miss(&vnode->fid, need_clear);
649
+ write_sequnlock(&vnode->cb_lock);
650
+ valid = false;
651
+ }
652
+
653
+ return valid;
654
+}
655
+
656
+/*
371657 * validate a vnode/inode
372658 * - there are several things we need to check
373659 * - parent dir data changes (rm, rmdir, rename, mkdir, create, link,
....@@ -378,41 +664,16 @@
378664 */
379665 int afs_validate(struct afs_vnode *vnode, struct key *key)
380666 {
381
- time64_t now = ktime_get_real_seconds();
382667 bool valid;
383668 int ret;
384669
385
- _enter("{v={%x:%u} fl=%lx},%x",
670
+ _enter("{v={%llx:%llu} fl=%lx},%x",
386671 vnode->fid.vid, vnode->fid.vnode, vnode->flags,
387672 key_serial(key));
388673
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);
674
+ rcu_read_lock();
675
+ valid = afs_check_validity(vnode);
676
+ rcu_read_unlock();
416677
417678 if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
418679 clear_nlink(&vnode->vfs_inode);
....@@ -428,7 +689,7 @@
428689 * access */
429690 if (!test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
430691 _debug("not promised");
431
- ret = afs_fetch_status(vnode, key, false);
692
+ ret = afs_fetch_status(vnode, key, false, NULL);
432693 if (ret < 0) {
433694 if (ret == -ENOENT) {
434695 set_bit(AFS_VNODE_DELETED, &vnode->flags);
....@@ -468,13 +729,29 @@
468729 {
469730 struct inode *inode = d_inode(path->dentry);
470731 struct afs_vnode *vnode = AFS_FS_I(inode);
471
- int seq = 0;
732
+ struct key *key;
733
+ int ret, seq = 0;
472734
473735 _enter("{ ino=%lu v=%u }", inode->i_ino, inode->i_generation);
736
+
737
+ if (vnode->volume &&
738
+ !(query_flags & AT_STATX_DONT_SYNC) &&
739
+ !test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
740
+ key = afs_request_key(vnode->volume->cell);
741
+ if (IS_ERR(key))
742
+ return PTR_ERR(key);
743
+ ret = afs_validate(vnode, key);
744
+ key_put(key);
745
+ if (ret < 0)
746
+ return ret;
747
+ }
474748
475749 do {
476750 read_seqbegin_or_lock(&vnode->cb_lock, &seq);
477751 generic_fillattr(inode, stat);
752
+ if (test_bit(AFS_VNODE_SILLY_DELETED, &vnode->flags) &&
753
+ stat->nlink > 0)
754
+ stat->nlink -= 1;
478755 } while (need_seqretry(&vnode->cb_lock, seq));
479756
480757 done_seqretry(&vnode->cb_lock, seq);
....@@ -503,7 +780,7 @@
503780
504781 vnode = AFS_FS_I(inode);
505782
506
- _enter("{%x:%u.%d}",
783
+ _enter("{%llx:%llu.%d}",
507784 vnode->fid.vid,
508785 vnode->fid.vnode,
509786 vnode->fid.unique);
....@@ -514,11 +791,6 @@
514791
515792 truncate_inode_pages_final(&inode->i_data);
516793 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
- }
522794
523795 while (!list_empty(&vnode->wb_keys)) {
524796 struct afs_wb_key *wbk = list_entry(vnode->wb_keys.next,
....@@ -540,61 +812,114 @@
540812
541813 afs_prune_wb_keys(vnode);
542814 afs_put_permits(rcu_access_pointer(vnode->permit_cache));
815
+ key_put(vnode->silly_key);
816
+ vnode->silly_key = NULL;
543817 key_put(vnode->lock_key);
544818 vnode->lock_key = NULL;
545819 _leave("");
546820 }
821
+
822
+static void afs_setattr_success(struct afs_operation *op)
823
+{
824
+ struct afs_vnode_param *vp = &op->file[0];
825
+ struct inode *inode = &vp->vnode->vfs_inode;
826
+ loff_t old_i_size = i_size_read(inode);
827
+
828
+ op->setattr.old_i_size = old_i_size;
829
+ afs_vnode_commit_status(op, vp);
830
+ /* inode->i_size has now been changed. */
831
+
832
+ if (op->setattr.attr->ia_valid & ATTR_SIZE) {
833
+ loff_t size = op->setattr.attr->ia_size;
834
+ if (size > old_i_size)
835
+ pagecache_isize_extended(inode, old_i_size, size);
836
+ }
837
+}
838
+
839
+static void afs_setattr_edit_file(struct afs_operation *op)
840
+{
841
+ struct afs_vnode_param *vp = &op->file[0];
842
+ struct inode *inode = &vp->vnode->vfs_inode;
843
+
844
+ if (op->setattr.attr->ia_valid & ATTR_SIZE) {
845
+ loff_t size = op->setattr.attr->ia_size;
846
+ loff_t i_size = op->setattr.old_i_size;
847
+
848
+ if (size < i_size)
849
+ truncate_pagecache(inode, size);
850
+ }
851
+}
852
+
853
+static const struct afs_operation_ops afs_setattr_operation = {
854
+ .issue_afs_rpc = afs_fs_setattr,
855
+ .issue_yfs_rpc = yfs_fs_setattr,
856
+ .success = afs_setattr_success,
857
+ .edit_dir = afs_setattr_edit_file,
858
+};
547859
548860 /*
549861 * set the attributes of an inode
550862 */
551863 int afs_setattr(struct dentry *dentry, struct iattr *attr)
552864 {
553
- struct afs_fs_cursor fc;
865
+ struct afs_operation *op;
554866 struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
555
- struct key *key;
556867 int ret;
557868
558
- _enter("{%x:%u},{n=%pd},%x",
869
+ _enter("{%llx:%llu},{n=%pd},%x",
559870 vnode->fid.vid, vnode->fid.vnode, dentry,
560871 attr->ia_valid);
561872
562873 if (!(attr->ia_valid & (ATTR_SIZE | ATTR_MODE | ATTR_UID | ATTR_GID |
563
- ATTR_MTIME))) {
874
+ ATTR_MTIME | ATTR_MTIME_SET | ATTR_TIMES_SET |
875
+ ATTR_TOUCH))) {
564876 _leave(" = 0 [unsupported]");
565877 return 0;
878
+ }
879
+
880
+ if (attr->ia_valid & ATTR_SIZE) {
881
+ if (!S_ISREG(vnode->vfs_inode.i_mode))
882
+ return -EISDIR;
883
+
884
+ ret = inode_newsize_ok(&vnode->vfs_inode, attr->ia_size);
885
+ if (ret)
886
+ return ret;
887
+
888
+ if (attr->ia_size == i_size_read(&vnode->vfs_inode))
889
+ attr->ia_valid &= ~ATTR_SIZE;
566890 }
567891
568892 /* flush any dirty data outstanding on a regular file */
569893 if (S_ISREG(vnode->vfs_inode.i_mode))
570894 filemap_write_and_wait(vnode->vfs_inode.i_mapping);
571895
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
- }
896
+ /* Prevent any new writebacks from starting whilst we do this. */
897
+ down_write(&vnode->validate_lock);
898
+
899
+ op = afs_alloc_operation(((attr->ia_valid & ATTR_FILE) ?
900
+ afs_file_key(attr->ia_file) : NULL),
901
+ vnode->volume);
902
+ if (IS_ERR(op)) {
903
+ ret = PTR_ERR(op);
904
+ goto out_unlock;
580905 }
581906
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
- }
907
+ afs_op_set_vnode(op, 0, vnode);
908
+ op->setattr.attr = attr;
588909
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);
910
+ if (attr->ia_valid & ATTR_SIZE) {
911
+ op->file[0].dv_delta = 1;
912
+ op->file[0].set_size = true;
592913 }
914
+ op->ctime = attr->ia_ctime;
915
+ op->file[0].update_ctime = 1;
916
+ op->file[0].modification = true;
593917
594
- if (!(attr->ia_valid & ATTR_FILE))
595
- key_put(key);
918
+ op->ops = &afs_setattr_operation;
919
+ ret = afs_do_sync_operation(op);
596920
597
-error:
921
+out_unlock:
922
+ up_write(&vnode->validate_lock);
598923 _leave(" = %d", ret);
599924 return ret;
600925 }