fs/smb/server/oplock.c
Source file repositories/reference/linux-study-clean/fs/smb/server/oplock.c
File Facts
- System
- Linux kernel
- Corpus path
fs/smb/server/oplock.c- Extension
.c- Size
- 50529 bytes
- Lines
- 1930
- 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.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/moduleparam.hglob.hoplock.hsmb_common.h../common/smb2status.hconnection.hmgmt/user_session.hmgmt/share_config.hmgmt/tree_connect.h
Detected Declarations
function alloc_opinfofunction lease_add_listfunction lease_del_listfunction alloc_leasefunction free_leasefunction __free_opinfofunction free_opinfo_rcufunction free_opinfofunction opinfo_putfunction opinfo_addfunction opinfo_delfunction opinfo_countfunction opinfo_count_incfunction opinfo_count_decfunction opinfo_write_to_readfunction opinfo_read_handle_to_readfunction opinfo_write_to_nonefunction opinfo_read_to_nonefunction lease_read_to_writefunction lease_none_upgradefunction close_id_del_oplockfunction grant_write_oplockfunction grant_read_oplockfunction grant_none_oplockfunction compare_guid_keyfunction same_client_has_leasefunction atomic_readfunction wait_for_break_ackfunction wake_up_oplock_breakfunction oplock_break_pendingfunction __smb2_oplock_break_notifunction smb2_oplock_break_notifunction __smb2_lease_break_notifunction smb2_lease_break_notifunction wait_lease_breakingfunction oplock_breakfunction destroy_lease_tablefunction list_for_each_entry_safefunction list_for_each_entry_rcufunction find_same_lease_keyfunction list_for_each_entryfunction copy_leasefunction add_lease_global_listfunction set_oplock_levelfunction smb_send_parent_lease_break_notifunction smb_lazy_parent_lease_break_closefunction smb_grant_oplockfunction smb_break_all_write_oplock
Annotated Snippet
if (ksmbd_conn_releasing(opinfo->conn)) {
atomic_dec(&opinfo->refcount);
opinfo = NULL;
}
}
}
up_read(&ci->m_lock);
return opinfo;
}
void opinfo_put(struct oplock_info *opinfo)
{
if (!opinfo)
return;
if (!atomic_dec_and_test(&opinfo->refcount))
return;
free_opinfo(opinfo);
}
static void opinfo_add(struct oplock_info *opinfo, struct ksmbd_file *fp)
{
struct ksmbd_inode *ci = fp->f_ci;
down_write(&ci->m_lock);
list_add(&opinfo->op_entry, &ci->m_op_list);
up_write(&ci->m_lock);
}
static void opinfo_del(struct oplock_info *opinfo)
{
struct ksmbd_inode *ci = opinfo->o_fp->f_ci;
if (opinfo->is_lease) {
write_lock(&lease_list_lock);
lease_del_list(opinfo);
write_unlock(&lease_list_lock);
}
down_write(&ci->m_lock);
list_del(&opinfo->op_entry);
up_write(&ci->m_lock);
}
static unsigned long opinfo_count(struct ksmbd_file *fp)
{
if (ksmbd_stream_fd(fp))
return atomic_read(&fp->f_ci->sop_count);
else
return atomic_read(&fp->f_ci->op_count);
}
static void opinfo_count_inc(struct ksmbd_file *fp)
{
if (ksmbd_stream_fd(fp))
return atomic_inc(&fp->f_ci->sop_count);
else
return atomic_inc(&fp->f_ci->op_count);
}
static void opinfo_count_dec(struct ksmbd_file *fp)
{
if (ksmbd_stream_fd(fp))
return atomic_dec(&fp->f_ci->sop_count);
else
return atomic_dec(&fp->f_ci->op_count);
}
/**
* opinfo_write_to_read() - convert a write oplock to read oplock
* @opinfo: current oplock info
*
* Return: 0 on success, otherwise -EINVAL
*/
int opinfo_write_to_read(struct oplock_info *opinfo)
{
struct lease *lease = opinfo->o_lease;
if (!(opinfo->level == SMB2_OPLOCK_LEVEL_BATCH ||
opinfo->level == SMB2_OPLOCK_LEVEL_EXCLUSIVE)) {
pr_err("bad oplock(0x%x)\n", opinfo->level);
if (opinfo->is_lease)
pr_err("lease state(0x%x)\n", lease->state);
return -EINVAL;
}
opinfo->level = SMB2_OPLOCK_LEVEL_II;
if (opinfo->is_lease)
lease->state = lease->new_state;
Annotation
- Immediate include surface: `linux/moduleparam.h`, `glob.h`, `oplock.h`, `smb_common.h`, `../common/smb2status.h`, `connection.h`, `mgmt/user_session.h`, `mgmt/share_config.h`.
- Detected declarations: `function alloc_opinfo`, `function lease_add_list`, `function lease_del_list`, `function alloc_lease`, `function free_lease`, `function __free_opinfo`, `function free_opinfo_rcu`, `function free_opinfo`, `function opinfo_put`, `function opinfo_add`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.