fs/ocfs2/quota_global.c

Source file repositories/reference/linux-study-clean/fs/ocfs2/quota_global.c

File Facts

System
Linux kernel
Corpus path
fs/ocfs2/quota_global.c
Extension
.c
Size
31343 bytes
Lines
1052
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 (!pcount) {
			err = ocfs2_extent_map_get_blocks(gqinode, blk, &pblock,
							  &pcount, NULL);
			if (err) {
				mlog_errno(err);
				return err;
			}
		} else {
			pcount--;
			pblock++;
		}
		bh = NULL;
		err = ocfs2_read_quota_phys_block(gqinode, pblock, &bh);
		if (err) {
			mlog_errno(err);
			return err;
		}
		memcpy(data, bh->b_data + offset, tocopy);
		brelse(bh);
		offset = 0;
		toread -= tocopy;
		data += tocopy;
		blk++;
	}
	return len;
}

/* Write to quotafile (we know the transaction is already started and has
 * enough credits) */
ssize_t ocfs2_quota_write(struct super_block *sb, int type,
			  const char *data, size_t len, loff_t off)
{
	struct mem_dqinfo *info = sb_dqinfo(sb, type);
	struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
	struct inode *gqinode = oinfo->dqi_gqinode;
	int offset = off & (sb->s_blocksize - 1);
	sector_t blk = off >> sb->s_blocksize_bits;
	int err = 0, new = 0, ja_type;
	struct buffer_head *bh = NULL;
	handle_t *handle = journal_current_handle();
	u64 pblock, pcount;

	if (!handle) {
		mlog(ML_ERROR, "Quota write (off=%llu, len=%llu) cancelled "
		     "because transaction was not started.\n",
		     (unsigned long long)off, (unsigned long long)len);
		return -EIO;
	}
	if (len > sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE - offset) {
		WARN_ON(1);
		len = sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE - offset;
	}

	if (i_size_read(gqinode) < off + len) {
		loff_t rounded_end =
				ocfs2_align_bytes_to_blocks(sb, off + len);

		/* Space is already allocated in ocfs2_acquire_dquot() */
		err = ocfs2_simple_size_update(gqinode,
					       oinfo->dqi_gqi_bh,
					       rounded_end);
		if (err < 0)
			goto out;
		new = 1;
	}
	err = ocfs2_extent_map_get_blocks(gqinode, blk, &pblock, &pcount, NULL);
	if (err) {
		mlog_errno(err);
		goto out;
	}
	/* Not rewriting whole block? */
	if ((offset || len < sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE) &&
	    !new) {
		err = ocfs2_read_quota_phys_block(gqinode, pblock, &bh);
		ja_type = OCFS2_JOURNAL_ACCESS_WRITE;
	} else {
		bh = sb_getblk(sb, pblock);
		if (!bh)
			err = -ENOMEM;
		ja_type = OCFS2_JOURNAL_ACCESS_CREATE;
	}
	if (err) {
		mlog_errno(err);
		goto out;
	}
	lock_buffer(bh);
	if (new)
		memset(bh->b_data, 0, sb->s_blocksize);
	memcpy(bh->b_data + offset, data, len);
	flush_dcache_folio(bh->b_folio);

Annotation

Implementation Notes