^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Implementation of operations over local quota file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/quota.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/quotaops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <cluster/masklog.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "ocfs2_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "ocfs2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "alloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "file.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "buffer_head_io.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "journal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "sysfile.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "dlmglue.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "quota.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "uptodate.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "super.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "ocfs2_trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* Number of local quota structures per block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static inline unsigned int ol_quota_entries_per_block(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return ((sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) sizeof(struct ocfs2_local_disk_dqblk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* Number of blocks with entries in one chunk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static inline unsigned int ol_chunk_blocks(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return ((sb->s_blocksize - sizeof(struct ocfs2_local_disk_chunk) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) OCFS2_QBLK_RESERVED_SPACE) << 3) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) ol_quota_entries_per_block(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* Number of entries in a chunk bitmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static unsigned int ol_chunk_entries(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return ol_chunk_blocks(sb) * ol_quota_entries_per_block(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* Offset of the chunk in quota file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static unsigned int ol_quota_chunk_block(struct super_block *sb, int c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* 1 block for local quota file info, 1 block per chunk for chunk info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return 1 + (ol_chunk_blocks(sb) + 1) * c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static unsigned int ol_dqblk_block(struct super_block *sb, int c, int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int epb = ol_quota_entries_per_block(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return ol_quota_chunk_block(sb, c) + 1 + off / epb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static unsigned int ol_dqblk_block_off(struct super_block *sb, int c, int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int epb = ol_quota_entries_per_block(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return (off % epb) * sizeof(struct ocfs2_local_disk_dqblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Offset of the dquot structure in the quota file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static loff_t ol_dqblk_off(struct super_block *sb, int c, int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return (ol_dqblk_block(sb, c, off) << sb->s_blocksize_bits) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ol_dqblk_block_off(sb, c, off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static inline unsigned int ol_dqblk_block_offset(struct super_block *sb, loff_t off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return off & ((1 << sb->s_blocksize_bits) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* Compute offset in the chunk of a structure with the given offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static int ol_dqblk_chunk_off(struct super_block *sb, int c, loff_t off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int epb = ol_quota_entries_per_block(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return ((off >> sb->s_blocksize_bits) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ol_quota_chunk_block(sb, c) - 1) * epb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) + ((unsigned int)(off & ((1 << sb->s_blocksize_bits) - 1))) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) sizeof(struct ocfs2_local_disk_dqblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* Write bufferhead into the fs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static int ocfs2_modify_bh(struct inode *inode, struct buffer_head *bh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) void (*modify)(struct buffer_head *, void *), void *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct super_block *sb = inode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) handle_t *handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) handle = ocfs2_start_trans(OCFS2_SB(sb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) OCFS2_QUOTA_BLOCK_UPDATE_CREDITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (IS_ERR(handle)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) status = PTR_ERR(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) status = ocfs2_journal_access_dq(handle, INODE_CACHE(inode), bh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) OCFS2_JOURNAL_ACCESS_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ocfs2_commit_trans(OCFS2_SB(sb), handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) lock_buffer(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) modify(bh, private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unlock_buffer(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ocfs2_journal_dirty(handle, bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) status = ocfs2_commit_trans(OCFS2_SB(sb), handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * Read quota block from a given logical offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * This function acquires ip_alloc_sem and thus it must not be called with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * transaction started.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int ocfs2_read_quota_block(struct inode *inode, u64 v_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct buffer_head **bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct buffer_head *tmp = *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (i_size_read(inode) >> inode->i_sb->s_blocksize_bits <= v_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return ocfs2_error(inode->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) "Quota file %llu is probably corrupted! Requested to read block %Lu but file has size only %Lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) (unsigned long long)OCFS2_I(inode)->ip_blkno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) (unsigned long long)v_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) (unsigned long long)i_size_read(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) rc = ocfs2_read_virt_blocks(inode, v_block, 1, &tmp, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ocfs2_validate_quota_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) mlog_errno(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* If ocfs2_read_virt_blocks() got us a new bh, pass it up. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (!rc && !*bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) *bh = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* Check whether we understand format of quota files */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static int ocfs2_local_check_quota_file(struct super_block *sb, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsigned int lmagics[OCFS2_MAXQUOTAS] = OCFS2_LOCAL_QMAGICS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) unsigned int lversions[OCFS2_MAXQUOTAS] = OCFS2_LOCAL_QVERSIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) unsigned int gmagics[OCFS2_MAXQUOTAS] = OCFS2_GLOBAL_QMAGICS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) unsigned int gversions[OCFS2_MAXQUOTAS] = OCFS2_GLOBAL_QVERSIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) unsigned int ino[OCFS2_MAXQUOTAS] = { USER_QUOTA_SYSTEM_INODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) GROUP_QUOTA_SYSTEM_INODE };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct buffer_head *bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct inode *linode = sb_dqopt(sb)->files[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct inode *ginode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct ocfs2_disk_dqheader *dqhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int status, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* First check whether we understand local quota file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) status = ocfs2_read_quota_block(linode, 0, &bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) mlog(ML_ERROR, "failed to read quota file header (type=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) dqhead = (struct ocfs2_disk_dqheader *)(bh->b_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (le32_to_cpu(dqhead->dqh_magic) != lmagics[type]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) mlog(ML_ERROR, "quota file magic does not match (%u != %u),"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) " type=%d\n", le32_to_cpu(dqhead->dqh_magic),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) lmagics[type], type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (le32_to_cpu(dqhead->dqh_version) != lversions[type]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) mlog(ML_ERROR, "quota file version does not match (%u != %u),"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) " type=%d\n", le32_to_cpu(dqhead->dqh_version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) lversions[type], type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* Next check whether we understand global quota file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ginode = ocfs2_get_system_file_inode(OCFS2_SB(sb), ino[type],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) OCFS2_INVALID_SLOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (!ginode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) mlog(ML_ERROR, "cannot get global quota file inode "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) "(type=%d)\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* Since the header is read only, we don't care about locking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) status = ocfs2_read_quota_block(ginode, 0, &bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) mlog(ML_ERROR, "failed to read global quota file header "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) "(type=%d)\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) dqhead = (struct ocfs2_disk_dqheader *)(bh->b_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (le32_to_cpu(dqhead->dqh_magic) != gmagics[type]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) mlog(ML_ERROR, "global quota file magic does not match "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) "(%u != %u), type=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) le32_to_cpu(dqhead->dqh_magic), gmagics[type], type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (le32_to_cpu(dqhead->dqh_version) != gversions[type]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) mlog(ML_ERROR, "global quota file version does not match "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) "(%u != %u), type=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) le32_to_cpu(dqhead->dqh_version), gversions[type],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) iput(ginode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* Release given list of quota file chunks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static void ocfs2_release_local_quota_bitmaps(struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct ocfs2_quota_chunk *pos, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) list_for_each_entry_safe(pos, next, head, qc_chunk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) list_del(&pos->qc_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) brelse(pos->qc_headerbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) kmem_cache_free(ocfs2_qf_chunk_cachep, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* Load quota bitmaps into memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static int ocfs2_load_local_quota_bitmaps(struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct ocfs2_local_disk_dqinfo *ldinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct ocfs2_quota_chunk *newchunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int i, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) INIT_LIST_HEAD(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) for (i = 0; i < le32_to_cpu(ldinfo->dqi_chunks); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) newchunk = kmem_cache_alloc(ocfs2_qf_chunk_cachep, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (!newchunk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ocfs2_release_local_quota_bitmaps(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) newchunk->qc_num = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) newchunk->qc_headerbh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) status = ocfs2_read_quota_block(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ol_quota_chunk_block(inode->i_sb, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) &newchunk->qc_headerbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) kmem_cache_free(ocfs2_qf_chunk_cachep, newchunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ocfs2_release_local_quota_bitmaps(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) list_add_tail(&newchunk->qc_chunk, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static void olq_update_info(struct buffer_head *bh, void *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct mem_dqinfo *info = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct ocfs2_local_disk_dqinfo *ldinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) OCFS2_LOCAL_INFO_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) spin_lock(&dq_data_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ldinfo->dqi_flags = cpu_to_le32(oinfo->dqi_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ldinfo->dqi_chunks = cpu_to_le32(oinfo->dqi_chunks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ldinfo->dqi_blocks = cpu_to_le32(oinfo->dqi_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) spin_unlock(&dq_data_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int ocfs2_add_recovery_chunk(struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct ocfs2_local_disk_chunk *dchunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct ocfs2_recovery_chunk *rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) rc = kmalloc(sizeof(struct ocfs2_recovery_chunk), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) rc->rc_chunk = chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) rc->rc_bitmap = kmalloc(sb->s_blocksize, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (!rc->rc_bitmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) kfree(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) memcpy(rc->rc_bitmap, dchunk->dqc_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) (ol_chunk_entries(sb) + 7) >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) list_add_tail(&rc->rc_list, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static void free_recovery_list(struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct ocfs2_recovery_chunk *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct ocfs2_recovery_chunk *rchunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) list_for_each_entry_safe(rchunk, next, head, rc_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) list_del(&rchunk->rc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) kfree(rchunk->rc_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) kfree(rchunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) void ocfs2_free_quota_recovery(struct ocfs2_quota_recovery *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) for (type = 0; type < OCFS2_MAXQUOTAS; type++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) free_recovery_list(&(rec->r_list[type]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) kfree(rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* Load entries in our quota file we have to recover*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static int ocfs2_recovery_load_quota(struct inode *lqinode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct ocfs2_local_disk_dqinfo *ldinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) int type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct super_block *sb = lqinode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct buffer_head *hbh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct ocfs2_local_disk_chunk *dchunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int i, chunks = le32_to_cpu(ldinfo->dqi_chunks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) for (i = 0; i < chunks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) hbh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) status = ocfs2_read_quota_block(lqinode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ol_quota_chunk_block(sb, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) &hbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) dchunk = (struct ocfs2_local_disk_chunk *)hbh->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (le32_to_cpu(dchunk->dqc_free) < ol_chunk_entries(sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) status = ocfs2_add_recovery_chunk(sb, dchunk, i, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) brelse(hbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) free_recovery_list(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static struct ocfs2_quota_recovery *ocfs2_alloc_quota_recovery(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct ocfs2_quota_recovery *rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) rec = kmalloc(sizeof(struct ocfs2_quota_recovery), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (!rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) for (type = 0; type < OCFS2_MAXQUOTAS; type++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) INIT_LIST_HEAD(&(rec->r_list[type]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* Load information we need for quota recovery into memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct ocfs2_quota_recovery *ocfs2_begin_quota_recovery(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct ocfs2_super *osb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) int slot_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) unsigned int feature[OCFS2_MAXQUOTAS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) OCFS2_FEATURE_RO_COMPAT_USRQUOTA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) OCFS2_FEATURE_RO_COMPAT_GRPQUOTA};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) unsigned int ino[OCFS2_MAXQUOTAS] = { LOCAL_USER_QUOTA_SYSTEM_INODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) LOCAL_GROUP_QUOTA_SYSTEM_INODE };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct super_block *sb = osb->sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct ocfs2_local_disk_dqinfo *ldinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) struct inode *lqinode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) struct ocfs2_quota_recovery *rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) printk(KERN_NOTICE "ocfs2: Beginning quota recovery on device (%s) for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) "slot %u\n", osb->dev_str, slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) rec = ocfs2_alloc_quota_recovery();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (!rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /* First init... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) for (type = 0; type < OCFS2_MAXQUOTAS; type++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, feature[type]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* At this point, journal of the slot is already replayed so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * we can trust metadata and data of the quota file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) lqinode = ocfs2_get_system_file_inode(osb, ino[type], slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (!lqinode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) status = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) status = ocfs2_inode_lock_full(lqinode, NULL, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) OCFS2_META_LOCK_RECOVERY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* Now read local header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) status = ocfs2_read_quota_block(lqinode, 0, &bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) mlog(ML_ERROR, "failed to read quota file info header "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) "(slot=%d type=%d)\n", slot_num, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) goto out_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) OCFS2_LOCAL_INFO_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) status = ocfs2_recovery_load_quota(lqinode, ldinfo, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) &rec->r_list[type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) out_lock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ocfs2_inode_unlock(lqinode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) iput(lqinode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ocfs2_free_quota_recovery(rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) rec = ERR_PTR(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* Sync changes in local quota file into global quota file and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * reinitialize local quota file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * The function expects local quota file to be already locked and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * s_umount locked in shared mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) static int ocfs2_recover_local_quota_file(struct inode *lqinode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) int type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct ocfs2_quota_recovery *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct super_block *sb = lqinode->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct ocfs2_local_disk_chunk *dchunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct ocfs2_local_disk_dqblk *dqblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct dquot *dquot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) handle_t *handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct buffer_head *hbh = NULL, *qbh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) int bit, chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct ocfs2_recovery_chunk *rchunk, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) qsize_t spacechange, inodechange;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) trace_ocfs2_recover_local_quota_file((unsigned long)lqinode->i_ino, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) list_for_each_entry_safe(rchunk, next, &(rec->r_list[type]), rc_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) chunk = rchunk->rc_chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) hbh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) status = ocfs2_read_quota_block(lqinode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ol_quota_chunk_block(sb, chunk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) &hbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) dchunk = (struct ocfs2_local_disk_chunk *)hbh->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) for_each_set_bit(bit, rchunk->rc_bitmap, ol_chunk_entries(sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) qbh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) status = ocfs2_read_quota_block(lqinode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ol_dqblk_block(sb, chunk, bit),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) &qbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) dqblk = (struct ocfs2_local_disk_dqblk *)(qbh->b_data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ol_dqblk_block_off(sb, chunk, bit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) dquot = dqget(sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) make_kqid(&init_user_ns, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) le64_to_cpu(dqblk->dqb_id)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (IS_ERR(dquot)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) status = PTR_ERR(dquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) mlog(ML_ERROR, "Failed to get quota structure "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) "for id %u, type %d. Cannot finish quota "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) "file recovery.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) (unsigned)le64_to_cpu(dqblk->dqb_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) goto out_put_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) status = ocfs2_lock_global_qf(oinfo, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) goto out_put_dquot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) handle = ocfs2_start_trans(OCFS2_SB(sb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) OCFS2_QSYNC_CREDITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (IS_ERR(handle)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) status = PTR_ERR(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) goto out_drop_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) down_write(&sb_dqopt(sb)->dqio_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) spin_lock(&dquot->dq_dqb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* Add usage from quota entry into quota changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * of our node. Auxiliary variables are important
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * due to signedness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) spacechange = le64_to_cpu(dqblk->dqb_spacemod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) inodechange = le64_to_cpu(dqblk->dqb_inodemod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) dquot->dq_dqb.dqb_curspace += spacechange;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) dquot->dq_dqb.dqb_curinodes += inodechange;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) spin_unlock(&dquot->dq_dqb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /* We want to drop reference held by the crashed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * node. Since we have our own reference we know
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * global structure actually won't be freed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) status = ocfs2_global_release_dquot(dquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) goto out_commit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* Release local quota file entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) status = ocfs2_journal_access_dq(handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) INODE_CACHE(lqinode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) qbh, OCFS2_JOURNAL_ACCESS_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) goto out_commit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) lock_buffer(qbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) WARN_ON(!ocfs2_test_bit_unaligned(bit, dchunk->dqc_bitmap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) ocfs2_clear_bit_unaligned(bit, dchunk->dqc_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) le32_add_cpu(&dchunk->dqc_free, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) unlock_buffer(qbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ocfs2_journal_dirty(handle, qbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) out_commit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) up_write(&sb_dqopt(sb)->dqio_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) ocfs2_commit_trans(OCFS2_SB(sb), handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) out_drop_lock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) ocfs2_unlock_global_qf(oinfo, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) out_put_dquot:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) dqput(dquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) out_put_bh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) brelse(qbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) brelse(hbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) list_del(&rchunk->rc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) kfree(rchunk->rc_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) kfree(rchunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) free_recovery_list(&(rec->r_list[type]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) /* Recover local quota files for given node different from us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct ocfs2_quota_recovery *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) int slot_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) unsigned int ino[OCFS2_MAXQUOTAS] = { LOCAL_USER_QUOTA_SYSTEM_INODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) LOCAL_GROUP_QUOTA_SYSTEM_INODE };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct super_block *sb = osb->sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct ocfs2_local_disk_dqinfo *ldinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) handle_t *handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct inode *lqinode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) printk(KERN_NOTICE "ocfs2: Finishing quota recovery on device (%s) for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) "slot %u\n", osb->dev_str, slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) down_read(&sb->s_umount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) for (type = 0; type < OCFS2_MAXQUOTAS; type++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (list_empty(&(rec->r_list[type])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) trace_ocfs2_finish_quota_recovery(slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) lqinode = ocfs2_get_system_file_inode(osb, ino[type], slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (!lqinode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) status = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) status = ocfs2_inode_lock_full(lqinode, NULL, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) OCFS2_META_LOCK_NOQUEUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /* Someone else is holding the lock? Then he must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * doing the recovery. Just skip the file... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (status == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) printk(KERN_NOTICE "ocfs2: Skipping quota recovery on "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) "device (%s) for slot %d because quota file is "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) "locked.\n", osb->dev_str, slot_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) } else if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) goto out_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /* Now read local header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) status = ocfs2_read_quota_block(lqinode, 0, &bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) mlog(ML_ERROR, "failed to read quota file info header "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) "(slot=%d type=%d)\n", slot_num, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) goto out_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) OCFS2_LOCAL_INFO_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /* Is recovery still needed? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) flags = le32_to_cpu(ldinfo->dqi_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (!(flags & OLQF_CLEAN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) status = ocfs2_recover_local_quota_file(lqinode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) /* We don't want to mark file as clean when it is actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (slot_num == osb->slot_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) goto out_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) /* Mark quota file as clean if we are recovering quota file of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * some other node. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) handle = ocfs2_start_trans(osb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) OCFS2_LOCAL_QINFO_WRITE_CREDITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (IS_ERR(handle)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) status = PTR_ERR(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) goto out_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) bh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) OCFS2_JOURNAL_ACCESS_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) goto out_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) lock_buffer(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) ldinfo->dqi_flags = cpu_to_le32(flags | OLQF_CLEAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) unlock_buffer(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) ocfs2_journal_dirty(handle, bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) out_trans:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) ocfs2_commit_trans(osb, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) out_bh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) out_lock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) ocfs2_inode_unlock(lqinode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) out_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) iput(lqinode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) up_read(&sb->s_umount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) kfree(rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) /* Read information header from quota file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static int ocfs2_local_read_info(struct super_block *sb, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) struct ocfs2_local_disk_dqinfo *ldinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) struct mem_dqinfo *info = sb_dqinfo(sb, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct ocfs2_mem_dqinfo *oinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) struct inode *lqinode = sb_dqopt(sb)->files[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct buffer_head *bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct ocfs2_quota_recovery *rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) int locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) info->dqi_max_spc_limit = 0x7fffffffffffffffLL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) info->dqi_max_ino_limit = 0x7fffffffffffffffLL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) oinfo = kmalloc(sizeof(struct ocfs2_mem_dqinfo), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (!oinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) mlog(ML_ERROR, "failed to allocate memory for ocfs2 quota"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) " info.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) info->dqi_priv = oinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) oinfo->dqi_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) INIT_LIST_HEAD(&oinfo->dqi_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) oinfo->dqi_rec = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) oinfo->dqi_lqi_bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) oinfo->dqi_libh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) status = ocfs2_global_read_info(sb, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) status = ocfs2_inode_lock(lqinode, &oinfo->dqi_lqi_bh, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) locked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /* Now read local header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) status = ocfs2_read_quota_block(lqinode, 0, &bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) mlog(ML_ERROR, "failed to read quota file info header "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) "(type=%d)\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) OCFS2_LOCAL_INFO_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) oinfo->dqi_flags = le32_to_cpu(ldinfo->dqi_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) oinfo->dqi_chunks = le32_to_cpu(ldinfo->dqi_chunks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) oinfo->dqi_blocks = le32_to_cpu(ldinfo->dqi_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) oinfo->dqi_libh = bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /* We crashed when using local quota file? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (!(oinfo->dqi_flags & OLQF_CLEAN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) rec = OCFS2_SB(sb)->quota_rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (!rec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) rec = ocfs2_alloc_quota_recovery();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (!rec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) OCFS2_SB(sb)->quota_rec = rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) status = ocfs2_recovery_load_quota(lqinode, ldinfo, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) &rec->r_list[type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) status = ocfs2_load_local_quota_bitmaps(lqinode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) ldinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) &oinfo->dqi_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /* Now mark quota file as used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) oinfo->dqi_flags &= ~OLQF_CLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) status = ocfs2_modify_bh(lqinode, bh, olq_update_info, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (oinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) iput(oinfo->dqi_gqinode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) ocfs2_simple_drop_lockres(OCFS2_SB(sb), &oinfo->dqi_gqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) ocfs2_lock_res_free(&oinfo->dqi_gqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) brelse(oinfo->dqi_lqi_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) ocfs2_inode_unlock(lqinode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) ocfs2_release_local_quota_bitmaps(&oinfo->dqi_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) kfree(oinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* Write local info to quota file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) static int ocfs2_local_write_info(struct super_block *sb, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) struct mem_dqinfo *info = sb_dqinfo(sb, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) struct buffer_head *bh = ((struct ocfs2_mem_dqinfo *)info->dqi_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) ->dqi_libh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) status = ocfs2_modify_bh(sb_dqopt(sb)->files[type], bh, olq_update_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) /* Release info from memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) static int ocfs2_local_free_info(struct super_block *sb, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct mem_dqinfo *info = sb_dqinfo(sb, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) struct ocfs2_quota_chunk *chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) struct ocfs2_local_disk_chunk *dchunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) int mark_clean = 1, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) iput(oinfo->dqi_gqinode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) ocfs2_simple_drop_lockres(OCFS2_SB(sb), &oinfo->dqi_gqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ocfs2_lock_res_free(&oinfo->dqi_gqlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) list_for_each_entry(chunk, &oinfo->dqi_chunk, qc_chunk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) dchunk = (struct ocfs2_local_disk_chunk *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) (chunk->qc_headerbh->b_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (chunk->qc_num < oinfo->dqi_chunks - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) len = ol_chunk_entries(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) len = (oinfo->dqi_blocks -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) ol_quota_chunk_block(sb, chunk->qc_num) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) * ol_quota_entries_per_block(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /* Not all entries free? Bug! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (le32_to_cpu(dchunk->dqc_free) != len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) mlog(ML_ERROR, "releasing quota file with used "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) "entries (type=%d)\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) mark_clean = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ocfs2_release_local_quota_bitmaps(&oinfo->dqi_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * s_umount held in exclusive mode protects us against racing with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * recovery thread...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (oinfo->dqi_rec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) ocfs2_free_quota_recovery(oinfo->dqi_rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) mark_clean = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (!mark_clean)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /* Mark local file as clean */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) oinfo->dqi_flags |= OLQF_CLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) status = ocfs2_modify_bh(sb_dqopt(sb)->files[type],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) oinfo->dqi_libh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) olq_update_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) ocfs2_inode_unlock(sb_dqopt(sb)->files[type], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) brelse(oinfo->dqi_libh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) brelse(oinfo->dqi_lqi_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) kfree(oinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) static void olq_set_dquot(struct buffer_head *bh, void *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) struct ocfs2_dquot *od = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) struct ocfs2_local_disk_dqblk *dqblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) struct super_block *sb = od->dq_dquot.dq_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) dqblk = (struct ocfs2_local_disk_dqblk *)(bh->b_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) + ol_dqblk_block_offset(sb, od->dq_local_off));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) dqblk->dqb_id = cpu_to_le64(from_kqid(&init_user_ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) od->dq_dquot.dq_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) spin_lock(&od->dq_dquot.dq_dqb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) dqblk->dqb_spacemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curspace -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) od->dq_origspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) dqblk->dqb_inodemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curinodes -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) od->dq_originodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) spin_unlock(&od->dq_dquot.dq_dqb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) trace_olq_set_dquot(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) (unsigned long long)le64_to_cpu(dqblk->dqb_spacemod),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) (unsigned long long)le64_to_cpu(dqblk->dqb_inodemod),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) from_kqid(&init_user_ns, od->dq_dquot.dq_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) /* Write dquot to local quota file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) int ocfs2_local_write_dquot(struct dquot *dquot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) struct super_block *sb = dquot->dq_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct inode *lqinode = sb_dqopt(sb)->files[dquot->dq_id.type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) status = ocfs2_read_quota_phys_block(lqinode, od->dq_local_phys_blk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) &bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) status = ocfs2_modify_bh(lqinode, bh, olq_set_dquot, od);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) /* Find free entry in local quota file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) static struct ocfs2_quota_chunk *ocfs2_find_free_entry(struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) int type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) int *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct mem_dqinfo *info = sb_dqinfo(sb, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) struct ocfs2_quota_chunk *chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) struct ocfs2_local_disk_chunk *dchunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) int found = 0, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) list_for_each_entry(chunk, &oinfo->dqi_chunk, qc_chunk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) dchunk = (struct ocfs2_local_disk_chunk *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) chunk->qc_headerbh->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (le32_to_cpu(dchunk->dqc_free) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (chunk->qc_num < oinfo->dqi_chunks - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) len = ol_chunk_entries(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) len = (oinfo->dqi_blocks -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) ol_quota_chunk_block(sb, chunk->qc_num) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * ol_quota_entries_per_block(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) found = ocfs2_find_next_zero_bit_unaligned(dchunk->dqc_bitmap, len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) /* We failed? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (found == len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) mlog(ML_ERROR, "Did not find empty entry in chunk %d with %u"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) " entries free (type=%d)\n", chunk->qc_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) le32_to_cpu(dchunk->dqc_free), type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) *offset = found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) /* Add new chunk to the local quota file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) int type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) int *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) struct mem_dqinfo *info = sb_dqinfo(sb, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) struct inode *lqinode = sb_dqopt(sb)->files[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) struct ocfs2_quota_chunk *chunk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct ocfs2_local_disk_chunk *dchunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) handle_t *handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) struct buffer_head *bh = NULL, *dbh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) u64 p_blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) /* We are protected by dqio_sem so no locking needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) status = ocfs2_extend_no_holes(lqinode, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) i_size_read(lqinode) + 2 * sb->s_blocksize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) i_size_read(lqinode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) status = ocfs2_simple_size_update(lqinode, oinfo->dqi_lqi_bh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) i_size_read(lqinode) + 2 * sb->s_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) chunk = kmem_cache_alloc(ocfs2_qf_chunk_cachep, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (!chunk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) /* Local quota info and two new blocks we initialize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) handle = ocfs2_start_trans(OCFS2_SB(sb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) OCFS2_LOCAL_QINFO_WRITE_CREDITS +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) 2 * OCFS2_QUOTA_BLOCK_UPDATE_CREDITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (IS_ERR(handle)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) status = PTR_ERR(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) /* Initialize chunk header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) &p_blkno, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) goto out_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) bh = sb_getblk(sb, p_blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (!bh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) goto out_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) dchunk = (struct ocfs2_local_disk_chunk *)bh->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) ocfs2_set_new_buffer_uptodate(INODE_CACHE(lqinode), bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode), bh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) OCFS2_JOURNAL_ACCESS_CREATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) goto out_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) lock_buffer(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) dchunk->dqc_free = cpu_to_le32(ol_quota_entries_per_block(sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) memset(dchunk->dqc_bitmap, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) sb->s_blocksize - sizeof(struct ocfs2_local_disk_chunk) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) OCFS2_QBLK_RESERVED_SPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) unlock_buffer(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) ocfs2_journal_dirty(handle, bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /* Initialize new block with structures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) &p_blkno, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) goto out_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) dbh = sb_getblk(sb, p_blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (!dbh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) goto out_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) ocfs2_set_new_buffer_uptodate(INODE_CACHE(lqinode), dbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode), dbh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) OCFS2_JOURNAL_ACCESS_CREATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) goto out_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) lock_buffer(dbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) memset(dbh->b_data, 0, sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) unlock_buffer(dbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) ocfs2_journal_dirty(handle, dbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /* Update local quotafile info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) oinfo->dqi_blocks += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) oinfo->dqi_chunks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) status = ocfs2_local_write_info(sb, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) goto out_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) status = ocfs2_commit_trans(OCFS2_SB(sb), handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) list_add_tail(&chunk->qc_chunk, &oinfo->dqi_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) chunk->qc_num = list_entry(chunk->qc_chunk.prev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct ocfs2_quota_chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) qc_chunk)->qc_num + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) chunk->qc_headerbh = bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) *offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) return chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) out_trans:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) ocfs2_commit_trans(OCFS2_SB(sb), handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) brelse(dbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) kmem_cache_free(ocfs2_qf_chunk_cachep, chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) return ERR_PTR(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /* Find free entry in local quota file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) static struct ocfs2_quota_chunk *ocfs2_extend_local_quota_file(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) int type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) int *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) struct mem_dqinfo *info = sb_dqinfo(sb, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) struct ocfs2_quota_chunk *chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) struct inode *lqinode = sb_dqopt(sb)->files[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) struct ocfs2_local_disk_chunk *dchunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) int epb = ol_quota_entries_per_block(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) unsigned int chunk_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) u64 p_blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) handle_t *handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (list_empty(&oinfo->dqi_chunk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) return ocfs2_local_quota_add_chunk(sb, type, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) /* Is the last chunk full? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) chunk = list_entry(oinfo->dqi_chunk.prev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) struct ocfs2_quota_chunk, qc_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) chunk_blocks = oinfo->dqi_blocks -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) ol_quota_chunk_block(sb, chunk->qc_num) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (ol_chunk_blocks(sb) == chunk_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) return ocfs2_local_quota_add_chunk(sb, type, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) /* We are protected by dqio_sem so no locking needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) status = ocfs2_extend_no_holes(lqinode, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) i_size_read(lqinode) + sb->s_blocksize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) i_size_read(lqinode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) status = ocfs2_simple_size_update(lqinode, oinfo->dqi_lqi_bh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) i_size_read(lqinode) + sb->s_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) /* Get buffer from the just added block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) &p_blkno, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) bh = sb_getblk(sb, p_blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (!bh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) ocfs2_set_new_buffer_uptodate(INODE_CACHE(lqinode), bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) /* Local quota info, chunk header and the new block we initialize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) handle = ocfs2_start_trans(OCFS2_SB(sb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) OCFS2_LOCAL_QINFO_WRITE_CREDITS +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 2 * OCFS2_QUOTA_BLOCK_UPDATE_CREDITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (IS_ERR(handle)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) status = PTR_ERR(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) /* Zero created block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode), bh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) OCFS2_JOURNAL_ACCESS_CREATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) goto out_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) lock_buffer(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) memset(bh->b_data, 0, sb->s_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) unlock_buffer(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) ocfs2_journal_dirty(handle, bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) /* Update chunk header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) chunk->qc_headerbh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) OCFS2_JOURNAL_ACCESS_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) goto out_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) dchunk = (struct ocfs2_local_disk_chunk *)chunk->qc_headerbh->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) lock_buffer(chunk->qc_headerbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) le32_add_cpu(&dchunk->dqc_free, ol_quota_entries_per_block(sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) unlock_buffer(chunk->qc_headerbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) ocfs2_journal_dirty(handle, chunk->qc_headerbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) /* Update file header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) oinfo->dqi_blocks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) status = ocfs2_local_write_info(sb, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) goto out_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) status = ocfs2_commit_trans(OCFS2_SB(sb), handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) *offset = chunk_blocks * epb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) return chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) out_trans:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) ocfs2_commit_trans(OCFS2_SB(sb), handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) return ERR_PTR(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) static void olq_alloc_dquot(struct buffer_head *bh, void *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) int *offset = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) struct ocfs2_local_disk_chunk *dchunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) dchunk = (struct ocfs2_local_disk_chunk *)bh->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) ocfs2_set_bit_unaligned(*offset, dchunk->dqc_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) le32_add_cpu(&dchunk->dqc_free, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) /* Create dquot in the local file for given id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) int ocfs2_create_local_dquot(struct dquot *dquot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) struct super_block *sb = dquot->dq_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) int type = dquot->dq_id.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) struct inode *lqinode = sb_dqopt(sb)->files[type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) struct ocfs2_quota_chunk *chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) u64 pcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) down_write(&OCFS2_I(lqinode)->ip_alloc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) chunk = ocfs2_find_free_entry(sb, type, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (!chunk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) chunk = ocfs2_extend_local_quota_file(sb, type, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (IS_ERR(chunk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) status = PTR_ERR(chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) } else if (IS_ERR(chunk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) status = PTR_ERR(chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) od->dq_local_off = ol_dqblk_off(sb, chunk->qc_num, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) od->dq_chunk = chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) status = ocfs2_extent_map_get_blocks(lqinode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) ol_dqblk_block(sb, chunk->qc_num, offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) &od->dq_local_phys_blk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) &pcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) /* Initialize dquot structure on disk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) status = ocfs2_local_write_dquot(dquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) /* Mark structure as allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) status = ocfs2_modify_bh(lqinode, chunk->qc_headerbh, olq_alloc_dquot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) up_write(&OCFS2_I(lqinode)->ip_alloc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) * Release dquot structure from local quota file. ocfs2_release_dquot() has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) * already started a transaction and written all changes to global quota file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) int ocfs2_local_release_dquot(handle_t *handle, struct dquot *dquot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) int type = dquot->dq_id.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) struct super_block *sb = dquot->dq_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) struct ocfs2_local_disk_chunk *dchunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) status = ocfs2_journal_access_dq(handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) INODE_CACHE(sb_dqopt(sb)->files[type]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) od->dq_chunk->qc_headerbh, OCFS2_JOURNAL_ACCESS_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) mlog_errno(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) offset = ol_dqblk_chunk_off(sb, od->dq_chunk->qc_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) od->dq_local_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) dchunk = (struct ocfs2_local_disk_chunk *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) (od->dq_chunk->qc_headerbh->b_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) /* Mark structure as freed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) lock_buffer(od->dq_chunk->qc_headerbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) ocfs2_clear_bit_unaligned(offset, dchunk->dqc_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) le32_add_cpu(&dchunk->dqc_free, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) unlock_buffer(od->dq_chunk->qc_headerbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) ocfs2_journal_dirty(handle, od->dq_chunk->qc_headerbh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) static const struct quota_format_ops ocfs2_format_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) .check_quota_file = ocfs2_local_check_quota_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) .read_file_info = ocfs2_local_read_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) .write_file_info = ocfs2_global_write_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) .free_file_info = ocfs2_local_free_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) struct quota_format_type ocfs2_quota_format = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) .qf_fmt_id = QFMT_OCFS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) .qf_ops = &ocfs2_format_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) .qf_owner = THIS_MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) };