fs/lockd/svcsubs.c

Source file repositories/reference/linux-study-clean/fs/lockd/svcsubs.c

File Facts

System
Linux kernel
Corpus path
fs/lockd/svcsubs.c
Extension
.c
Size
12280 bytes
Lines
534
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

switch (error) {
		case -EWOULDBLOCK:
			nlmerr = nlm__int__drop_reply;
			deferred = nlmerr;
			break;
		case -ESTALE:
			nlmerr = nlm__int__stale_fh;
			break;
		default:
			nlmerr = nlm__int__failed;
			break;
		}
	}

	return deferred ? deferred : nlmerr;
}

/*
 * Lookup file info. If it doesn't exist, create a file info struct
 * and open a (VFS) file for the given inode.
 */
__be32
nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
		struct lockd_lock *lock, int mode)
{
	struct nlm_file	*file;
	unsigned int	hash;
	__be32		nfserr;

	nlm_debug_print_fh("nlm_lookup_file", &lock->fh);

	hash = file_hash(&lock->fh);

	/* Lock file table */
	mutex_lock(&nlm_file_mutex);

	hlist_for_each_entry(file, &nlm_files[hash], f_list)
		if (!nfs_compare_fh(&file->f_handle, &lock->fh)) {
			mutex_lock(&file->f_mutex);
			nfserr = nlm_do_fopen(rqstp, file, mode);
			mutex_unlock(&file->f_mutex);
			if (nfserr)
				goto out_unlock;
			goto found;
		}
	nlm_debug_print_fh("creating file for", &lock->fh);

	nfserr = nlm_lck_denied_nolocks;
	file = kzalloc_obj(*file);
	if (!file)
		goto out_free;

	memcpy(&file->f_handle, &lock->fh, sizeof(struct nfs_fh));
	mutex_init(&file->f_mutex);
	INIT_HLIST_NODE(&file->f_list);
	INIT_LIST_HEAD(&file->f_blocks);

	nfserr = nlm_do_fopen(rqstp, file, mode);
	if (nfserr)
		goto out_free;

	hlist_add_head(&file->f_list, &nlm_files[hash]);

found:
	dprintk("lockd: found file %p (count %d)\n", file, file->f_count);
	*result = file;
	file->f_count++;

out_unlock:
	mutex_unlock(&nlm_file_mutex);
	return nfserr;

out_free:
	kfree(file);
	goto out_unlock;
}

/*
 * Delete a file after having released all locks, blocks and shares
 */
static inline void
nlm_delete_file(struct nlm_file *file)
{
	nlm_debug_print_file("closing file", file);
	if (!hlist_unhashed(&file->f_list)) {
		hlist_del(&file->f_list);
		if (file->f_file[O_RDONLY])
			nlmsvc_ops->fclose(file->f_file[O_RDONLY]);
		if (file->f_file[O_WRONLY])
			nlmsvc_ops->fclose(file->f_file[O_WRONLY]);

Annotation

Implementation Notes