~ubuntu-branches/ubuntu/vivid/aufs/vivid

« back to all changes in this revision

Viewing changes to fs/aufs25/wkq.c

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2008-08-21 14:58:54 UTC
  • mfrom: (1.1.8 upstream) (4.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080821145854-4b49x09r4zmvlk5o
Tags: 0+20080719-4
01_vserver_apparmor.dpatch: [UPDATE] Disable vserver patches on kernel 
2.6.26, because they are not needed anymore. (Closes: #495921)

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
/*
20
20
 * workqueue for asynchronous/super-io/delegated operations
21
21
 *
22
 
 * $Id: wkq.c,v 1.6 2008/06/02 02:35:50 sfjro Exp $
 
22
 * $Id: wkq.c,v 1.10 2008/07/14 00:17:48 sfjro Exp $
23
23
 */
24
24
 
25
25
#include <linux/module.h>
195
195
        }
196
196
}
197
197
 
 
198
#if defined(CONFIG_4KSTACKS) || defined(Test4KSTACKS)
 
199
#define AuWkqCompDeclare(name)  struct completion *comp = NULL
 
200
 
 
201
static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
 
202
{
 
203
        *comp = kmalloc(sizeof(**comp), GFP_NOFS);
 
204
        if (*comp) {
 
205
                init_completion(*comp);
 
206
                wkinfo->comp = *comp;
 
207
                return 0;
 
208
        }
 
209
        return -ENOMEM;
 
210
}
 
211
 
 
212
static void au_wkq_comp_free(struct completion *comp)
 
213
{
 
214
        kfree(comp);
 
215
}
 
216
 
 
217
#else
 
218
 
 
219
#define AuWkqCompDeclare(name) \
 
220
        DECLARE_COMPLETION_ONSTACK(_ ## name); \
 
221
        struct completion *comp = &_ ## name
 
222
 
 
223
static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp)
 
224
{
 
225
        wkinfo->comp = *comp;
 
226
        return 0;
 
227
}
 
228
 
 
229
static void au_wkq_comp_free(struct completion *comp)
 
230
{
 
231
        /* empty */
 
232
}
 
233
#endif /* 4KSTACKS */
 
234
 
198
235
int au_wkq_run(au_wkq_func_t func, void *args, struct super_block *sb,
199
236
               unsigned int flags)
200
237
{
201
 
        int err, do_wait;
202
 
        DECLARE_COMPLETION_ONSTACK(comp);
 
238
        int err;
 
239
        AuWkqCompDeclare(comp);
203
240
        struct au_wkinfo _wkinfo = {
204
241
                .flags  = flags,
205
242
                .func   = func,
206
 
                .args   = args,
207
 
                .comp   = &comp
 
243
                .args   = args
208
244
        }, *wkinfo = &_wkinfo;
 
245
        const unsigned char do_wait = au_ftest_wkq(flags, WAIT);
209
246
 
210
247
        LKTRTrace("0x%x\n", flags);
211
 
        /* in dlgt mode, inotify will be fired from aufsd */
212
 
        AuDebugOn(au_ftest_wkq(flags, DLGT) && au_test_wkq(current));
 
248
#if 1 /* tmp debug */
 
249
        if (au_test_wkq(current))
 
250
                au_dbg_blocked();
 
251
#endif
 
252
        AuDebugOn(au_test_wkq(current));
213
253
 
214
 
        err = 0;
215
 
        do_wait = au_ftest_wkq(flags, WAIT);
216
 
        if (unlikely(!do_wait)) {
 
254
        if (do_wait) {
 
255
                err = au_wkq_comp_alloc(wkinfo, &comp);
 
256
                if (unlikely(err))
 
257
                        goto out;
 
258
        } else {
217
259
                AuDebugOn(!sb);
218
260
                /*
219
261
                 * wkq_func() must free this wkinfo.
220
262
                 * it highly depends upon the implementation of workqueue.
221
263
                 */
222
264
                err = -ENOMEM;
223
 
                wkinfo = kmalloc(sizeof(*wkinfo), GFP_TEMPORARY);
 
265
                wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS);
224
266
                if (unlikely(!wkinfo))
225
267
                        goto out;
226
268
 
237
279
        INIT_WORK(&wkinfo->wk, wkq_func);
238
280
        dlgt_cred_store(flags, wkinfo);
239
281
        do_wkq(wkinfo);
240
 
        if (do_wait)
 
282
        if (do_wait) {
241
283
                /* no timeout, no interrupt */
242
284
                wait_for_completion(wkinfo->comp);
 
285
                au_wkq_comp_free(comp);
 
286
        }
243
287
 out:
244
288
        AuTraceErr(err);
245
289
        return err;
268
312
 
269
313
        /* '+1' is for accounting  of nowait queue */
270
314
        err = -ENOMEM;
271
 
        au_wkq = kcalloc(aufs_nwkq + 1, sizeof(*au_wkq), GFP_KERNEL);
 
315
        au_wkq = kcalloc(aufs_nwkq + 1, sizeof(*au_wkq), GFP_NOFS);
272
316
        if (unlikely(!au_wkq))
273
317
                goto out;
274
318
 
277
321
                au_wkq[i].q = create_singlethread_workqueue(AUFS_WKQ_NAME);
278
322
                if (au_wkq[i].q && !IS_ERR(au_wkq[i].q)) {
279
323
                        atomic_set(&au_wkq[i].busy, 0);
280
 
                        au_wkq[i].max_busy = 0;
 
324
                        au_wkq_max_busy_init(au_wkq + i);
281
325
                        continue;
282
326
                }
283
327
 
289
333
        /* nowait accounting */
290
334
        nowaitq = au_wkq + aufs_nwkq;
291
335
        atomic_set(&nowaitq->busy, 0);
292
 
        nowaitq->max_busy = 0;
 
336
        au_wkq_max_busy_init(nowaitq);
293
337
        nowaitq->q = NULL;
294
338
        /* smp_mb(); */ /* atomic_set */
295
339