Skip to content

Commit 3f490f7

Browse files
committed
Merge tag 'for-f2fs-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs updates from Jaegeuk Kim: "This patch-set includes the following major enhancement patches: - remount_fs callback function - restore parent inode number to enhance the fsync performance - xattr security labels - reduce the number of redundant lock/unlock data pages - avoid frequent write_inode calls The other minor bug fixes are as follows. - endian conversion bugs - various bugs in the roll-forward recovery routine" * tag 'for-f2fs-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (56 commits) f2fs: fix to recover i_size from roll-forward f2fs: remove the unused argument "sbi" of func destroy_fsync_dnodes() f2fs: remove reusing any prefree segments f2fs: code cleanup and simplify in func {find/add}_gc_inode f2fs: optimize the init_dirty_segmap function f2fs: fix an endian conversion bug detected by sparse f2fs: fix crc endian conversion f2fs: add remount_fs callback support f2fs: recover wrong pino after checkpoint during fsync f2fs: optimize do_write_data_page() f2fs: make locate_dirty_segment() as static f2fs: remove unnecessary parameter "offset" from __add_sum_entry() f2fs: avoid freqeunt write_inode calls f2fs: optimise the truncate_data_blocks_range() range f2fs: use the F2FS specific flags in f2fs_ioctl() f2fs: sync dir->i_size with its block allocation f2fs: fix i_blocks translation on various types of files f2fs: set sb->s_fs_info before calling parse_options() f2fs: support xattr security labels f2fs: fix iget/iput of dir during recovery ...
2 parents c4eb1b0 + a1dd3c1 commit 3f490f7

20 files changed

Lines changed: 750 additions & 451 deletions

File tree

Documentation/filesystems/f2fs.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,13 @@ Cleaning Overhead
9898
MOUNT OPTIONS
9999
================================================================================
100100

101-
background_gc_off Turn off cleaning operations, namely garbage collection,
102-
triggered in background when I/O subsystem is idle.
101+
background_gc=%s Turn on/off cleaning operations, namely garbage
102+
collection, triggered in background when I/O subsystem is
103+
idle. If background_gc=on, it will turn on the garbage
104+
collection and if background_gc=off, garbage collection
105+
will be truned off.
106+
Default value for this option is on. So garbage
107+
collection is on by default.
103108
disable_roll_forward Disable the roll-forward recovery routine
104109
discard Issue discard/TRIM commands when a segment is cleaned.
105110
no_heap Disable heap-style segment allocation which finds free

fs/f2fs/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,15 @@ config F2FS_FS_POSIX_ACL
5151
Linux website <http://acl.bestbits.at/>.
5252

5353
If you don't know what Access Control Lists are, say N
54+
55+
config F2FS_FS_SECURITY
56+
bool "F2FS Security Labels"
57+
depends on F2FS_FS_XATTR
58+
help
59+
Security labels provide an access control facility to support Linux
60+
Security Models (LSMs) accepted by AppArmor, SELinux, Smack and TOMOYO
61+
Linux. This option enables an extended attribute handler for file
62+
security labels in the f2fs filesystem, so that it requires enabling
63+
the extended attribute support in advance.
64+
65+
If you are not using a security module, say N.

fs/f2fs/acl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ static int f2fs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
250250
}
251251
}
252252

253-
error = f2fs_setxattr(inode, name_index, "", value, size);
253+
error = f2fs_setxattr(inode, name_index, "", value, size, NULL);
254254

255255
kfree(value);
256256
if (!error)

fs/f2fs/checkpoint.c

Lines changed: 76 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,8 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
357357
unsigned long blk_size = sbi->blocksize;
358358
struct f2fs_checkpoint *cp_block;
359359
unsigned long long cur_version = 0, pre_version = 0;
360-
unsigned int crc = 0;
361360
size_t crc_offset;
361+
__u32 crc = 0;
362362

363363
/* Read the 1st cp block in this CP pack */
364364
cp_page_1 = get_meta_page(sbi, cp_addr);
@@ -369,7 +369,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
369369
if (crc_offset >= blk_size)
370370
goto invalid_cp1;
371371

372-
crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
372+
crc = le32_to_cpu(*((__u32 *)((unsigned char *)cp_block + crc_offset)));
373373
if (!f2fs_crc_valid(crc, cp_block, crc_offset))
374374
goto invalid_cp1;
375375

@@ -384,7 +384,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
384384
if (crc_offset >= blk_size)
385385
goto invalid_cp2;
386386

387-
crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
387+
crc = le32_to_cpu(*((__u32 *)((unsigned char *)cp_block + crc_offset)));
388388
if (!f2fs_crc_valid(crc, cp_block, crc_offset))
389389
goto invalid_cp2;
390390

@@ -450,13 +450,30 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
450450
return -EINVAL;
451451
}
452452

453-
void set_dirty_dir_page(struct inode *inode, struct page *page)
453+
static int __add_dirty_inode(struct inode *inode, struct dir_inode_entry *new)
454454
{
455455
struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
456456
struct list_head *head = &sbi->dir_inode_list;
457-
struct dir_inode_entry *new;
458457
struct list_head *this;
459458

459+
list_for_each(this, head) {
460+
struct dir_inode_entry *entry;
461+
entry = list_entry(this, struct dir_inode_entry, list);
462+
if (entry->inode == inode)
463+
return -EEXIST;
464+
}
465+
list_add_tail(&new->list, head);
466+
#ifdef CONFIG_F2FS_STAT_FS
467+
sbi->n_dirty_dirs++;
468+
#endif
469+
return 0;
470+
}
471+
472+
void set_dirty_dir_page(struct inode *inode, struct page *page)
473+
{
474+
struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
475+
struct dir_inode_entry *new;
476+
460477
if (!S_ISDIR(inode->i_mode))
461478
return;
462479
retry:
@@ -469,23 +486,31 @@ void set_dirty_dir_page(struct inode *inode, struct page *page)
469486
INIT_LIST_HEAD(&new->list);
470487

471488
spin_lock(&sbi->dir_inode_lock);
472-
list_for_each(this, head) {
473-
struct dir_inode_entry *entry;
474-
entry = list_entry(this, struct dir_inode_entry, list);
475-
if (entry->inode == inode) {
476-
kmem_cache_free(inode_entry_slab, new);
477-
goto out;
478-
}
479-
}
480-
list_add_tail(&new->list, head);
481-
sbi->n_dirty_dirs++;
489+
if (__add_dirty_inode(inode, new))
490+
kmem_cache_free(inode_entry_slab, new);
482491

483-
BUG_ON(!S_ISDIR(inode->i_mode));
484-
out:
485492
inc_page_count(sbi, F2FS_DIRTY_DENTS);
486493
inode_inc_dirty_dents(inode);
487494
SetPagePrivate(page);
495+
spin_unlock(&sbi->dir_inode_lock);
496+
}
488497

498+
void add_dirty_dir_inode(struct inode *inode)
499+
{
500+
struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
501+
struct dir_inode_entry *new;
502+
retry:
503+
new = kmem_cache_alloc(inode_entry_slab, GFP_NOFS);
504+
if (!new) {
505+
cond_resched();
506+
goto retry;
507+
}
508+
new->inode = inode;
509+
INIT_LIST_HEAD(&new->list);
510+
511+
spin_lock(&sbi->dir_inode_lock);
512+
if (__add_dirty_inode(inode, new))
513+
kmem_cache_free(inode_entry_slab, new);
489514
spin_unlock(&sbi->dir_inode_lock);
490515
}
491516

@@ -499,21 +524,49 @@ void remove_dirty_dir_inode(struct inode *inode)
499524
return;
500525

501526
spin_lock(&sbi->dir_inode_lock);
502-
if (atomic_read(&F2FS_I(inode)->dirty_dents))
503-
goto out;
527+
if (atomic_read(&F2FS_I(inode)->dirty_dents)) {
528+
spin_unlock(&sbi->dir_inode_lock);
529+
return;
530+
}
504531

505532
list_for_each(this, head) {
506533
struct dir_inode_entry *entry;
507534
entry = list_entry(this, struct dir_inode_entry, list);
508535
if (entry->inode == inode) {
509536
list_del(&entry->list);
510537
kmem_cache_free(inode_entry_slab, entry);
538+
#ifdef CONFIG_F2FS_STAT_FS
511539
sbi->n_dirty_dirs--;
540+
#endif
541+
break;
542+
}
543+
}
544+
spin_unlock(&sbi->dir_inode_lock);
545+
546+
/* Only from the recovery routine */
547+
if (is_inode_flag_set(F2FS_I(inode), FI_DELAY_IPUT)) {
548+
clear_inode_flag(F2FS_I(inode), FI_DELAY_IPUT);
549+
iput(inode);
550+
}
551+
}
552+
553+
struct inode *check_dirty_dir_inode(struct f2fs_sb_info *sbi, nid_t ino)
554+
{
555+
struct list_head *head = &sbi->dir_inode_list;
556+
struct list_head *this;
557+
struct inode *inode = NULL;
558+
559+
spin_lock(&sbi->dir_inode_lock);
560+
list_for_each(this, head) {
561+
struct dir_inode_entry *entry;
562+
entry = list_entry(this, struct dir_inode_entry, list);
563+
if (entry->inode->i_ino == ino) {
564+
inode = entry->inode;
512565
break;
513566
}
514567
}
515-
out:
516568
spin_unlock(&sbi->dir_inode_lock);
569+
return inode;
517570
}
518571

519572
void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi)
@@ -595,7 +648,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
595648
block_t start_blk;
596649
struct page *cp_page;
597650
unsigned int data_sum_blocks, orphan_blocks;
598-
unsigned int crc32 = 0;
651+
__u32 crc32 = 0;
599652
void *kaddr;
600653
int i;
601654

@@ -664,8 +717,8 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
664717
get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP));
665718

666719
crc32 = f2fs_crc32(ckpt, le32_to_cpu(ckpt->checksum_offset));
667-
*(__le32 *)((unsigned char *)ckpt +
668-
le32_to_cpu(ckpt->checksum_offset))
720+
*((__le32 *)((unsigned char *)ckpt +
721+
le32_to_cpu(ckpt->checksum_offset)))
669722
= cpu_to_le32(crc32);
670723

671724
start_blk = __start_cp_addr(sbi);

fs/f2fs/data.c

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs,
6868
struct buffer_head *bh_result)
6969
{
7070
struct f2fs_inode_info *fi = F2FS_I(inode);
71+
#ifdef CONFIG_F2FS_STAT_FS
7172
struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
73+
#endif
7274
pgoff_t start_fofs, end_fofs;
7375
block_t start_blkaddr;
7476

@@ -78,7 +80,9 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs,
7880
return 0;
7981
}
8082

83+
#ifdef CONFIG_F2FS_STAT_FS
8184
sbi->total_hit_ext++;
85+
#endif
8286
start_fofs = fi->ext.fofs;
8387
end_fofs = fi->ext.fofs + fi->ext.len - 1;
8488
start_blkaddr = fi->ext.blk_addr;
@@ -96,7 +100,9 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs,
96100
else
97101
bh_result->b_size = UINT_MAX;
98102

103+
#ifdef CONFIG_F2FS_STAT_FS
99104
sbi->read_hit_ext++;
105+
#endif
100106
read_unlock(&fi->ext.ext_lock);
101107
return 1;
102108
}
@@ -199,7 +205,7 @@ struct page *find_data_page(struct inode *inode, pgoff_t index, bool sync)
199205
if (dn.data_blkaddr == NEW_ADDR)
200206
return ERR_PTR(-EINVAL);
201207

202-
page = grab_cache_page(mapping, index);
208+
page = grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS);
203209
if (!page)
204210
return ERR_PTR(-ENOMEM);
205211

@@ -233,18 +239,23 @@ struct page *get_lock_data_page(struct inode *inode, pgoff_t index)
233239
struct page *page;
234240
int err;
235241

242+
repeat:
243+
page = grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS);
244+
if (!page)
245+
return ERR_PTR(-ENOMEM);
246+
236247
set_new_dnode(&dn, inode, NULL, NULL, 0);
237248
err = get_dnode_of_data(&dn, index, LOOKUP_NODE);
238-
if (err)
249+
if (err) {
250+
f2fs_put_page(page, 1);
239251
return ERR_PTR(err);
252+
}
240253
f2fs_put_dnode(&dn);
241254

242-
if (dn.data_blkaddr == NULL_ADDR)
255+
if (dn.data_blkaddr == NULL_ADDR) {
256+
f2fs_put_page(page, 1);
243257
return ERR_PTR(-ENOENT);
244-
repeat:
245-
page = grab_cache_page(mapping, index);
246-
if (!page)
247-
return ERR_PTR(-ENOMEM);
258+
}
248259

249260
if (PageUptodate(page))
250261
return page;
@@ -274,28 +285,31 @@ struct page *get_lock_data_page(struct inode *inode, pgoff_t index)
274285
*
275286
* Also, caller should grab and release a mutex by calling mutex_lock_op() and
276287
* mutex_unlock_op().
288+
* Note that, npage is set only by make_empty_dir.
277289
*/
278-
struct page *get_new_data_page(struct inode *inode, pgoff_t index,
279-
bool new_i_size)
290+
struct page *get_new_data_page(struct inode *inode,
291+
struct page *npage, pgoff_t index, bool new_i_size)
280292
{
281293
struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
282294
struct address_space *mapping = inode->i_mapping;
283295
struct page *page;
284296
struct dnode_of_data dn;
285297
int err;
286298

287-
set_new_dnode(&dn, inode, NULL, NULL, 0);
299+
set_new_dnode(&dn, inode, npage, npage, 0);
288300
err = get_dnode_of_data(&dn, index, ALLOC_NODE);
289301
if (err)
290302
return ERR_PTR(err);
291303

292304
if (dn.data_blkaddr == NULL_ADDR) {
293305
if (reserve_new_block(&dn)) {
294-
f2fs_put_dnode(&dn);
306+
if (!npage)
307+
f2fs_put_dnode(&dn);
295308
return ERR_PTR(-ENOSPC);
296309
}
297310
}
298-
f2fs_put_dnode(&dn);
311+
if (!npage)
312+
f2fs_put_dnode(&dn);
299313
repeat:
300314
page = grab_cache_page(mapping, index);
301315
if (!page)
@@ -325,6 +339,8 @@ struct page *get_new_data_page(struct inode *inode, pgoff_t index,
325339
if (new_i_size &&
326340
i_size_read(inode) < ((index + 1) << PAGE_CACHE_SHIFT)) {
327341
i_size_write(inode, ((index + 1) << PAGE_CACHE_SHIFT));
342+
/* Only the directory inode sets new_i_size */
343+
set_inode_flag(F2FS_I(inode), FI_UPDATE_DIR);
328344
mark_inode_dirty_sync(inode);
329345
}
330346
return page;
@@ -481,8 +497,9 @@ int do_write_data_page(struct page *page)
481497
* If current allocation needs SSR,
482498
* it had better in-place writes for updated data.
483499
*/
484-
if (old_blk_addr != NEW_ADDR && !is_cold_data(page) &&
485-
need_inplace_update(inode)) {
500+
if (unlikely(old_blk_addr != NEW_ADDR &&
501+
!is_cold_data(page) &&
502+
need_inplace_update(inode))) {
486503
rewrite_data_page(F2FS_SB(inode->i_sb), page,
487504
old_blk_addr);
488505
} else {
@@ -684,6 +701,27 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
684701
return err;
685702
}
686703

704+
static int f2fs_write_end(struct file *file,
705+
struct address_space *mapping,
706+
loff_t pos, unsigned len, unsigned copied,
707+
struct page *page, void *fsdata)
708+
{
709+
struct inode *inode = page->mapping->host;
710+
711+
SetPageUptodate(page);
712+
set_page_dirty(page);
713+
714+
if (pos + copied > i_size_read(inode)) {
715+
i_size_write(inode, pos + copied);
716+
mark_inode_dirty(inode);
717+
update_inode_page(inode);
718+
}
719+
720+
unlock_page(page);
721+
page_cache_release(page);
722+
return copied;
723+
}
724+
687725
static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb,
688726
const struct iovec *iov, loff_t offset, unsigned long nr_segs)
689727
{
@@ -741,7 +779,7 @@ const struct address_space_operations f2fs_dblock_aops = {
741779
.writepage = f2fs_write_data_page,
742780
.writepages = f2fs_write_data_pages,
743781
.write_begin = f2fs_write_begin,
744-
.write_end = nobh_write_end,
782+
.write_end = f2fs_write_end,
745783
.set_page_dirty = f2fs_set_data_page_dirty,
746784
.invalidatepage = f2fs_invalidate_data_page,
747785
.releasepage = f2fs_release_data_page,

fs/f2fs/debug.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,12 @@ static void update_mem_info(struct f2fs_sb_info *sbi)
175175

176176
static int stat_show(struct seq_file *s, void *v)
177177
{
178-
struct f2fs_stat_info *si, *next;
178+
struct f2fs_stat_info *si;
179179
int i = 0;
180180
int j;
181181

182182
mutex_lock(&f2fs_stat_mutex);
183-
list_for_each_entry_safe(si, next, &f2fs_stat_list, stat_list) {
183+
list_for_each_entry(si, &f2fs_stat_list, stat_list) {
184184
char devname[BDEVNAME_SIZE];
185185

186186
update_general_status(si->sbi);

0 commit comments

Comments
 (0)