~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to fs/exofs/super.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
 * struct to hold what we get from mount options
49
49
 */
50
50
struct exofs_mountopt {
 
51
        bool is_osdname;
51
52
        const char *dev_name;
52
53
        uint64_t pid;
53
54
        int timeout;
56
57
/*
57
58
 * exofs-specific mount-time options.
58
59
 */
59
 
enum { Opt_pid, Opt_to, Opt_mkfs, Opt_format, Opt_err };
 
60
enum { Opt_name, Opt_pid, Opt_to, Opt_err };
60
61
 
61
62
/*
62
63
 * Our mount-time options.  These should ideally be 64-bit unsigned, but the
64
65
 * sufficient for most applications now.
65
66
 */
66
67
static match_table_t tokens = {
 
68
        {Opt_name, "osdname=%s"},
67
69
        {Opt_pid, "pid=%u"},
68
70
        {Opt_to, "to=%u"},
69
71
        {Opt_err, NULL}
94
96
 
95
97
                token = match_token(p, tokens, args);
96
98
                switch (token) {
 
99
                case Opt_name:
 
100
                        opts->dev_name = match_strdup(&args[0]);
 
101
                        if (unlikely(!opts->dev_name)) {
 
102
                                EXOFS_ERR("Error allocating dev_name");
 
103
                                return -ENOMEM;
 
104
                        }
 
105
                        opts->is_osdname = true;
 
106
                        break;
97
107
                case Opt_pid:
98
108
                        if (0 == match_strlcpy(str, &args[0], sizeof(str)))
99
109
                                return -EINVAL;
203
213
static const struct super_operations exofs_sops;
204
214
static const struct export_operations exofs_export_ops;
205
215
 
 
216
static const struct osd_attr g_attr_sb_stats = ATTR_DEF(
 
217
        EXOFS_APAGE_SB_DATA,
 
218
        EXOFS_ATTR_SB_STATS,
 
219
        sizeof(struct exofs_sb_stats));
 
220
 
 
221
static int __sbi_read_stats(struct exofs_sb_info *sbi)
 
222
{
 
223
        struct osd_attr attrs[] = {
 
224
                [0] = g_attr_sb_stats,
 
225
        };
 
226
        struct exofs_io_state *ios;
 
227
        int ret;
 
228
 
 
229
        ret = exofs_get_io_state(&sbi->layout, &ios);
 
230
        if (unlikely(ret)) {
 
231
                EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__);
 
232
                return ret;
 
233
        }
 
234
 
 
235
        ios->cred = sbi->s_cred;
 
236
 
 
237
        ios->in_attr = attrs;
 
238
        ios->in_attr_len = ARRAY_SIZE(attrs);
 
239
 
 
240
        ret = exofs_sbi_read(ios);
 
241
        if (unlikely(ret)) {
 
242
                EXOFS_ERR("Error reading super_block stats => %d\n", ret);
 
243
                goto out;
 
244
        }
 
245
 
 
246
        ret = extract_attr_from_ios(ios, &attrs[0]);
 
247
        if (ret) {
 
248
                EXOFS_ERR("%s: extract_attr of sb_stats failed\n", __func__);
 
249
                goto out;
 
250
        }
 
251
        if (attrs[0].len) {
 
252
                struct exofs_sb_stats *ess;
 
253
 
 
254
                if (unlikely(attrs[0].len != sizeof(*ess))) {
 
255
                        EXOFS_ERR("%s: Wrong version of exofs_sb_stats "
 
256
                                  "size(%d) != expected(%zd)\n",
 
257
                                  __func__, attrs[0].len, sizeof(*ess));
 
258
                        goto out;
 
259
                }
 
260
 
 
261
                ess = attrs[0].val_ptr;
 
262
                sbi->s_nextid = le64_to_cpu(ess->s_nextid);
 
263
                sbi->s_numfiles = le32_to_cpu(ess->s_numfiles);
 
264
        }
 
265
 
 
266
out:
 
267
        exofs_put_io_state(ios);
 
268
        return ret;
 
269
}
 
270
 
 
271
static void stats_done(struct exofs_io_state *ios, void *p)
 
272
{
 
273
        exofs_put_io_state(ios);
 
274
        /* Good thanks nothing to do anymore */
 
275
}
 
276
 
 
277
/* Asynchronously write the stats attribute */
 
278
int exofs_sbi_write_stats(struct exofs_sb_info *sbi)
 
279
{
 
280
        struct osd_attr attrs[] = {
 
281
                [0] = g_attr_sb_stats,
 
282
        };
 
283
        struct exofs_io_state *ios;
 
284
        int ret;
 
285
 
 
286
        ret = exofs_get_io_state(&sbi->layout, &ios);
 
287
        if (unlikely(ret)) {
 
288
                EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__);
 
289
                return ret;
 
290
        }
 
291
 
 
292
        sbi->s_ess.s_nextid   = cpu_to_le64(sbi->s_nextid);
 
293
        sbi->s_ess.s_numfiles = cpu_to_le64(sbi->s_numfiles);
 
294
        attrs[0].val_ptr = &sbi->s_ess;
 
295
 
 
296
        ios->cred = sbi->s_cred;
 
297
        ios->done = stats_done;
 
298
        ios->private = sbi;
 
299
        ios->out_attr = attrs;
 
300
        ios->out_attr_len = ARRAY_SIZE(attrs);
 
301
 
 
302
        ret = exofs_sbi_write(ios);
 
303
        if (unlikely(ret)) {
 
304
                EXOFS_ERR("%s: exofs_sbi_write failed.\n", __func__);
 
305
                exofs_put_io_state(ios);
 
306
        }
 
307
 
 
308
        return ret;
 
309
}
 
310
 
206
311
/*
207
312
 * Write the superblock to the OSD
208
313
 */
213
318
        struct exofs_io_state *ios;
214
319
        int ret = -ENOMEM;
215
320
 
 
321
        fscb = kmalloc(sizeof(*fscb), GFP_KERNEL);
 
322
        if (unlikely(!fscb))
 
323
                return -ENOMEM;
 
324
 
 
325
        sbi = sb->s_fs_info;
 
326
 
 
327
        /* NOTE: We no longer dirty the super_block anywhere in exofs. The
 
328
         * reason we write the fscb here on unmount is so we can stay backwards
 
329
         * compatible with fscb->s_version == 1. (What we are not compatible
 
330
         * with is if a new version FS crashed and then we try to mount an old
 
331
         * version). Otherwise the exofs_fscb is read-only from mkfs time. All
 
332
         * the writeable info is set in exofs_sbi_write_stats() above.
 
333
         */
 
334
        ret = exofs_get_io_state(&sbi->layout, &ios);
 
335
        if (unlikely(ret))
 
336
                goto out;
 
337
 
216
338
        lock_super(sb);
217
 
        sbi = sb->s_fs_info;
218
 
        fscb = &sbi->s_fscb;
219
 
 
220
 
        ret = exofs_get_io_state(&sbi->layout, &ios);
221
 
        if (ret)
222
 
                goto out;
223
 
 
224
 
        /* Note: We only write the changing part of the fscb. .i.e upto the
225
 
         *       the fscb->s_dev_table_oid member. There is no read-modify-write
226
 
         *       here.
227
 
         */
 
339
 
228
340
        ios->length = offsetof(struct exofs_fscb, s_dev_table_oid);
229
341
        memset(fscb, 0, ios->length);
230
342
        fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
239
351
        ios->cred = sbi->s_cred;
240
352
 
241
353
        ret = exofs_sbi_write(ios);
242
 
        if (unlikely(ret)) {
 
354
        if (unlikely(ret))
243
355
                EXOFS_ERR("%s: exofs_sbi_write failed.\n", __func__);
244
 
                goto out;
245
 
        }
246
 
        sb->s_dirt = 0;
247
 
 
 
356
        else
 
357
                sb->s_dirt = 0;
 
358
 
 
359
 
 
360
        unlock_super(sb);
248
361
out:
249
362
        EXOFS_DBGMSG("s_nextid=0x%llx ret=%d\n", _LLU(sbi->s_nextid), ret);
250
363
        exofs_put_io_state(ios);
251
 
        unlock_super(sb);
 
364
        kfree(fscb);
252
365
        return ret;
253
366
}
254
367
 
292
405
        int num_pend;
293
406
        struct exofs_sb_info *sbi = sb->s_fs_info;
294
407
 
295
 
        if (sb->s_dirt)
296
 
                exofs_write_super(sb);
297
 
 
298
408
        /* make sure there are no pending commands */
299
409
        for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0;
300
410
             num_pend = atomic_read(&sbi->s_curr_pending)) {
301
411
                wait_queue_head_t wq;
 
412
 
 
413
                printk(KERN_NOTICE "%s: !!Pending operations in flight. "
 
414
                       "This is a BUG. please report to osd-dev@open-osd.org\n",
 
415
                       __func__);
302
416
                init_waitqueue_head(&wq);
303
417
                wait_event_timeout(wq,
304
418
                                  (atomic_read(&sbi->s_curr_pending) == 0),
390
504
        return 0;
391
505
}
392
506
 
 
507
static unsigned __ra_pages(struct exofs_layout *layout)
 
508
{
 
509
        const unsigned _MIN_RA = 32; /* min 128K read-ahead */
 
510
        unsigned ra_pages = layout->group_width * layout->stripe_unit /
 
511
                                PAGE_SIZE;
 
512
        unsigned max_io_pages = exofs_max_io_pages(layout, ~0);
 
513
 
 
514
        ra_pages *= 2; /* two stripes */
 
515
        if (ra_pages < _MIN_RA)
 
516
                ra_pages = roundup(_MIN_RA, ra_pages / 2);
 
517
 
 
518
        if (ra_pages > max_io_pages)
 
519
                ra_pages = max_io_pages;
 
520
 
 
521
        return ra_pages;
 
522
}
 
523
 
393
524
/* @odi is valid only as long as @fscb_dev is valid */
394
525
static int exofs_devs_2_odi(struct exofs_dt_device_info *dt_dev,
395
526
                             struct osd_dev_info *odi)
495
626
                }
496
627
 
497
628
                od = osduld_info_lookup(&odi);
498
 
                if (unlikely(IS_ERR(od))) {
 
629
                if (IS_ERR(od)) {
499
630
                        ret = PTR_ERR(od);
500
631
                        EXOFS_ERR("ERROR: device requested is not found "
501
632
                                  "osd_name-%s =>%d\n", odi.osdname, ret);
558
689
                goto free_bdi;
559
690
 
560
691
        /* use mount options to fill superblock */
561
 
        od = osduld_path_lookup(opts->dev_name);
 
692
        if (opts->is_osdname) {
 
693
                struct osd_dev_info odi = {.systemid_len = 0};
 
694
 
 
695
                odi.osdname_len = strlen(opts->dev_name);
 
696
                odi.osdname = (u8 *)opts->dev_name;
 
697
                od = osduld_info_lookup(&odi);
 
698
        } else {
 
699
                od = osduld_path_lookup(opts->dev_name);
 
700
        }
562
701
        if (IS_ERR(od)) {
563
 
                ret = PTR_ERR(od);
 
702
                ret = -EINVAL;
564
703
                goto free_sbi;
565
704
        }
566
705
 
594
733
                goto free_sbi;
595
734
 
596
735
        sb->s_magic = le16_to_cpu(fscb.s_magic);
 
736
        /* NOTE: we read below to be backward compatible with old versions */
597
737
        sbi->s_nextid = le64_to_cpu(fscb.s_nextid);
598
738
        sbi->s_numfiles = le32_to_cpu(fscb.s_numfiles);
599
739
 
604
744
                ret = -EINVAL;
605
745
                goto free_sbi;
606
746
        }
607
 
        if (le32_to_cpu(fscb.s_version) != EXOFS_FSCB_VER) {
 
747
        if (le32_to_cpu(fscb.s_version) > EXOFS_FSCB_VER) {
608
748
                EXOFS_ERR("ERROR: Bad FSCB version expected-%d got-%d\n",
609
749
                          EXOFS_FSCB_VER, le32_to_cpu(fscb.s_version));
610
750
                ret = -EINVAL;
622
762
                        goto free_sbi;
623
763
        }
624
764
 
 
765
        __sbi_read_stats(sbi);
 
766
 
625
767
        /* set up operation vectors */
 
768
        sbi->bdi.ra_pages = __ra_pages(&sbi->layout);
626
769
        sb->s_bdi = &sbi->bdi;
627
770
        sb->s_fs_info = sbi;
628
771
        sb->s_op = &exofs_sops;
652
795
 
653
796
        _exofs_print_device("Mounting", opts->dev_name, sbi->layout.s_ods[0],
654
797
                            sbi->layout.s_pid);
 
798
        if (opts->is_osdname)
 
799
                kfree(opts->dev_name);
655
800
        return 0;
656
801
 
657
802
free_sbi:
660
805
        EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n",
661
806
                  opts->dev_name, sbi->layout.s_pid, ret);
662
807
        exofs_free_sbi(sbi);
 
808
        if (opts->is_osdname)
 
809
                kfree(opts->dev_name);
663
810
        return ret;
664
811
}
665
812
 
677
824
        if (ret)
678
825
                return ERR_PTR(ret);
679
826
 
680
 
        opts.dev_name = dev_name;
 
827
        if (!opts.dev_name)
 
828
                opts.dev_name = dev_name;
681
829
        return mount_nodev(type, flags, &opts, exofs_fill_super);
682
830
}
683
831