inode.c 20.8 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>
21
#include <linux/sched.h>
22 23
#include <linux/mount.h>
#include <linux/namei.h>
24
#include <linux/iversion.h>
L
Linus Torvalds 已提交
25
#include "internal.h"
26
#include "afs_fs.h"
L
Linus Torvalds 已提交
27

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();
}

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
/*
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);
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;
108
		inode->i_fop	= &afs_file_operations;
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;
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;
127
			inode->i_mapping->a_ops	= &afs_fs_aops;
128
		} else {
129
			inode->i_mode	= S_IFLNK | status->mode;
130
			inode->i_op	= &afs_symlink_inode_operations;
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
	}

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;
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;
168 169 170 171
	struct timespec64 t;
	umode_t mode;
	bool data_changed = false;

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

176 177 178
	BUG_ON(test_bit(AFS_VNODE_UNSET, &vnode->flags));

	if (status->type != vnode->status.type) {
179 180 181 182 183
		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);
184
		afs_protocol_error(NULL, afs_eproto_bad_status);
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
		return;
	}

	if (status->nlink != vnode->status.nlink)
		set_nlink(&vnode->vfs_inode, status->nlink);

	if (status->owner != vnode->status.owner)
		vnode->vfs_inode.i_uid = make_kuid(&init_user_ns, status->owner);

	if (status->group != vnode->status.group)
		vnode->vfs_inode.i_gid = make_kgid(&init_user_ns, status->group);

	if (status->mode != vnode->status.mode) {
		mode = vnode->vfs_inode.i_mode;
		mode &= ~S_IALLUGO;
		mode |= status->mode;
		WRITE_ONCE(vnode->vfs_inode.i_mode, mode);
	}

	t = status->mtime_client;
	vnode->vfs_inode.i_ctime = t;
	vnode->vfs_inode.i_mtime = t;
	vnode->vfs_inode.i_atime = t;

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

	vnode->status = *status;

214
	if (vp->dv_before + vp->dv_delta != status->data_version) {
215 216 217
		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,
218
				(unsigned long long)vp->dv_before + vp->dv_delta,
219
				(unsigned long long)status->data_version,
220
				op->type ? op->type->name : "???");
221

222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
		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);
		}
	} 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;
	}

	if (data_changed) {
		inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);
240
		afs_set_i_size(vnode, status->size);
241 242 243 244 245 246
	}
}

/*
 * Apply a callback to a vnode.
 */
247 248
static void afs_apply_callback(struct afs_operation *op,
			       struct afs_vnode_param *vp)
249
{
250 251
	struct afs_callback *cb = &vp->scb.callback;
	struct afs_vnode *vnode = vp->vnode;
252

253
	if (!afs_cb_is_broken(vp->cb_break_before, vnode)) {
254
		vnode->cb_expires_at	= cb->expires_at;
255
		vnode->cb_server	= op->server;
256 257 258 259 260 261 262 263
		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().
 */
264
void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *vp)
265
{
266 267 268 269 270
	struct afs_vnode *vnode = vp->vnode;

	_enter("");

	ASSERTCMP(op->error, ==, 0);
271 272 273

	write_seqlock(&vnode->cb_lock);

274 275
	if (vp->scb.have_error) {
		if (vp->scb.status.abort_code == VNOVNODE) {
276 277
			set_bit(AFS_VNODE_DELETED, &vnode->flags);
			clear_nlink(&vnode->vfs_inode);
278
			__afs_break_callback(vnode, afs_cb_break_for_deleted);
279 280
		}
	} else {
281 282 283 284
		if (vp->scb.have_status)
			afs_apply_status(op, vp);
		if (vp->scb.have_cb)
			afs_apply_callback(op, vp);
285
	}
286 287 288

	write_sequnlock(&vnode->cb_lock);

289 290
	if (op->error == 0 && vp->scb.have_status)
		afs_cache_permit(vnode, op->key, vp->cb_break_before, &vp->scb);
291 292
}

293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
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,
};

315 316 317
/*
 * Fetch file status from the volume.
 */
318 319
int afs_fetch_status(struct afs_vnode *vnode, struct key *key, bool is_new,
		     afs_access_t *_caller_access)
320
{
321
	struct afs_operation *op;
322

323
	_enter("%s,{%llx:%llu.%u,S=%lx}",
324 325 326 327
	       vnode->volume->name,
	       vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique,
	       vnode->flags);

328 329 330
	op = afs_alloc_operation(key, vnode->volume);
	if (IS_ERR(op))
		return PTR_ERR(op);
331

332
	afs_op_set_vnode(op, 0, vnode);
333

334 335 336 337
	op->nr_files	= 1;
	op->ops		= &afs_fetch_status_operation;
	afs_begin_vnode_operation(op);
	afs_wait_for_operation(op);
338

339 340 341
	if (_caller_access)
		*_caller_access = op->file[0].scb.status.caller_access;
	return afs_put_operation(op);
342 343
}

L
Linus Torvalds 已提交
344
/*
345
 * ilookup() comparator
L
Linus Torvalds 已提交
346
 */
347
int afs_ilookup5_test_by_fid(struct inode *inode, void *opaque)
L
Linus Torvalds 已提交
348
{
349
	struct afs_vnode *vnode = AFS_FS_I(inode);
350
	struct afs_fid *fid = opaque;
L
Linus Torvalds 已提交
351

352 353 354
	return (fid->vnode == vnode->fid.vnode &&
		fid->vnode_hi == vnode->fid.vnode_hi &&
		fid->unique == vnode->fid.unique);
355
}
L
Linus Torvalds 已提交
356

357
/*
358
 * iget5() comparator
359
 */
360
static int afs_iget5_test(struct inode *inode, void *opaque)
361
{
362 363 364 365
	struct afs_vnode_param *vp = opaque;
	//struct afs_vnode *vnode = AFS_FS_I(inode);

	return afs_ilookup5_test_by_fid(inode, &vp->fid);
366 367
}

L
Linus Torvalds 已提交
368 369 370 371 372
/*
 * iget5() inode initialiser
 */
static int afs_iget5_set(struct inode *inode, void *opaque)
{
373 374
	struct afs_vnode_param *vp = opaque;
	struct afs_super_info *as = AFS_FS_S(inode->i_sb);
L
Linus Torvalds 已提交
375 376
	struct afs_vnode *vnode = AFS_FS_I(inode);

377 378
	vnode->volume		= as->volume;
	vnode->fid		= vp->fid;
L
Linus Torvalds 已提交
379

380 381 382
	/* YFS supports 96-bit vnode IDs, but Linux only supports
	 * 64-bit inode numbers.
	 */
383 384
	inode->i_ino		= vnode->fid.vnode;
	inode->i_generation	= vnode->fid.unique;
L
Linus Torvalds 已提交
385
	return 0;
386
}
L
Linus Torvalds 已提交
387

388 389 390 391 392 393 394 395 396 397 398 399 400
/*
 * 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;

401 402 403 404 405
	if (vnode->status.type == AFS_FTYPE_DIR) {
		vnode->cache = NULL;
		return;
	}

406 407
	key.vnode_id		= vnode->fid.vnode;
	key.unique		= vnode->fid.unique;
408 409
	key.vnode_id_ext[0]	= vnode->fid.vnode >> 32;
	key.vnode_id_ext[1]	= vnode->fid.vnode_hi;
410 411 412 413 414 415
	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),
416
					      vnode, vnode->status.size, true);
417 418 419
#endif
}

L
Linus Torvalds 已提交
420 421 422
/*
 * inode retrieval
 */
423
struct inode *afs_iget(struct afs_operation *op, struct afs_vnode_param *vp)
L
Linus Torvalds 已提交
424
{
425 426
	struct afs_vnode_param *dvp = &op->file[0];
	struct super_block *sb = dvp->vnode->vfs_inode.i_sb;
L
Linus Torvalds 已提交
427 428 429 430
	struct afs_vnode *vnode;
	struct inode *inode;
	int ret;

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

433
	inode = iget5_locked(sb, vp->fid.vnode, afs_iget5_test, afs_iget5_set, vp);
L
Linus Torvalds 已提交
434 435
	if (!inode) {
		_leave(" = -ENOMEM");
436
		return ERR_PTR(-ENOMEM);
L
Linus Torvalds 已提交
437 438 439 440
	}

	vnode = AFS_FS_I(inode);

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

L
Linus Torvalds 已提交
444 445
	/* deal with an existing inode */
	if (!(inode->i_state & I_NEW)) {
446 447
		_leave(" = %p", inode);
		return inode;
L
Linus Torvalds 已提交
448 449
	}

450 451 452
	ret = afs_inode_init_from_status(op, vp, vnode);
	if (ret < 0)
		goto bad_inode;
453

454 455
	afs_get_inode_cache(vnode);

L
Linus Torvalds 已提交
456
	/* success */
457
	clear_bit(AFS_VNODE_UNSET, &vnode->flags);
L
Linus Torvalds 已提交
458
	unlock_new_inode(inode);
459
	_leave(" = %p", inode);
460
	return inode;
L
Linus Torvalds 已提交
461 462

	/* failure */
463
bad_inode:
464
	iget_failed(inode);
L
Linus Torvalds 已提交
465
	_leave(" = %d [bad]", ret);
466
	return ERR_PTR(ret);
467
}
L
Linus Torvalds 已提交
468

469 470 471 472 473 474 475 476 477 478 479 480 481 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
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 已提交
537 538 539 540 541 542
/*
 * 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
 */
void afs_zap_data(struct afs_vnode *vnode)
{
543
	_enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
D
David Howells 已提交
544

545 546 547 548
#ifdef CONFIG_AFS_FSCACHE
	fscache_invalidate(vnode->cache);
#endif

D
David Howells 已提交
549
	/* nuke all the non-dirty pages that aren't locked, mapped or being
550 551 552 553 554 555
	 * 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 已提交
556 557
}

558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
/*
 * 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;
}

578
/*
579
 * Check the validity of a vnode/inode.
580
 */
581
bool afs_check_validity(struct afs_vnode *vnode)
582
{
583
	struct afs_volume *volume = vnode->volume;
584
	enum afs_cb_break_reason need_clear = afs_cb_break_no_break;
585
	time64_t now = ktime_get_real_seconds();
586
	bool valid;
587 588
	unsigned int cb_break, cb_s_break, cb_v_break;
	int seq = 0;
589

590 591 592 593 594
	do {
		read_seqbegin_or_lock(&vnode->cb_lock, &seq);
		cb_v_break = READ_ONCE(volume->cb_v_break);
		cb_break = vnode->cb_break;

595 596
		if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags) &&
		    afs_get_s_break_rcu(vnode, &cb_s_break)) {
597 598 599 600
			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;
601
				need_clear = afs_cb_break_for_vsbreak;
602 603
				valid = false;
			} else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) {
604
				need_clear = afs_cb_break_for_zap;
605 606
				valid = false;
			} else if (vnode->cb_expires_at - 10 <= now) {
607
				need_clear = afs_cb_break_for_lapsed;
608 609 610 611 612
				valid = false;
			} else {
				valid = true;
			}
		} else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
613
			valid = true;
614 615 616
		} else {
			vnode->cb_v_break = cb_v_break;
			valid = false;
617 618
		}

619 620 621
	} while (need_seqretry(&vnode->cb_lock, seq));

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

623
	if (need_clear != afs_cb_break_no_break) {
624 625
		write_seqlock(&vnode->cb_lock);
		if (cb_break == vnode->cb_break)
626 627 628
			__afs_break_callback(vnode, need_clear);
		else
			trace_afs_cb_miss(&vnode->fid, need_clear);
629 630 631 632
		write_sequnlock(&vnode->cb_lock);
		valid = false;
	}

633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
	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));

654
	rcu_read_lock();
655
	valid = afs_check_validity(vnode);
656
	rcu_read_unlock();
D
David Howells 已提交
657 658 659 660

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

661
	if (valid)
662 663
		goto valid;

664
	down_write(&vnode->validate_lock);
665 666 667 668 669

	/* 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 */
670
	if (!test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
671
		_debug("not promised");
672
		ret = afs_fetch_status(vnode, key, false, NULL);
673 674 675 676 677
		if (ret < 0) {
			if (ret == -ENOENT) {
				set_bit(AFS_VNODE_DELETED, &vnode->flags);
				ret = -ESTALE;
			}
678
			goto error_unlock;
679
		}
680 681 682 683 684 685 686 687 688 689 690
		_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 已提交
691 692
	if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags))
		afs_zap_data(vnode);
693
	up_write(&vnode->validate_lock);
694 695 696 697 698
valid:
	_leave(" = 0");
	return 0;

error_unlock:
699
	up_write(&vnode->validate_lock);
700 701 702 703
	_leave(" = %d", ret);
	return ret;
}

L
Linus Torvalds 已提交
704 705 706
/*
 * read the attributes of an inode
 */
707 708
int afs_getattr(const struct path *path, struct kstat *stat,
		u32 request_mask, unsigned int query_flags)
L
Linus Torvalds 已提交
709
{
710
	struct inode *inode = d_inode(path->dentry);
711 712
	struct afs_vnode *vnode = AFS_FS_I(inode);
	int seq = 0;
L
Linus Torvalds 已提交
713

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

716 717 718 719 720 721
	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 已提交
722
	return 0;
723
}
L
Linus Torvalds 已提交
724

725 726 727 728 729 730 731 732 733 734 735 736 737
/*
 * 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 已提交
738 739 740
/*
 * clear an AFS inode
 */
741
void afs_evict_inode(struct inode *inode)
L
Linus Torvalds 已提交
742 743 744 745 746
{
	struct afs_vnode *vnode;

	vnode = AFS_FS_I(inode);

747
	_enter("{%llx:%llu.%d}",
748
	       vnode->fid.vid,
L
Linus Torvalds 已提交
749
	       vnode->fid.vnode,
750
	       vnode->fid.unique);
L
Linus Torvalds 已提交
751

752 753 754 755
	_debug("CLEAR INODE %p", inode);

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

756
	truncate_inode_pages_final(&inode->i_data);
757
	clear_inode(inode);
758

759 760 761 762 763 764
	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 已提交
765

766
#ifdef CONFIG_AFS_FSCACHE
767 768 769 770 771 772 773 774
	{
		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 已提交
775 776
#endif

777
	afs_prune_wb_keys(vnode);
778
	afs_put_permits(rcu_access_pointer(vnode->permit_cache));
779 780
	key_put(vnode->silly_key);
	vnode->silly_key = NULL;
781 782
	key_put(vnode->lock_key);
	vnode->lock_key = NULL;
L
Linus Torvalds 已提交
783
	_leave("");
784
}
785

786 787 788 789 790 791 792 793 794 795 796
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,
};

797 798 799 800 801
/*
 * set the attributes of an inode
 */
int afs_setattr(struct dentry *dentry, struct iattr *attr)
{
802
	struct afs_operation *op;
803
	struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
804

805
	_enter("{%llx:%llu},{n=%pd},%x",
A
Al Viro 已提交
806
	       vnode->fid.vid, vnode->fid.vnode, dentry,
807 808 809 810 811 812 813 814 815
	       attr->ia_valid);

	if (!(attr->ia_valid & (ATTR_SIZE | ATTR_MODE | ATTR_UID | ATTR_GID |
				ATTR_MTIME))) {
		_leave(" = 0 [unsupported]");
		return 0;
	}

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

819 820 821 822 823
	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);
824

825 826
	afs_op_set_vnode(op, 0, vnode);
	op->setattr.attr = attr;
827

828 829
	if (attr->ia_valid & ATTR_SIZE)
		op->file[0].dv_delta = 1;
830

831 832
	op->ops = &afs_setattr_operation;
	return afs_do_sync_operation(op);
833
}
新手
引导
客服 返回
顶部