fs/nfs/nfs4state.c

Source file repositories/reference/linux-study-clean/fs/nfs/nfs4state.c

File Facts

System
Linux kernel
Corpus path
fs/nfs/nfs4state.c
Extension
.c
Size
72417 bytes
Lines
2714
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: exported/initcall integration point
Status
integration 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 (state->n_rdonly == 0) {
			newstate &= ~FMODE_READ;
			call_close |= test_bit(NFS_O_RDONLY_STATE, &state->flags);
			call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags);
		}
		if (state->n_wronly == 0) {
			newstate &= ~FMODE_WRITE;
			call_close |= test_bit(NFS_O_WRONLY_STATE, &state->flags);
			call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags);
		}
		if (newstate == 0)
			clear_bit(NFS_DELEGATED_STATE, &state->flags);
	}
	nfs4_state_set_mode_locked(state, newstate);
	spin_unlock(&owner->so_lock);

	if (!call_close) {
		nfs4_put_open_state(state);
		nfs4_put_state_owner(owner);
	} else
		nfs4_do_close(state, gfp_mask, wait);
}

void nfs4_close_state(struct nfs4_state *state, fmode_t fmode)
{
	__nfs4_close(state, fmode, GFP_KERNEL, 0);
}

void nfs4_close_sync(struct nfs4_state *state, fmode_t fmode)
{
	__nfs4_close(state, fmode, GFP_KERNEL, 1);
}

/*
 * Search the state->lock_states for an existing lock_owner
 * that is compatible with either of the given owners.
 * If the second is non-zero, then the first refers to a Posix-lock
 * owner (current->files) and the second refers to a flock/OFD
 * owner (struct file*).  In that case, prefer a match for the first
 * owner.
 * If both sorts of locks are held on the one file we cannot know
 * which stateid was intended to be used, so a "correct" choice cannot
 * be made.  Failing that, a "consistent" choice is preferable.  The
 * consistent choice we make is to prefer the first owner, that of a
 * Posix lock.
 */
static struct nfs4_lock_state *
__nfs4_find_lock_state(struct nfs4_state *state,
		       fl_owner_t owner, fl_owner_t owner2)
{
	struct nfs4_lock_state *pos, *ret = NULL;
	list_for_each_entry(pos, &state->lock_states, ls_locks) {
		if (pos->ls_owner == owner) {
			ret = pos;
			break;
		}
		if (pos->ls_owner == owner2)
			ret = pos;
	}
	if (ret)
		refcount_inc(&ret->ls_count);
	return ret;
}

/*
 * Return a compatible lock_state. If no initialized lock_state structure
 * exists, return an uninitialized one.
 *
 */
static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t owner)
{
	struct nfs4_lock_state *lsp;
	struct nfs_server *server = state->owner->so_server;

	lsp = kzalloc_obj(*lsp, GFP_KERNEL_ACCOUNT);
	if (lsp == NULL)
		return NULL;
	nfs4_init_seqid_counter(&lsp->ls_seqid);
	refcount_set(&lsp->ls_count, 1);
	lsp->ls_state = state;
	lsp->ls_owner = owner;
	lsp->ls_seqid.owner_id = atomic64_inc_return(&server->owner_ctr);
	INIT_LIST_HEAD(&lsp->ls_locks);
	return lsp;
}

void nfs4_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp)
{
	nfs4_destroy_seqid_counter(&lsp->ls_seqid);
	kfree(lsp);

Annotation

Implementation Notes