0001
0002
0003
0004
0005
0006 #include <linux/fs.h>
0007 #include <linux/slab.h>
0008 #include <linux/quota.h>
0009 #include <linux/quotaops.h>
0010 #include <linux/module.h>
0011
0012 #include <cluster/masklog.h>
0013
0014 #include "ocfs2_fs.h"
0015 #include "ocfs2.h"
0016 #include "inode.h"
0017 #include "alloc.h"
0018 #include "file.h"
0019 #include "buffer_head_io.h"
0020 #include "journal.h"
0021 #include "sysfile.h"
0022 #include "dlmglue.h"
0023 #include "quota.h"
0024 #include "uptodate.h"
0025 #include "super.h"
0026 #include "ocfs2_trace.h"
0027
0028
0029 static inline unsigned int ol_quota_entries_per_block(struct super_block *sb)
0030 {
0031 return ((sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE) /
0032 sizeof(struct ocfs2_local_disk_dqblk));
0033 }
0034
0035
0036 static inline unsigned int ol_chunk_blocks(struct super_block *sb)
0037 {
0038 return ((sb->s_blocksize - sizeof(struct ocfs2_local_disk_chunk) -
0039 OCFS2_QBLK_RESERVED_SPACE) << 3) /
0040 ol_quota_entries_per_block(sb);
0041 }
0042
0043
0044 static unsigned int ol_chunk_entries(struct super_block *sb)
0045 {
0046 return ol_chunk_blocks(sb) * ol_quota_entries_per_block(sb);
0047 }
0048
0049
0050 static unsigned int ol_quota_chunk_block(struct super_block *sb, int c)
0051 {
0052
0053 return 1 + (ol_chunk_blocks(sb) + 1) * c;
0054 }
0055
0056 static unsigned int ol_dqblk_block(struct super_block *sb, int c, int off)
0057 {
0058 int epb = ol_quota_entries_per_block(sb);
0059
0060 return ol_quota_chunk_block(sb, c) + 1 + off / epb;
0061 }
0062
0063 static unsigned int ol_dqblk_block_off(struct super_block *sb, int c, int off)
0064 {
0065 int epb = ol_quota_entries_per_block(sb);
0066
0067 return (off % epb) * sizeof(struct ocfs2_local_disk_dqblk);
0068 }
0069
0070
0071 static loff_t ol_dqblk_off(struct super_block *sb, int c, int off)
0072 {
0073 return (ol_dqblk_block(sb, c, off) << sb->s_blocksize_bits) +
0074 ol_dqblk_block_off(sb, c, off);
0075 }
0076
0077 static inline unsigned int ol_dqblk_block_offset(struct super_block *sb, loff_t off)
0078 {
0079 return off & ((1 << sb->s_blocksize_bits) - 1);
0080 }
0081
0082
0083 static int ol_dqblk_chunk_off(struct super_block *sb, int c, loff_t off)
0084 {
0085 int epb = ol_quota_entries_per_block(sb);
0086
0087 return ((off >> sb->s_blocksize_bits) -
0088 ol_quota_chunk_block(sb, c) - 1) * epb
0089 + ((unsigned int)(off & ((1 << sb->s_blocksize_bits) - 1))) /
0090 sizeof(struct ocfs2_local_disk_dqblk);
0091 }
0092
0093
0094 static int ocfs2_modify_bh(struct inode *inode, struct buffer_head *bh,
0095 void (*modify)(struct buffer_head *, void *), void *private)
0096 {
0097 struct super_block *sb = inode->i_sb;
0098 handle_t *handle;
0099 int status;
0100
0101 handle = ocfs2_start_trans(OCFS2_SB(sb),
0102 OCFS2_QUOTA_BLOCK_UPDATE_CREDITS);
0103 if (IS_ERR(handle)) {
0104 status = PTR_ERR(handle);
0105 mlog_errno(status);
0106 return status;
0107 }
0108 status = ocfs2_journal_access_dq(handle, INODE_CACHE(inode), bh,
0109 OCFS2_JOURNAL_ACCESS_WRITE);
0110 if (status < 0) {
0111 mlog_errno(status);
0112 ocfs2_commit_trans(OCFS2_SB(sb), handle);
0113 return status;
0114 }
0115 lock_buffer(bh);
0116 modify(bh, private);
0117 unlock_buffer(bh);
0118 ocfs2_journal_dirty(handle, bh);
0119
0120 status = ocfs2_commit_trans(OCFS2_SB(sb), handle);
0121 if (status < 0) {
0122 mlog_errno(status);
0123 return status;
0124 }
0125 return 0;
0126 }
0127
0128
0129
0130
0131
0132
0133
0134 static int ocfs2_read_quota_block(struct inode *inode, u64 v_block,
0135 struct buffer_head **bh)
0136 {
0137 int rc = 0;
0138 struct buffer_head *tmp = *bh;
0139
0140 if (i_size_read(inode) >> inode->i_sb->s_blocksize_bits <= v_block)
0141 return ocfs2_error(inode->i_sb,
0142 "Quota file %llu is probably corrupted! Requested to read block %Lu but file has size only %Lu\n",
0143 (unsigned long long)OCFS2_I(inode)->ip_blkno,
0144 (unsigned long long)v_block,
0145 (unsigned long long)i_size_read(inode));
0146
0147 rc = ocfs2_read_virt_blocks(inode, v_block, 1, &tmp, 0,
0148 ocfs2_validate_quota_block);
0149 if (rc)
0150 mlog_errno(rc);
0151
0152
0153 if (!rc && !*bh)
0154 *bh = tmp;
0155
0156 return rc;
0157 }
0158
0159
0160 static int ocfs2_local_check_quota_file(struct super_block *sb, int type)
0161 {
0162 unsigned int lmagics[OCFS2_MAXQUOTAS] = OCFS2_LOCAL_QMAGICS;
0163 unsigned int lversions[OCFS2_MAXQUOTAS] = OCFS2_LOCAL_QVERSIONS;
0164 unsigned int gmagics[OCFS2_MAXQUOTAS] = OCFS2_GLOBAL_QMAGICS;
0165 unsigned int gversions[OCFS2_MAXQUOTAS] = OCFS2_GLOBAL_QVERSIONS;
0166 unsigned int ino[OCFS2_MAXQUOTAS] = { USER_QUOTA_SYSTEM_INODE,
0167 GROUP_QUOTA_SYSTEM_INODE };
0168 struct buffer_head *bh = NULL;
0169 struct inode *linode = sb_dqopt(sb)->files[type];
0170 struct inode *ginode = NULL;
0171 struct ocfs2_disk_dqheader *dqhead;
0172 int status, ret = 0;
0173
0174
0175 status = ocfs2_read_quota_block(linode, 0, &bh);
0176 if (status) {
0177 mlog_errno(status);
0178 mlog(ML_ERROR, "failed to read quota file header (type=%d)\n",
0179 type);
0180 goto out_err;
0181 }
0182 dqhead = (struct ocfs2_disk_dqheader *)(bh->b_data);
0183 if (le32_to_cpu(dqhead->dqh_magic) != lmagics[type]) {
0184 mlog(ML_ERROR, "quota file magic does not match (%u != %u),"
0185 " type=%d\n", le32_to_cpu(dqhead->dqh_magic),
0186 lmagics[type], type);
0187 goto out_err;
0188 }
0189 if (le32_to_cpu(dqhead->dqh_version) != lversions[type]) {
0190 mlog(ML_ERROR, "quota file version does not match (%u != %u),"
0191 " type=%d\n", le32_to_cpu(dqhead->dqh_version),
0192 lversions[type], type);
0193 goto out_err;
0194 }
0195 brelse(bh);
0196 bh = NULL;
0197
0198
0199 ginode = ocfs2_get_system_file_inode(OCFS2_SB(sb), ino[type],
0200 OCFS2_INVALID_SLOT);
0201 if (!ginode) {
0202 mlog(ML_ERROR, "cannot get global quota file inode "
0203 "(type=%d)\n", type);
0204 goto out_err;
0205 }
0206
0207 status = ocfs2_read_quota_block(ginode, 0, &bh);
0208 if (status) {
0209 mlog_errno(status);
0210 mlog(ML_ERROR, "failed to read global quota file header "
0211 "(type=%d)\n", type);
0212 goto out_err;
0213 }
0214 dqhead = (struct ocfs2_disk_dqheader *)(bh->b_data);
0215 if (le32_to_cpu(dqhead->dqh_magic) != gmagics[type]) {
0216 mlog(ML_ERROR, "global quota file magic does not match "
0217 "(%u != %u), type=%d\n",
0218 le32_to_cpu(dqhead->dqh_magic), gmagics[type], type);
0219 goto out_err;
0220 }
0221 if (le32_to_cpu(dqhead->dqh_version) != gversions[type]) {
0222 mlog(ML_ERROR, "global quota file version does not match "
0223 "(%u != %u), type=%d\n",
0224 le32_to_cpu(dqhead->dqh_version), gversions[type],
0225 type);
0226 goto out_err;
0227 }
0228
0229 ret = 1;
0230 out_err:
0231 brelse(bh);
0232 iput(ginode);
0233 return ret;
0234 }
0235
0236
0237 static void ocfs2_release_local_quota_bitmaps(struct list_head *head)
0238 {
0239 struct ocfs2_quota_chunk *pos, *next;
0240
0241 list_for_each_entry_safe(pos, next, head, qc_chunk) {
0242 list_del(&pos->qc_chunk);
0243 brelse(pos->qc_headerbh);
0244 kmem_cache_free(ocfs2_qf_chunk_cachep, pos);
0245 }
0246 }
0247
0248
0249 static int ocfs2_load_local_quota_bitmaps(struct inode *inode,
0250 struct ocfs2_local_disk_dqinfo *ldinfo,
0251 struct list_head *head)
0252 {
0253 struct ocfs2_quota_chunk *newchunk;
0254 int i, status;
0255
0256 INIT_LIST_HEAD(head);
0257 for (i = 0; i < le32_to_cpu(ldinfo->dqi_chunks); i++) {
0258 newchunk = kmem_cache_alloc(ocfs2_qf_chunk_cachep, GFP_NOFS);
0259 if (!newchunk) {
0260 ocfs2_release_local_quota_bitmaps(head);
0261 return -ENOMEM;
0262 }
0263 newchunk->qc_num = i;
0264 newchunk->qc_headerbh = NULL;
0265 status = ocfs2_read_quota_block(inode,
0266 ol_quota_chunk_block(inode->i_sb, i),
0267 &newchunk->qc_headerbh);
0268 if (status) {
0269 mlog_errno(status);
0270 kmem_cache_free(ocfs2_qf_chunk_cachep, newchunk);
0271 ocfs2_release_local_quota_bitmaps(head);
0272 return status;
0273 }
0274 list_add_tail(&newchunk->qc_chunk, head);
0275 }
0276 return 0;
0277 }
0278
0279 static void olq_update_info(struct buffer_head *bh, void *private)
0280 {
0281 struct mem_dqinfo *info = private;
0282 struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
0283 struct ocfs2_local_disk_dqinfo *ldinfo;
0284
0285 ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
0286 OCFS2_LOCAL_INFO_OFF);
0287 spin_lock(&dq_data_lock);
0288 ldinfo->dqi_flags = cpu_to_le32(oinfo->dqi_flags);
0289 ldinfo->dqi_chunks = cpu_to_le32(oinfo->dqi_chunks);
0290 ldinfo->dqi_blocks = cpu_to_le32(oinfo->dqi_blocks);
0291 spin_unlock(&dq_data_lock);
0292 }
0293
0294 static int ocfs2_add_recovery_chunk(struct super_block *sb,
0295 struct ocfs2_local_disk_chunk *dchunk,
0296 int chunk,
0297 struct list_head *head)
0298 {
0299 struct ocfs2_recovery_chunk *rc;
0300
0301 rc = kmalloc(sizeof(struct ocfs2_recovery_chunk), GFP_NOFS);
0302 if (!rc)
0303 return -ENOMEM;
0304 rc->rc_chunk = chunk;
0305 rc->rc_bitmap = kmalloc(sb->s_blocksize, GFP_NOFS);
0306 if (!rc->rc_bitmap) {
0307 kfree(rc);
0308 return -ENOMEM;
0309 }
0310 memcpy(rc->rc_bitmap, dchunk->dqc_bitmap,
0311 (ol_chunk_entries(sb) + 7) >> 3);
0312 list_add_tail(&rc->rc_list, head);
0313 return 0;
0314 }
0315
0316 static void free_recovery_list(struct list_head *head)
0317 {
0318 struct ocfs2_recovery_chunk *next;
0319 struct ocfs2_recovery_chunk *rchunk;
0320
0321 list_for_each_entry_safe(rchunk, next, head, rc_list) {
0322 list_del(&rchunk->rc_list);
0323 kfree(rchunk->rc_bitmap);
0324 kfree(rchunk);
0325 }
0326 }
0327
0328 void ocfs2_free_quota_recovery(struct ocfs2_quota_recovery *rec)
0329 {
0330 int type;
0331
0332 for (type = 0; type < OCFS2_MAXQUOTAS; type++)
0333 free_recovery_list(&(rec->r_list[type]));
0334 kfree(rec);
0335 }
0336
0337
0338 static int ocfs2_recovery_load_quota(struct inode *lqinode,
0339 struct ocfs2_local_disk_dqinfo *ldinfo,
0340 int type,
0341 struct list_head *head)
0342 {
0343 struct super_block *sb = lqinode->i_sb;
0344 struct buffer_head *hbh;
0345 struct ocfs2_local_disk_chunk *dchunk;
0346 int i, chunks = le32_to_cpu(ldinfo->dqi_chunks);
0347 int status = 0;
0348
0349 for (i = 0; i < chunks; i++) {
0350 hbh = NULL;
0351 status = ocfs2_read_quota_block(lqinode,
0352 ol_quota_chunk_block(sb, i),
0353 &hbh);
0354 if (status) {
0355 mlog_errno(status);
0356 break;
0357 }
0358 dchunk = (struct ocfs2_local_disk_chunk *)hbh->b_data;
0359 if (le32_to_cpu(dchunk->dqc_free) < ol_chunk_entries(sb))
0360 status = ocfs2_add_recovery_chunk(sb, dchunk, i, head);
0361 brelse(hbh);
0362 if (status < 0)
0363 break;
0364 }
0365 if (status < 0)
0366 free_recovery_list(head);
0367 return status;
0368 }
0369
0370 static struct ocfs2_quota_recovery *ocfs2_alloc_quota_recovery(void)
0371 {
0372 int type;
0373 struct ocfs2_quota_recovery *rec;
0374
0375 rec = kmalloc(sizeof(struct ocfs2_quota_recovery), GFP_NOFS);
0376 if (!rec)
0377 return NULL;
0378 for (type = 0; type < OCFS2_MAXQUOTAS; type++)
0379 INIT_LIST_HEAD(&(rec->r_list[type]));
0380 return rec;
0381 }
0382
0383
0384 struct ocfs2_quota_recovery *ocfs2_begin_quota_recovery(
0385 struct ocfs2_super *osb,
0386 int slot_num)
0387 {
0388 unsigned int feature[OCFS2_MAXQUOTAS] = {
0389 OCFS2_FEATURE_RO_COMPAT_USRQUOTA,
0390 OCFS2_FEATURE_RO_COMPAT_GRPQUOTA};
0391 unsigned int ino[OCFS2_MAXQUOTAS] = { LOCAL_USER_QUOTA_SYSTEM_INODE,
0392 LOCAL_GROUP_QUOTA_SYSTEM_INODE };
0393 struct super_block *sb = osb->sb;
0394 struct ocfs2_local_disk_dqinfo *ldinfo;
0395 struct inode *lqinode;
0396 struct buffer_head *bh;
0397 int type;
0398 int status = 0;
0399 struct ocfs2_quota_recovery *rec;
0400
0401 printk(KERN_NOTICE "ocfs2: Beginning quota recovery on device (%s) for "
0402 "slot %u\n", osb->dev_str, slot_num);
0403
0404 rec = ocfs2_alloc_quota_recovery();
0405 if (!rec)
0406 return ERR_PTR(-ENOMEM);
0407
0408
0409 for (type = 0; type < OCFS2_MAXQUOTAS; type++) {
0410 if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, feature[type]))
0411 continue;
0412
0413
0414 lqinode = ocfs2_get_system_file_inode(osb, ino[type], slot_num);
0415 if (!lqinode) {
0416 status = -ENOENT;
0417 goto out;
0418 }
0419 status = ocfs2_inode_lock_full(lqinode, NULL, 1,
0420 OCFS2_META_LOCK_RECOVERY);
0421 if (status < 0) {
0422 mlog_errno(status);
0423 goto out_put;
0424 }
0425
0426 bh = NULL;
0427 status = ocfs2_read_quota_block(lqinode, 0, &bh);
0428 if (status) {
0429 mlog_errno(status);
0430 mlog(ML_ERROR, "failed to read quota file info header "
0431 "(slot=%d type=%d)\n", slot_num, type);
0432 goto out_lock;
0433 }
0434 ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
0435 OCFS2_LOCAL_INFO_OFF);
0436 status = ocfs2_recovery_load_quota(lqinode, ldinfo, type,
0437 &rec->r_list[type]);
0438 brelse(bh);
0439 out_lock:
0440 ocfs2_inode_unlock(lqinode, 1);
0441 out_put:
0442 iput(lqinode);
0443 if (status < 0)
0444 break;
0445 }
0446 out:
0447 if (status < 0) {
0448 ocfs2_free_quota_recovery(rec);
0449 rec = ERR_PTR(status);
0450 }
0451 return rec;
0452 }
0453
0454
0455
0456
0457
0458 static int ocfs2_recover_local_quota_file(struct inode *lqinode,
0459 int type,
0460 struct ocfs2_quota_recovery *rec)
0461 {
0462 struct super_block *sb = lqinode->i_sb;
0463 struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
0464 struct ocfs2_local_disk_chunk *dchunk;
0465 struct ocfs2_local_disk_dqblk *dqblk;
0466 struct dquot *dquot;
0467 handle_t *handle;
0468 struct buffer_head *hbh = NULL, *qbh = NULL;
0469 int status = 0;
0470 int bit, chunk;
0471 struct ocfs2_recovery_chunk *rchunk, *next;
0472 qsize_t spacechange, inodechange;
0473
0474 trace_ocfs2_recover_local_quota_file((unsigned long)lqinode->i_ino, type);
0475
0476 list_for_each_entry_safe(rchunk, next, &(rec->r_list[type]), rc_list) {
0477 chunk = rchunk->rc_chunk;
0478 hbh = NULL;
0479 status = ocfs2_read_quota_block(lqinode,
0480 ol_quota_chunk_block(sb, chunk),
0481 &hbh);
0482 if (status) {
0483 mlog_errno(status);
0484 break;
0485 }
0486 dchunk = (struct ocfs2_local_disk_chunk *)hbh->b_data;
0487 for_each_set_bit(bit, rchunk->rc_bitmap, ol_chunk_entries(sb)) {
0488 qbh = NULL;
0489 status = ocfs2_read_quota_block(lqinode,
0490 ol_dqblk_block(sb, chunk, bit),
0491 &qbh);
0492 if (status) {
0493 mlog_errno(status);
0494 break;
0495 }
0496 dqblk = (struct ocfs2_local_disk_dqblk *)(qbh->b_data +
0497 ol_dqblk_block_off(sb, chunk, bit));
0498 dquot = dqget(sb,
0499 make_kqid(&init_user_ns, type,
0500 le64_to_cpu(dqblk->dqb_id)));
0501 if (IS_ERR(dquot)) {
0502 status = PTR_ERR(dquot);
0503 mlog(ML_ERROR, "Failed to get quota structure "
0504 "for id %u, type %d. Cannot finish quota "
0505 "file recovery.\n",
0506 (unsigned)le64_to_cpu(dqblk->dqb_id),
0507 type);
0508 goto out_put_bh;
0509 }
0510 status = ocfs2_lock_global_qf(oinfo, 1);
0511 if (status < 0) {
0512 mlog_errno(status);
0513 goto out_put_dquot;
0514 }
0515
0516 handle = ocfs2_start_trans(OCFS2_SB(sb),
0517 OCFS2_QSYNC_CREDITS);
0518 if (IS_ERR(handle)) {
0519 status = PTR_ERR(handle);
0520 mlog_errno(status);
0521 goto out_drop_lock;
0522 }
0523 down_write(&sb_dqopt(sb)->dqio_sem);
0524 spin_lock(&dquot->dq_dqb_lock);
0525
0526
0527
0528 spacechange = le64_to_cpu(dqblk->dqb_spacemod);
0529 inodechange = le64_to_cpu(dqblk->dqb_inodemod);
0530 dquot->dq_dqb.dqb_curspace += spacechange;
0531 dquot->dq_dqb.dqb_curinodes += inodechange;
0532 spin_unlock(&dquot->dq_dqb_lock);
0533
0534
0535
0536 status = ocfs2_global_release_dquot(dquot);
0537 if (status < 0) {
0538 mlog_errno(status);
0539 goto out_commit;
0540 }
0541
0542 status = ocfs2_journal_access_dq(handle,
0543 INODE_CACHE(lqinode),
0544 qbh, OCFS2_JOURNAL_ACCESS_WRITE);
0545 if (status < 0) {
0546 mlog_errno(status);
0547 goto out_commit;
0548 }
0549 lock_buffer(qbh);
0550 WARN_ON(!ocfs2_test_bit_unaligned(bit, dchunk->dqc_bitmap));
0551 ocfs2_clear_bit_unaligned(bit, dchunk->dqc_bitmap);
0552 le32_add_cpu(&dchunk->dqc_free, 1);
0553 unlock_buffer(qbh);
0554 ocfs2_journal_dirty(handle, qbh);
0555 out_commit:
0556 up_write(&sb_dqopt(sb)->dqio_sem);
0557 ocfs2_commit_trans(OCFS2_SB(sb), handle);
0558 out_drop_lock:
0559 ocfs2_unlock_global_qf(oinfo, 1);
0560 out_put_dquot:
0561 dqput(dquot);
0562 out_put_bh:
0563 brelse(qbh);
0564 if (status < 0)
0565 break;
0566 }
0567 brelse(hbh);
0568 list_del(&rchunk->rc_list);
0569 kfree(rchunk->rc_bitmap);
0570 kfree(rchunk);
0571 if (status < 0)
0572 break;
0573 }
0574 if (status < 0)
0575 free_recovery_list(&(rec->r_list[type]));
0576 if (status)
0577 mlog_errno(status);
0578 return status;
0579 }
0580
0581
0582 int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
0583 struct ocfs2_quota_recovery *rec,
0584 int slot_num)
0585 {
0586 unsigned int ino[OCFS2_MAXQUOTAS] = { LOCAL_USER_QUOTA_SYSTEM_INODE,
0587 LOCAL_GROUP_QUOTA_SYSTEM_INODE };
0588 struct super_block *sb = osb->sb;
0589 struct ocfs2_local_disk_dqinfo *ldinfo;
0590 struct buffer_head *bh;
0591 handle_t *handle;
0592 int type;
0593 int status = 0;
0594 struct inode *lqinode;
0595 unsigned int flags;
0596
0597 printk(KERN_NOTICE "ocfs2: Finishing quota recovery on device (%s) for "
0598 "slot %u\n", osb->dev_str, slot_num);
0599
0600 down_read(&sb->s_umount);
0601 for (type = 0; type < OCFS2_MAXQUOTAS; type++) {
0602 if (list_empty(&(rec->r_list[type])))
0603 continue;
0604 trace_ocfs2_finish_quota_recovery(slot_num);
0605 lqinode = ocfs2_get_system_file_inode(osb, ino[type], slot_num);
0606 if (!lqinode) {
0607 status = -ENOENT;
0608 goto out;
0609 }
0610 status = ocfs2_inode_lock_full(lqinode, NULL, 1,
0611 OCFS2_META_LOCK_NOQUEUE);
0612
0613
0614 if (status == -EAGAIN) {
0615 printk(KERN_NOTICE "ocfs2: Skipping quota recovery on "
0616 "device (%s) for slot %d because quota file is "
0617 "locked.\n", osb->dev_str, slot_num);
0618 status = 0;
0619 goto out_put;
0620 } else if (status < 0) {
0621 mlog_errno(status);
0622 goto out_put;
0623 }
0624
0625 bh = NULL;
0626 status = ocfs2_read_quota_block(lqinode, 0, &bh);
0627 if (status) {
0628 mlog_errno(status);
0629 mlog(ML_ERROR, "failed to read quota file info header "
0630 "(slot=%d type=%d)\n", slot_num, type);
0631 goto out_lock;
0632 }
0633 ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
0634 OCFS2_LOCAL_INFO_OFF);
0635
0636 flags = le32_to_cpu(ldinfo->dqi_flags);
0637 if (!(flags & OLQF_CLEAN))
0638 status = ocfs2_recover_local_quota_file(lqinode,
0639 type,
0640 rec);
0641
0642
0643 if (slot_num == osb->slot_num)
0644 goto out_bh;
0645
0646
0647 handle = ocfs2_start_trans(osb,
0648 OCFS2_LOCAL_QINFO_WRITE_CREDITS);
0649 if (IS_ERR(handle)) {
0650 status = PTR_ERR(handle);
0651 mlog_errno(status);
0652 goto out_bh;
0653 }
0654 status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode),
0655 bh,
0656 OCFS2_JOURNAL_ACCESS_WRITE);
0657 if (status < 0) {
0658 mlog_errno(status);
0659 goto out_trans;
0660 }
0661 lock_buffer(bh);
0662 ldinfo->dqi_flags = cpu_to_le32(flags | OLQF_CLEAN);
0663 unlock_buffer(bh);
0664 ocfs2_journal_dirty(handle, bh);
0665 out_trans:
0666 ocfs2_commit_trans(osb, handle);
0667 out_bh:
0668 brelse(bh);
0669 out_lock:
0670 ocfs2_inode_unlock(lqinode, 1);
0671 out_put:
0672 iput(lqinode);
0673 if (status < 0)
0674 break;
0675 }
0676 out:
0677 up_read(&sb->s_umount);
0678 kfree(rec);
0679 return status;
0680 }
0681
0682
0683 static int ocfs2_local_read_info(struct super_block *sb, int type)
0684 {
0685 struct ocfs2_local_disk_dqinfo *ldinfo;
0686 struct mem_dqinfo *info = sb_dqinfo(sb, type);
0687 struct ocfs2_mem_dqinfo *oinfo;
0688 struct inode *lqinode = sb_dqopt(sb)->files[type];
0689 int status;
0690 struct buffer_head *bh = NULL;
0691 struct ocfs2_quota_recovery *rec;
0692 int locked = 0;
0693
0694 info->dqi_max_spc_limit = 0x7fffffffffffffffLL;
0695 info->dqi_max_ino_limit = 0x7fffffffffffffffLL;
0696 oinfo = kmalloc(sizeof(struct ocfs2_mem_dqinfo), GFP_NOFS);
0697 if (!oinfo) {
0698 mlog(ML_ERROR, "failed to allocate memory for ocfs2 quota"
0699 " info.");
0700 goto out_err;
0701 }
0702 info->dqi_priv = oinfo;
0703 oinfo->dqi_type = type;
0704 INIT_LIST_HEAD(&oinfo->dqi_chunk);
0705 oinfo->dqi_rec = NULL;
0706 oinfo->dqi_lqi_bh = NULL;
0707 oinfo->dqi_libh = NULL;
0708
0709 status = ocfs2_global_read_info(sb, type);
0710 if (status < 0)
0711 goto out_err;
0712
0713 status = ocfs2_inode_lock(lqinode, &oinfo->dqi_lqi_bh, 1);
0714 if (status < 0) {
0715 mlog_errno(status);
0716 goto out_err;
0717 }
0718 locked = 1;
0719
0720
0721 status = ocfs2_read_quota_block(lqinode, 0, &bh);
0722 if (status) {
0723 mlog_errno(status);
0724 mlog(ML_ERROR, "failed to read quota file info header "
0725 "(type=%d)\n", type);
0726 goto out_err;
0727 }
0728 ldinfo = (struct ocfs2_local_disk_dqinfo *)(bh->b_data +
0729 OCFS2_LOCAL_INFO_OFF);
0730 oinfo->dqi_flags = le32_to_cpu(ldinfo->dqi_flags);
0731 oinfo->dqi_chunks = le32_to_cpu(ldinfo->dqi_chunks);
0732 oinfo->dqi_blocks = le32_to_cpu(ldinfo->dqi_blocks);
0733 oinfo->dqi_libh = bh;
0734
0735
0736 if (!(oinfo->dqi_flags & OLQF_CLEAN)) {
0737 rec = OCFS2_SB(sb)->quota_rec;
0738 if (!rec) {
0739 rec = ocfs2_alloc_quota_recovery();
0740 if (!rec) {
0741 status = -ENOMEM;
0742 mlog_errno(status);
0743 goto out_err;
0744 }
0745 OCFS2_SB(sb)->quota_rec = rec;
0746 }
0747
0748 status = ocfs2_recovery_load_quota(lqinode, ldinfo, type,
0749 &rec->r_list[type]);
0750 if (status < 0) {
0751 mlog_errno(status);
0752 goto out_err;
0753 }
0754 }
0755
0756 status = ocfs2_load_local_quota_bitmaps(lqinode,
0757 ldinfo,
0758 &oinfo->dqi_chunk);
0759 if (status < 0) {
0760 mlog_errno(status);
0761 goto out_err;
0762 }
0763
0764
0765 oinfo->dqi_flags &= ~OLQF_CLEAN;
0766 status = ocfs2_modify_bh(lqinode, bh, olq_update_info, info);
0767 if (status < 0) {
0768 mlog_errno(status);
0769 goto out_err;
0770 }
0771
0772 return 0;
0773 out_err:
0774 if (oinfo) {
0775 iput(oinfo->dqi_gqinode);
0776 ocfs2_simple_drop_lockres(OCFS2_SB(sb), &oinfo->dqi_gqlock);
0777 ocfs2_lock_res_free(&oinfo->dqi_gqlock);
0778 brelse(oinfo->dqi_lqi_bh);
0779 if (locked)
0780 ocfs2_inode_unlock(lqinode, 1);
0781 ocfs2_release_local_quota_bitmaps(&oinfo->dqi_chunk);
0782 kfree(oinfo);
0783 }
0784 brelse(bh);
0785 return -1;
0786 }
0787
0788
0789 static int ocfs2_local_write_info(struct super_block *sb, int type)
0790 {
0791 struct mem_dqinfo *info = sb_dqinfo(sb, type);
0792 struct buffer_head *bh = ((struct ocfs2_mem_dqinfo *)info->dqi_priv)
0793 ->dqi_libh;
0794 int status;
0795
0796 status = ocfs2_modify_bh(sb_dqopt(sb)->files[type], bh, olq_update_info,
0797 info);
0798 if (status < 0) {
0799 mlog_errno(status);
0800 return -1;
0801 }
0802
0803 return 0;
0804 }
0805
0806
0807 static int ocfs2_local_free_info(struct super_block *sb, int type)
0808 {
0809 struct mem_dqinfo *info = sb_dqinfo(sb, type);
0810 struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
0811 struct ocfs2_quota_chunk *chunk;
0812 struct ocfs2_local_disk_chunk *dchunk;
0813 int mark_clean = 1, len;
0814 int status;
0815
0816 iput(oinfo->dqi_gqinode);
0817 ocfs2_simple_drop_lockres(OCFS2_SB(sb), &oinfo->dqi_gqlock);
0818 ocfs2_lock_res_free(&oinfo->dqi_gqlock);
0819 list_for_each_entry(chunk, &oinfo->dqi_chunk, qc_chunk) {
0820 dchunk = (struct ocfs2_local_disk_chunk *)
0821 (chunk->qc_headerbh->b_data);
0822 if (chunk->qc_num < oinfo->dqi_chunks - 1) {
0823 len = ol_chunk_entries(sb);
0824 } else {
0825 len = (oinfo->dqi_blocks -
0826 ol_quota_chunk_block(sb, chunk->qc_num) - 1)
0827 * ol_quota_entries_per_block(sb);
0828 }
0829
0830 if (le32_to_cpu(dchunk->dqc_free) != len) {
0831 mlog(ML_ERROR, "releasing quota file with used "
0832 "entries (type=%d)\n", type);
0833 mark_clean = 0;
0834 }
0835 }
0836 ocfs2_release_local_quota_bitmaps(&oinfo->dqi_chunk);
0837
0838
0839
0840
0841
0842 if (oinfo->dqi_rec) {
0843 ocfs2_free_quota_recovery(oinfo->dqi_rec);
0844 mark_clean = 0;
0845 }
0846
0847 if (!mark_clean)
0848 goto out;
0849
0850
0851 oinfo->dqi_flags |= OLQF_CLEAN;
0852 status = ocfs2_modify_bh(sb_dqopt(sb)->files[type],
0853 oinfo->dqi_libh,
0854 olq_update_info,
0855 info);
0856 if (status < 0) {
0857 mlog_errno(status);
0858 goto out;
0859 }
0860
0861 out:
0862 ocfs2_inode_unlock(sb_dqopt(sb)->files[type], 1);
0863 brelse(oinfo->dqi_libh);
0864 brelse(oinfo->dqi_lqi_bh);
0865 kfree(oinfo);
0866 return 0;
0867 }
0868
0869 static void olq_set_dquot(struct buffer_head *bh, void *private)
0870 {
0871 struct ocfs2_dquot *od = private;
0872 struct ocfs2_local_disk_dqblk *dqblk;
0873 struct super_block *sb = od->dq_dquot.dq_sb;
0874
0875 dqblk = (struct ocfs2_local_disk_dqblk *)(bh->b_data
0876 + ol_dqblk_block_offset(sb, od->dq_local_off));
0877
0878 dqblk->dqb_id = cpu_to_le64(from_kqid(&init_user_ns,
0879 od->dq_dquot.dq_id));
0880 spin_lock(&od->dq_dquot.dq_dqb_lock);
0881 dqblk->dqb_spacemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curspace -
0882 od->dq_origspace);
0883 dqblk->dqb_inodemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curinodes -
0884 od->dq_originodes);
0885 spin_unlock(&od->dq_dquot.dq_dqb_lock);
0886 trace_olq_set_dquot(
0887 (unsigned long long)le64_to_cpu(dqblk->dqb_spacemod),
0888 (unsigned long long)le64_to_cpu(dqblk->dqb_inodemod),
0889 from_kqid(&init_user_ns, od->dq_dquot.dq_id));
0890 }
0891
0892
0893 int ocfs2_local_write_dquot(struct dquot *dquot)
0894 {
0895 struct super_block *sb = dquot->dq_sb;
0896 struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
0897 struct buffer_head *bh;
0898 struct inode *lqinode = sb_dqopt(sb)->files[dquot->dq_id.type];
0899 int status;
0900
0901 status = ocfs2_read_quota_phys_block(lqinode, od->dq_local_phys_blk,
0902 &bh);
0903 if (status) {
0904 mlog_errno(status);
0905 goto out;
0906 }
0907 status = ocfs2_modify_bh(lqinode, bh, olq_set_dquot, od);
0908 if (status < 0) {
0909 mlog_errno(status);
0910 goto out;
0911 }
0912 out:
0913 brelse(bh);
0914 return status;
0915 }
0916
0917
0918 static struct ocfs2_quota_chunk *ocfs2_find_free_entry(struct super_block *sb,
0919 int type,
0920 int *offset)
0921 {
0922 struct mem_dqinfo *info = sb_dqinfo(sb, type);
0923 struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
0924 struct ocfs2_quota_chunk *chunk = NULL, *iter;
0925 struct ocfs2_local_disk_chunk *dchunk;
0926 int found = 0, len;
0927
0928 list_for_each_entry(iter, &oinfo->dqi_chunk, qc_chunk) {
0929 dchunk = (struct ocfs2_local_disk_chunk *)
0930 iter->qc_headerbh->b_data;
0931 if (le32_to_cpu(dchunk->dqc_free) > 0) {
0932 chunk = iter;
0933 break;
0934 }
0935 }
0936 if (!chunk)
0937 return NULL;
0938
0939 if (chunk->qc_num < oinfo->dqi_chunks - 1) {
0940 len = ol_chunk_entries(sb);
0941 } else {
0942 len = (oinfo->dqi_blocks -
0943 ol_quota_chunk_block(sb, chunk->qc_num) - 1)
0944 * ol_quota_entries_per_block(sb);
0945 }
0946
0947 found = ocfs2_find_next_zero_bit_unaligned(dchunk->dqc_bitmap, len, 0);
0948
0949 if (found == len) {
0950 mlog(ML_ERROR, "Did not find empty entry in chunk %d with %u"
0951 " entries free (type=%d)\n", chunk->qc_num,
0952 le32_to_cpu(dchunk->dqc_free), type);
0953 return ERR_PTR(-EIO);
0954 }
0955 *offset = found;
0956 return chunk;
0957 }
0958
0959
0960 static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk(
0961 struct super_block *sb,
0962 int type,
0963 int *offset)
0964 {
0965 struct mem_dqinfo *info = sb_dqinfo(sb, type);
0966 struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
0967 struct inode *lqinode = sb_dqopt(sb)->files[type];
0968 struct ocfs2_quota_chunk *chunk = NULL;
0969 struct ocfs2_local_disk_chunk *dchunk;
0970 int status;
0971 handle_t *handle;
0972 struct buffer_head *bh = NULL, *dbh = NULL;
0973 u64 p_blkno;
0974
0975
0976 status = ocfs2_extend_no_holes(lqinode, NULL,
0977 i_size_read(lqinode) + 2 * sb->s_blocksize,
0978 i_size_read(lqinode));
0979 if (status < 0) {
0980 mlog_errno(status);
0981 goto out;
0982 }
0983 status = ocfs2_simple_size_update(lqinode, oinfo->dqi_lqi_bh,
0984 i_size_read(lqinode) + 2 * sb->s_blocksize);
0985 if (status < 0) {
0986 mlog_errno(status);
0987 goto out;
0988 }
0989
0990 chunk = kmem_cache_alloc(ocfs2_qf_chunk_cachep, GFP_NOFS);
0991 if (!chunk) {
0992 status = -ENOMEM;
0993 mlog_errno(status);
0994 goto out;
0995 }
0996
0997 handle = ocfs2_start_trans(OCFS2_SB(sb),
0998 OCFS2_LOCAL_QINFO_WRITE_CREDITS +
0999 2 * OCFS2_QUOTA_BLOCK_UPDATE_CREDITS);
1000 if (IS_ERR(handle)) {
1001 status = PTR_ERR(handle);
1002 mlog_errno(status);
1003 goto out;
1004 }
1005
1006
1007 status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks,
1008 &p_blkno, NULL, NULL);
1009 if (status < 0) {
1010 mlog_errno(status);
1011 goto out_trans;
1012 }
1013 bh = sb_getblk(sb, p_blkno);
1014 if (!bh) {
1015 status = -ENOMEM;
1016 mlog_errno(status);
1017 goto out_trans;
1018 }
1019 dchunk = (struct ocfs2_local_disk_chunk *)bh->b_data;
1020 ocfs2_set_new_buffer_uptodate(INODE_CACHE(lqinode), bh);
1021 status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode), bh,
1022 OCFS2_JOURNAL_ACCESS_CREATE);
1023 if (status < 0) {
1024 mlog_errno(status);
1025 goto out_trans;
1026 }
1027 lock_buffer(bh);
1028 dchunk->dqc_free = cpu_to_le32(ol_quota_entries_per_block(sb));
1029 memset(dchunk->dqc_bitmap, 0,
1030 sb->s_blocksize - sizeof(struct ocfs2_local_disk_chunk) -
1031 OCFS2_QBLK_RESERVED_SPACE);
1032 unlock_buffer(bh);
1033 ocfs2_journal_dirty(handle, bh);
1034
1035
1036 status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks + 1,
1037 &p_blkno, NULL, NULL);
1038 if (status < 0) {
1039 mlog_errno(status);
1040 goto out_trans;
1041 }
1042 dbh = sb_getblk(sb, p_blkno);
1043 if (!dbh) {
1044 status = -ENOMEM;
1045 mlog_errno(status);
1046 goto out_trans;
1047 }
1048 ocfs2_set_new_buffer_uptodate(INODE_CACHE(lqinode), dbh);
1049 status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode), dbh,
1050 OCFS2_JOURNAL_ACCESS_CREATE);
1051 if (status < 0) {
1052 mlog_errno(status);
1053 goto out_trans;
1054 }
1055 lock_buffer(dbh);
1056 memset(dbh->b_data, 0, sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE);
1057 unlock_buffer(dbh);
1058 ocfs2_journal_dirty(handle, dbh);
1059
1060
1061 oinfo->dqi_blocks += 2;
1062 oinfo->dqi_chunks++;
1063 status = ocfs2_local_write_info(sb, type);
1064 if (status < 0) {
1065 mlog_errno(status);
1066 goto out_trans;
1067 }
1068 status = ocfs2_commit_trans(OCFS2_SB(sb), handle);
1069 if (status < 0) {
1070 mlog_errno(status);
1071 goto out;
1072 }
1073
1074 list_add_tail(&chunk->qc_chunk, &oinfo->dqi_chunk);
1075 chunk->qc_num = list_entry(chunk->qc_chunk.prev,
1076 struct ocfs2_quota_chunk,
1077 qc_chunk)->qc_num + 1;
1078 chunk->qc_headerbh = bh;
1079 *offset = 0;
1080 return chunk;
1081 out_trans:
1082 ocfs2_commit_trans(OCFS2_SB(sb), handle);
1083 out:
1084 brelse(bh);
1085 brelse(dbh);
1086 kmem_cache_free(ocfs2_qf_chunk_cachep, chunk);
1087 return ERR_PTR(status);
1088 }
1089
1090
1091 static struct ocfs2_quota_chunk *ocfs2_extend_local_quota_file(
1092 struct super_block *sb,
1093 int type,
1094 int *offset)
1095 {
1096 struct mem_dqinfo *info = sb_dqinfo(sb, type);
1097 struct ocfs2_mem_dqinfo *oinfo = info->dqi_priv;
1098 struct ocfs2_quota_chunk *chunk;
1099 struct inode *lqinode = sb_dqopt(sb)->files[type];
1100 struct ocfs2_local_disk_chunk *dchunk;
1101 int epb = ol_quota_entries_per_block(sb);
1102 unsigned int chunk_blocks;
1103 struct buffer_head *bh;
1104 u64 p_blkno;
1105 int status;
1106 handle_t *handle;
1107
1108 if (list_empty(&oinfo->dqi_chunk))
1109 return ocfs2_local_quota_add_chunk(sb, type, offset);
1110
1111 chunk = list_entry(oinfo->dqi_chunk.prev,
1112 struct ocfs2_quota_chunk, qc_chunk);
1113 chunk_blocks = oinfo->dqi_blocks -
1114 ol_quota_chunk_block(sb, chunk->qc_num) - 1;
1115 if (ol_chunk_blocks(sb) == chunk_blocks)
1116 return ocfs2_local_quota_add_chunk(sb, type, offset);
1117
1118
1119 status = ocfs2_extend_no_holes(lqinode, NULL,
1120 i_size_read(lqinode) + sb->s_blocksize,
1121 i_size_read(lqinode));
1122 if (status < 0) {
1123 mlog_errno(status);
1124 goto out;
1125 }
1126 status = ocfs2_simple_size_update(lqinode, oinfo->dqi_lqi_bh,
1127 i_size_read(lqinode) + sb->s_blocksize);
1128 if (status < 0) {
1129 mlog_errno(status);
1130 goto out;
1131 }
1132
1133
1134 status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks,
1135 &p_blkno, NULL, NULL);
1136 if (status < 0) {
1137 mlog_errno(status);
1138 goto out;
1139 }
1140 bh = sb_getblk(sb, p_blkno);
1141 if (!bh) {
1142 status = -ENOMEM;
1143 mlog_errno(status);
1144 goto out;
1145 }
1146 ocfs2_set_new_buffer_uptodate(INODE_CACHE(lqinode), bh);
1147
1148
1149 handle = ocfs2_start_trans(OCFS2_SB(sb),
1150 OCFS2_LOCAL_QINFO_WRITE_CREDITS +
1151 2 * OCFS2_QUOTA_BLOCK_UPDATE_CREDITS);
1152 if (IS_ERR(handle)) {
1153 status = PTR_ERR(handle);
1154 mlog_errno(status);
1155 goto out;
1156 }
1157
1158 status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode), bh,
1159 OCFS2_JOURNAL_ACCESS_CREATE);
1160 if (status < 0) {
1161 mlog_errno(status);
1162 goto out_trans;
1163 }
1164 lock_buffer(bh);
1165 memset(bh->b_data, 0, sb->s_blocksize);
1166 unlock_buffer(bh);
1167 ocfs2_journal_dirty(handle, bh);
1168
1169
1170 status = ocfs2_journal_access_dq(handle, INODE_CACHE(lqinode),
1171 chunk->qc_headerbh,
1172 OCFS2_JOURNAL_ACCESS_WRITE);
1173 if (status < 0) {
1174 mlog_errno(status);
1175 goto out_trans;
1176 }
1177
1178 dchunk = (struct ocfs2_local_disk_chunk *)chunk->qc_headerbh->b_data;
1179 lock_buffer(chunk->qc_headerbh);
1180 le32_add_cpu(&dchunk->dqc_free, ol_quota_entries_per_block(sb));
1181 unlock_buffer(chunk->qc_headerbh);
1182 ocfs2_journal_dirty(handle, chunk->qc_headerbh);
1183
1184
1185 oinfo->dqi_blocks++;
1186 status = ocfs2_local_write_info(sb, type);
1187 if (status < 0) {
1188 mlog_errno(status);
1189 goto out_trans;
1190 }
1191
1192 status = ocfs2_commit_trans(OCFS2_SB(sb), handle);
1193 if (status < 0) {
1194 mlog_errno(status);
1195 goto out;
1196 }
1197 *offset = chunk_blocks * epb;
1198 return chunk;
1199 out_trans:
1200 ocfs2_commit_trans(OCFS2_SB(sb), handle);
1201 out:
1202 return ERR_PTR(status);
1203 }
1204
1205 static void olq_alloc_dquot(struct buffer_head *bh, void *private)
1206 {
1207 int *offset = private;
1208 struct ocfs2_local_disk_chunk *dchunk;
1209
1210 dchunk = (struct ocfs2_local_disk_chunk *)bh->b_data;
1211 ocfs2_set_bit_unaligned(*offset, dchunk->dqc_bitmap);
1212 le32_add_cpu(&dchunk->dqc_free, -1);
1213 }
1214
1215
1216 int ocfs2_create_local_dquot(struct dquot *dquot)
1217 {
1218 struct super_block *sb = dquot->dq_sb;
1219 int type = dquot->dq_id.type;
1220 struct inode *lqinode = sb_dqopt(sb)->files[type];
1221 struct ocfs2_quota_chunk *chunk;
1222 struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
1223 int offset;
1224 int status;
1225 u64 pcount;
1226
1227 down_write(&OCFS2_I(lqinode)->ip_alloc_sem);
1228 chunk = ocfs2_find_free_entry(sb, type, &offset);
1229 if (!chunk) {
1230 chunk = ocfs2_extend_local_quota_file(sb, type, &offset);
1231 if (IS_ERR(chunk)) {
1232 status = PTR_ERR(chunk);
1233 goto out;
1234 }
1235 } else if (IS_ERR(chunk)) {
1236 status = PTR_ERR(chunk);
1237 goto out;
1238 }
1239 od->dq_local_off = ol_dqblk_off(sb, chunk->qc_num, offset);
1240 od->dq_chunk = chunk;
1241 status = ocfs2_extent_map_get_blocks(lqinode,
1242 ol_dqblk_block(sb, chunk->qc_num, offset),
1243 &od->dq_local_phys_blk,
1244 &pcount,
1245 NULL);
1246
1247
1248 status = ocfs2_local_write_dquot(dquot);
1249 if (status < 0) {
1250 mlog_errno(status);
1251 goto out;
1252 }
1253
1254
1255 status = ocfs2_modify_bh(lqinode, chunk->qc_headerbh, olq_alloc_dquot,
1256 &offset);
1257 if (status < 0) {
1258 mlog_errno(status);
1259 goto out;
1260 }
1261 out:
1262 up_write(&OCFS2_I(lqinode)->ip_alloc_sem);
1263 return status;
1264 }
1265
1266
1267
1268
1269
1270 int ocfs2_local_release_dquot(handle_t *handle, struct dquot *dquot)
1271 {
1272 int status;
1273 int type = dquot->dq_id.type;
1274 struct ocfs2_dquot *od = OCFS2_DQUOT(dquot);
1275 struct super_block *sb = dquot->dq_sb;
1276 struct ocfs2_local_disk_chunk *dchunk;
1277 int offset;
1278
1279 status = ocfs2_journal_access_dq(handle,
1280 INODE_CACHE(sb_dqopt(sb)->files[type]),
1281 od->dq_chunk->qc_headerbh, OCFS2_JOURNAL_ACCESS_WRITE);
1282 if (status < 0) {
1283 mlog_errno(status);
1284 goto out;
1285 }
1286 offset = ol_dqblk_chunk_off(sb, od->dq_chunk->qc_num,
1287 od->dq_local_off);
1288 dchunk = (struct ocfs2_local_disk_chunk *)
1289 (od->dq_chunk->qc_headerbh->b_data);
1290
1291 lock_buffer(od->dq_chunk->qc_headerbh);
1292 ocfs2_clear_bit_unaligned(offset, dchunk->dqc_bitmap);
1293 le32_add_cpu(&dchunk->dqc_free, 1);
1294 unlock_buffer(od->dq_chunk->qc_headerbh);
1295 ocfs2_journal_dirty(handle, od->dq_chunk->qc_headerbh);
1296
1297 out:
1298 return status;
1299 }
1300
1301 static const struct quota_format_ops ocfs2_format_ops = {
1302 .check_quota_file = ocfs2_local_check_quota_file,
1303 .read_file_info = ocfs2_local_read_info,
1304 .write_file_info = ocfs2_global_write_info,
1305 .free_file_info = ocfs2_local_free_info,
1306 };
1307
1308 struct quota_format_type ocfs2_quota_format = {
1309 .qf_fmt_id = QFMT_OCFS2,
1310 .qf_ops = &ocfs2_format_ops,
1311 .qf_owner = THIS_MODULE
1312 };