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.

Dependency Surface

Detected Declarations

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

Implementation Notes