inode.c 21.3 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10
/*
 * Copyright (c) 2002 Red Hat, Inc. All rights reserved.
 *
 * This software may be freely redistributed under the terms of the
 * GNU General Public License.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
11
 * Authors: David Woodhouse <dwmw2@infradead.org>
L
Linus Torvalds 已提交
12 13 14 15 16 17 18 19 20
 *          David Howells <dhowells@redhat.com>
 *
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
A
Alexey Dobriyan 已提交
21
#include <linux/sched.h>
22 23
#include <linux/mount.h>
#include <linux/namei.h>
J
Jeff Layton 已提交
24
#include <linux/iversion.h>
L
Linus Torvalds 已提交
25
#include "internal.h"
26
#include "afs_fs.h"
L
Linus Torvalds 已提交
27

D
David Howells 已提交
28 29 30 31 32
static const struct inode_operations afs_symlink_inode_operations = {
	.get_link	= page_get_link,
	.listxattr	= afs_listxattr,
};

33 34 35 36
static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *parent_vnode)
{
	static unsigned long once_only;

37
	pr_warn("kAFS: AFS vnode with undefined type %u\n", vnode->status.type);
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
	pr_warn("kAFS: A=%d m=%o s=%llx v=%llx\n",
		vnode->status.abort_code,
		vnode->status.mode,
		vnode->status.size,
		vnode->status.data_version);
	pr_warn("kAFS: vnode %llx:%llx:%x\n",
		vnode->fid.vid,
		vnode->fid.vnode,
		vnode->fid.unique);
	if (parent_vnode)
		pr_warn("kAFS: dir %llx:%llx:%x\n",
			parent_vnode->fid.vid,
			parent_vnode->fid.vnode,
			parent_vnode->fid.unique);

	if (!test_and_set_bit(0, &once_only))
		dump_stack();
}

D
David Howells 已提交
57 58 59 60 61 62 63 64 65 66
/*
 * Set the file size and block count.  Estimate the number of 512 bytes blocks
 * used, rounded up to nearest 1K for consistency with other AFS clients.
 */
static void afs_set_i_size(struct afs_vnode *vnode, u64 size)
{
	i_size_write(&vnode->vfs_inode, size);
	vnode->vfs_inode.i_blocks = ((size + 1023) >> 10) << 1;
}

L
Linus Torvalds 已提交
67
/*
D
David Howells 已提交
68
 * Initialise an inode from the vnode status.
L
Linus Torvalds 已提交
69
 */
70 71 72
static int afs_inode_init_from_status(struct afs_operation *op,
				      struct afs_vnode_param *vp,
				      struct afs_vnode *vnode)
L
Linus Torvalds 已提交
73
{
74
	struct afs_file_status *status = &vp->scb.status;
L
Linus Torvalds 已提交
75
	struct inode *inode = AFS_VNODE_TO_I(vnode);
76
	struct timespec64 t;
L
Linus Torvalds 已提交
77

78 79 80 81
	_enter("{%llx:%llu.%u} %s",
	       vp->fid.vid, vp->fid.vnode, vp->fid.unique,
	       op->type ? op->type->name : "???");

82
	_debug("FS: ft=%d lk=%d sz=%llu ver=%Lu mod=%hu",
83 84 85 86 87
	       status->type,
	       status->nlink,
	       (unsigned long long) status->size,
	       status->data_version,
	       status->mode);
L
Linus Torvalds 已提交
88

89 90
	write_seqlock(&vnode->cb_lock);

91 92
	vnode->cb_v_break = op->cb_v_break;
	vnode->cb_s_break = op->cb_s_break;
93
	vnode->status = *status;
94

95 96 97 98
	t = status->mtime_client;
	inode->i_ctime = t;
	inode->i_mtime = t;
	inode->i_atime = t;
99
	inode->i_flags |= S_NOATIME;
100 101 102
	inode->i_uid = make_kuid(&init_user_ns, status->owner);
	inode->i_gid = make_kgid(&init_user_ns, status->group);
	set_nlink(&vnode->vfs_inode, status->nlink);
D
David Howells 已提交
103

104
	switch (status->type) {
L
Linus Torvalds 已提交
105
	case AFS_FTYPE_FILE:
106
		inode->i_mode	= S_IFREG | status->mode;
L
Linus Torvalds 已提交
107
		inode->i_op	= &afs_file_inode_operations;
D
David Howells 已提交
108
		inode->i_fop	= &afs_file_operations;
D
David Howells 已提交
109
		inode->i_mapping->a_ops	= &afs_fs_aops;
L
Linus Torvalds 已提交
110 111
		break;
	case AFS_FTYPE_DIR:
112
		inode->i_mode	= S_IFDIR | status->mode;
L
Linus Torvalds 已提交
113 114
		inode->i_op	= &afs_dir_inode_operations;
		inode->i_fop	= &afs_dir_file_operations;
D
David Howells 已提交
115
		inode->i_mapping->a_ops	= &afs_dir_aops;
L
Linus Torvalds 已提交
116 117
		break;
	case AFS_FTYPE_SYMLINK:
118
		/* Symlinks with a mode of 0644 are actually mountpoints. */
119
		if ((status->mode & 0777) == 0644) {
120 121 122 123 124 125 126
			inode->i_flags |= S_AUTOMOUNT;

			set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags);

			inode->i_mode	= S_IFDIR | 0555;
			inode->i_op	= &afs_mntpt_inode_operations;
			inode->i_fop	= &afs_mntpt_file_operations;
D
David Howells 已提交
127
			inode->i_mapping->a_ops	= &afs_fs_aops;
128
		} else {
129
			inode->i_mode	= S_IFLNK | status->mode;
D
David Howells 已提交
130
			inode->i_op	= &afs_symlink_inode_operations;
D
David Howells 已提交
131
			inode->i_mapping->a_ops	= &afs_fs_aops;
132
		}
133
		inode_nohighmem(inode);
L
Linus Torvalds 已提交
134 135
		break;
	default:
136
		dump_vnode(vnode, op->file[0].vnode != vnode ? op->file[0].vnode : NULL);
137
		write_sequnlock(&vnode->cb_lock);
138
		return afs_protocol_error(NULL, afs_eproto_file_type);
L
Linus Torvalds 已提交
139 140
	}

D
David Howells 已提交
141
	afs_set_i_size(vnode, status->size);
142

143 144 145
	vnode->invalid_before	= status->data_version;
	inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);

146
	if (!vp->scb.have_cb) {
147 148 149 150
		/* it's a symlink we just created (the fileserver
		 * didn't give us a callback) */
		vnode->cb_expires_at = ktime_get_real_seconds();
	} else {
151
		vnode->cb_expires_at = vp->scb.callback.expires_at;
152
		vnode->cb_server = op->server;
153 154 155 156
		set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
	}

	write_sequnlock(&vnode->cb_lock);
L
Linus Torvalds 已提交
157
	return 0;
D
David Howells 已提交
158
}
L
Linus Torvalds 已提交
159

160 161 162
/*
 * Update the core inode struct from a returned status record.
 */
163 164
static void afs_apply_status(struct afs_operation *op,
			     struct afs_vnode_param *vp)
165
{
166 167
	struct afs_file_status *status = &vp->scb.status;
	struct afs_vnode *vnode = vp->vnode;
D
David Howells 已提交
168
	struct inode *inode = &vnode->vfs_inode;
169 170 171
	struct timespec64 t;
	umode_t mode;
	bool data_changed = false;
D
David Howells 已提交
172
	bool change_size = false;
173

174 175 176 177
	_enter("{%llx:%llu.%u} %s",
	       vp->fid.vid, vp->fid.vnode, vp->fid.unique,
	       op->type ? op->type->name : "???");

178 179 180
	BUG_ON(test_bit(AFS_VNODE_UNSET, &vnode->flags));

	if (status->type != vnode->status.type) {
181 182 183 184 185
		pr_warn("Vnode %llx:%llx:%x changed type %u to %u\n",
			vnode->fid.vid,
			vnode->fid.vnode,
			vnode->fid.unique,
			status->type, vnode->status.type);
186
		afs_protocol_error(NULL, afs_eproto_bad_status);
187 188 189 190
		return;
	}

	if (status->nlink != vnode->status.nlink)
D
David Howells 已提交
191
		set_nlink(inode, status->nlink);
192 193

	if (status->owner != vnode->status.owner)
D
David Howells 已提交
194
		inode->i_uid = make_kuid(&init_user_ns, status->owner);
195 196

	if (status->group != vnode->status.group)
D
David Howells 已提交
197
		inode->i_gid = make_kgid(&init_user_ns, status->group);
198 199

	if (status->mode != vnode->status.mode) {
D
David Howells 已提交
200
		mode = inode->i_mode;
201 202
		mode &= ~S_IALLUGO;
		mode |= status->mode;
D
David Howells 已提交
203
		WRITE_ONCE(inode->i_mode, mode);
204 205 206
	}

	t = status->mtime_client;
D
David Howells 已提交
207 208 209
	inode->i_mtime = t;
	if (vp->update_ctime)
		inode->i_ctime = op->ctime;
210 211 212 213 214 215

	if (vnode->status.data_version != status->data_version)
		data_changed = true;

	vnode->status = *status;

216
	if (vp->dv_before + vp->dv_delta != status->data_version) {
217 218 219
		if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags))
			pr_warn("kAFS: vnode modified {%llx:%llu} %llx->%llx %s\n",
				vnode->fid.vid, vnode->fid.vnode,
220
				(unsigned long long)vp->dv_before + vp->dv_delta,
221
				(unsigned long long)status->data_version,
222
				op->type ? op->type->name : "???");
223

224 225 226 227 228 229 230
		vnode->invalid_before = status->data_version;
		if (vnode->status.type == AFS_FTYPE_DIR) {
			if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
				afs_stat_v(vnode, n_inval);
		} else {
			set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
		}
D
David Howells 已提交
231
		change_size = true;
232 233 234 235 236 237 238
	} else if (vnode->status.type == AFS_FTYPE_DIR) {
		/* Expected directory change is handled elsewhere so
		 * that we can locally edit the directory and save on a
		 * download.
		 */
		if (test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
			data_changed = false;
D
David Howells 已提交
239
		change_size = true;
240 241 242
	}

	if (data_changed) {
D
David Howells 已提交
243
		inode_set_iversion_raw(inode, status->data_version);
D
David Howells 已提交
244 245 246 247 248 249

		/* Only update the size if the data version jumped.  If the
		 * file is being modified locally, then we might have our own
		 * idea of what the size should be that's not the same as
		 * what's on the server.
		 */
D
David Howells 已提交
250
		if (change_size) {
D
David Howells 已提交
251
			afs_set_i_size(vnode, status->size);
D
David Howells 已提交
252 253 254
			inode->i_ctime = t;
			inode->i_atime = t;
		}
255 256 257 258 259 260
	}
}

/*
 * Apply a callback to a vnode.
 */
261 262
static void afs_apply_callback(struct afs_operation *op,
			       struct afs_vnode_param *vp)
263
{
264 265
	struct afs_callback *cb = &vp->scb.callback;
	struct afs_vnode *vnode = vp->vnode;
266

267
	if (!afs_cb_is_broken(vp->cb_break_before, vnode)) {
268
		vnode->cb_expires_at	= cb->expires_at;
269
		vnode->cb_server	= op->server;
270 271 272 273 274 275 276 277
		set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
	}
}

/*
 * Apply the received status and callback to an inode all in the same critical
 * section to avoid races with afs_validate().
 */
278
void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *vp)
279
{
280 281 282 283 284
	struct afs_vnode *vnode = vp->vnode;

	_enter("");

	ASSERTCMP(op->error, ==, 0);
285 286 287

	write_seqlock(&vnode->cb_lock);

288 289
	if (vp->scb.have_error) {
		if (vp->scb.status.abort_code == VNOVNODE) {
290 291
			set_bit(AFS_VNODE_DELETED, &vnode->flags);
			clear_nlink(&vnode->vfs_inode);
292
			__afs_break_callback(vnode, afs_cb_break_for_deleted);
293 294
		}
	} else {
295 296 297 298
		if (vp->scb.have_status)
			afs_apply_status(op, vp);
		if (vp->scb.have_cb)
			afs_apply_callback(op, vp);
299
	}
300 301 302

	write_sequnlock(&vnode->cb_lock);

303 304
	if (op->error == 0 && vp->scb.have_status)
		afs_cache_permit(vnode, op->key, vp->cb_break_before, &vp->scb);
305 306
}

307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
static void afs_fetch_status_success(struct afs_operation *op)
{
	struct afs_vnode_param *vp = &op->file[0];
	struct afs_vnode *vnode = vp->vnode;
	int ret;

	if (vnode->vfs_inode.i_state & I_NEW) {
		ret = afs_inode_init_from_status(op, vp, vnode);
		op->error = ret;
		if (ret == 0)
			afs_cache_permit(vnode, op->key, vp->cb_break_before, &vp->scb);
	} else {
		afs_vnode_commit_status(op, vp);
	}
}

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_fetch_status_success,
};

329 330 331
/*
 * Fetch file status from the volume.
 */
332 333
int afs_fetch_status(struct afs_vnode *vnode, struct key *key, bool is_new,
		     afs_access_t *_caller_access)
334
{
335
	struct afs_operation *op;
336

337
	_enter("%s,{%llx:%llu.%u,S=%lx}",
338 339 340 341
	       vnode->volume->name,
	       vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique,
	       vnode->flags);

342 343 344
	op = afs_alloc_operation(key, vnode->volume);
	if (IS_ERR(op))
		return PTR_ERR(op);
345

346
	afs_op_set_vnode(op, 0, vnode);
347

348 349 350 351
	op->nr_files	= 1;
	op->ops		= &afs_fetch_status_operation;
	afs_begin_vnode_operation(op);
	afs_wait_for_operation(op);
352

353 354 355
	if (_caller_access)
		*_caller_access = op->file[0].scb.status.caller_access;
	return afs_put_operation(op);
356 357
}

L
Linus Torvalds 已提交
358
/*
359
 * ilookup() comparator
L
Linus Torvalds 已提交
360
 */
361
int afs_ilookup5_test_by_fid(struct inode *inode, void *opaque)
L
Linus Torvalds 已提交
362
{
363
	struct afs_vnode *vnode = AFS_FS_I(inode);
364
	struct afs_fid *fid = opaque;
L
Linus Torvalds 已提交
365

366 367 368
	return (fid->vnode == vnode->fid.vnode &&
		fid->vnode_hi == vnode->fid.vnode_hi &&
		fid->unique == vnode->fid.unique);
D
David Howells 已提交
369
}
L
Linus Torvalds 已提交
370

371
/*
372
 * iget5() comparator
373
 */
374
static int afs_iget5_test(struct inode *inode, void *opaque)
375
{
376 377 378 379
	struct afs_vnode_param *vp = opaque;
	//struct afs_vnode *vnode = AFS_FS_I(inode);

	return afs_ilookup5_test_by_fid(inode, &vp->fid);
380 381
}

L
Linus Torvalds 已提交
382 383 384 385 386
/*
 * iget5() inode initialiser
 */
static int afs_iget5_set(struct inode *inode, void *opaque)
{
387 388
	struct afs_vnode_param *vp = opaque;
	struct afs_super_info *as = AFS_FS_S(inode->i_sb);
L
Linus Torvalds 已提交
389 390
	struct afs_vnode *vnode = AFS_FS_I(inode);

391 392
	vnode->volume		= as->volume;
	vnode->fid		= vp->fid;
L
Linus Torvalds 已提交
393

394 395 396
	/* YFS supports 96-bit vnode IDs, but Linux only supports
	 * 64-bit inode numbers.
	 */
397 398
	inode->i_ino		= vnode->fid.vnode;
	inode->i_generation	= vnode->fid.unique;
L
Linus Torvalds 已提交
399
	return 0;
D
David Howells 已提交
400
}
L
Linus Torvalds 已提交
401

402 403 404 405 406 407 408 409 410 411 412 413 414
/*
 * Get a cache cookie for an inode.
 */
static void afs_get_inode_cache(struct afs_vnode *vnode)
{
#ifdef CONFIG_AFS_FSCACHE
	struct {
		u32 vnode_id;
		u32 unique;
		u32 vnode_id_ext[2];	/* Allow for a 96-bit key */
	} __packed key;
	struct afs_vnode_cache_aux aux;

D
David Howells 已提交
415 416 417 418 419
	if (vnode->status.type == AFS_FTYPE_DIR) {
		vnode->cache = NULL;
		return;
	}

420 421
	key.vnode_id		= vnode->fid.vnode;
	key.unique		= vnode->fid.unique;
422 423
	key.vnode_id_ext[0]	= vnode->fid.vnode >> 32;
	key.vnode_id_ext[1]	= vnode->fid.vnode_hi;
424 425 426 427 428 429
	aux.data_version	= vnode->status.data_version;

	vnode->cache = fscache_acquire_cookie(vnode->volume->cache,
					      &afs_vnode_cache_index_def,
					      &key, sizeof(key),
					      &aux, sizeof(aux),
430
					      vnode, vnode->status.size, true);
431 432 433
#endif
}

L
Linus Torvalds 已提交
434 435 436
/*
 * inode retrieval
 */
437
struct inode *afs_iget(struct afs_operation *op, struct afs_vnode_param *vp)
L
Linus Torvalds 已提交
438
{
439 440
	struct afs_vnode_param *dvp = &op->file[0];
	struct super_block *sb = dvp->vnode->vfs_inode.i_sb;
L
Linus Torvalds 已提交
441 442 443 444
	struct afs_vnode *vnode;
	struct inode *inode;
	int ret;

445
	_enter(",{%llx:%llu.%u},,", vp->fid.vid, vp->fid.vnode, vp->fid.unique);
L
Linus Torvalds 已提交
446

447
	inode = iget5_locked(sb, vp->fid.vnode, afs_iget5_test, afs_iget5_set, vp);
L
Linus Torvalds 已提交
448 449
	if (!inode) {
		_leave(" = -ENOMEM");
450
		return ERR_PTR(-ENOMEM);
L
Linus Torvalds 已提交
451 452 453 454
	}

	vnode = AFS_FS_I(inode);

455 456 457
	_debug("GOT INODE %p { vl=%llx vn=%llx, u=%x }",
	       inode, vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);

L
Linus Torvalds 已提交
458 459
	/* deal with an existing inode */
	if (!(inode->i_state & I_NEW)) {
460 461
		_leave(" = %p", inode);
		return inode;
L
Linus Torvalds 已提交
462 463
	}

464 465 466
	ret = afs_inode_init_from_status(op, vp, vnode);
	if (ret < 0)
		goto bad_inode;
467

468 469
	afs_get_inode_cache(vnode);

L
Linus Torvalds 已提交
470
	/* success */
471
	clear_bit(AFS_VNODE_UNSET, &vnode->flags);
L
Linus Torvalds 已提交
472
	unlock_new_inode(inode);
473
	_leave(" = %p", inode);
474
	return inode;
L
Linus Torvalds 已提交
475 476

	/* failure */
D
David Howells 已提交
477
bad_inode:
D
David Howells 已提交
478
	iget_failed(inode);
L
Linus Torvalds 已提交
479
	_leave(" = %d [bad]", ret);
480
	return ERR_PTR(ret);
D
David Howells 已提交
481
}
L
Linus Torvalds 已提交
482

483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
static int afs_iget5_set_root(struct inode *inode, void *opaque)
{
	struct afs_super_info *as = AFS_FS_S(inode->i_sb);
	struct afs_vnode *vnode = AFS_FS_I(inode);

	vnode->volume		= as->volume;
	vnode->fid.vid		= as->volume->vid,
	vnode->fid.vnode	= 1;
	vnode->fid.unique	= 1;
	inode->i_ino		= 1;
	inode->i_generation	= 1;
	return 0;
}

/*
 * Set up the root inode for a volume.  This is always vnode 1, unique 1 within
 * the volume.
 */
struct inode *afs_root_iget(struct super_block *sb, struct key *key)
{
	struct afs_super_info *as = AFS_FS_S(sb);
	struct afs_operation *op;
	struct afs_vnode *vnode;
	struct inode *inode;
	int ret;

	_enter(",{%llx},,", as->volume->vid);

	inode = iget5_locked(sb, 1, NULL, afs_iget5_set_root, NULL);
	if (!inode) {
		_leave(" = -ENOMEM");
		return ERR_PTR(-ENOMEM);
	}

	_debug("GOT ROOT INODE %p { vl=%llx }", inode, as->volume->vid);

	BUG_ON(!(inode->i_state & I_NEW));

	vnode = AFS_FS_I(inode);
	vnode->cb_v_break = as->volume->cb_v_break,

	op = afs_alloc_operation(key, as->volume);
	if (IS_ERR(op)) {
		ret = PTR_ERR(op);
		goto error;
	}

	afs_op_set_vnode(op, 0, vnode);

	op->nr_files	= 1;
	op->ops		= &afs_fetch_status_operation;
	ret = afs_do_sync_operation(op);
	if (ret < 0)
		goto error;

	afs_get_inode_cache(vnode);

	clear_bit(AFS_VNODE_UNSET, &vnode->flags);
	unlock_new_inode(inode);
	_leave(" = %p", inode);
	return inode;

error:
	iget_failed(inode);
	_leave(" = %d [bad]", ret);
	return ERR_PTR(ret);
}

D
David Howells 已提交
551 552 553 554
/*
 * mark the data attached to an inode as obsolete due to a write on the server
 * - might also want to ditch all the outstanding writes and dirty pages
 */
D
David Howells 已提交
555
static void afs_zap_data(struct afs_vnode *vnode)
D
David Howells 已提交
556
{
557
	_enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
D
David Howells 已提交
558

559 560 561 562
#ifdef CONFIG_AFS_FSCACHE
	fscache_invalidate(vnode->cache);
#endif

D
David Howells 已提交
563
	/* nuke all the non-dirty pages that aren't locked, mapped or being
564 565 566 567 568 569
	 * written back in a regular file and completely discard the pages in a
	 * directory or symlink */
	if (S_ISREG(vnode->vfs_inode.i_mode))
		invalidate_remote_inode(&vnode->vfs_inode);
	else
		invalidate_inode_pages2(vnode->vfs_inode.i_mapping);
D
David Howells 已提交
570 571
}

572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591
/*
 * Get the server reinit counter for a vnode's current server.
 */
static bool afs_get_s_break_rcu(struct afs_vnode *vnode, unsigned int *_s_break)
{
	struct afs_server_list *slist = rcu_dereference(vnode->volume->servers);
	struct afs_server *server;
	int i;

	for (i = 0; i < slist->nr_servers; i++) {
		server = slist->servers[i].server;
		if (server == vnode->cb_server) {
			*_s_break = READ_ONCE(server->cb_s_break);
			return true;
		}
	}

	return false;
}

592
/*
593
 * Check the validity of a vnode/inode.
594
 */
595
bool afs_check_validity(struct afs_vnode *vnode)
596
{
597
	struct afs_volume *volume = vnode->volume;
598
	enum afs_cb_break_reason need_clear = afs_cb_break_no_break;
599
	time64_t now = ktime_get_real_seconds();
600
	bool valid;
601 602
	unsigned int cb_break, cb_s_break, cb_v_break;
	int seq = 0;
603

604 605 606 607 608
	do {
		read_seqbegin_or_lock(&vnode->cb_lock, &seq);
		cb_v_break = READ_ONCE(volume->cb_v_break);
		cb_break = vnode->cb_break;

609 610
		if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags) &&
		    afs_get_s_break_rcu(vnode, &cb_s_break)) {
611 612 613 614
			if (vnode->cb_s_break != cb_s_break ||
			    vnode->cb_v_break != cb_v_break) {
				vnode->cb_s_break = cb_s_break;
				vnode->cb_v_break = cb_v_break;
615
				need_clear = afs_cb_break_for_vsbreak;
616 617
				valid = false;
			} else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) {
618
				need_clear = afs_cb_break_for_zap;
619 620
				valid = false;
			} else if (vnode->cb_expires_at - 10 <= now) {
621
				need_clear = afs_cb_break_for_lapsed;
622 623 624 625 626
				valid = false;
			} else {
				valid = true;
			}
		} else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
627
			valid = true;
628 629 630
		} else {
			vnode->cb_v_break = cb_v_break;
			valid = false;
631 632
		}

633 634 635
	} while (need_seqretry(&vnode->cb_lock, seq));

	done_seqretry(&vnode->cb_lock, seq);
636

637
	if (need_clear != afs_cb_break_no_break) {
638 639
		write_seqlock(&vnode->cb_lock);
		if (cb_break == vnode->cb_break)
640 641 642
			__afs_break_callback(vnode, need_clear);
		else
			trace_afs_cb_miss(&vnode->fid, need_clear);
643 644 645 646
		write_sequnlock(&vnode->cb_lock);
		valid = false;
	}

647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667
	return valid;
}

/*
 * validate a vnode/inode
 * - there are several things we need to check
 *   - parent dir data changes (rm, rmdir, rename, mkdir, create, link,
 *     symlink)
 *   - parent dir metadata changed (security changes)
 *   - dentry data changed (write, truncate)
 *   - dentry metadata changed (security changes)
 */
int afs_validate(struct afs_vnode *vnode, struct key *key)
{
	bool valid;
	int ret;

	_enter("{v={%llx:%llu} fl=%lx},%x",
	       vnode->fid.vid, vnode->fid.vnode, vnode->flags,
	       key_serial(key));

668
	rcu_read_lock();
669
	valid = afs_check_validity(vnode);
670
	rcu_read_unlock();
D
David Howells 已提交
671 672 673 674

	if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
		clear_nlink(&vnode->vfs_inode);

675
	if (valid)
676 677
		goto valid;

D
David Howells 已提交
678
	down_write(&vnode->validate_lock);
679 680 681 682 683

	/* if the promise has expired, we need to check the server again to get
	 * a new promise - note that if the (parent) directory's metadata was
	 * changed then the security may be different and we may no longer have
	 * access */
684
	if (!test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
685
		_debug("not promised");
686
		ret = afs_fetch_status(vnode, key, false, NULL);
687 688 689 690 691
		if (ret < 0) {
			if (ret == -ENOENT) {
				set_bit(AFS_VNODE_DELETED, &vnode->flags);
				ret = -ESTALE;
			}
692
			goto error_unlock;
693
		}
694 695 696 697 698 699 700 701 702 703 704
		_debug("new promise [fl=%lx]", vnode->flags);
	}

	if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
		_debug("file already deleted");
		ret = -ESTALE;
		goto error_unlock;
	}

	/* if the vnode's data version number changed then its contents are
	 * different */
D
David Howells 已提交
705 706
	if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags))
		afs_zap_data(vnode);
D
David Howells 已提交
707
	up_write(&vnode->validate_lock);
708 709 710 711 712
valid:
	_leave(" = 0");
	return 0;

error_unlock:
D
David Howells 已提交
713
	up_write(&vnode->validate_lock);
714 715 716 717
	_leave(" = %d", ret);
	return ret;
}

L
Linus Torvalds 已提交
718 719 720
/*
 * read the attributes of an inode
 */
721 722
int afs_getattr(const struct path *path, struct kstat *stat,
		u32 request_mask, unsigned int query_flags)
L
Linus Torvalds 已提交
723
{
724
	struct inode *inode = d_inode(path->dentry);
725 726
	struct afs_vnode *vnode = AFS_FS_I(inode);
	int seq = 0;
L
Linus Torvalds 已提交
727

728
	_enter("{ ino=%lu v=%u }", inode->i_ino, inode->i_generation);
L
Linus Torvalds 已提交
729

730 731 732 733 734 735
	do {
		read_seqbegin_or_lock(&vnode->cb_lock, &seq);
		generic_fillattr(inode, stat);
	} while (need_seqretry(&vnode->cb_lock, seq));

	done_seqretry(&vnode->cb_lock, seq);
L
Linus Torvalds 已提交
736
	return 0;
D
David Howells 已提交
737
}
L
Linus Torvalds 已提交
738

739 740 741 742 743 744 745 746 747 748 749 750 751
/*
 * discard an AFS inode
 */
int afs_drop_inode(struct inode *inode)
{
	_enter("");

	if (test_bit(AFS_VNODE_PSEUDODIR, &AFS_FS_I(inode)->flags))
		return generic_delete_inode(inode);
	else
		return generic_drop_inode(inode);
}

L
Linus Torvalds 已提交
752 753 754
/*
 * clear an AFS inode
 */
755
void afs_evict_inode(struct inode *inode)
L
Linus Torvalds 已提交
756 757 758 759 760
{
	struct afs_vnode *vnode;

	vnode = AFS_FS_I(inode);

761
	_enter("{%llx:%llu.%d}",
762
	       vnode->fid.vid,
L
Linus Torvalds 已提交
763
	       vnode->fid.vnode,
764
	       vnode->fid.unique);
L
Linus Torvalds 已提交
765

766 767 768 769
	_debug("CLEAR INODE %p", inode);

	ASSERTCMP(inode->i_ino, ==, vnode->fid.vnode);

770
	truncate_inode_pages_final(&inode->i_data);
771
	clear_inode(inode);
772

773 774 775 776 777 778
	while (!list_empty(&vnode->wb_keys)) {
		struct afs_wb_key *wbk = list_entry(vnode->wb_keys.next,
						    struct afs_wb_key, vnode_link);
		list_del(&wbk->vnode_link);
		afs_put_wb_key(wbk);
	}
L
Linus Torvalds 已提交
779

D
David Howells 已提交
780
#ifdef CONFIG_AFS_FSCACHE
781 782 783 784 785 786 787 788
	{
		struct afs_vnode_cache_aux aux;

		aux.data_version = vnode->status.data_version;
		fscache_relinquish_cookie(vnode->cache, &aux,
					  test_bit(AFS_VNODE_DELETED, &vnode->flags));
		vnode->cache = NULL;
	}
L
Linus Torvalds 已提交
789 790
#endif

791
	afs_prune_wb_keys(vnode);
D
David Howells 已提交
792
	afs_put_permits(rcu_access_pointer(vnode->permit_cache));
793 794
	key_put(vnode->silly_key);
	vnode->silly_key = NULL;
795 796
	key_put(vnode->lock_key);
	vnode->lock_key = NULL;
L
Linus Torvalds 已提交
797
	_leave("");
D
David Howells 已提交
798
}
799

800 801 802 803 804 805 806 807 808 809 810
static void afs_setattr_success(struct afs_operation *op)
{
	afs_vnode_commit_status(op, &op->file[0]);
}

static const struct afs_operation_ops afs_setattr_operation = {
	.issue_afs_rpc	= afs_fs_setattr,
	.issue_yfs_rpc	= yfs_fs_setattr,
	.success	= afs_setattr_success,
};

811 812 813 814 815
/*
 * set the attributes of an inode
 */
int afs_setattr(struct dentry *dentry, struct iattr *attr)
{
816
	struct afs_operation *op;
817
	struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
818

819
	_enter("{%llx:%llu},{n=%pd},%x",
A
Al Viro 已提交
820
	       vnode->fid.vid, vnode->fid.vnode, dentry,
821 822 823
	       attr->ia_valid);

	if (!(attr->ia_valid & (ATTR_SIZE | ATTR_MODE | ATTR_UID | ATTR_GID |
D
David Howells 已提交
824 825
				ATTR_MTIME | ATTR_MTIME_SET | ATTR_TIMES_SET |
				ATTR_TOUCH))) {
826 827 828 829 830
		_leave(" = 0 [unsupported]");
		return 0;
	}

	/* flush any dirty data outstanding on a regular file */
831
	if (S_ISREG(vnode->vfs_inode.i_mode))
832 833
		filemap_write_and_wait(vnode->vfs_inode.i_mapping);

834 835 836 837 838
	op = afs_alloc_operation(((attr->ia_valid & ATTR_FILE) ?
				  afs_file_key(attr->ia_file) : NULL),
				 vnode->volume);
	if (IS_ERR(op))
		return PTR_ERR(op);
839

840 841
	afs_op_set_vnode(op, 0, vnode);
	op->setattr.attr = attr;
842

843 844
	if (attr->ia_valid & ATTR_SIZE)
		op->file[0].dv_delta = 1;
D
David Howells 已提交
845 846
	op->ctime = attr->ia_ctime;
	op->file[0].update_ctime = 1;
847

848 849
	op->ops = &afs_setattr_operation;
	return afs_do_sync_operation(op);
850
}