Whamcloud - gitweb
be8ea4cb2e8a0ba22a286fbe0da51e26e655fdeb
[fs/lustre-release.git] / lustre / kernel_patches / patches / quota-replace-dqptr-sem-sles11.patch
1 diff -urp linux-2.6.32-53.7.orig/fs/quota/dquot.c linux-2.6.32.46-0/fs/quota/dquot.c
2 --- linux-2.6.32-53.7.orig/fs/quota/dquot.c     2013-04-26 11:56:35.000000000 -0400
3 +++ linux-2.6.32-53.7/fs/quota/dquot.c  2013-04-26 12:00:44.000000000 -0400
4 @@ -89,22 +89,17 @@
5  /*
6   * There are three quota SMP locks. dq_list_lock protects all lists with quotas
7   * and quota formats, dqstats structure containing statistics about the lists
8 - * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures and
9 - * also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes.
10 - * i_blocks and i_bytes updates itself are guarded by i_lock acquired directly
11 - * in inode_add_bytes() and inode_sub_bytes(). dq_state_lock protects
12 - * modifications of quota state (on quotaon and quotaoff) and readers who care
13 - * about latest values take it as well.
14 + * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures.
15 + * dq_state_lock protects modifications of quota state (on quotaon and quotaoff)
16 + * and readers who care about latest values take it as well.
17   *
18 - * The spinlock ordering is hence: dq_data_lock > dq_list_lock > i_lock,
19 + * The spinlock ordering is hence: i_lock > dq_data_lock > dq_list_lock,
20   *   dq_list_lock > dq_state_lock
21   *
22   * Note that some things (eg. sb pointer, type, id) doesn't change during
23   * the life of the dquot structure and so needn't to be protected by a lock
24   *
25 - * Any operation working on dquots via inode pointers must hold dqptr_sem.  If
26 - * operation is just reading pointers from inode (or not using them at all) the
27 - * read lock is enough. If pointers are altered function must hold write lock
28 + * Any operation working on dquots via inode pointers must hold i_lock.
29   * (these locking rules also apply for S_NOQUOTA flag in the inode - note that
30   * for altering the flag i_mutex is also needed).
31   *
32 @@ -118,15 +113,8 @@
33   * spinlock to internal buffers before writing.
34   *
35   * Lock ordering (including related VFS locks) is the following:
36 - *   i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock >
37 - *   dqio_mutex
38 - * The lock ordering of dqptr_sem imposed by quota code is only dqonoff_sem >
39 - * dqptr_sem. But filesystem has to count with the fact that functions such as
40 - * dquot_alloc_space() acquire dqptr_sem and they usually have to be called
41 - * from inside a transaction to keep filesystem consistency after a crash. Also
42 - * filesystems usually want to do some IO on dquot from ->mark_dirty which is
43 - * called with dqptr_sem held.
44 - * i_mutex on quota files is special (it's below dqio_mutex)
45 + *  i_mutex > dqonoff_sem > journal_lock > dquot->dq_lock > dqio_mutex
46 + *  i_mutex on quota files is special (it's below dqio_mutex)
47   */
48  
49  static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock);
50 @@ -867,7 +855,6 @@ static inline int dqput_blocks(struct dq
51  /*
52   * Remove references to dquots from inode and add dquot to list for freeing
53   * if we have the last referece to dquot
54 - * We can't race with anybody because we hold dqptr_sem for writing...
55   */
56  static int remove_inode_dquot_ref(struct inode *inode, int type,
57                                   struct list_head *tofree_head)
58 @@ -925,10 +912,12 @@ static void remove_dquot_ref(struct supe
59                  *  We have to scan also I_NEW inodes because they can already
60                  *  have quota pointer initialized. Luckily, we need to touch
61                  *  only quota pointers and these have separate locking
62 -                *  (dqptr_sem).
63 +                *  (i_lock).
64                  */
65 +               spin_lock(&inode->i_lock);
66                 if (!IS_NOQUOTA(inode))
67                         remove_inode_dquot_ref(inode, type, tofree_head);
68 +               spin_unlock(&inode->i_lock);
69         }
70         spin_unlock(&inode_lock);
71  }
72 @@ -939,9 +928,7 @@ static void drop_dquot_ref(struct super_
73         LIST_HEAD(tofree_head);
74  
75         if (sb->dq_op) {
76 -               down_write(&sb_dqopt(sb)->dqptr_sem);
77                 remove_dquot_ref(sb, type, &tofree_head);
78 -               up_write(&sb_dqopt(sb)->dqptr_sem);
79                 put_dquot_list(&tofree_head);
80         }
81  }
82 @@ -1303,8 +1290,6 @@ static int info_bdq_free(struct dquot *d
83  
84  /*
85   *     Initialize quota pointers in inode
86 - *     We do things in a bit complicated way but by that we avoid calling
87 - *     dqget() and thus filesystem callbacks under dqptr_sem.
88   */
89  int dquot_initialize(struct inode *inode, int type)
90  {
91 @@ -1334,8 +1319,7 @@ int dquot_initialize(struct inode *inode
92                 got[cnt] = dqget(sb, id, cnt);
93         }
94  
95 -       down_write(&sb_dqopt(sb)->dqptr_sem);
96 -       /* Having dqptr_sem we know NOQUOTA flags can't be altered... */
97 +       spin_lock(&inode->i_lock);
98         if (IS_NOQUOTA(inode))
99                 goto out_err;
100         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
101 @@ -1352,12 +1336,16 @@ int dquot_initialize(struct inode *inode
102                          * did a write before quota was turned on
103                          */
104                         rsv = inode_get_rsv_space(inode);
105 -                       if (unlikely(rsv))
106 +                       if (unlikely(rsv)) {
107 +                               spin_lock(&dq_data_lock);
108                                 dquot_resv_space(inode->i_dquot[cnt], rsv);
109 +                               spin_unlock(&dq_data_lock);
110 +                       }
111                 }
112         }
113  out_err:
114 -       up_write(&sb_dqopt(sb)->dqptr_sem);
115 +       spin_unlock(&inode->i_lock);
116 +
117         /* Drop unused references */
118         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
119                 dqput(got[cnt]);
120 @@ -1373,12 +1361,12 @@ int dquot_drop(struct inode *inode)
121         int cnt;
122         struct dquot *put[MAXQUOTAS];
123  
124 -       down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
125 +       spin_lock(&inode->i_lock);
126         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
127                 put[cnt] = inode->i_dquot[cnt];
128                 inode->i_dquot[cnt] = NULL;
129         }
130 -       up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
131 +       spin_unlock(&inode->i_lock);
132  
133         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
134                 dqput(put[cnt]);
135 @@ -1421,27 +1409,42 @@ static qsize_t *inode_reserved_space(str
136         return inode->i_sb->dq_op->get_reserved_space(inode);
137  }
138  
139 +static inline void __inode_add_rsv_space(struct inode *inode, qsize_t number)
140 +{
141 +       *inode_reserved_space(inode) += number;
142 +}
143 +
144  void inode_add_rsv_space(struct inode *inode, qsize_t number)
145  {
146         spin_lock(&inode->i_lock);
147 -       *inode_reserved_space(inode) += number;
148 +       __inode_add_rsv_space(inode, number);
149         spin_unlock(&inode->i_lock);
150  }
151  EXPORT_SYMBOL(inode_add_rsv_space);
152  
153 -void inode_claim_rsv_space(struct inode *inode, qsize_t number)
154 +static inline void __inode_claim_rsv_space(struct inode *inode, qsize_t number)
155  {
156 -       spin_lock(&inode->i_lock);
157         *inode_reserved_space(inode) -= number;
158         __inode_add_bytes(inode, number);
159 +}
160 +
161 +void inode_claim_rsv_space(struct inode *inode, qsize_t number)
162 +{
163 +       spin_lock(&inode->i_lock);
164 +       __inode_claim_rsv_space(inode, number);
165         spin_unlock(&inode->i_lock);
166  }
167  EXPORT_SYMBOL(inode_claim_rsv_space);
168  
169 +static inline void __inode_sub_rsv_space(struct inode *inode, qsize_t number)
170 +{
171 +       *inode_reserved_space(inode) -= number;
172 +}
173 +
174  void inode_sub_rsv_space(struct inode *inode, qsize_t number)
175  {
176         spin_lock(&inode->i_lock);
177 -       *inode_reserved_space(inode) -= number;
178 +       __inode_sub_rsv_space(inode, number);
179         spin_unlock(&inode->i_lock);
180  }
181  EXPORT_SYMBOL(inode_sub_rsv_space);
182 @@ -1452,9 +1455,8 @@ static qsize_t inode_get_rsv_space(struc
183  
184         if (!inode->i_sb->dq_op->get_reserved_space)
185                 return 0;
186 -       spin_lock(&inode->i_lock);
187 +
188         ret = *inode_reserved_space(inode);
189 -       spin_unlock(&inode->i_lock);
190         return ret;
191  }
192  
193 @@ -1462,17 +1464,17 @@ static void inode_incr_space(struct inod
194                                 int reserve)
195  {
196         if (reserve)
197 -               inode_add_rsv_space(inode, number);
198 +               __inode_add_rsv_space(inode, number);
199         else
200 -               inode_add_bytes(inode, number);
201 +               __inode_add_bytes(inode, number);
202  }
203  
204  static void inode_decr_space(struct inode *inode, qsize_t number, int reserve)
205  {
206         if (reserve)
207 -               inode_sub_rsv_space(inode, number);
208 +               __inode_sub_rsv_space(inode, number);
209         else
210 -               inode_sub_bytes(inode, number);
211 +               __inode_sub_bytes(inode, number);
212  }
213  
214  /*
215 @@ -1492,6 +1494,7 @@ int __dquot_alloc_space(struct inode *in
216  {
217         int cnt, ret = QUOTA_OK;
218         char warntype[MAXQUOTAS];
219 +       struct dquot *dquot[MAXQUOTAS] = { NULL };
220  
221         /*
222          * First test before acquiring mutex - solves deadlocks when we
223 @@ -1502,10 +1505,11 @@ int __dquot_alloc_space(struct inode *in
224                 goto out;
225         }
226  
227 -       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
228 +       spin_lock(&inode->i_lock);
229         if (IS_NOQUOTA(inode)) {
230                 inode_incr_space(inode, number, reserve);
231 -               goto out_unlock;
232 +               spin_unlock(&inode->i_lock);
233 +               goto out;
234         }
235  
236         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
237 @@ -1523,36 +1529,40 @@ int __dquot_alloc_space(struct inode *int inode *in
238  
239         spin_lock(&dq_data_lock);
240         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
241 -               if (!inode->i_dquot[cnt])
242 +               dquot[cnt] = inode->i_dquot[cnt];
243 +               if (!dquot[cnt])
244                         continue;
245 -               if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt)
246 -                   == NO_QUOTA) {
247 +               atomic_inc(&dquot[cnt]->dq_count);
248 +               if (check_bdq(dquot[cnt], number, warn, warntype + cnt) ==
249 +                   NO_QUOTA) {
250                         ret = NO_QUOTA;
251                         spin_unlock(&dq_data_lock);
252 +                       spin_unlock(&inode->i_lock);
253                         goto out_flush_warn;
254                 }
255         }
256         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
257 -               if (!inode->i_dquot[cnt])
258 +               if (!dquot[cnt])
259                         continue;
260                 if (reserve)
261 -                       dquot_resv_space(inode->i_dquot[cnt], number);
262 +                       dquot_resv_space(dquot[cnt], number);
263                 else
264 -                       dquot_incr_space(inode->i_dquot[cnt], number);
265 +                       dquot_incr_space(dquot[cnt], number);
266         }
267         inode_incr_space(inode, number, reserve);
268         spin_unlock(&dq_data_lock);
269 +       spin_unlock(&inode->i_lock);
270  
271         if (reserve)
272                 goto out_flush_warn;
273         /* Dirtify all the dquots - this can block when journalling */
274         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
275 -               if (inode->i_dquot[cnt])
276 -                       mark_dquot_dirty(inode->i_dquot[cnt]);
277 +               if (dquot[cnt])
278 +                       mark_dquot_dirty(dquot[cnt]);
279  out_flush_warn:
280 -       flush_warnings(inode->i_dquot, warntype);
281 -out_unlock:
282 -       up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
283 +       flush_warnings(dquot, warntype);
284 +       for (cnt = 0; cnt < MAXQUOTAS; cnt++)
285 +               dqput(dquot[cnt]);
286  out:
287         return ret;
288  }
289 @@ -1566,6 +1573,7 @@ int dquot_alloc_inode(const struct inode
290  {
291         int cnt, ret = NO_QUOTA;
292         char warntype[MAXQUOTAS];
293 +       struct dquot *dquot[MAXQUOTAS] = { NULL };
294  
295         /* First test before acquiring mutex - solves deadlocks when we
296           * re-enter the quota code and are already holding the mutex */
297 @@ -1573,35 +1581,41 @@ int dquot_alloc_inode(const struct inode
298                 return QUOTA_OK;
299         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
300                 warntype[cnt] = QUOTA_NL_NOWARN;
301 -       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
302 +
303 +       spin_lock(&((struct inode *)inode)->i_lock);
304         if (IS_NOQUOTA(inode)) {
305 -               up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
306 +               spin_unlock(&((struct inode *)inode)->i_lock);
307                 return QUOTA_OK;
308         }
309         spin_lock(&dq_data_lock);
310         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
311 -               if (!inode->i_dquot[cnt])
312 +               dquot[cnt] = inode->i_dquot[cnt];
313 +               if (!dquot[cnt])
314                         continue;
315 -               if (check_idq(inode->i_dquot[cnt], number, warntype+cnt)
316 +               atomic_inc(&dquot[cnt]->dq_count);
317 +               if (check_idq(dquot[cnt], number, warntype+cnt)
318                     == NO_QUOTA)
319                         goto warn_put_all;
320         }
321  
322         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
323 -               if (!inode->i_dquot[cnt])
324 +               if (!dquot[cnt])
325                         continue;
326 -               dquot_incr_inodes(inode->i_dquot[cnt], number);
327 +               dquot_incr_inodes(dquot[cnt], number);
328         }
329         ret = QUOTA_OK;
330  warn_put_all:
331         spin_unlock(&dq_data_lock);
332 +       spin_unlock(&((struct inode *)inode)->i_lock);
333 +
334         if (ret == QUOTA_OK)
335                 /* Dirtify all the dquots - this can block when journalling */
336                 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
337 -                       if (inode->i_dquot[cnt])
338 -                               mark_dquot_dirty(inode->i_dquot[cnt]);
339 -       flush_warnings(inode->i_dquot, warntype);
340 -       up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
341 +                       if (dquot[cnt])
342 +                               mark_dquot_dirty(dquot[cnt]);
343 +       flush_warnings(dquot, warntype);
344 +       for (cnt = 0; cnt < MAXQUOTAS; cnt++)
345 +               dqput(dquot[cnt]);
346         return ret;
347  }
348  EXPORT_SYMBOL(dquot_alloc_inode);
349 @@ -1610,34 +1624,40 @@ int dquot_claim_space(struct inode *inod
350  {
351         int cnt;
352         int ret = QUOTA_OK;
353 +       struct dquot *dquot[MAXQUOTAS] = { NULL };
354  
355         if (IS_NOQUOTA(inode)) {
356                 inode_claim_rsv_space(inode, number);
357                 goto out;
358         }
359  
360 -       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
361 +       spin_lock(&inode->i_lock);
362         if (IS_NOQUOTA(inode))  {
363 -               up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
364 -               inode_claim_rsv_space(inode, number);
365 +               __inode_claim_rsv_space(inode, number);
366 +               spin_unlock(&inode->i_lock);
367                 goto out;
368         }
369  
370         spin_lock(&dq_data_lock);
371         /* Claim reserved quotas to allocated quotas */
372         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
373 -               if (inode->i_dquot[cnt])
374 -                       dquot_claim_reserved_space(inode->i_dquot[cnt],
375 -                                                       number);
376 +               dquot[cnt] = inode->i_dquot[cnt];
377 +               if (dquot[cnt]) {
378 +                       atomic_inc(&dquot[cnt]->dq_count);
379 +                       dquot_claim_reserved_space(dquot[cnt], number);
380 +               }
381         }
382         /* Update inode bytes */
383 -       inode_claim_rsv_space(inode, number);
384 +       __inode_claim_rsv_space(inode, number);
385         spin_unlock(&dq_data_lock);
386 +       spin_unlock(&inode->i_lock);
387 +
388         /* Dirtify all the dquots - this can block when journalling */
389         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
390 -               if (inode->i_dquot[cnt])
391 -                       mark_dquot_dirty(inode->i_dquot[cnt]);
392 -       up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
393 +               if (dquot[cnt])
394 +                       mark_dquot_dirty(dquot[cnt]);
395 +       for (cnt = 0; cnt < MAXQUOTAS; cnt++)
396 +               dqput(dquot[cnt]);
397  out:
398         return ret;
399  }
400 @@ -1650,6 +1670,7 @@ int __dquot_free_space(struct inode *ino
401  {
402         unsigned int cnt;
403         char warntype[MAXQUOTAS];
404 +       struct dquot *dquot[MAXQUOTAS] = { NULL };
405  
406         /* First test before acquiring mutex - solves deadlocks when we
407           * re-enter the quota code and are already holding the mutex */
408 @@ -1659,34 +1680,37 @@ out_sub:
409                 return QUOTA_OK;
410         }
411  
412 -       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
413 -       /* Now recheck reliably when holding dqptr_sem */
414 +       spin_lock(&inode->i_lock);
415         if (IS_NOQUOTA(inode)) {
416 -               up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
417 +               spin_unlock(&inode->i_lock);
418                 goto out_sub;
419         }
420         spin_lock(&dq_data_lock);
421         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
422 -               if (!inode->i_dquot[cnt])
423 +               dquot[cnt] = inode->i_dquot[cnt];
424 +               if (!dquot[cnt])
425                         continue;
426 -               warntype[cnt] = info_bdq_free(inode->i_dquot[cnt], number);
427 +               atomic_inc(&dquot[cnt]->dq_count);
428 +               warntype[cnt] = info_bdq_free(dquot[cnt], number);
429                 if (reserve)
430 -                       dquot_free_reserved_space(inode->i_dquot[cnt], number);
431 +                       dquot_free_reserved_space(dquot[cnt], number);
432                 else
433 -                       dquot_decr_space(inode->i_dquot[cnt], number);
434 +                       dquot_decr_space(dquot[cnt], number);
435         }
436         inode_decr_space(inode, number, reserve);
437         spin_unlock(&dq_data_lock);
438 +       spin_unlock(&inode->i_lock);
439  
440         if (reserve)
441 -               goto out_unlock;
442 +               goto out;
443         /* Dirtify all the dquots - this can block when journalling */
444         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
445 -               if (inode->i_dquot[cnt])
446 -                       mark_dquot_dirty(inode->i_dquot[cnt]);
447 -out_unlock:
448 -       flush_warnings(inode->i_dquot, warntype);
449 -       up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
450 +               if (dquot[cnt])
451 +                       mark_dquot_dirty(dquot[cnt]);
452 +out:
453 +       flush_warnings(dquot, warntype);
454 +       for (cnt = 0; cnt < MAXQUOTAS; cnt++)
455 +               dqput(dquot[cnt]);
456         return QUOTA_OK;
457  }
458  
459 @@ -1713,32 +1737,37 @@ int dquot_free_inode(const struct inode
460  {
461         unsigned int cnt;
462         char warntype[MAXQUOTAS];
463 +       struct dquot *dquot[MAXQUOTAS] = { NULL };
464  
465         /* First test before acquiring mutex - solves deadlocks when we
466           * re-enter the quota code and are already holding the mutex */
467         if (IS_NOQUOTA(inode))
468                 return QUOTA_OK;
469  
470 -       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
471 -       /* Now recheck reliably when holding dqptr_sem */
472 +       spin_lock(&((struct inode *)inode)->i_lock);
473         if (IS_NOQUOTA(inode)) {
474 -               up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
475 +               spin_unlock(&((struct inode *)inode)->i_lock);
476                 return QUOTA_OK;
477         }
478         spin_lock(&dq_data_lock);
479         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
480 -               if (!inode->i_dquot[cnt])
481 +               dquot[cnt] = inode->i_dquot[cnt];
482 +               if (!dquot[cnt])
483                         continue;
484 -               warntype[cnt] = info_idq_free(inode->i_dquot[cnt], number);
485 -               dquot_decr_inodes(inode->i_dquot[cnt], number);
486 +               atomic_inc(&dquot[cnt]->dq_count);
487 +               warntype[cnt] = info_idq_free(dquot[cnt], number);
488 +               dquot_decr_inodes(dquot[cnt], number);
489         }
490         spin_unlock(&dq_data_lock);
491 +       spin_unlock(&((struct inode *)inode)->i_lock);
492 +
493         /* Dirtify all the dquots - this can block when journalling */
494         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
495 -               if (inode->i_dquot[cnt])
496 -                       mark_dquot_dirty(inode->i_dquot[cnt]);
497 -       flush_warnings(inode->i_dquot, warntype);
498 -       up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
499 +               if (dquot[cnt])
500 +                       mark_dquot_dirty(dquot[cnt]);
501 +       flush_warnings(dquot, warntype);
502 +       for (cnt = 0; cnt < MAXQUOTAS; cnt++)
503 +               dqput(dquot[cnt]);
504         return QUOTA_OK;
505  }
506  EXPORT_SYMBOL(dquot_free_inode);
507 @@ -1778,14 +1807,13 @@ int dquot_transfer(struct inode *inode,
508                 transfer_to[GRPQUOTA] = dqget(inode->i_sb, iattr->ia_gid,
509                                               GRPQUOTA);
510  
511 -       down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
512 -       /* Now recheck reliably when holding dqptr_sem */
513 +       spin_lock(&inode->i_lock);
514         if (IS_NOQUOTA(inode)) {        /* File without quota accounting? */
515 -               up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
516 +               spin_unlock(&inode->i_lock);
517                 goto put_all;
518         }
519         spin_lock(&dq_data_lock);
520 -       cur_space = inode_get_bytes(inode);
521 +       cur_space = __inode_get_bytes(inode);
522         rsv_space = inode_get_rsv_space(inode);
523         space = cur_space + rsv_space;
524         /* Build the transfer_from list and check the limits */
525 @@ -1828,7 +1856,7 @@ int dquot_transfer(struct inode *inode,
526                 inode->i_dquot[cnt] = transfer_to[cnt];
527         }
528         spin_unlock(&dq_data_lock);
529 -       up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
530 +       spin_unlock(&inode->i_lock);
531  
532         /* Dirtify all the dquots - this can block when journalling */
533         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
534 @@ -1852,7 +1880,7 @@ put_all:
535         return ret;
536  over_quota:
537         spin_unlock(&dq_data_lock);
538 -       up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
539 +       spin_unlock(&inode->i_lock);
540         /* Clear dquot pointers we don't want to dqput() */
541         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
542                 transfer_from[cnt] = NULL;
543 @@ -2104,13 +2132,13 @@ static int vfs_load_quota_inode(struct i
544                 /* We don't want quota and atime on quota files (deadlocks
545                  * possible) Also nobody should write to the file - we use
546                  * special IO operations which ignore the immutable bit. */
547 -               down_write(&dqopt->dqptr_sem);
548                 mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
549 +               spin_lock(&inode->i_lock);
550                 oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE |
551                                              S_NOQUOTA);
552                 inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
553 +               spin_unlock(&inode->i_lock);
554                 mutex_unlock(&inode->i_mutex);
555 -               up_write(&dqopt->dqptr_sem);
556                 sb->dq_op->drop(inode);
557         }
558  
559 @@ -2147,14 +2175,14 @@ out_file_init:
560         iput(inode);
561  out_lock:
562         if (oldflags != -1) {
563 -               down_write(&dqopt->dqptr_sem);
564                 mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
565 +               spin_lock(&inode->i_lock);
566                 /* Set the flags back (in the case of accidental quotaon()
567                  * on a wrong file we don't want to mess up the flags) */
568                 inode->i_flags &= ~(S_NOATIME | S_NOQUOTA | S_IMMUTABLE);
569                 inode->i_flags |= oldflags;
570 +               spin_unlock(&inode->i_lock);
571                 mutex_unlock(&inode->i_mutex);
572 -               up_write(&dqopt->dqptr_sem);
573         }
574         mutex_unlock(&dqopt->dqonoff_mutex);
575  out_fmt:
576 diff -urp linux-2.6.32-53.7.orig/fs/quota/quota.c linux-2.6.32.46-0/fs/quota/quota.c
577 --- linux-2.6.32-53.7.orig/fs/quota/quota.c     2009-12-02 22:51:21.000000000 -0500
578 +++ linux-2.6.32-53.7/fs/quota/quota.c  2013-04-26 11:59:22.000000000 -0400
579 @@ -255,13 +255,13 @@ static int do_quotactl(struct super_bloc
580                 case Q_GETFMT: {
581                         __u32 fmt;
582  
583 -                       down_read(&sb_dqopt(sb)->dqptr_sem);
584 +                       mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
585                         if (!sb_has_quota_active(sb, type)) {
586 -                               up_read(&sb_dqopt(sb)->dqptr_sem);
587 +                               mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
588                                 return -ESRCH;
589                         }
590                         fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id;
591 -                       up_read(&sb_dqopt(sb)->dqptr_sem);
592 +                       mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
593                         if (copy_to_user(addr, &fmt, sizeof(fmt)))
594                                 return -EFAULT;
595                         return 0;
596 diff -urp linux-2.6.32-53.7.orig/fs/stat.c linux-2.6.32.46-0/fs/stat.c
597 --- linux-2.6.32-53.7.orig/fs/stat.c    2013-04-26 11:56:28.000000000 -0400
598 +++ linux-2.6.32-53.7/fs/stat.c 2013-04-26 11:59:22.000000000 -0400
599 @@ -422,9 +422,8 @@ void inode_add_bytes(struct inode *inode
600  
601  EXPORT_SYMBOL(inode_add_bytes);
602  
603 -void inode_sub_bytes(struct inode *inode, loff_t bytes)
604 +void __inode_sub_bytes(struct inode *inode, loff_t bytes)
605  {
606 -       spin_lock(&inode->i_lock);
607         inode->i_blocks -= bytes >> 9;
608         bytes &= 511;
609         if (inode->i_bytes < bytes) {
610 @@ -432,17 +431,28 @@ void inode_sub_bytes(struct inode *inode
611                 inode->i_bytes += 512;
612         }
613         inode->i_bytes -= bytes;
614 +}
615 +
616 +void inode_sub_bytes(struct inode *inode, loff_t bytes)
617 +{
618 +       spin_lock(&inode->i_lock);
619 +       __inode_sub_bytes(inode, bytes);
620         spin_unlock(&inode->i_lock);
621  }
622  
623  EXPORT_SYMBOL(inode_sub_bytes);
624  
625 +loff_t __inode_get_bytes(struct inode *inode)
626 +{
627 +       return (((loff_t)inode->i_blocks) << 9) + inode->i_bytes;
628 +}
629 +
630  loff_t inode_get_bytes(struct inode *inode)
631  {
632         loff_t ret;
633  
634         spin_lock(&inode->i_lock);
635 -       ret = (((loff_t)inode->i_blocks) << 9) + inode->i_bytes;
636 +       ret = __inode_get_bytes(inode);
637         spin_unlock(&inode->i_lock);
638         return ret;
639  }
640 diff -urp linux-2.6.32-53.7.orig/fs/super.c linux-2.6.32.46-0/fs/super.c
641 --- linux-2.6.32-53.7.orig/fs/super.c   2013-04-26 11:56:52.000000000 -0400
642 +++ linux-2.6.32-53.7/fs/super.c        2013-04-26 11:59:22.000000000 -0400
643 @@ -98,7 +98,6 @@ static struct super_block *alloc_super(s
644                 mutex_init(&s->s_vfs_rename_mutex);
645                 mutex_init(&s->s_dquot.dqio_mutex);
646                 mutex_init(&s->s_dquot.dqonoff_mutex);
647 -               init_rwsem(&s->s_dquot.dqptr_sem);
648                 init_waitqueue_head(&s->s_wait_unfrozen);
649                 s->s_maxbytes = MAX_NON_LFS;
650                 s->dq_op = sb_dquot_ops;
651 diff -urp linux-2.6.32-53.7.orig/include/linux/fs.h linux-2.6.32.46-0/include/linux/fs.h
652 --- linux-2.6.32-53.7.orig/include/linux/fs.h   2013-04-26 11:56:52.000000000 -0400
653 +++ linux-2.6.32-53.7/include/linux/fs.h        2013-04-26 11:59:22.000000000 -0400
654 @@ -2356,7 +2356,9 @@ extern void generic_fillattr(struct inod
655  extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
656  void __inode_add_bytes(struct inode *inode, loff_t bytes);
657  void inode_add_bytes(struct inode *inode, loff_t bytes);
658 +void __inode_sub_bytes(struct inode *inode, loff_t bytes);
659  void inode_sub_bytes(struct inode *inode, loff_t bytes);
660 +loff_t __inode_get_bytes(struct inode *inode);
661  loff_t inode_get_bytes(struct inode *inode);
662  void inode_set_bytes(struct inode *inode, loff_t bytes);
663