diff options
Diffstat (limited to 'fs/xfs/xfs_dquot.c')
-rw-r--r-- | fs/xfs/xfs_dquot.c | 103 |
1 files changed, 26 insertions, 77 deletions
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index b4ff40b5f918..cbcb7bea38e2 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c | |||
@@ -63,82 +63,6 @@ int xfs_dqerror_mod = 33; | |||
63 | static struct lock_class_key xfs_dquot_other_class; | 63 | static struct lock_class_key xfs_dquot_other_class; |
64 | 64 | ||
65 | /* | 65 | /* |
66 | * Allocate and initialize a dquot. We don't always allocate fresh memory; | ||
67 | * we try to reclaim a free dquot if the number of incore dquots are above | ||
68 | * a threshold. | ||
69 | * The only field inside the core that gets initialized at this point | ||
70 | * is the d_id field. The idea is to fill in the entire q_core | ||
71 | * when we read in the on disk dquot. | ||
72 | */ | ||
73 | STATIC xfs_dquot_t * | ||
74 | xfs_qm_dqinit( | ||
75 | xfs_mount_t *mp, | ||
76 | xfs_dqid_t id, | ||
77 | uint type) | ||
78 | { | ||
79 | xfs_dquot_t *dqp; | ||
80 | boolean_t brandnewdquot; | ||
81 | |||
82 | brandnewdquot = xfs_qm_dqalloc_incore(&dqp); | ||
83 | dqp->dq_flags = type; | ||
84 | dqp->q_core.d_id = cpu_to_be32(id); | ||
85 | dqp->q_mount = mp; | ||
86 | |||
87 | /* | ||
88 | * No need to re-initialize these if this is a reclaimed dquot. | ||
89 | */ | ||
90 | if (brandnewdquot) { | ||
91 | INIT_LIST_HEAD(&dqp->q_freelist); | ||
92 | mutex_init(&dqp->q_qlock); | ||
93 | init_waitqueue_head(&dqp->q_pinwait); | ||
94 | |||
95 | /* | ||
96 | * Because we want to use a counting completion, complete | ||
97 | * the flush completion once to allow a single access to | ||
98 | * the flush completion without blocking. | ||
99 | */ | ||
100 | init_completion(&dqp->q_flush); | ||
101 | complete(&dqp->q_flush); | ||
102 | |||
103 | trace_xfs_dqinit(dqp); | ||
104 | } else { | ||
105 | /* | ||
106 | * Only the q_core portion was zeroed in dqreclaim_one(). | ||
107 | * So, we need to reset others. | ||
108 | */ | ||
109 | dqp->q_nrefs = 0; | ||
110 | dqp->q_blkno = 0; | ||
111 | INIT_LIST_HEAD(&dqp->q_mplist); | ||
112 | INIT_LIST_HEAD(&dqp->q_hashlist); | ||
113 | dqp->q_bufoffset = 0; | ||
114 | dqp->q_fileoffset = 0; | ||
115 | dqp->q_transp = NULL; | ||
116 | dqp->q_gdquot = NULL; | ||
117 | dqp->q_res_bcount = 0; | ||
118 | dqp->q_res_icount = 0; | ||
119 | dqp->q_res_rtbcount = 0; | ||
120 | atomic_set(&dqp->q_pincount, 0); | ||
121 | dqp->q_hash = NULL; | ||
122 | ASSERT(list_empty(&dqp->q_freelist)); | ||
123 | |||
124 | trace_xfs_dqreuse(dqp); | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * In either case we need to make sure group quotas have a different | ||
129 | * lock class than user quotas, to make sure lockdep knows we can | ||
130 | * locks of one of each at the same time. | ||
131 | */ | ||
132 | if (!(type & XFS_DQ_USER)) | ||
133 | lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class); | ||
134 | |||
135 | /* | ||
136 | * log item gets initialized later | ||
137 | */ | ||
138 | return (dqp); | ||
139 | } | ||
140 | |||
141 | /* | ||
142 | * This is called to free all the memory associated with a dquot | 66 | * This is called to free all the memory associated with a dquot |
143 | */ | 67 | */ |
144 | void | 68 | void |
@@ -567,7 +491,32 @@ xfs_qm_dqread( | |||
567 | int error; | 491 | int error; |
568 | int cancelflags = 0; | 492 | int cancelflags = 0; |
569 | 493 | ||
570 | dqp = xfs_qm_dqinit(mp, id, type); | 494 | |
495 | dqp = kmem_zone_zalloc(xfs_Gqm->qm_dqzone, KM_SLEEP); | ||
496 | |||
497 | dqp->dq_flags = type; | ||
498 | dqp->q_core.d_id = cpu_to_be32(id); | ||
499 | dqp->q_mount = mp; | ||
500 | INIT_LIST_HEAD(&dqp->q_freelist); | ||
501 | mutex_init(&dqp->q_qlock); | ||
502 | init_waitqueue_head(&dqp->q_pinwait); | ||
503 | |||
504 | /* | ||
505 | * Because we want to use a counting completion, complete | ||
506 | * the flush completion once to allow a single access to | ||
507 | * the flush completion without blocking. | ||
508 | */ | ||
509 | init_completion(&dqp->q_flush); | ||
510 | complete(&dqp->q_flush); | ||
511 | |||
512 | /* | ||
513 | * Make sure group quotas have a different lock class than user | ||
514 | * quotas. | ||
515 | */ | ||
516 | if (!(type & XFS_DQ_USER)) | ||
517 | lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class); | ||
518 | |||
519 | atomic_inc(&xfs_Gqm->qm_totaldquots); | ||
571 | 520 | ||
572 | trace_xfs_dqread(dqp); | 521 | trace_xfs_dqread(dqp); |
573 | 522 | ||