fs/afs/inode.c

Source file repositories/reference/linux-study-clean/fs/afs/inode.c

File Facts

System
Linux kernel
Corpus path
fs/afs/inode.c
Extension
.c
Size
22984 bytes
Lines
855
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if ((status->mode & 0777) == 0644) {
			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;
		} else {
			inode->i_mode	= S_IFLNK | status->mode;
			inode->i_op	= &afs_symlink_inode_operations;
		}
		inode->i_mapping->a_ops	= &afs_symlink_aops;
		inode_nohighmem(inode);
		mapping_set_release_always(inode->i_mapping);
		break;
	default:
		dump_vnode(vnode, op->file[0].vnode != vnode ? op->file[0].vnode : NULL);
		write_sequnlock(&vnode->cb_lock);
		return afs_protocol_error(NULL, afs_eproto_file_type);
	}

	i_size_write(inode, status->size);
	inode_set_bytes(inode, status->size);
	afs_set_netfs_context(vnode);

	vnode->invalid_before	= status->data_version;
	trace_afs_set_dv(vnode, status->data_version);
	inode_set_iversion_raw(&vnode->netfs.inode, status->data_version);

	if (!vp->scb.have_cb) {
		/* it's a symlink we just created (the fileserver
		 * didn't give us a callback) */
		afs_clear_cb_promise(vnode, afs_cb_promise_set_new_symlink);
	} else {
		vnode->cb_server = op->server;
		afs_set_cb_promise(vnode, vp->scb.callback.expires_at,
				   afs_cb_promise_set_new_inode);
	}

	write_sequnlock(&vnode->cb_lock);
	return 0;
}

/*
 * Update the core inode struct from a returned status record.
 */
static void afs_apply_status(struct afs_operation *op,
			     struct afs_vnode_param *vp)
{
	struct afs_file_status *status = &vp->scb.status;
	struct afs_vnode *vnode = vp->vnode;
	struct netfs_inode *ictx = &vnode->netfs;
	struct inode *inode = &ictx->inode;
	struct timespec64 t;
	umode_t mode;
	bool unexpected_jump = false;
	bool data_changed = false;
	bool change_size = vp->set_size;

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

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

	if (status->type != vnode->status.type) {
		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);
		afs_protocol_error(NULL, afs_eproto_bad_status);
		return;
	}

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

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

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

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

Annotation

Implementation Notes