fs/gfs2/quota.c
Source file repositories/reference/linux-study-clean/fs/gfs2/quota.c
File Facts
- System
- Linux kernel
- Corpus path
fs/gfs2/quota.c- Extension
.c- Size
- 44663 bytes
- Lines
- 1818
- 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/sched.hlinux/slab.hlinux/mm.hlinux/spinlock.hlinux/completion.hlinux/buffer_head.hlinux/sort.hlinux/fs.hlinux/bio.hlinux/gfs2_ondisk.hlinux/kthread.hlinux/freezer.hlinux/quota.hlinux/dqblk_xfs.hlinux/lockref.hlinux/list_lru.hlinux/rcupdate.hlinux/rculist_bl.hlinux/bit_spinlock.hlinux/jhash.hlinux/vmalloc.hgfs2.hincore.hbmap.hglock.hglops.hlog.hmeta_io.hquota.hrgrp.hsuper.htrans.h
Detected Declarations
function gfs2_qd_hashfunction spin_lock_bucketfunction spin_unlock_bucketfunction gfs2_qd_deallocfunction gfs2_qd_disposefunction gfs2_qd_list_disposefunction gfs2_qd_isolatefunction gfs2_qd_shrink_scanfunction gfs2_qd_shrink_countfunction gfs2_qd_shrinker_initfunction gfs2_qd_shrinker_exitfunction qd2indexfunction qd2offsetfunction hlist_bl_for_each_entry_rcufunction qd_getfunction __qd_holdfunction qd_putfunction slot_getfunction slot_holdfunction slot_putfunction bh_getfunction bh_putfunction qd_grab_syncfunction qd_ungrab_syncfunction qdsb_putfunction qd_unlockfunction qdsb_getfunction gfs2_qa_getfunction gfs2_qa_putfunction gfs2_quota_holdfunction gfs2_quota_unholdfunction sort_qdfunction do_qcfunction gfs2_write_buf_to_pagefunction gfs2_write_disk_quotafunction gfs2_adjust_quotafunction do_syncfunction update_qdfunction do_glockfunction gfs2_quota_lockfunction need_syncfunction gfs2_quota_unlockfunction print_messagefunction gfs2_quota_checkfunction time_after_eqfunction gfs2_quota_changefunction gfs2_quota_syncfunction list_for_each_entry
Annotated Snippet
if (lockref_get_not_dead(&qd->qd_lockref)) {
list_lru_del_obj(&gfs2_qd_lru, &qd->qd_lru);
return qd;
}
}
return NULL;
}
static int qd_get(struct gfs2_sbd *sdp, struct kqid qid,
struct gfs2_quota_data **qdp)
{
struct gfs2_quota_data *qd, *new_qd;
unsigned int hash = gfs2_qd_hash(sdp, qid);
rcu_read_lock();
*qdp = qd = gfs2_qd_search_bucket(hash, sdp, qid);
rcu_read_unlock();
if (qd)
return 0;
new_qd = qd_alloc(hash, sdp, qid);
if (!new_qd)
return -ENOMEM;
spin_lock(&qd_lock);
spin_lock_bucket(hash);
*qdp = qd = gfs2_qd_search_bucket(hash, sdp, qid);
if (qd == NULL) {
*qdp = new_qd;
list_add(&new_qd->qd_list, &sdp->sd_quota_list);
hlist_bl_add_head_rcu(&new_qd->qd_hlist, &qd_hash_table[hash]);
atomic_inc(&sdp->sd_quota_count);
}
spin_unlock_bucket(hash);
spin_unlock(&qd_lock);
if (qd) {
gfs2_glock_put(new_qd->qd_gl);
kmem_cache_free(gfs2_quotad_cachep, new_qd);
}
return 0;
}
static void __qd_hold(struct gfs2_quota_data *qd)
{
struct gfs2_sbd *sdp = qd->qd_sbd;
gfs2_assert(sdp, qd->qd_lockref.count > 0);
qd->qd_lockref.count++;
}
static void qd_put(struct gfs2_quota_data *qd)
{
struct gfs2_sbd *sdp;
if (lockref_put_or_lock(&qd->qd_lockref))
return;
BUG_ON(__lockref_is_dead(&qd->qd_lockref));
sdp = qd->qd_sbd;
if (unlikely(!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))) {
lockref_mark_dead(&qd->qd_lockref);
spin_unlock(&qd->qd_lockref.lock);
list_lru_del_obj(&gfs2_qd_lru, &qd->qd_lru);
gfs2_qd_dispose(qd);
return;
}
qd->qd_lockref.count = 0;
list_lru_add_obj(&gfs2_qd_lru, &qd->qd_lru);
spin_unlock(&qd->qd_lockref.lock);
}
static int slot_get(struct gfs2_quota_data *qd)
{
struct gfs2_sbd *sdp = qd->qd_sbd;
unsigned int bit;
int error = 0;
spin_lock(&sdp->sd_bitmap_lock);
if (qd->qd_slot_ref == 0) {
bit = find_first_zero_bit(sdp->sd_quota_bitmap,
sdp->sd_quota_slots);
if (bit >= sdp->sd_quota_slots) {
error = -ENOSPC;
Annotation
- Immediate include surface: `linux/sched.h`, `linux/slab.h`, `linux/mm.h`, `linux/spinlock.h`, `linux/completion.h`, `linux/buffer_head.h`, `linux/sort.h`, `linux/fs.h`.
- Detected declarations: `function gfs2_qd_hash`, `function spin_lock_bucket`, `function spin_unlock_bucket`, `function gfs2_qd_dealloc`, `function gfs2_qd_dispose`, `function gfs2_qd_list_dispose`, `function gfs2_qd_isolate`, `function gfs2_qd_shrink_scan`, `function gfs2_qd_shrink_count`, `function gfs2_qd_shrinker_init`.
- 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.