fs/smb/server/vfs_cache.c

Source file repositories/reference/linux-study-clean/fs/smb/server/vfs_cache.c

File Facts

System
Linux kernel
Corpus path
fs/smb/server/vfs_cache.c
Extension
.c
Size
36176 bytes
Lines
1504
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 (opinfo) {
			const struct ksmbd_const_name *const_names;
			int count;
			unsigned int level;

			if (opinfo->is_lease) {
				const_names = ksmbd_lease_const_names;
				count = ARRAY_SIZE(ksmbd_lease_const_names);
				level = le32_to_cpu(opinfo->o_lease->state);
			} else {
				const_names = ksmbd_oplock_const_names;
				count = ARRAY_SIZE(ksmbd_oplock_const_names);
				level = opinfo->level;
			}
			rcu_read_unlock();
			ksmbd_proc_show_const_name(m, " %-15s",
						   const_names, count, level);
		} else {
			rcu_read_unlock();
			seq_printf(m, " %-15s", " ");
		}

		seq_printf(m, " %#010x %#010x %s\n",
			   le32_to_cpu(fp->daccess),
			   le32_to_cpu(fp->saccess),
			   fp->filp->f_path.dentry->d_name.name);
	}
	read_unlock(&global_ft.lock);
	return 0;
}

static int create_proc_files(void)
{
	ksmbd_proc_create("files", proc_show_files, NULL);
	return 0;
}
#else
static int create_proc_files(void) { return 0; }
#endif

static bool durable_scavenger_running;
static DEFINE_MUTEX(durable_scavenger_lock);
static wait_queue_head_t dh_wq;

void ksmbd_set_fd_limit(unsigned long limit)
{
	limit = min(limit, get_max_files());
	atomic_long_set(&fd_limit, limit);
}

static bool fd_limit_depleted(void)
{
	long v = atomic_long_dec_return(&fd_limit);

	if (v >= 0)
		return false;
	atomic_long_inc(&fd_limit);
	return true;
}

static void fd_limit_close(void)
{
	atomic_long_inc(&fd_limit);
}

/*
 * INODE hash
 */

static unsigned long inode_hash(struct super_block *sb, unsigned long hashval)
{
	unsigned long tmp;

	tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) /
		L1_CACHE_BYTES;
	tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> inode_hash_shift);
	return tmp & inode_hash_mask;
}

static struct ksmbd_inode *__ksmbd_inode_lookup(struct dentry *de)
{
	struct hlist_head *head = inode_hashtable +
		inode_hash(d_inode(de)->i_sb, (unsigned long)de);
	struct ksmbd_inode *ci = NULL, *ret_ci = NULL;

	hlist_for_each_entry(ci, head, m_hash) {
		if (ci->m_de == de) {
			if (atomic_inc_not_zero(&ci->m_count))
				ret_ci = ci;
			break;

Annotation

Implementation Notes