Whamcloud - gitweb
1e231162ea48836bd147659f4e11859eac3ee9af
[fs/lustre-release.git] / lustre / kernel_patches / patches / quota-avoid-dqget-calls-sles11sp2.patch
1 In dquot_initialize(), we'd call dqget() only when i_dquot not
2 initialized, which can avoid 2 pair of dqget()/dqput() in most
3 case. It could relieve the global locks contenion caused by
4 dqget()/dqput().
5 --- linux-3.0/fs/quota/dquot.c.orig     2013-07-18 09:46:28.000000000 -0400
6 +++ linux-3.0/fs/quota/dquot.c  2013-07-18 09:49:20.000000000 -0400
7 @@ -1342,8 +1342,8 @@
8  static void __dquot_initialize(struct inode *inode, int type)
9  {
10         unsigned int id = 0;
11 -       int cnt;
12 -       struct dquot *got[MAXQUOTAS];
13 +       int cnt, ret = 0, dq_get = 0;
14 +       struct dquot *got[MAXQUOTAS] = { NULL, NULL };
15         struct super_block *sb = inode->i_sb;
16         qsize_t rsv;
17  
18 @@ -1352,7 +1352,14 @@
19         if (!dquot_active(inode))
20                 return;
21  
22 -       /* First get references to structures we might need. */
23 +       /* In most case, the i_dquot should have been initialized, except
24 +        * the newly allocated one. We'd always try to skip the dqget() and
25 +        * dqput() calls to avoid unnecessary global lock contention. */
26 +       if (!(inode->i_state & I_NEW))
27 +               goto init_idquot;
28 +
29 +get_dquots:
30 +       dq_get = 1;
31         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
32                 got[cnt] = NULL;
33                 if (type != -1 && cnt != type)
34 @@ -1367,7 +1374,7 @@
35                 }
36                 got[cnt] = dqget(sb, id, cnt);
37         }
38 -
39 +init_idquot:
40         spin_lock(&inode->i_lock);
41         if (IS_NOQUOTA(inode))
42                 goto out_err;
43 @@ -1381,10 +1388,14 @@
44                 /* Avoid races with quotaoff() */
45                 if (!sb_has_quota_active(sb, cnt))
46                         continue;
47 -               /* We could race with quotaon or dqget() could have failed */
48 -               if (!got[cnt])
49 -                       continue;
50                 if (!inode->i_dquot[cnt]) {
51 +                       if (dq_get == 0) {
52 +                               spin_unlock(&inode->i_lock);
53 +                               goto get_dquots;
54 +                       }
55 +                       /* We could race with quotaon or dqget() could have failed */
56 +                       if (!got[cnt])
57 +                               continue;
58                         inode->i_dquot[cnt] = got[cnt];
59                         got[cnt] = NULL;
60                         /*
61 @@ -1388,7 +1399,7 @@
62                          * did a write before quota was turned on
63                          */
64                         rsv = inode_get_rsv_space(inode);
65 -                       if (unlikely(rsv)) {
66 +                       if (unlikely(rsv) && likely(inode->i_dquot[cnt])) {
67                                 spin_lock(&dq_data_lock);
68                                 dquot_resv_space(inode->i_dquot[cnt], rsv);
69                                 spin_unlock(&dq_data_lock);
70 @@ -1488,7 +1399,8 @@
71         spin_unlock(&inode->i_lock);
72  
73         /* Drop unused references */
74 -       dqput_all(got);
75 +       if (dq_get)
76 +               dqput_all(got);
77  }
78  
79  void dquot_initialize(struct inode *inode)