Root/fs/ocfs2/quota_local.c

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

Archive Download this file



interactive