diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-17 12:46:33 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-17 12:46:33 -0400 |
| commit | b7c142dbf1e7422d0be7f7faa3f1163ad9da9788 (patch) | |
| tree | 6e62c8654bb9c329f89246235062ac2a289960df | |
| parent | 0bd8df908de2aefe312d05bd25cd3abc21a6d1da (diff) | |
| parent | f2c5dbd7b7396457efc114f825acfdd4db4608f8 (diff) | |
Merge branch 'linux-next' of git://git.infradead.org/ubifs-2.6
* 'linux-next' of git://git.infradead.org/ubifs-2.6:
UBIFS: start using hrtimers
hrtimer: export ktime_add_safe
UBIFS: do not forget to register BDI device
UBIFS: allow sync option in rootflags
UBIFS: remove dead code
UBIFS: use anonymous device
UBIFS: return proper error code if the compr is not present
UBIFS: return error if link and unlink race
UBIFS: reset no_space flag after inode deletion
| -rw-r--r-- | fs/ubifs/budget.c | 4 | ||||
| -rw-r--r-- | fs/ubifs/dir.c | 19 | ||||
| -rw-r--r-- | fs/ubifs/io.c | 34 | ||||
| -rw-r--r-- | fs/ubifs/recovery.c | 31 | ||||
| -rw-r--r-- | fs/ubifs/super.c | 73 | ||||
| -rw-r--r-- | fs/ubifs/ubifs.h | 13 | ||||
| -rw-r--r-- | kernel/hrtimer.c | 2 |
7 files changed, 104 insertions, 72 deletions
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index af1914462f02..eaf6d891d46f 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c | |||
| @@ -91,7 +91,6 @@ static int shrink_liability(struct ubifs_info *c, int nr_to_write) | |||
| 91 | return nr_written; | 91 | return nr_written; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | |||
| 95 | /** | 94 | /** |
| 96 | * run_gc - run garbage collector. | 95 | * run_gc - run garbage collector. |
| 97 | * @c: UBIFS file-system description object | 96 | * @c: UBIFS file-system description object |
| @@ -628,7 +627,7 @@ void ubifs_convert_page_budget(struct ubifs_info *c) | |||
| 628 | * | 627 | * |
| 629 | * This function releases budget corresponding to a dirty inode. It is usually | 628 | * This function releases budget corresponding to a dirty inode. It is usually |
| 630 | * called when after the inode has been written to the media and marked as | 629 | * called when after the inode has been written to the media and marked as |
| 631 | * clean. | 630 | * clean. It also causes the "no space" flags to be cleared. |
| 632 | */ | 631 | */ |
| 633 | void ubifs_release_dirty_inode_budget(struct ubifs_info *c, | 632 | void ubifs_release_dirty_inode_budget(struct ubifs_info *c, |
| 634 | struct ubifs_inode *ui) | 633 | struct ubifs_inode *ui) |
| @@ -636,6 +635,7 @@ void ubifs_release_dirty_inode_budget(struct ubifs_info *c, | |||
| 636 | struct ubifs_budget_req req; | 635 | struct ubifs_budget_req req; |
| 637 | 636 | ||
| 638 | memset(&req, 0, sizeof(struct ubifs_budget_req)); | 637 | memset(&req, 0, sizeof(struct ubifs_budget_req)); |
| 638 | /* The "no space" flags will be cleared because dd_growth is > 0 */ | ||
| 639 | req.dd_growth = c->inode_budget + ALIGN(ui->data_len, 8); | 639 | req.dd_growth = c->inode_budget + ALIGN(ui->data_len, 8); |
| 640 | ubifs_release_budget(c, &req); | 640 | ubifs_release_budget(c, &req); |
| 641 | } | 641 | } |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index f55d523c52bb..552fb0111fff 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
| @@ -528,6 +528,25 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 528 | inode->i_nlink, dir->i_ino); | 528 | inode->i_nlink, dir->i_ino); |
| 529 | ubifs_assert(mutex_is_locked(&dir->i_mutex)); | 529 | ubifs_assert(mutex_is_locked(&dir->i_mutex)); |
| 530 | ubifs_assert(mutex_is_locked(&inode->i_mutex)); | 530 | ubifs_assert(mutex_is_locked(&inode->i_mutex)); |
| 531 | |||
| 532 | /* | ||
| 533 | * Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing | ||
| 534 | * otherwise has the potential to corrupt the orphan inode list. | ||
| 535 | * | ||
| 536 | * Indeed, consider a scenario when 'vfs_link(dirA/fileA)' and | ||
| 537 | * 'vfs_unlink(dirA/fileA, dirB/fileB)' race. 'vfs_link()' does not | ||
| 538 | * lock 'dirA->i_mutex', so this is possible. Both of the functions | ||
| 539 | * lock 'fileA->i_mutex' though. Suppose 'vfs_unlink()' wins, and takes | ||
| 540 | * 'fileA->i_mutex' mutex first. Suppose 'fileA->i_nlink' is 1. In this | ||
| 541 | * case 'ubifs_unlink()' will drop the last reference, and put 'inodeA' | ||
| 542 | * to the list of orphans. After this, 'vfs_link()' will link | ||
| 543 | * 'dirB/fileB' to 'inodeA'. This is a problem because, for example, | ||
| 544 | * the subsequent 'vfs_unlink(dirB/fileB)' will add the same inode | ||
| 545 | * to the list of orphans. | ||
| 546 | */ | ||
| 547 | if (inode->i_nlink == 0) | ||
| 548 | return -ENOENT; | ||
| 549 | |||
| 531 | err = dbg_check_synced_i_size(inode); | 550 | err = dbg_check_synced_i_size(inode); |
| 532 | if (err) | 551 | if (err) |
| 533 | return err; | 552 | return err; |
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index e8e632a1dcdf..bc5857199ec2 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c | |||
| @@ -293,13 +293,14 @@ void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last) | |||
| 293 | * | 293 | * |
| 294 | * This function is called when the write-buffer timer expires. | 294 | * This function is called when the write-buffer timer expires. |
| 295 | */ | 295 | */ |
| 296 | static void wbuf_timer_callback_nolock(unsigned long data) | 296 | static enum hrtimer_restart wbuf_timer_callback_nolock(struct hrtimer *timer) |
| 297 | { | 297 | { |
| 298 | struct ubifs_wbuf *wbuf = (struct ubifs_wbuf *)data; | 298 | struct ubifs_wbuf *wbuf = container_of(timer, struct ubifs_wbuf, timer); |
| 299 | 299 | ||
| 300 | wbuf->need_sync = 1; | 300 | wbuf->need_sync = 1; |
| 301 | wbuf->c->need_wbuf_sync = 1; | 301 | wbuf->c->need_wbuf_sync = 1; |
| 302 | ubifs_wake_up_bgt(wbuf->c); | 302 | ubifs_wake_up_bgt(wbuf->c); |
| 303 | return HRTIMER_NORESTART; | ||
| 303 | } | 304 | } |
| 304 | 305 | ||
| 305 | /** | 306 | /** |
| @@ -308,13 +309,12 @@ static void wbuf_timer_callback_nolock(unsigned long data) | |||
| 308 | */ | 309 | */ |
| 309 | static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | 310 | static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) |
| 310 | { | 311 | { |
| 311 | ubifs_assert(!timer_pending(&wbuf->timer)); | 312 | ubifs_assert(!hrtimer_active(&wbuf->timer)); |
| 312 | 313 | ||
| 313 | if (!wbuf->timeout) | 314 | if (!ktime_to_ns(wbuf->softlimit)) |
| 314 | return; | 315 | return; |
| 315 | 316 | hrtimer_start_range_ns(&wbuf->timer, wbuf->softlimit, wbuf->delta, | |
| 316 | wbuf->timer.expires = jiffies + wbuf->timeout; | 317 | HRTIMER_MODE_REL); |
| 317 | add_timer(&wbuf->timer); | ||
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | /** | 320 | /** |
| @@ -329,7 +329,7 @@ static void cancel_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | |||
| 329 | * should be canceled. | 329 | * should be canceled. |
| 330 | */ | 330 | */ |
| 331 | wbuf->need_sync = 0; | 331 | wbuf->need_sync = 0; |
| 332 | del_timer(&wbuf->timer); | 332 | hrtimer_cancel(&wbuf->timer); |
| 333 | } | 333 | } |
| 334 | 334 | ||
| 335 | /** | 335 | /** |
| @@ -825,6 +825,7 @@ out: | |||
| 825 | int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) | 825 | int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) |
| 826 | { | 826 | { |
| 827 | size_t size; | 827 | size_t size; |
| 828 | ktime_t hardlimit; | ||
| 828 | 829 | ||
| 829 | wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); | 830 | wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); |
| 830 | if (!wbuf->buf) | 831 | if (!wbuf->buf) |
| @@ -845,14 +846,21 @@ int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) | |||
| 845 | wbuf->sync_callback = NULL; | 846 | wbuf->sync_callback = NULL; |
| 846 | mutex_init(&wbuf->io_mutex); | 847 | mutex_init(&wbuf->io_mutex); |
| 847 | spin_lock_init(&wbuf->lock); | 848 | spin_lock_init(&wbuf->lock); |
| 848 | |||
| 849 | wbuf->c = c; | 849 | wbuf->c = c; |
| 850 | init_timer(&wbuf->timer); | ||
| 851 | wbuf->timer.function = wbuf_timer_callback_nolock; | ||
| 852 | wbuf->timer.data = (unsigned long)wbuf; | ||
| 853 | wbuf->timeout = DEFAULT_WBUF_TIMEOUT; | ||
| 854 | wbuf->next_ino = 0; | 850 | wbuf->next_ino = 0; |
| 855 | 851 | ||
| 852 | hrtimer_init(&wbuf->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
| 853 | wbuf->timer.function = wbuf_timer_callback_nolock; | ||
| 854 | /* | ||
| 855 | * Make write-buffer soft limit to be 20% of the hard limit. The | ||
| 856 | * write-buffer timer is allowed to expire any time between the soft | ||
| 857 | * and hard limits. | ||
| 858 | */ | ||
| 859 | hardlimit = ktime_set(DEFAULT_WBUF_TIMEOUT_SECS, 0); | ||
| 860 | wbuf->delta = (DEFAULT_WBUF_TIMEOUT_SECS * NSEC_PER_SEC) * 2 / 10; | ||
| 861 | wbuf->softlimit = ktime_sub_ns(hardlimit, wbuf->delta); | ||
| 862 | hrtimer_set_expires_range_ns(&wbuf->timer, wbuf->softlimit, | ||
| 863 | wbuf->delta); | ||
| 856 | return 0; | 864 | return 0; |
| 857 | } | 865 | } |
| 858 | 866 | ||
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index 10662975d2ef..805605250f12 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
| @@ -343,33 +343,15 @@ int ubifs_write_rcvrd_mst_node(struct ubifs_info *c) | |||
| 343 | * | 343 | * |
| 344 | * This function returns %1 if @offs was in the last write to the LEB whose data | 344 | * This function returns %1 if @offs was in the last write to the LEB whose data |
| 345 | * is in @buf, otherwise %0 is returned. The determination is made by checking | 345 | * is in @buf, otherwise %0 is returned. The determination is made by checking |
| 346 | * for subsequent empty space starting from the next min_io_size boundary (or a | 346 | * for subsequent empty space starting from the next @c->min_io_size boundary. |
| 347 | * bit less than the common header size if min_io_size is one). | ||
| 348 | */ | 347 | */ |
| 349 | static int is_last_write(const struct ubifs_info *c, void *buf, int offs) | 348 | static int is_last_write(const struct ubifs_info *c, void *buf, int offs) |
| 350 | { | 349 | { |
| 351 | int empty_offs; | 350 | int empty_offs, check_len; |
| 352 | int check_len; | ||
| 353 | uint8_t *p; | 351 | uint8_t *p; |
| 354 | 352 | ||
| 355 | if (c->min_io_size == 1) { | ||
| 356 | check_len = c->leb_size - offs; | ||
| 357 | p = buf + check_len; | ||
| 358 | for (; check_len > 0; check_len--) | ||
| 359 | if (*--p != 0xff) | ||
| 360 | break; | ||
| 361 | /* | ||
| 362 | * 'check_len' is the size of the corruption which cannot be | ||
| 363 | * more than the size of 1 node if it was caused by an unclean | ||
| 364 | * unmount. | ||
| 365 | */ | ||
| 366 | if (check_len > UBIFS_MAX_NODE_SZ) | ||
| 367 | return 0; | ||
| 368 | return 1; | ||
| 369 | } | ||
| 370 | |||
| 371 | /* | 353 | /* |
| 372 | * Round up to the next c->min_io_size boundary i.e. 'offs' is in the | 354 | * Round up to the next @c->min_io_size boundary i.e. @offs is in the |
| 373 | * last wbuf written. After that should be empty space. | 355 | * last wbuf written. After that should be empty space. |
| 374 | */ | 356 | */ |
| 375 | empty_offs = ALIGN(offs + 1, c->min_io_size); | 357 | empty_offs = ALIGN(offs + 1, c->min_io_size); |
| @@ -392,7 +374,7 @@ static int is_last_write(const struct ubifs_info *c, void *buf, int offs) | |||
| 392 | * | 374 | * |
| 393 | * This function pads up to the next min_io_size boundary (if there is one) and | 375 | * This function pads up to the next min_io_size boundary (if there is one) and |
| 394 | * sets empty space to all 0xff. @buf, @offs and @len are updated to the next | 376 | * sets empty space to all 0xff. @buf, @offs and @len are updated to the next |
| 395 | * min_io_size boundary (if there is one). | 377 | * @c->min_io_size boundary. |
| 396 | */ | 378 | */ |
| 397 | static void clean_buf(const struct ubifs_info *c, void **buf, int lnum, | 379 | static void clean_buf(const struct ubifs_info *c, void **buf, int lnum, |
| 398 | int *offs, int *len) | 380 | int *offs, int *len) |
| @@ -402,11 +384,6 @@ static void clean_buf(const struct ubifs_info *c, void **buf, int lnum, | |||
| 402 | lnum = lnum; | 384 | lnum = lnum; |
| 403 | dbg_rcvry("cleaning corruption at %d:%d", lnum, *offs); | 385 | dbg_rcvry("cleaning corruption at %d:%d", lnum, *offs); |
| 404 | 386 | ||
| 405 | if (c->min_io_size == 1) { | ||
| 406 | memset(*buf, 0xff, c->leb_size - *offs); | ||
| 407 | return; | ||
| 408 | } | ||
| 409 | |||
| 410 | ubifs_assert(!(*offs & 7)); | 387 | ubifs_assert(!(*offs & 7)); |
| 411 | empty_offs = ALIGN(*offs, c->min_io_size); | 388 | empty_offs = ALIGN(*offs, c->min_io_size); |
| 412 | pad_len = empty_offs - *offs; | 389 | pad_len = empty_offs - *offs; |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 3260b73abe29..79fad43f3c57 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
| @@ -361,6 +361,11 @@ static void ubifs_delete_inode(struct inode *inode) | |||
| 361 | out: | 361 | out: |
| 362 | if (ui->dirty) | 362 | if (ui->dirty) |
| 363 | ubifs_release_dirty_inode_budget(c, ui); | 363 | ubifs_release_dirty_inode_budget(c, ui); |
| 364 | else { | ||
| 365 | /* We've deleted something - clean the "no space" flags */ | ||
| 366 | c->nospace = c->nospace_rp = 0; | ||
| 367 | smp_wmb(); | ||
| 368 | } | ||
| 364 | clear_inode(inode); | 369 | clear_inode(inode); |
| 365 | } | 370 | } |
| 366 | 371 | ||
| @@ -792,7 +797,7 @@ static int alloc_wbufs(struct ubifs_info *c) | |||
| 792 | * does not need to be synchronized by timer. | 797 | * does not need to be synchronized by timer. |
| 793 | */ | 798 | */ |
| 794 | c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; | 799 | c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; |
| 795 | c->jheads[GCHD].wbuf.timeout = 0; | 800 | c->jheads[GCHD].wbuf.softlimit = ktime_set(0, 0); |
| 796 | 801 | ||
| 797 | return 0; | 802 | return 0; |
| 798 | } | 803 | } |
| @@ -933,6 +938,27 @@ static const match_table_t tokens = { | |||
| 933 | }; | 938 | }; |
| 934 | 939 | ||
| 935 | /** | 940 | /** |
| 941 | * parse_standard_option - parse a standard mount option. | ||
| 942 | * @option: the option to parse | ||
| 943 | * | ||
| 944 | * Normally, standard mount options like "sync" are passed to file-systems as | ||
| 945 | * flags. However, when a "rootflags=" kernel boot parameter is used, they may | ||
| 946 | * be present in the options string. This function tries to deal with this | ||
| 947 | * situation and parse standard options. Returns 0 if the option was not | ||
| 948 | * recognized, and the corresponding integer flag if it was. | ||
| 949 | * | ||
| 950 | * UBIFS is only interested in the "sync" option, so do not check for anything | ||
| 951 | * else. | ||
| 952 | */ | ||
| 953 | static int parse_standard_option(const char *option) | ||
| 954 | { | ||
| 955 | ubifs_msg("parse %s", option); | ||
| 956 | if (!strcmp(option, "sync")) | ||
| 957 | return MS_SYNCHRONOUS; | ||
| 958 | return 0; | ||
| 959 | } | ||
| 960 | |||
| 961 | /** | ||
| 936 | * ubifs_parse_options - parse mount parameters. | 962 | * ubifs_parse_options - parse mount parameters. |
| 937 | * @c: UBIFS file-system description object | 963 | * @c: UBIFS file-system description object |
| 938 | * @options: parameters to parse | 964 | * @options: parameters to parse |
| @@ -1008,9 +1034,19 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, | |||
| 1008 | break; | 1034 | break; |
| 1009 | } | 1035 | } |
| 1010 | default: | 1036 | default: |
| 1011 | ubifs_err("unrecognized mount option \"%s\" " | 1037 | { |
| 1012 | "or missing value", p); | 1038 | unsigned long flag; |
| 1013 | return -EINVAL; | 1039 | struct super_block *sb = c->vfs_sb; |
| 1040 | |||
| 1041 | flag = parse_standard_option(p); | ||
| 1042 | if (!flag) { | ||
| 1043 | ubifs_err("unrecognized mount option \"%s\" " | ||
| 1044 | "or missing value", p); | ||
| 1045 | return -EINVAL; | ||
| 1046 | } | ||
| 1047 | sb->s_flags |= flag; | ||
| 1048 | break; | ||
| 1049 | } | ||
| 1014 | } | 1050 | } |
| 1015 | } | 1051 | } |
| 1016 | 1052 | ||
| @@ -1180,6 +1216,7 @@ static int mount_ubifs(struct ubifs_info *c) | |||
| 1180 | if (!ubifs_compr_present(c->default_compr)) { | 1216 | if (!ubifs_compr_present(c->default_compr)) { |
| 1181 | ubifs_err("'compressor \"%s\" is not compiled in", | 1217 | ubifs_err("'compressor \"%s\" is not compiled in", |
| 1182 | ubifs_compr_name(c->default_compr)); | 1218 | ubifs_compr_name(c->default_compr)); |
| 1219 | err = -ENOTSUPP; | ||
| 1183 | goto out_free; | 1220 | goto out_free; |
| 1184 | } | 1221 | } |
| 1185 | 1222 | ||
| @@ -1656,7 +1693,7 @@ static void ubifs_remount_ro(struct ubifs_info *c) | |||
| 1656 | 1693 | ||
| 1657 | for (i = 0; i < c->jhead_cnt; i++) { | 1694 | for (i = 0; i < c->jhead_cnt; i++) { |
| 1658 | ubifs_wbuf_sync(&c->jheads[i].wbuf); | 1695 | ubifs_wbuf_sync(&c->jheads[i].wbuf); |
| 1659 | del_timer_sync(&c->jheads[i].wbuf.timer); | 1696 | hrtimer_cancel(&c->jheads[i].wbuf.timer); |
| 1660 | } | 1697 | } |
| 1661 | 1698 | ||
| 1662 | c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); | 1699 | c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); |
| @@ -1719,7 +1756,7 @@ static void ubifs_put_super(struct super_block *sb) | |||
| 1719 | if (c->jheads) | 1756 | if (c->jheads) |
| 1720 | for (i = 0; i < c->jhead_cnt; i++) { | 1757 | for (i = 0; i < c->jhead_cnt; i++) { |
| 1721 | ubifs_wbuf_sync(&c->jheads[i].wbuf); | 1758 | ubifs_wbuf_sync(&c->jheads[i].wbuf); |
| 1722 | del_timer_sync(&c->jheads[i].wbuf.timer); | 1759 | hrtimer_cancel(&c->jheads[i].wbuf.timer); |
| 1723 | } | 1760 | } |
| 1724 | 1761 | ||
| 1725 | /* | 1762 | /* |
| @@ -1911,6 +1948,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1911 | INIT_LIST_HEAD(&c->orph_list); | 1948 | INIT_LIST_HEAD(&c->orph_list); |
| 1912 | INIT_LIST_HEAD(&c->orph_new); | 1949 | INIT_LIST_HEAD(&c->orph_new); |
| 1913 | 1950 | ||
| 1951 | c->vfs_sb = sb; | ||
| 1914 | c->highest_inum = UBIFS_FIRST_INO; | 1952 | c->highest_inum = UBIFS_FIRST_INO; |
| 1915 | c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM; | 1953 | c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM; |
| 1916 | 1954 | ||
| @@ -1945,13 +1983,10 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1945 | if (err) | 1983 | if (err) |
| 1946 | goto out_bdi; | 1984 | goto out_bdi; |
| 1947 | 1985 | ||
| 1948 | c->vfs_sb = sb; | ||
| 1949 | |||
| 1950 | sb->s_fs_info = c; | 1986 | sb->s_fs_info = c; |
| 1951 | sb->s_magic = UBIFS_SUPER_MAGIC; | 1987 | sb->s_magic = UBIFS_SUPER_MAGIC; |
| 1952 | sb->s_blocksize = UBIFS_BLOCK_SIZE; | 1988 | sb->s_blocksize = UBIFS_BLOCK_SIZE; |
| 1953 | sb->s_blocksize_bits = UBIFS_BLOCK_SHIFT; | 1989 | sb->s_blocksize_bits = UBIFS_BLOCK_SHIFT; |
| 1954 | sb->s_dev = c->vi.cdev; | ||
| 1955 | sb->s_maxbytes = c->max_inode_sz = key_max_inode_size(c); | 1990 | sb->s_maxbytes = c->max_inode_sz = key_max_inode_size(c); |
| 1956 | if (c->max_inode_sz > MAX_LFS_FILESIZE) | 1991 | if (c->max_inode_sz > MAX_LFS_FILESIZE) |
| 1957 | sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; | 1992 | sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; |
| @@ -1996,16 +2031,9 @@ out_free: | |||
| 1996 | static int sb_test(struct super_block *sb, void *data) | 2031 | static int sb_test(struct super_block *sb, void *data) |
| 1997 | { | 2032 | { |
| 1998 | dev_t *dev = data; | 2033 | dev_t *dev = data; |
| 2034 | struct ubifs_info *c = sb->s_fs_info; | ||
| 1999 | 2035 | ||
| 2000 | return sb->s_dev == *dev; | 2036 | return c->vi.cdev == *dev; |
| 2001 | } | ||
| 2002 | |||
| 2003 | static int sb_set(struct super_block *sb, void *data) | ||
| 2004 | { | ||
| 2005 | dev_t *dev = data; | ||
| 2006 | |||
| 2007 | sb->s_dev = *dev; | ||
| 2008 | return 0; | ||
| 2009 | } | 2037 | } |
| 2010 | 2038 | ||
| 2011 | static int ubifs_get_sb(struct file_system_type *fs_type, int flags, | 2039 | static int ubifs_get_sb(struct file_system_type *fs_type, int flags, |
| @@ -2033,7 +2061,7 @@ static int ubifs_get_sb(struct file_system_type *fs_type, int flags, | |||
| 2033 | 2061 | ||
| 2034 | dbg_gen("opened ubi%d_%d", vi.ubi_num, vi.vol_id); | 2062 | dbg_gen("opened ubi%d_%d", vi.ubi_num, vi.vol_id); |
| 2035 | 2063 | ||
| 2036 | sb = sget(fs_type, &sb_test, &sb_set, &vi.cdev); | 2064 | sb = sget(fs_type, &sb_test, &set_anon_super, &vi.cdev); |
| 2037 | if (IS_ERR(sb)) { | 2065 | if (IS_ERR(sb)) { |
| 2038 | err = PTR_ERR(sb); | 2066 | err = PTR_ERR(sb); |
| 2039 | goto out_close; | 2067 | goto out_close; |
| @@ -2073,16 +2101,11 @@ out_close: | |||
| 2073 | return err; | 2101 | return err; |
| 2074 | } | 2102 | } |
| 2075 | 2103 | ||
| 2076 | static void ubifs_kill_sb(struct super_block *sb) | ||
| 2077 | { | ||
| 2078 | generic_shutdown_super(sb); | ||
| 2079 | } | ||
| 2080 | |||
| 2081 | static struct file_system_type ubifs_fs_type = { | 2104 | static struct file_system_type ubifs_fs_type = { |
| 2082 | .name = "ubifs", | 2105 | .name = "ubifs", |
| 2083 | .owner = THIS_MODULE, | 2106 | .owner = THIS_MODULE, |
| 2084 | .get_sb = ubifs_get_sb, | 2107 | .get_sb = ubifs_get_sb, |
| 2085 | .kill_sb = ubifs_kill_sb | 2108 | .kill_sb = kill_anon_super, |
| 2086 | }; | 2109 | }; |
| 2087 | 2110 | ||
| 2088 | /* | 2111 | /* |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 0a8341e14088..1bf01d820066 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
| @@ -95,8 +95,8 @@ | |||
| 95 | */ | 95 | */ |
| 96 | #define BGT_NAME_PATTERN "ubifs_bgt%d_%d" | 96 | #define BGT_NAME_PATTERN "ubifs_bgt%d_%d" |
| 97 | 97 | ||
| 98 | /* Default write-buffer synchronization timeout (5 secs) */ | 98 | /* Default write-buffer synchronization timeout in seconds */ |
| 99 | #define DEFAULT_WBUF_TIMEOUT (5 * HZ) | 99 | #define DEFAULT_WBUF_TIMEOUT_SECS 5 |
| 100 | 100 | ||
| 101 | /* Maximum possible inode number (only 32-bit inodes are supported now) */ | 101 | /* Maximum possible inode number (only 32-bit inodes are supported now) */ |
| 102 | #define MAX_INUM 0xFFFFFFFF | 102 | #define MAX_INUM 0xFFFFFFFF |
| @@ -650,8 +650,10 @@ typedef int (*ubifs_lpt_scan_callback)(struct ubifs_info *c, | |||
| 650 | * @io_mutex: serializes write-buffer I/O | 650 | * @io_mutex: serializes write-buffer I/O |
| 651 | * @lock: serializes @buf, @lnum, @offs, @avail, @used, @next_ino and @inodes | 651 | * @lock: serializes @buf, @lnum, @offs, @avail, @used, @next_ino and @inodes |
| 652 | * fields | 652 | * fields |
| 653 | * @softlimit: soft write-buffer timeout interval | ||
| 654 | * @delta: hard and soft timeouts delta (the timer expire inteval is @softlimit | ||
| 655 | * and @softlimit + @delta) | ||
| 653 | * @timer: write-buffer timer | 656 | * @timer: write-buffer timer |
| 654 | * @timeout: timer expire interval in jiffies | ||
| 655 | * @need_sync: it is set if its timer expired and needs sync | 657 | * @need_sync: it is set if its timer expired and needs sync |
| 656 | * @next_ino: points to the next position of the following inode number | 658 | * @next_ino: points to the next position of the following inode number |
| 657 | * @inodes: stores the inode numbers of the nodes which are in wbuf | 659 | * @inodes: stores the inode numbers of the nodes which are in wbuf |
| @@ -678,8 +680,9 @@ struct ubifs_wbuf { | |||
| 678 | int (*sync_callback)(struct ubifs_info *c, int lnum, int free, int pad); | 680 | int (*sync_callback)(struct ubifs_info *c, int lnum, int free, int pad); |
| 679 | struct mutex io_mutex; | 681 | struct mutex io_mutex; |
| 680 | spinlock_t lock; | 682 | spinlock_t lock; |
| 681 | struct timer_list timer; | 683 | ktime_t softlimit; |
| 682 | int timeout; | 684 | unsigned long long delta; |
| 685 | struct hrtimer timer; | ||
| 683 | int need_sync; | 686 | int need_sync; |
| 684 | int next_ino; | 687 | int next_ino; |
| 685 | ino_t *inodes; | 688 | ino_t *inodes; |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index b675a67c9ac3..9002958a96e7 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
| @@ -380,6 +380,8 @@ ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs) | |||
| 380 | return res; | 380 | return res; |
| 381 | } | 381 | } |
| 382 | 382 | ||
| 383 | EXPORT_SYMBOL_GPL(ktime_add_safe); | ||
| 384 | |||
| 383 | #ifdef CONFIG_DEBUG_OBJECTS_TIMERS | 385 | #ifdef CONFIG_DEBUG_OBJECTS_TIMERS |
| 384 | 386 | ||
| 385 | static struct debug_obj_descr hrtimer_debug_descr; | 387 | static struct debug_obj_descr hrtimer_debug_descr; |
