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