diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-17 09:04:38 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-17 09:04:38 -0400 |
| commit | 54e514b91b95d6441c12a7955addfb9f9d2afc65 (patch) | |
| tree | 8b73d901bd2a6ec5a31f34a8954e5ea92216dd6c /fs/nilfs2 | |
| parent | 4fc8adcfec3da639da76e8314c9ccefe5bf9a045 (diff) | |
| parent | 6c8c90319c0bb1c9e0b68e721359b89ae4f28465 (diff) | |
Merge branch 'akpm' (patches from Andrew)
Merge third patchbomb from Andrew Morton:
- various misc things
- a couple of lib/ optimisations
- provide DIV_ROUND_CLOSEST_ULL()
- checkpatch updates
- rtc tree
- befs, nilfs2, hfs, hfsplus, fatfs, adfs, affs, bfs
- ptrace fixes
- fork() fixes
- seccomp cleanups
- more mmap_sem hold time reductions from Davidlohr
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (138 commits)
proc: show locks in /proc/pid/fdinfo/X
docs: add missing and new /proc/PID/status file entries, fix typos
drivers/rtc/rtc-at91rm9200.c: make IO endian agnostic
Documentation/spi/spidev_test.c: fix warning
drivers/rtc/rtc-s5m.c: allow usage on device type different than main MFD type
.gitignore: ignore *.tar
MAINTAINERS: add Mediatek SoC mailing list
tomoyo: reduce mmap_sem hold for mm->exe_file
powerpc/oprofile: reduce mmap_sem hold for exe_file
oprofile: reduce mmap_sem hold for mm->exe_file
mips: ip32: add platform data hooks to use DS1685 driver
lib/Kconfig: fix up HAVE_ARCH_BITREVERSE help text
x86: switch to using asm-generic for seccomp.h
sparc: switch to using asm-generic for seccomp.h
powerpc: switch to using asm-generic for seccomp.h
parisc: switch to using asm-generic for seccomp.h
mips: switch to using asm-generic for seccomp.h
microblaze: use asm-generic for seccomp.h
arm: use asm-generic for seccomp.h
seccomp: allow COMPAT sigreturn overrides
...
Diffstat (limited to 'fs/nilfs2')
| -rw-r--r-- | fs/nilfs2/alloc.c | 5 | ||||
| -rw-r--r-- | fs/nilfs2/bmap.c | 48 | ||||
| -rw-r--r-- | fs/nilfs2/bmap.h | 13 | ||||
| -rw-r--r-- | fs/nilfs2/btree.c | 63 | ||||
| -rw-r--r-- | fs/nilfs2/cpfile.c | 58 | ||||
| -rw-r--r-- | fs/nilfs2/direct.c | 17 | ||||
| -rw-r--r-- | fs/nilfs2/inode.c | 25 | ||||
| -rw-r--r-- | fs/nilfs2/mdt.c | 54 | ||||
| -rw-r--r-- | fs/nilfs2/mdt.h | 10 | ||||
| -rw-r--r-- | fs/nilfs2/page.c | 24 | ||||
| -rw-r--r-- | fs/nilfs2/segment.c | 17 | ||||
| -rw-r--r-- | fs/nilfs2/super.c | 2 |
12 files changed, 274 insertions, 62 deletions
diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c index 741fd02e0444..8df0f3b7839b 100644 --- a/fs/nilfs2/alloc.c +++ b/fs/nilfs2/alloc.c | |||
| @@ -405,13 +405,14 @@ nilfs_palloc_rest_groups_in_desc_block(const struct inode *inode, | |||
| 405 | static int nilfs_palloc_count_desc_blocks(struct inode *inode, | 405 | static int nilfs_palloc_count_desc_blocks(struct inode *inode, |
| 406 | unsigned long *desc_blocks) | 406 | unsigned long *desc_blocks) |
| 407 | { | 407 | { |
| 408 | unsigned long blknum; | 408 | __u64 blknum; |
| 409 | int ret; | 409 | int ret; |
| 410 | 410 | ||
| 411 | ret = nilfs_bmap_last_key(NILFS_I(inode)->i_bmap, &blknum); | 411 | ret = nilfs_bmap_last_key(NILFS_I(inode)->i_bmap, &blknum); |
| 412 | if (likely(!ret)) | 412 | if (likely(!ret)) |
| 413 | *desc_blocks = DIV_ROUND_UP( | 413 | *desc_blocks = DIV_ROUND_UP( |
| 414 | blknum, NILFS_MDT(inode)->mi_blocks_per_desc_block); | 414 | (unsigned long)blknum, |
| 415 | NILFS_MDT(inode)->mi_blocks_per_desc_block); | ||
| 415 | return ret; | 416 | return ret; |
| 416 | } | 417 | } |
| 417 | 418 | ||
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c index aadbd0b5e3e8..27f75bcbeb30 100644 --- a/fs/nilfs2/bmap.c +++ b/fs/nilfs2/bmap.c | |||
| @@ -152,9 +152,7 @@ static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr) | |||
| 152 | * | 152 | * |
| 153 | * %-EEXIST - A record associated with @key already exist. | 153 | * %-EEXIST - A record associated with @key already exist. |
| 154 | */ | 154 | */ |
| 155 | int nilfs_bmap_insert(struct nilfs_bmap *bmap, | 155 | int nilfs_bmap_insert(struct nilfs_bmap *bmap, __u64 key, unsigned long rec) |
| 156 | unsigned long key, | ||
| 157 | unsigned long rec) | ||
| 158 | { | 156 | { |
| 159 | int ret; | 157 | int ret; |
| 160 | 158 | ||
| @@ -191,19 +189,47 @@ static int nilfs_bmap_do_delete(struct nilfs_bmap *bmap, __u64 key) | |||
| 191 | return bmap->b_ops->bop_delete(bmap, key); | 189 | return bmap->b_ops->bop_delete(bmap, key); |
| 192 | } | 190 | } |
| 193 | 191 | ||
| 194 | int nilfs_bmap_last_key(struct nilfs_bmap *bmap, unsigned long *key) | 192 | /** |
| 193 | * nilfs_bmap_seek_key - seek a valid entry and return its key | ||
| 194 | * @bmap: bmap struct | ||
| 195 | * @start: start key number | ||
| 196 | * @keyp: place to store valid key | ||
| 197 | * | ||
| 198 | * Description: nilfs_bmap_seek_key() seeks a valid key on @bmap | ||
| 199 | * starting from @start, and stores it to @keyp if found. | ||
| 200 | * | ||
| 201 | * Return Value: On success, 0 is returned. On error, one of the following | ||
| 202 | * negative error codes is returned. | ||
| 203 | * | ||
| 204 | * %-EIO - I/O error. | ||
| 205 | * | ||
| 206 | * %-ENOMEM - Insufficient amount of memory available. | ||
| 207 | * | ||
| 208 | * %-ENOENT - No valid entry was found | ||
| 209 | */ | ||
| 210 | int nilfs_bmap_seek_key(struct nilfs_bmap *bmap, __u64 start, __u64 *keyp) | ||
| 195 | { | 211 | { |
| 196 | __u64 lastkey; | ||
| 197 | int ret; | 212 | int ret; |
| 198 | 213 | ||
| 199 | down_read(&bmap->b_sem); | 214 | down_read(&bmap->b_sem); |
| 200 | ret = bmap->b_ops->bop_last_key(bmap, &lastkey); | 215 | ret = bmap->b_ops->bop_seek_key(bmap, start, keyp); |
| 216 | up_read(&bmap->b_sem); | ||
| 217 | |||
| 218 | if (ret < 0) | ||
| 219 | ret = nilfs_bmap_convert_error(bmap, __func__, ret); | ||
| 220 | return ret; | ||
| 221 | } | ||
| 222 | |||
| 223 | int nilfs_bmap_last_key(struct nilfs_bmap *bmap, __u64 *keyp) | ||
| 224 | { | ||
| 225 | int ret; | ||
| 226 | |||
| 227 | down_read(&bmap->b_sem); | ||
| 228 | ret = bmap->b_ops->bop_last_key(bmap, keyp); | ||
| 201 | up_read(&bmap->b_sem); | 229 | up_read(&bmap->b_sem); |
| 202 | 230 | ||
| 203 | if (ret < 0) | 231 | if (ret < 0) |
| 204 | ret = nilfs_bmap_convert_error(bmap, __func__, ret); | 232 | ret = nilfs_bmap_convert_error(bmap, __func__, ret); |
| 205 | else | ||
| 206 | *key = lastkey; | ||
| 207 | return ret; | 233 | return ret; |
| 208 | } | 234 | } |
| 209 | 235 | ||
| @@ -224,7 +250,7 @@ int nilfs_bmap_last_key(struct nilfs_bmap *bmap, unsigned long *key) | |||
| 224 | * | 250 | * |
| 225 | * %-ENOENT - A record associated with @key does not exist. | 251 | * %-ENOENT - A record associated with @key does not exist. |
| 226 | */ | 252 | */ |
| 227 | int nilfs_bmap_delete(struct nilfs_bmap *bmap, unsigned long key) | 253 | int nilfs_bmap_delete(struct nilfs_bmap *bmap, __u64 key) |
| 228 | { | 254 | { |
| 229 | int ret; | 255 | int ret; |
| 230 | 256 | ||
| @@ -235,7 +261,7 @@ int nilfs_bmap_delete(struct nilfs_bmap *bmap, unsigned long key) | |||
| 235 | return nilfs_bmap_convert_error(bmap, __func__, ret); | 261 | return nilfs_bmap_convert_error(bmap, __func__, ret); |
| 236 | } | 262 | } |
| 237 | 263 | ||
| 238 | static int nilfs_bmap_do_truncate(struct nilfs_bmap *bmap, unsigned long key) | 264 | static int nilfs_bmap_do_truncate(struct nilfs_bmap *bmap, __u64 key) |
| 239 | { | 265 | { |
| 240 | __u64 lastkey; | 266 | __u64 lastkey; |
| 241 | int ret; | 267 | int ret; |
| @@ -276,7 +302,7 @@ static int nilfs_bmap_do_truncate(struct nilfs_bmap *bmap, unsigned long key) | |||
| 276 | * | 302 | * |
| 277 | * %-ENOMEM - Insufficient amount of memory available. | 303 | * %-ENOMEM - Insufficient amount of memory available. |
| 278 | */ | 304 | */ |
| 279 | int nilfs_bmap_truncate(struct nilfs_bmap *bmap, unsigned long key) | 305 | int nilfs_bmap_truncate(struct nilfs_bmap *bmap, __u64 key) |
| 280 | { | 306 | { |
| 281 | int ret; | 307 | int ret; |
| 282 | 308 | ||
diff --git a/fs/nilfs2/bmap.h b/fs/nilfs2/bmap.h index b89e68076adc..bfa817ce40b3 100644 --- a/fs/nilfs2/bmap.h +++ b/fs/nilfs2/bmap.h | |||
| @@ -76,8 +76,10 @@ struct nilfs_bmap_operations { | |||
| 76 | union nilfs_binfo *); | 76 | union nilfs_binfo *); |
| 77 | int (*bop_mark)(struct nilfs_bmap *, __u64, int); | 77 | int (*bop_mark)(struct nilfs_bmap *, __u64, int); |
| 78 | 78 | ||
| 79 | /* The following functions are internal use only. */ | 79 | int (*bop_seek_key)(const struct nilfs_bmap *, __u64, __u64 *); |
| 80 | int (*bop_last_key)(const struct nilfs_bmap *, __u64 *); | 80 | int (*bop_last_key)(const struct nilfs_bmap *, __u64 *); |
| 81 | |||
| 82 | /* The following functions are internal use only. */ | ||
| 81 | int (*bop_check_insert)(const struct nilfs_bmap *, __u64); | 83 | int (*bop_check_insert)(const struct nilfs_bmap *, __u64); |
| 82 | int (*bop_check_delete)(struct nilfs_bmap *, __u64); | 84 | int (*bop_check_delete)(struct nilfs_bmap *, __u64); |
| 83 | int (*bop_gather_data)(struct nilfs_bmap *, __u64 *, __u64 *, int); | 85 | int (*bop_gather_data)(struct nilfs_bmap *, __u64 *, __u64 *, int); |
| @@ -153,10 +155,11 @@ int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *); | |||
| 153 | int nilfs_bmap_read(struct nilfs_bmap *, struct nilfs_inode *); | 155 | int nilfs_bmap_read(struct nilfs_bmap *, struct nilfs_inode *); |
| 154 | void nilfs_bmap_write(struct nilfs_bmap *, struct nilfs_inode *); | 156 | void nilfs_bmap_write(struct nilfs_bmap *, struct nilfs_inode *); |
| 155 | int nilfs_bmap_lookup_contig(struct nilfs_bmap *, __u64, __u64 *, unsigned); | 157 | int nilfs_bmap_lookup_contig(struct nilfs_bmap *, __u64, __u64 *, unsigned); |
| 156 | int nilfs_bmap_insert(struct nilfs_bmap *, unsigned long, unsigned long); | 158 | int nilfs_bmap_insert(struct nilfs_bmap *bmap, __u64 key, unsigned long rec); |
| 157 | int nilfs_bmap_delete(struct nilfs_bmap *, unsigned long); | 159 | int nilfs_bmap_delete(struct nilfs_bmap *bmap, __u64 key); |
| 158 | int nilfs_bmap_last_key(struct nilfs_bmap *, unsigned long *); | 160 | int nilfs_bmap_seek_key(struct nilfs_bmap *bmap, __u64 start, __u64 *keyp); |
| 159 | int nilfs_bmap_truncate(struct nilfs_bmap *, unsigned long); | 161 | int nilfs_bmap_last_key(struct nilfs_bmap *bmap, __u64 *keyp); |
| 162 | int nilfs_bmap_truncate(struct nilfs_bmap *bmap, __u64 key); | ||
| 160 | void nilfs_bmap_clear(struct nilfs_bmap *); | 163 | void nilfs_bmap_clear(struct nilfs_bmap *); |
| 161 | int nilfs_bmap_propagate(struct nilfs_bmap *, struct buffer_head *); | 164 | int nilfs_bmap_propagate(struct nilfs_bmap *, struct buffer_head *); |
| 162 | void nilfs_bmap_lookup_dirty_buffers(struct nilfs_bmap *, struct list_head *); | 165 | void nilfs_bmap_lookup_dirty_buffers(struct nilfs_bmap *, struct list_head *); |
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c index ecdbae19a766..059f37137f9a 100644 --- a/fs/nilfs2/btree.c +++ b/fs/nilfs2/btree.c | |||
| @@ -633,6 +633,44 @@ static int nilfs_btree_do_lookup_last(const struct nilfs_bmap *btree, | |||
| 633 | return 0; | 633 | return 0; |
| 634 | } | 634 | } |
| 635 | 635 | ||
| 636 | /** | ||
| 637 | * nilfs_btree_get_next_key - get next valid key from btree path array | ||
| 638 | * @btree: bmap struct of btree | ||
| 639 | * @path: array of nilfs_btree_path struct | ||
| 640 | * @minlevel: start level | ||
| 641 | * @nextkey: place to store the next valid key | ||
| 642 | * | ||
| 643 | * Return Value: If a next key was found, 0 is returned. Otherwise, | ||
| 644 | * -ENOENT is returned. | ||
| 645 | */ | ||
| 646 | static int nilfs_btree_get_next_key(const struct nilfs_bmap *btree, | ||
| 647 | const struct nilfs_btree_path *path, | ||
| 648 | int minlevel, __u64 *nextkey) | ||
| 649 | { | ||
| 650 | struct nilfs_btree_node *node; | ||
| 651 | int maxlevel = nilfs_btree_height(btree) - 1; | ||
| 652 | int index, next_adj, level; | ||
| 653 | |||
| 654 | /* Next index is already set to bp_index for leaf nodes. */ | ||
| 655 | next_adj = 0; | ||
| 656 | for (level = minlevel; level <= maxlevel; level++) { | ||
| 657 | if (level == maxlevel) | ||
| 658 | node = nilfs_btree_get_root(btree); | ||
| 659 | else | ||
| 660 | node = nilfs_btree_get_nonroot_node(path, level); | ||
| 661 | |||
| 662 | index = path[level].bp_index + next_adj; | ||
| 663 | if (index < nilfs_btree_node_get_nchildren(node)) { | ||
| 664 | /* Next key is in this node */ | ||
| 665 | *nextkey = nilfs_btree_node_get_key(node, index); | ||
| 666 | return 0; | ||
| 667 | } | ||
| 668 | /* For non-leaf nodes, next index is stored at bp_index + 1. */ | ||
| 669 | next_adj = 1; | ||
| 670 | } | ||
| 671 | return -ENOENT; | ||
| 672 | } | ||
| 673 | |||
| 636 | static int nilfs_btree_lookup(const struct nilfs_bmap *btree, | 674 | static int nilfs_btree_lookup(const struct nilfs_bmap *btree, |
| 637 | __u64 key, int level, __u64 *ptrp) | 675 | __u64 key, int level, __u64 *ptrp) |
| 638 | { | 676 | { |
| @@ -1563,6 +1601,27 @@ out: | |||
| 1563 | return ret; | 1601 | return ret; |
| 1564 | } | 1602 | } |
| 1565 | 1603 | ||
| 1604 | static int nilfs_btree_seek_key(const struct nilfs_bmap *btree, __u64 start, | ||
| 1605 | __u64 *keyp) | ||
| 1606 | { | ||
| 1607 | struct nilfs_btree_path *path; | ||
| 1608 | const int minlevel = NILFS_BTREE_LEVEL_NODE_MIN; | ||
| 1609 | int ret; | ||
| 1610 | |||
| 1611 | path = nilfs_btree_alloc_path(); | ||
| 1612 | if (!path) | ||
| 1613 | return -ENOMEM; | ||
| 1614 | |||
| 1615 | ret = nilfs_btree_do_lookup(btree, path, start, NULL, minlevel, 0); | ||
| 1616 | if (!ret) | ||
| 1617 | *keyp = start; | ||
| 1618 | else if (ret == -ENOENT) | ||
| 1619 | ret = nilfs_btree_get_next_key(btree, path, minlevel, keyp); | ||
| 1620 | |||
| 1621 | nilfs_btree_free_path(path); | ||
| 1622 | return ret; | ||
| 1623 | } | ||
| 1624 | |||
| 1566 | static int nilfs_btree_last_key(const struct nilfs_bmap *btree, __u64 *keyp) | 1625 | static int nilfs_btree_last_key(const struct nilfs_bmap *btree, __u64 *keyp) |
| 1567 | { | 1626 | { |
| 1568 | struct nilfs_btree_path *path; | 1627 | struct nilfs_btree_path *path; |
| @@ -2298,7 +2357,9 @@ static const struct nilfs_bmap_operations nilfs_btree_ops = { | |||
| 2298 | .bop_assign = nilfs_btree_assign, | 2357 | .bop_assign = nilfs_btree_assign, |
| 2299 | .bop_mark = nilfs_btree_mark, | 2358 | .bop_mark = nilfs_btree_mark, |
| 2300 | 2359 | ||
| 2360 | .bop_seek_key = nilfs_btree_seek_key, | ||
| 2301 | .bop_last_key = nilfs_btree_last_key, | 2361 | .bop_last_key = nilfs_btree_last_key, |
| 2362 | |||
| 2302 | .bop_check_insert = NULL, | 2363 | .bop_check_insert = NULL, |
| 2303 | .bop_check_delete = nilfs_btree_check_delete, | 2364 | .bop_check_delete = nilfs_btree_check_delete, |
| 2304 | .bop_gather_data = nilfs_btree_gather_data, | 2365 | .bop_gather_data = nilfs_btree_gather_data, |
| @@ -2318,7 +2379,9 @@ static const struct nilfs_bmap_operations nilfs_btree_ops_gc = { | |||
| 2318 | .bop_assign = nilfs_btree_assign_gc, | 2379 | .bop_assign = nilfs_btree_assign_gc, |
| 2319 | .bop_mark = NULL, | 2380 | .bop_mark = NULL, |
| 2320 | 2381 | ||
| 2382 | .bop_seek_key = NULL, | ||
| 2321 | .bop_last_key = NULL, | 2383 | .bop_last_key = NULL, |
| 2384 | |||
| 2322 | .bop_check_insert = NULL, | 2385 | .bop_check_insert = NULL, |
| 2323 | .bop_check_delete = NULL, | 2386 | .bop_check_delete = NULL, |
| 2324 | .bop_gather_data = NULL, | 2387 | .bop_gather_data = NULL, |
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c index 0d58075f34e2..b6596cab9e99 100644 --- a/fs/nilfs2/cpfile.c +++ b/fs/nilfs2/cpfile.c | |||
| @@ -53,6 +53,13 @@ nilfs_cpfile_get_offset(const struct inode *cpfile, __u64 cno) | |||
| 53 | return do_div(tcno, nilfs_cpfile_checkpoints_per_block(cpfile)); | 53 | return do_div(tcno, nilfs_cpfile_checkpoints_per_block(cpfile)); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | static __u64 nilfs_cpfile_first_checkpoint_in_block(const struct inode *cpfile, | ||
| 57 | unsigned long blkoff) | ||
| 58 | { | ||
| 59 | return (__u64)nilfs_cpfile_checkpoints_per_block(cpfile) * blkoff | ||
| 60 | + 1 - NILFS_MDT(cpfile)->mi_first_entry_offset; | ||
| 61 | } | ||
| 62 | |||
| 56 | static unsigned long | 63 | static unsigned long |
| 57 | nilfs_cpfile_checkpoints_in_block(const struct inode *cpfile, | 64 | nilfs_cpfile_checkpoints_in_block(const struct inode *cpfile, |
| 58 | __u64 curr, | 65 | __u64 curr, |
| @@ -146,6 +153,44 @@ static inline int nilfs_cpfile_get_checkpoint_block(struct inode *cpfile, | |||
| 146 | create, nilfs_cpfile_block_init, bhp); | 153 | create, nilfs_cpfile_block_init, bhp); |
| 147 | } | 154 | } |
| 148 | 155 | ||
| 156 | /** | ||
| 157 | * nilfs_cpfile_find_checkpoint_block - find and get a buffer on cpfile | ||
| 158 | * @cpfile: inode of cpfile | ||
| 159 | * @start_cno: start checkpoint number (inclusive) | ||
| 160 | * @end_cno: end checkpoint number (inclusive) | ||
| 161 | * @cnop: place to store the next checkpoint number | ||
| 162 | * @bhp: place to store a pointer to buffer_head struct | ||
| 163 | * | ||
| 164 | * Return Value: On success, it returns 0. On error, the following negative | ||
| 165 | * error code is returned. | ||
| 166 | * | ||
| 167 | * %-ENOMEM - Insufficient memory available. | ||
| 168 | * | ||
| 169 | * %-EIO - I/O error | ||
| 170 | * | ||
| 171 | * %-ENOENT - no block exists in the range. | ||
| 172 | */ | ||
| 173 | static int nilfs_cpfile_find_checkpoint_block(struct inode *cpfile, | ||
| 174 | __u64 start_cno, __u64 end_cno, | ||
| 175 | __u64 *cnop, | ||
| 176 | struct buffer_head **bhp) | ||
| 177 | { | ||
| 178 | unsigned long start, end, blkoff; | ||
| 179 | int ret; | ||
| 180 | |||
| 181 | if (unlikely(start_cno > end_cno)) | ||
| 182 | return -ENOENT; | ||
| 183 | |||
| 184 | start = nilfs_cpfile_get_blkoff(cpfile, start_cno); | ||
| 185 | end = nilfs_cpfile_get_blkoff(cpfile, end_cno); | ||
| 186 | |||
| 187 | ret = nilfs_mdt_find_block(cpfile, start, end, &blkoff, bhp); | ||
| 188 | if (!ret) | ||
| 189 | *cnop = (blkoff == start) ? start_cno : | ||
| 190 | nilfs_cpfile_first_checkpoint_in_block(cpfile, blkoff); | ||
| 191 | return ret; | ||
| 192 | } | ||
| 193 | |||
| 149 | static inline int nilfs_cpfile_delete_checkpoint_block(struct inode *cpfile, | 194 | static inline int nilfs_cpfile_delete_checkpoint_block(struct inode *cpfile, |
| 150 | __u64 cno) | 195 | __u64 cno) |
| 151 | { | 196 | { |
| @@ -403,14 +448,15 @@ static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop, | |||
| 403 | return -ENOENT; /* checkpoint number 0 is invalid */ | 448 | return -ENOENT; /* checkpoint number 0 is invalid */ |
| 404 | down_read(&NILFS_MDT(cpfile)->mi_sem); | 449 | down_read(&NILFS_MDT(cpfile)->mi_sem); |
| 405 | 450 | ||
| 406 | for (n = 0; cno < cur_cno && n < nci; cno += ncps) { | 451 | for (n = 0; n < nci; cno += ncps) { |
| 407 | ncps = nilfs_cpfile_checkpoints_in_block(cpfile, cno, cur_cno); | 452 | ret = nilfs_cpfile_find_checkpoint_block( |
| 408 | ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &bh); | 453 | cpfile, cno, cur_cno - 1, &cno, &bh); |
| 409 | if (ret < 0) { | 454 | if (ret < 0) { |
| 410 | if (ret != -ENOENT) | 455 | if (likely(ret == -ENOENT)) |
| 411 | goto out; | 456 | break; |
| 412 | continue; /* skip hole */ | 457 | goto out; |
| 413 | } | 458 | } |
| 459 | ncps = nilfs_cpfile_checkpoints_in_block(cpfile, cno, cur_cno); | ||
| 414 | 460 | ||
| 415 | kaddr = kmap_atomic(bh->b_page); | 461 | kaddr = kmap_atomic(bh->b_page); |
| 416 | cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr); | 462 | cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr); |
diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c index 82f4865e86dd..ebf89fd8ac1a 100644 --- a/fs/nilfs2/direct.c +++ b/fs/nilfs2/direct.c | |||
| @@ -173,6 +173,21 @@ static int nilfs_direct_delete(struct nilfs_bmap *bmap, __u64 key) | |||
| 173 | return ret; | 173 | return ret; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | static int nilfs_direct_seek_key(const struct nilfs_bmap *direct, __u64 start, | ||
| 177 | __u64 *keyp) | ||
| 178 | { | ||
| 179 | __u64 key; | ||
| 180 | |||
| 181 | for (key = start; key <= NILFS_DIRECT_KEY_MAX; key++) { | ||
| 182 | if (nilfs_direct_get_ptr(direct, key) != | ||
| 183 | NILFS_BMAP_INVALID_PTR) { | ||
| 184 | *keyp = key; | ||
| 185 | return 0; | ||
| 186 | } | ||
| 187 | } | ||
| 188 | return -ENOENT; | ||
| 189 | } | ||
| 190 | |||
| 176 | static int nilfs_direct_last_key(const struct nilfs_bmap *direct, __u64 *keyp) | 191 | static int nilfs_direct_last_key(const struct nilfs_bmap *direct, __u64 *keyp) |
| 177 | { | 192 | { |
| 178 | __u64 key, lastkey; | 193 | __u64 key, lastkey; |
| @@ -355,7 +370,9 @@ static const struct nilfs_bmap_operations nilfs_direct_ops = { | |||
| 355 | .bop_assign = nilfs_direct_assign, | 370 | .bop_assign = nilfs_direct_assign, |
| 356 | .bop_mark = NULL, | 371 | .bop_mark = NULL, |
| 357 | 372 | ||
| 373 | .bop_seek_key = nilfs_direct_seek_key, | ||
| 358 | .bop_last_key = nilfs_direct_last_key, | 374 | .bop_last_key = nilfs_direct_last_key, |
| 375 | |||
| 359 | .bop_check_insert = nilfs_direct_check_insert, | 376 | .bop_check_insert = nilfs_direct_check_insert, |
| 360 | .bop_check_delete = NULL, | 377 | .bop_check_delete = NULL, |
| 361 | .bop_gather_data = nilfs_direct_gather_data, | 378 | .bop_gather_data = nilfs_direct_gather_data, |
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 36f057fa8aa3..be936df4ba73 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
| @@ -106,7 +106,7 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff, | |||
| 106 | err = nilfs_transaction_begin(inode->i_sb, &ti, 1); | 106 | err = nilfs_transaction_begin(inode->i_sb, &ti, 1); |
| 107 | if (unlikely(err)) | 107 | if (unlikely(err)) |
| 108 | goto out; | 108 | goto out; |
| 109 | err = nilfs_bmap_insert(ii->i_bmap, (unsigned long)blkoff, | 109 | err = nilfs_bmap_insert(ii->i_bmap, blkoff, |
| 110 | (unsigned long)bh_result); | 110 | (unsigned long)bh_result); |
| 111 | if (unlikely(err != 0)) { | 111 | if (unlikely(err != 0)) { |
| 112 | if (err == -EEXIST) { | 112 | if (err == -EEXIST) { |
| @@ -441,21 +441,20 @@ struct inode *nilfs_new_inode(struct inode *dir, umode_t mode) | |||
| 441 | void nilfs_set_inode_flags(struct inode *inode) | 441 | void nilfs_set_inode_flags(struct inode *inode) |
| 442 | { | 442 | { |
| 443 | unsigned int flags = NILFS_I(inode)->i_flags; | 443 | unsigned int flags = NILFS_I(inode)->i_flags; |
| 444 | unsigned int new_fl = 0; | ||
| 444 | 445 | ||
| 445 | inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | | ||
| 446 | S_DIRSYNC); | ||
| 447 | if (flags & FS_SYNC_FL) | 446 | if (flags & FS_SYNC_FL) |
| 448 | inode->i_flags |= S_SYNC; | 447 | new_fl |= S_SYNC; |
| 449 | if (flags & FS_APPEND_FL) | 448 | if (flags & FS_APPEND_FL) |
| 450 | inode->i_flags |= S_APPEND; | 449 | new_fl |= S_APPEND; |
| 451 | if (flags & FS_IMMUTABLE_FL) | 450 | if (flags & FS_IMMUTABLE_FL) |
| 452 | inode->i_flags |= S_IMMUTABLE; | 451 | new_fl |= S_IMMUTABLE; |
| 453 | if (flags & FS_NOATIME_FL) | 452 | if (flags & FS_NOATIME_FL) |
| 454 | inode->i_flags |= S_NOATIME; | 453 | new_fl |= S_NOATIME; |
| 455 | if (flags & FS_DIRSYNC_FL) | 454 | if (flags & FS_DIRSYNC_FL) |
| 456 | inode->i_flags |= S_DIRSYNC; | 455 | new_fl |= S_DIRSYNC; |
| 457 | mapping_set_gfp_mask(inode->i_mapping, | 456 | inode_set_flags(inode, new_fl, S_SYNC | S_APPEND | S_IMMUTABLE | |
| 458 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | 457 | S_NOATIME | S_DIRSYNC); |
| 459 | } | 458 | } |
| 460 | 459 | ||
| 461 | int nilfs_read_inode_common(struct inode *inode, | 460 | int nilfs_read_inode_common(struct inode *inode, |
| @@ -540,6 +539,8 @@ static int __nilfs_read_inode(struct super_block *sb, | |||
| 540 | brelse(bh); | 539 | brelse(bh); |
| 541 | up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); | 540 | up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem); |
| 542 | nilfs_set_inode_flags(inode); | 541 | nilfs_set_inode_flags(inode); |
| 542 | mapping_set_gfp_mask(inode->i_mapping, | ||
| 543 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | ||
| 543 | return 0; | 544 | return 0; |
| 544 | 545 | ||
| 545 | failed_unmap: | 546 | failed_unmap: |
| @@ -712,7 +713,7 @@ void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh, int flags) | |||
| 712 | static void nilfs_truncate_bmap(struct nilfs_inode_info *ii, | 713 | static void nilfs_truncate_bmap(struct nilfs_inode_info *ii, |
| 713 | unsigned long from) | 714 | unsigned long from) |
| 714 | { | 715 | { |
| 715 | unsigned long b; | 716 | __u64 b; |
| 716 | int ret; | 717 | int ret; |
| 717 | 718 | ||
| 718 | if (!test_bit(NILFS_I_BMAP, &ii->i_state)) | 719 | if (!test_bit(NILFS_I_BMAP, &ii->i_state)) |
| @@ -727,7 +728,7 @@ repeat: | |||
| 727 | if (b < from) | 728 | if (b < from) |
| 728 | return; | 729 | return; |
| 729 | 730 | ||
| 730 | b -= min_t(unsigned long, NILFS_MAX_TRUNCATE_BLOCKS, b - from); | 731 | b -= min_t(__u64, NILFS_MAX_TRUNCATE_BLOCKS, b - from); |
| 731 | ret = nilfs_bmap_truncate(ii->i_bmap, b); | 732 | ret = nilfs_bmap_truncate(ii->i_bmap, b); |
| 732 | nilfs_relax_pressure_in_lock(ii->vfs_inode.i_sb); | 733 | nilfs_relax_pressure_in_lock(ii->vfs_inode.i_sb); |
| 733 | if (!ret || (ret == -ENOMEM && | 734 | if (!ret || (ret == -ENOMEM && |
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index 892cf5ffdb8e..dee34d990281 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c | |||
| @@ -261,6 +261,60 @@ int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create, | |||
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | /** | 263 | /** |
| 264 | * nilfs_mdt_find_block - find and get a buffer on meta data file. | ||
| 265 | * @inode: inode of the meta data file | ||
| 266 | * @start: start block offset (inclusive) | ||
| 267 | * @end: end block offset (inclusive) | ||
| 268 | * @blkoff: block offset | ||
| 269 | * @out_bh: place to store a pointer to buffer_head struct | ||
| 270 | * | ||
| 271 | * nilfs_mdt_find_block() looks up an existing block in range of | ||
| 272 | * [@start, @end] and stores pointer to a buffer head of the block to | ||
| 273 | * @out_bh, and block offset to @blkoff, respectively. @out_bh and | ||
| 274 | * @blkoff are substituted only when zero is returned. | ||
| 275 | * | ||
| 276 | * Return Value: On success, it returns 0. On error, the following negative | ||
| 277 | * error code is returned. | ||
| 278 | * | ||
| 279 | * %-ENOMEM - Insufficient memory available. | ||
| 280 | * | ||
| 281 | * %-EIO - I/O error | ||
| 282 | * | ||
| 283 | * %-ENOENT - no block was found in the range | ||
| 284 | */ | ||
| 285 | int nilfs_mdt_find_block(struct inode *inode, unsigned long start, | ||
| 286 | unsigned long end, unsigned long *blkoff, | ||
| 287 | struct buffer_head **out_bh) | ||
| 288 | { | ||
| 289 | __u64 next; | ||
| 290 | int ret; | ||
| 291 | |||
| 292 | if (unlikely(start > end)) | ||
| 293 | return -ENOENT; | ||
| 294 | |||
| 295 | ret = nilfs_mdt_read_block(inode, start, true, out_bh); | ||
| 296 | if (!ret) { | ||
| 297 | *blkoff = start; | ||
| 298 | goto out; | ||
| 299 | } | ||
| 300 | if (unlikely(ret != -ENOENT || start == ULONG_MAX)) | ||
| 301 | goto out; | ||
| 302 | |||
| 303 | ret = nilfs_bmap_seek_key(NILFS_I(inode)->i_bmap, start + 1, &next); | ||
| 304 | if (!ret) { | ||
| 305 | if (next <= end) { | ||
| 306 | ret = nilfs_mdt_read_block(inode, next, true, out_bh); | ||
| 307 | if (!ret) | ||
| 308 | *blkoff = next; | ||
| 309 | } else { | ||
| 310 | ret = -ENOENT; | ||
| 311 | } | ||
| 312 | } | ||
| 313 | out: | ||
| 314 | return ret; | ||
| 315 | } | ||
| 316 | |||
| 317 | /** | ||
| 264 | * nilfs_mdt_delete_block - make a hole on the meta data file. | 318 | * nilfs_mdt_delete_block - make a hole on the meta data file. |
| 265 | * @inode: inode of the meta data file | 319 | * @inode: inode of the meta data file |
| 266 | * @block: block offset | 320 | * @block: block offset |
diff --git a/fs/nilfs2/mdt.h b/fs/nilfs2/mdt.h index ab172e8549c5..fe529a87a208 100644 --- a/fs/nilfs2/mdt.h +++ b/fs/nilfs2/mdt.h | |||
| @@ -78,6 +78,9 @@ int nilfs_mdt_get_block(struct inode *, unsigned long, int, | |||
| 78 | void (*init_block)(struct inode *, | 78 | void (*init_block)(struct inode *, |
| 79 | struct buffer_head *, void *), | 79 | struct buffer_head *, void *), |
| 80 | struct buffer_head **); | 80 | struct buffer_head **); |
| 81 | int nilfs_mdt_find_block(struct inode *inode, unsigned long start, | ||
| 82 | unsigned long end, unsigned long *blkoff, | ||
| 83 | struct buffer_head **out_bh); | ||
| 81 | int nilfs_mdt_delete_block(struct inode *, unsigned long); | 84 | int nilfs_mdt_delete_block(struct inode *, unsigned long); |
| 82 | int nilfs_mdt_forget_block(struct inode *, unsigned long); | 85 | int nilfs_mdt_forget_block(struct inode *, unsigned long); |
| 83 | int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long); | 86 | int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long); |
| @@ -111,7 +114,10 @@ static inline __u64 nilfs_mdt_cno(struct inode *inode) | |||
| 111 | return ((struct the_nilfs *)inode->i_sb->s_fs_info)->ns_cno; | 114 | return ((struct the_nilfs *)inode->i_sb->s_fs_info)->ns_cno; |
| 112 | } | 115 | } |
| 113 | 116 | ||
| 114 | #define nilfs_mdt_bgl_lock(inode, bg) \ | 117 | static inline spinlock_t * |
| 115 | (&NILFS_MDT(inode)->mi_bgl->locks[(bg) & (NR_BG_LOCKS-1)].lock) | 118 | nilfs_mdt_bgl_lock(struct inode *inode, unsigned int block_group) |
| 119 | { | ||
| 120 | return bgl_lock_ptr(NILFS_MDT(inode)->mi_bgl, block_group); | ||
| 121 | } | ||
| 116 | 122 | ||
| 117 | #endif /* _NILFS_MDT_H */ | 123 | #endif /* _NILFS_MDT_H */ |
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c index 700ecbcca55d..45d650addd56 100644 --- a/fs/nilfs2/page.c +++ b/fs/nilfs2/page.c | |||
| @@ -89,18 +89,16 @@ struct buffer_head *nilfs_grab_buffer(struct inode *inode, | |||
| 89 | void nilfs_forget_buffer(struct buffer_head *bh) | 89 | void nilfs_forget_buffer(struct buffer_head *bh) |
| 90 | { | 90 | { |
| 91 | struct page *page = bh->b_page; | 91 | struct page *page = bh->b_page; |
| 92 | const unsigned long clear_bits = | ||
| 93 | (1 << BH_Uptodate | 1 << BH_Dirty | 1 << BH_Mapped | | ||
| 94 | 1 << BH_Async_Write | 1 << BH_NILFS_Volatile | | ||
| 95 | 1 << BH_NILFS_Checked | 1 << BH_NILFS_Redirected); | ||
| 92 | 96 | ||
| 93 | lock_buffer(bh); | 97 | lock_buffer(bh); |
| 94 | clear_buffer_nilfs_volatile(bh); | 98 | set_mask_bits(&bh->b_state, clear_bits, 0); |
| 95 | clear_buffer_nilfs_checked(bh); | ||
| 96 | clear_buffer_nilfs_redirected(bh); | ||
| 97 | clear_buffer_async_write(bh); | ||
| 98 | clear_buffer_dirty(bh); | ||
| 99 | if (nilfs_page_buffers_clean(page)) | 99 | if (nilfs_page_buffers_clean(page)) |
| 100 | __nilfs_clear_page_dirty(page); | 100 | __nilfs_clear_page_dirty(page); |
| 101 | 101 | ||
| 102 | clear_buffer_uptodate(bh); | ||
| 103 | clear_buffer_mapped(bh); | ||
| 104 | bh->b_blocknr = -1; | 102 | bh->b_blocknr = -1; |
| 105 | ClearPageUptodate(page); | 103 | ClearPageUptodate(page); |
| 106 | ClearPageMappedToDisk(page); | 104 | ClearPageMappedToDisk(page); |
| @@ -421,6 +419,10 @@ void nilfs_clear_dirty_page(struct page *page, bool silent) | |||
| 421 | 419 | ||
| 422 | if (page_has_buffers(page)) { | 420 | if (page_has_buffers(page)) { |
| 423 | struct buffer_head *bh, *head; | 421 | struct buffer_head *bh, *head; |
| 422 | const unsigned long clear_bits = | ||
| 423 | (1 << BH_Uptodate | 1 << BH_Dirty | 1 << BH_Mapped | | ||
| 424 | 1 << BH_Async_Write | 1 << BH_NILFS_Volatile | | ||
| 425 | 1 << BH_NILFS_Checked | 1 << BH_NILFS_Redirected); | ||
| 424 | 426 | ||
| 425 | bh = head = page_buffers(page); | 427 | bh = head = page_buffers(page); |
| 426 | do { | 428 | do { |
| @@ -430,13 +432,7 @@ void nilfs_clear_dirty_page(struct page *page, bool silent) | |||
| 430 | "discard block %llu, size %zu", | 432 | "discard block %llu, size %zu", |
| 431 | (u64)bh->b_blocknr, bh->b_size); | 433 | (u64)bh->b_blocknr, bh->b_size); |
| 432 | } | 434 | } |
| 433 | clear_buffer_async_write(bh); | 435 | set_mask_bits(&bh->b_state, clear_bits, 0); |
| 434 | clear_buffer_dirty(bh); | ||
| 435 | clear_buffer_nilfs_volatile(bh); | ||
| 436 | clear_buffer_nilfs_checked(bh); | ||
| 437 | clear_buffer_nilfs_redirected(bh); | ||
| 438 | clear_buffer_uptodate(bh); | ||
| 439 | clear_buffer_mapped(bh); | ||
| 440 | unlock_buffer(bh); | 436 | unlock_buffer(bh); |
| 441 | } while (bh = bh->b_this_page, bh != head); | 437 | } while (bh = bh->b_this_page, bh != head); |
| 442 | } | 438 | } |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 0c3f303baf32..c6abbad9b8e3 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/pagemap.h> | 24 | #include <linux/pagemap.h> |
| 25 | #include <linux/buffer_head.h> | 25 | #include <linux/buffer_head.h> |
| 26 | #include <linux/writeback.h> | 26 | #include <linux/writeback.h> |
| 27 | #include <linux/bitops.h> | ||
| 27 | #include <linux/bio.h> | 28 | #include <linux/bio.h> |
| 28 | #include <linux/completion.h> | 29 | #include <linux/completion.h> |
| 29 | #include <linux/blkdev.h> | 30 | #include <linux/blkdev.h> |
| @@ -1588,7 +1589,6 @@ static void nilfs_segctor_prepare_write(struct nilfs_sc_info *sci) | |||
| 1588 | 1589 | ||
| 1589 | list_for_each_entry(bh, &segbuf->sb_segsum_buffers, | 1590 | list_for_each_entry(bh, &segbuf->sb_segsum_buffers, |
| 1590 | b_assoc_buffers) { | 1591 | b_assoc_buffers) { |
| 1591 | set_buffer_async_write(bh); | ||
| 1592 | if (bh->b_page != bd_page) { | 1592 | if (bh->b_page != bd_page) { |
| 1593 | if (bd_page) { | 1593 | if (bd_page) { |
| 1594 | lock_page(bd_page); | 1594 | lock_page(bd_page); |
| @@ -1688,7 +1688,6 @@ static void nilfs_abort_logs(struct list_head *logs, int err) | |||
| 1688 | list_for_each_entry(segbuf, logs, sb_list) { | 1688 | list_for_each_entry(segbuf, logs, sb_list) { |
| 1689 | list_for_each_entry(bh, &segbuf->sb_segsum_buffers, | 1689 | list_for_each_entry(bh, &segbuf->sb_segsum_buffers, |
| 1690 | b_assoc_buffers) { | 1690 | b_assoc_buffers) { |
| 1691 | clear_buffer_async_write(bh); | ||
| 1692 | if (bh->b_page != bd_page) { | 1691 | if (bh->b_page != bd_page) { |
| 1693 | if (bd_page) | 1692 | if (bd_page) |
| 1694 | end_page_writeback(bd_page); | 1693 | end_page_writeback(bd_page); |
| @@ -1768,7 +1767,6 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) | |||
| 1768 | b_assoc_buffers) { | 1767 | b_assoc_buffers) { |
| 1769 | set_buffer_uptodate(bh); | 1768 | set_buffer_uptodate(bh); |
| 1770 | clear_buffer_dirty(bh); | 1769 | clear_buffer_dirty(bh); |
| 1771 | clear_buffer_async_write(bh); | ||
| 1772 | if (bh->b_page != bd_page) { | 1770 | if (bh->b_page != bd_page) { |
| 1773 | if (bd_page) | 1771 | if (bd_page) |
| 1774 | end_page_writeback(bd_page); | 1772 | end_page_writeback(bd_page); |
| @@ -1788,12 +1786,13 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) | |||
| 1788 | */ | 1786 | */ |
| 1789 | list_for_each_entry(bh, &segbuf->sb_payload_buffers, | 1787 | list_for_each_entry(bh, &segbuf->sb_payload_buffers, |
| 1790 | b_assoc_buffers) { | 1788 | b_assoc_buffers) { |
| 1791 | set_buffer_uptodate(bh); | 1789 | const unsigned long set_bits = (1 << BH_Uptodate); |
| 1792 | clear_buffer_dirty(bh); | 1790 | const unsigned long clear_bits = |
| 1793 | clear_buffer_async_write(bh); | 1791 | (1 << BH_Dirty | 1 << BH_Async_Write | |
| 1794 | clear_buffer_delay(bh); | 1792 | 1 << BH_Delay | 1 << BH_NILFS_Volatile | |
| 1795 | clear_buffer_nilfs_volatile(bh); | 1793 | 1 << BH_NILFS_Redirected); |
| 1796 | clear_buffer_nilfs_redirected(bh); | 1794 | |
| 1795 | set_mask_bits(&bh->b_state, clear_bits, set_bits); | ||
| 1797 | if (bh == segbuf->sb_super_root) { | 1796 | if (bh == segbuf->sb_super_root) { |
| 1798 | if (bh->b_page != bd_page) { | 1797 | if (bh->b_page != bd_page) { |
| 1799 | end_page_writeback(bd_page); | 1798 | end_page_writeback(bd_page); |
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 5bc2a1cf73c3..c1725f20a9d1 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
| @@ -1020,7 +1020,7 @@ int nilfs_checkpoint_is_mounted(struct super_block *sb, __u64 cno) | |||
| 1020 | struct dentry *dentry; | 1020 | struct dentry *dentry; |
| 1021 | int ret; | 1021 | int ret; |
| 1022 | 1022 | ||
| 1023 | if (cno < 0 || cno > nilfs->ns_cno) | 1023 | if (cno > nilfs->ns_cno) |
| 1024 | return false; | 1024 | return false; |
| 1025 | 1025 | ||
| 1026 | if (cno >= nilfs_last_cno(nilfs)) | 1026 | if (cno >= nilfs_last_cno(nilfs)) |
