diff options
Diffstat (limited to 'fs/nilfs2')
-rw-r--r-- | fs/nilfs2/Kconfig | 25 | ||||
-rw-r--r-- | fs/nilfs2/bmap.c | 5 | ||||
-rw-r--r-- | fs/nilfs2/cpfile.c | 5 | ||||
-rw-r--r-- | fs/nilfs2/dat.c | 9 | ||||
-rw-r--r-- | fs/nilfs2/dir.c | 1 | ||||
-rw-r--r-- | fs/nilfs2/mdt.c | 4 | ||||
-rw-r--r-- | fs/nilfs2/segment.c | 44 |
7 files changed, 57 insertions, 36 deletions
diff --git a/fs/nilfs2/Kconfig b/fs/nilfs2/Kconfig new file mode 100644 index 000000000000..72da095d4009 --- /dev/null +++ b/fs/nilfs2/Kconfig | |||
@@ -0,0 +1,25 @@ | |||
1 | config NILFS2_FS | ||
2 | tristate "NILFS2 file system support (EXPERIMENTAL)" | ||
3 | depends on BLOCK && EXPERIMENTAL | ||
4 | select CRC32 | ||
5 | help | ||
6 | NILFS2 is a log-structured file system (LFS) supporting continuous | ||
7 | snapshotting. In addition to versioning capability of the entire | ||
8 | file system, users can even restore files mistakenly overwritten or | ||
9 | destroyed just a few seconds ago. Since this file system can keep | ||
10 | consistency like conventional LFS, it achieves quick recovery after | ||
11 | system crashes. | ||
12 | |||
13 | NILFS2 creates a number of checkpoints every few seconds or per | ||
14 | synchronous write basis (unless there is no change). Users can | ||
15 | select significant versions among continuously created checkpoints, | ||
16 | and can change them into snapshots which will be preserved for long | ||
17 | periods until they are changed back to checkpoints. Each | ||
18 | snapshot is mountable as a read-only file system concurrently with | ||
19 | its writable mount, and this feature is convenient for online backup. | ||
20 | |||
21 | Some features including atime, extended attributes, and POSIX ACLs, | ||
22 | are not supported yet. | ||
23 | |||
24 | To compile this file system support as a module, choose M here: the | ||
25 | module will be called nilfs2. If unsure, say N. | ||
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c index 36df60b6d8a4..99d58a028b94 100644 --- a/fs/nilfs2/bmap.c +++ b/fs/nilfs2/bmap.c | |||
@@ -568,6 +568,7 @@ void nilfs_bmap_abort_update_v(struct nilfs_bmap *bmap, | |||
568 | } | 568 | } |
569 | 569 | ||
570 | static struct lock_class_key nilfs_bmap_dat_lock_key; | 570 | static struct lock_class_key nilfs_bmap_dat_lock_key; |
571 | static struct lock_class_key nilfs_bmap_mdt_lock_key; | ||
571 | 572 | ||
572 | /** | 573 | /** |
573 | * nilfs_bmap_read - read a bmap from an inode | 574 | * nilfs_bmap_read - read a bmap from an inode |
@@ -603,7 +604,11 @@ int nilfs_bmap_read(struct nilfs_bmap *bmap, struct nilfs_inode *raw_inode) | |||
603 | bmap->b_ptr_type = NILFS_BMAP_PTR_VS; | 604 | bmap->b_ptr_type = NILFS_BMAP_PTR_VS; |
604 | bmap->b_last_allocated_key = 0; | 605 | bmap->b_last_allocated_key = 0; |
605 | bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR; | 606 | bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR; |
607 | lockdep_set_class(&bmap->b_sem, &nilfs_bmap_mdt_lock_key); | ||
606 | break; | 608 | break; |
609 | case NILFS_IFILE_INO: | ||
610 | lockdep_set_class(&bmap->b_sem, &nilfs_bmap_mdt_lock_key); | ||
611 | /* Fall through */ | ||
607 | default: | 612 | default: |
608 | bmap->b_ptr_type = NILFS_BMAP_PTR_VM; | 613 | bmap->b_ptr_type = NILFS_BMAP_PTR_VM; |
609 | bmap->b_last_allocated_key = 0; | 614 | bmap->b_last_allocated_key = 0; |
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c index 7d49813f66d6..aec942cf79e3 100644 --- a/fs/nilfs2/cpfile.c +++ b/fs/nilfs2/cpfile.c | |||
@@ -307,7 +307,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, | |||
307 | ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); | 307 | ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); |
308 | if (ret < 0) { | 308 | if (ret < 0) { |
309 | if (ret != -ENOENT) | 309 | if (ret != -ENOENT) |
310 | goto out_header; | 310 | break; |
311 | /* skip hole */ | 311 | /* skip hole */ |
312 | ret = 0; | 312 | ret = 0; |
313 | continue; | 313 | continue; |
@@ -340,7 +340,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, | |||
340 | continue; | 340 | continue; |
341 | printk(KERN_ERR "%s: cannot delete block\n", | 341 | printk(KERN_ERR "%s: cannot delete block\n", |
342 | __func__); | 342 | __func__); |
343 | goto out_header; | 343 | break; |
344 | } | 344 | } |
345 | } | 345 | } |
346 | 346 | ||
@@ -358,7 +358,6 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, | |||
358 | kunmap_atomic(kaddr, KM_USER0); | 358 | kunmap_atomic(kaddr, KM_USER0); |
359 | } | 359 | } |
360 | 360 | ||
361 | out_header: | ||
362 | brelse(header_bh); | 361 | brelse(header_bh); |
363 | 362 | ||
364 | out_sem: | 363 | out_sem: |
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c index 0b2710e2d565..8927ca27e6f7 100644 --- a/fs/nilfs2/dat.c +++ b/fs/nilfs2/dat.c | |||
@@ -134,15 +134,6 @@ void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req, | |||
134 | entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr, | 134 | entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr, |
135 | req->pr_entry_bh, kaddr); | 135 | req->pr_entry_bh, kaddr); |
136 | entry->de_start = cpu_to_le64(nilfs_mdt_cno(dat)); | 136 | entry->de_start = cpu_to_le64(nilfs_mdt_cno(dat)); |
137 | if (entry->de_blocknr != cpu_to_le64(0) || | ||
138 | entry->de_end != cpu_to_le64(NILFS_CNO_MAX)) { | ||
139 | printk(KERN_CRIT | ||
140 | "%s: vbn = %llu, start = %llu, end = %llu, pbn = %llu\n", | ||
141 | __func__, (unsigned long long)req->pr_entry_nr, | ||
142 | (unsigned long long)le64_to_cpu(entry->de_start), | ||
143 | (unsigned long long)le64_to_cpu(entry->de_end), | ||
144 | (unsigned long long)le64_to_cpu(entry->de_blocknr)); | ||
145 | } | ||
146 | entry->de_blocknr = cpu_to_le64(blocknr); | 137 | entry->de_blocknr = cpu_to_le64(blocknr); |
147 | kunmap_atomic(kaddr, KM_USER0); | 138 | kunmap_atomic(kaddr, KM_USER0); |
148 | 139 | ||
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c index 54100acc1102..1a4fa04cf071 100644 --- a/fs/nilfs2/dir.c +++ b/fs/nilfs2/dir.c | |||
@@ -43,7 +43,6 @@ | |||
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <linux/pagemap.h> | 45 | #include <linux/pagemap.h> |
46 | #include <linux/smp_lock.h> | ||
47 | #include "nilfs.h" | 46 | #include "nilfs.h" |
48 | #include "page.h" | 47 | #include "page.h" |
49 | 48 | ||
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index 3d3ddb3f5177..2dfd47714ae5 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c | |||
@@ -412,8 +412,10 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc) | |||
412 | return 0; /* Do not request flush for shadow page cache */ | 412 | return 0; /* Do not request flush for shadow page cache */ |
413 | if (!sb) { | 413 | if (!sb) { |
414 | writer = nilfs_get_writer(NILFS_MDT(inode)->mi_nilfs); | 414 | writer = nilfs_get_writer(NILFS_MDT(inode)->mi_nilfs); |
415 | if (!writer) | 415 | if (!writer) { |
416 | nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs); | ||
416 | return -EROFS; | 417 | return -EROFS; |
418 | } | ||
417 | sb = writer->s_super; | 419 | sb = writer->s_super; |
418 | } | 420 | } |
419 | 421 | ||
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index aa977549919e..51ff3d0a4ee2 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -1829,26 +1829,13 @@ static int nilfs_segctor_write(struct nilfs_sc_info *sci, | |||
1829 | err = nilfs_segbuf_write(segbuf, &wi); | 1829 | err = nilfs_segbuf_write(segbuf, &wi); |
1830 | 1830 | ||
1831 | res = nilfs_segbuf_wait(segbuf, &wi); | 1831 | res = nilfs_segbuf_wait(segbuf, &wi); |
1832 | err = unlikely(err) ? : res; | 1832 | err = err ? : res; |
1833 | if (unlikely(err)) | 1833 | if (err) |
1834 | return err; | 1834 | return err; |
1835 | } | 1835 | } |
1836 | return 0; | 1836 | return 0; |
1837 | } | 1837 | } |
1838 | 1838 | ||
1839 | static int nilfs_page_has_uncleared_buffer(struct page *page) | ||
1840 | { | ||
1841 | struct buffer_head *head, *bh; | ||
1842 | |||
1843 | head = bh = page_buffers(page); | ||
1844 | do { | ||
1845 | if (buffer_dirty(bh) && !list_empty(&bh->b_assoc_buffers)) | ||
1846 | return 1; | ||
1847 | bh = bh->b_this_page; | ||
1848 | } while (bh != head); | ||
1849 | return 0; | ||
1850 | } | ||
1851 | |||
1852 | static void __nilfs_end_page_io(struct page *page, int err) | 1839 | static void __nilfs_end_page_io(struct page *page, int err) |
1853 | { | 1840 | { |
1854 | if (!err) { | 1841 | if (!err) { |
@@ -1872,13 +1859,26 @@ static void nilfs_end_page_io(struct page *page, int err) | |||
1872 | if (!page) | 1859 | if (!page) |
1873 | return; | 1860 | return; |
1874 | 1861 | ||
1875 | if (buffer_nilfs_node(page_buffers(page)) && | 1862 | if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page)) { |
1876 | nilfs_page_has_uncleared_buffer(page)) | 1863 | /* |
1877 | /* For b-tree node pages, this function may be called twice | 1864 | * For b-tree node pages, this function may be called twice |
1878 | or more because they might be split in a segment. | 1865 | * or more because they might be split in a segment. |
1879 | This check assures that cleanup has been done for all | 1866 | */ |
1880 | buffers in a split btnode page. */ | 1867 | if (PageDirty(page)) { |
1868 | /* | ||
1869 | * For pages holding split b-tree node buffers, dirty | ||
1870 | * flag on the buffers may be cleared discretely. | ||
1871 | * In that case, the page is once redirtied for | ||
1872 | * remaining buffers, and it must be cancelled if | ||
1873 | * all the buffers get cleaned later. | ||
1874 | */ | ||
1875 | lock_page(page); | ||
1876 | if (nilfs_page_buffers_clean(page)) | ||
1877 | __nilfs_clear_page_dirty(page); | ||
1878 | unlock_page(page); | ||
1879 | } | ||
1881 | return; | 1880 | return; |
1881 | } | ||
1882 | 1882 | ||
1883 | __nilfs_end_page_io(page, err); | 1883 | __nilfs_end_page_io(page, err); |
1884 | } | 1884 | } |
@@ -1940,7 +1940,7 @@ static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci, | |||
1940 | } | 1940 | } |
1941 | if (bh->b_page != fs_page) { | 1941 | if (bh->b_page != fs_page) { |
1942 | nilfs_end_page_io(fs_page, err); | 1942 | nilfs_end_page_io(fs_page, err); |
1943 | if (unlikely(fs_page == failed_page)) | 1943 | if (fs_page && fs_page == failed_page) |
1944 | goto done; | 1944 | goto done; |
1945 | fs_page = bh->b_page; | 1945 | fs_page = bh->b_page; |
1946 | } | 1946 | } |