diff options
Diffstat (limited to 'fs/ubifs')
-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 |
6 files changed, 102 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; |