6 #include <linux/slab.h>
7 #include <linux/quota.h>
68 static void ocfs2_global_disk2memdqb(
struct dquot *
dquot,
void *
dp)
93 static void ocfs2_global_mem2diskdqb(
void *dp,
struct dquot *dquot)
111 static int ocfs2_global_is_id(
void *dp,
struct dquot *dquot)
115 sb_dqinfo(dquot->
dq_sb, dquot->
dq_id.type)->dqi_priv;
126 .mem2disk_dqblk = ocfs2_global_mem2diskdqb,
127 .disk2mem_dqblk = ocfs2_global_disk2memdqb,
128 .is_id = ocfs2_global_is_id,
134 ocfs2_block_dqtrailer(sb->
s_blocksize, bh->b_data);
136 trace_ocfs2_validate_quota_block((
unsigned long long)bh->b_blocknr);
138 BUG_ON(!buffer_uptodate(bh));
149 struct buffer_head **bhp)
165 size_t len, loff_t off)
169 loff_t
i_size = i_size_read(gqinode);
173 struct buffer_head *bh;
174 size_t toread, tocopy;
175 u64 pblock = 0, pcount = 0;
179 if (off + len > i_size)
201 memcpy(data, bh->b_data + offset, tocopy);
214 const char *
data,
size_t len, loff_t off)
221 int err = 0,
new = 0, ja_type;
222 struct buffer_head *bh =
NULL;
223 handle_t *
handle = journal_current_handle();
227 mlog(
ML_ERROR,
"Quota write (off=%llu, len=%llu) cancelled "
228 "because transaction was not started.\n",
229 (
unsigned long long)off, (
unsigned long long)len);
237 if (gqinode->
i_size < off + len) {
239 ocfs2_align_bytes_to_blocks(sb, off + len);
260 bh = sb_getblk(sb, pblock);
272 memcpy(bh->b_data + offset, data, len);
274 set_buffer_uptodate(bh);
298 struct buffer_head *bh =
NULL;
350 mlog(
ML_ERROR,
"failed to get global quota inode (type=%d)\n",
377 status = sb->
s_op->quota_read(sb, type, (
char *)&dinfo,
399 oinfo->
dqi_gi.dqi_qtree_depth = qtree_depth(&oinfo->
dqi_gi);
421 spin_lock(&dq_data_lock);
425 spin_unlock(&dq_data_lock);
430 size = sb->
s_op->quota_write(sb, type, (
char *)&dinfo,
434 mlog(
ML_ERROR,
"Cannot write global quota info structure\n");
450 err = __ocfs2_global_write_info(sb, type);
455 static int ocfs2_global_qinit_alloc(
struct super_block *sb,
int type)
463 return oinfo->
dqi_gi.dqi_qtree_depth;
466 static int ocfs2_calc_global_qinit_credits(
struct super_block *sb,
int type)
470 return (ocfs2_global_qinit_alloc(sb, type) + 2) *
481 int type = dquot->
dq_id.type;
484 s64 spacechange, inodechange;
485 time_t olditime, oldbtime;
487 err = sb->
s_op->quota_read(sb, type, (
char *)&dqblk,
503 spacechange = dquot->
dq_dqb.dqb_curspace -
504 OCFS2_DQUOT(dquot)->dq_origspace;
505 inodechange = dquot->
dq_dqb.dqb_curinodes -
506 OCFS2_DQUOT(dquot)->dq_originodes;
507 olditime = dquot->
dq_dqb.dqb_itime;
508 oldbtime = dquot->
dq_dqb.dqb_btime;
509 ocfs2_global_disk2memdqb(dquot, &dqblk);
511 dquot->
dq_dqb.dqb_curspace,
512 (
long long)spacechange,
513 dquot->
dq_dqb.dqb_curinodes,
514 (
long long)inodechange);
516 dquot->
dq_dqb.dqb_curspace += spacechange;
518 dquot->
dq_dqb.dqb_curinodes += inodechange;
520 if (dquot->
dq_dqb.dqb_bsoftlimit &&
521 dquot->
dq_dqb.dqb_curspace > dquot->
dq_dqb.dqb_bsoftlimit) {
524 if (dquot->
dq_dqb.dqb_btime > 0)
528 dquot->
dq_dqb.dqb_btime = oldbtime;
531 dquot->
dq_dqb.dqb_btime = 0;
535 if (dquot->
dq_dqb.dqb_isoftlimit &&
536 dquot->
dq_dqb.dqb_curinodes > dquot->
dq_dqb.dqb_isoftlimit) {
539 if (dquot->
dq_dqb.dqb_itime > 0)
543 dquot->
dq_dqb.dqb_itime = olditime;
546 dquot->
dq_dqb.dqb_itime = 0;
556 OCFS2_DQUOT(dquot)->dq_origspace = dquot->
dq_dqb.dqb_curspace;
557 OCFS2_DQUOT(dquot)->dq_originodes = dquot->
dq_dqb.dqb_curinodes;
561 mlog(
ML_ERROR,
"Failed to lock quota info, losing quota write"
562 " (type=%d, id=%u)\n", dquot->
dq_id.type,
567 OCFS2_DQUOT(dquot)->dq_use_count--;
571 if (freeing && !OCFS2_DQUOT(dquot)->dq_use_count) {
573 if (info_dirty(sb_dqinfo(sb, type))) {
574 err2 = __ocfs2_global_write_info(sb, type);
590 static int ocfs2_sync_dquot_helper(
struct dquot *dquot,
unsigned long type)
601 if (type != dquot->
dq_id.type)
608 if (IS_ERR(handle)) {
609 status = PTR_ERR(handle);
614 status = ocfs2_sync_dquot(dquot);
645 static int ocfs2_write_dquot(
struct dquot *dquot)
655 if (IS_ERR(handle)) {
656 status = PTR_ERR(handle);
668 static int ocfs2_calc_qdel_credits(
struct super_block *sb,
int type)
676 return (oinfo->
dqi_gi.dqi_qtree_depth + 2) *
682 static int ocfs2_release_dquot(
struct dquot *dquot)
686 sb_dqinfo(dquot->
dq_sb, dquot->
dq_id.type)->dqi_priv;
701 ocfs2_calc_qdel_credits(dquot->
dq_sb, dquot->
dq_id.type));
702 if (IS_ERR(handle)) {
703 status = PTR_ERR(handle);
708 status = ocfs2_global_release_dquot(dquot);
737 static int ocfs2_acquire_dquot(
struct dquot *dquot)
743 int type = dquot->
dq_id.type;
746 int need_alloc = ocfs2_global_qinit_alloc(sb, type);
770 OCFS2_DQUOT(dquot)->dq_use_count++;
771 OCFS2_DQUOT(dquot)->dq_origspace = dquot->
dq_dqb.dqb_curspace;
772 OCFS2_DQUOT(dquot)->dq_originodes = dquot->
dq_dqb.dqb_curinodes;
779 WARN_ON(journal_current_handle());
788 ocfs2_calc_global_qinit_credits(sb, type));
789 if (IS_ERR(handle)) {
790 status = PTR_ERR(handle);
797 if (ex && info_dirty(sb_dqinfo(sb, type))) {
798 err = __ocfs2_global_write_info(sb, type);
821 static int ocfs2_mark_dquot_dirty(
struct dquot *dquot)
832 int type = dquot->
dq_id.type;
842 spin_lock(&dq_data_lock);
845 spin_unlock(&dq_data_lock);
848 if (!sync || journal_current_handle()) {
849 status = ocfs2_write_dquot(dquot);
856 if (IS_ERR(handle)) {
857 status = PTR_ERR(handle);
862 status = ocfs2_sync_dquot(dquot);
881 static int ocfs2_write_info(
struct super_block *sb,
int type)
891 if (IS_ERR(handle)) {
892 status = PTR_ERR(handle);
906 static struct dquot *ocfs2_alloc_dquot(
struct super_block *sb,
int type)
916 static void ocfs2_destroy_dquot(
struct dquot *dquot)
923 .acquire_dquot = ocfs2_acquire_dquot,
924 .release_dquot = ocfs2_release_dquot,
925 .mark_dirty = ocfs2_mark_dquot_dirty,
926 .write_info = ocfs2_write_info,
927 .alloc_dquot = ocfs2_alloc_dquot,
928 .destroy_dquot = ocfs2_destroy_dquot,