Re: [f2fs-dev] [PATCH v2 7/7] f2fs: should check the remaining dentry bits

2016-04-25 Thread Jaegeuk Kim
Change log from v1:
 o remove wron f2fs_bug_on()

>From 545c0c9055b0d8dc5d134d9340b3cd80eeecdafa Mon Sep 17 00:00:00 2001
From: Jaegeuk Kim 
Date: Mon, 25 Apr 2016 14:24:44 -0700
Subject: [PATCH] f2fs: should check the remaining dentry bits

Let's consider a race condition between f2fs_add_regular_entry and
find_target_dentry.

1.
- f2fs_add_regular_entry updated len: 24 first.
   |
Bits:  0 0 0 1
Lens: 24 0 0 3 (name: foo)
   |->
- find_target_dentry checks the first bit to find "foo", then ++pointer.

2.
- f2fs_add_regular_entry updates bits.
   |>|>|
Bits:  1 1 1 1
Lens: 24 0 0 3 (name: foo)
 |
- find_target_dentry is checking second bit, but it's len is zero, which
makes the process being terminated.

In this case, user can add additional dentry named "foo" accordingly.
This patch enables to check the remaining bits.

Signed-off-by: He YunLei 
Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/dir.c | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index e90380d..0ad7b9a 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -100,12 +100,6 @@ static struct f2fs_dir_entry *find_in_block(struct page 
*dentry_page,
*res_page = dentry_page;
else
kunmap(dentry_page);
-
-   /*
-* For the most part, it should be a bug when name_len is zero.
-* We stop here for figuring out where the bugs has occurred.
-*/
-   f2fs_bug_on(F2FS_P_SB(dentry_page), d.max < 0);
return de;
 }
 
@@ -149,9 +143,9 @@ struct f2fs_dir_entry *find_target_dentry(struct 
fscrypt_name *fname,
 
/* remain bug on condition */
if (unlikely(!de->name_len))
-   d->max = -1;
-
-   bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
+   bit_pos++;
+   else
+   bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
}
 
de = NULL;
-- 
2.6.3


--
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 1/3] resize.f2fs: support to expand partition size

2016-04-25 Thread He YunLei
hi, kim

On 2016/4/26 8:28, Jaegeuk Kim wrote:
> Now user can expand existing partition with resize.f2fs.
> Currently, it doesn't support shrink an image.
>
> For example,
>   # resize.f2fs -t [# of sectors] [image]
>
> Signed-off-by: Jaegeuk Kim 
> ---
>   fsck/Makefile.am  |   4 +-
>   fsck/f2fs.h   |   4 +-
>   fsck/fsck.h   |   2 +
>   fsck/main.c   |  64 ++
>   fsck/resize.c | 578 
> ++
>   include/f2fs_fs.h |  17 ++
>   man/Makefile.am   |   2 +-
>   man/defrag.f2fs.8 |   3 +-
>   man/dump.f2fs.8   |   3 +-
>   man/fsck.f2fs.8   |   3 +-
>   man/mkfs.f2fs.8   |   3 +-
>   man/resize.f2fs.8 |  49 +
>   12 files changed, 724 insertions(+), 8 deletions(-)
>   create mode 100644 fsck/resize.c
>   create mode 100644 man/resize.f2fs.8
>
> diff --git a/fsck/Makefile.am b/fsck/Makefile.am
> index 73df884..3586625 100644
> --- a/fsck/Makefile.am
> +++ b/fsck/Makefile.am
> @@ -3,9 +3,11 @@
>   AM_CPPFLAGS = ${libuuid_CFLAGS} -I$(top_srcdir)/include
>   AM_CFLAGS = -Wall
>   sbin_PROGRAMS = fsck.f2fs
> -fsck_f2fs_SOURCES = main.c fsck.c dump.c mount.c defrag.c f2fs.h fsck.h 
> $(top_srcdir)/include/f2fs_fs.h
> +fsck_f2fs_SOURCES = main.c fsck.c dump.c mount.c defrag.c f2fs.h fsck.h 
> $(top_srcdir)/include/f2fs_fs.h  \
> + resize.c
>   fsck_f2fs_LDADD = ${libuuid_LIBS} $(top_builddir)/lib/libf2fs.la
>
>   install-data-hook:
>   ln -sf fsck.f2fs $(DESTDIR)/$(sbindir)/dump.f2fs
>   ln -sf fsck.f2fs $(DESTDIR)/$(sbindir)/defrag.f2fs
> + ln -sf fsck.f2fs $(DESTDIR)/$(sbindir)/resize.f2fs
> diff --git a/fsck/f2fs.h b/fsck/f2fs.h
> index a618b47..4b3c666 100644
> --- a/fsck/f2fs.h
> +++ b/fsck/f2fs.h
> @@ -323,9 +323,9 @@ static inline block_t sum_blk_addr(struct f2fs_sb_info 
> *sbi, int base, int type)
>   #define segno_in_journal(jnl, i)(jnl->sit_j.entries[i].segno)
>
>   #define SIT_ENTRY_OFFSET(sit_i, segno)  \
> - (segno % sit_i->sents_per_block)
> + ((segno) % sit_i->sents_per_block)
>   #define SIT_BLOCK_OFFSET(sit_i, segno)  \
> - (segno / SIT_ENTRY_PER_BLOCK)
> + ((segno) / SIT_ENTRY_PER_BLOCK)
>   #define TOTAL_SEGS(sbi) (SM_I(sbi)->main_segments)
>
>   static inline bool IS_VALID_NID(struct f2fs_sb_info *sbi, u32 nid)
> diff --git a/fsck/fsck.h b/fsck/fsck.h
> index 5fc214e..db11b41 100644
> --- a/fsck/fsck.h
> +++ b/fsck/fsck.h
> @@ -179,4 +179,6 @@ extern int dump_info_from_blkaddr(struct f2fs_sb_info *, 
> u32);
>   /* defrag.c */
>   int f2fs_defragment(struct f2fs_sb_info *, u64, u64, u64, int);
>
> +/* resize.c */
> +int f2fs_resize(struct f2fs_sb_info *);
>   #endif /* _FSCK_H_ */
> diff --git a/fsck/main.c b/fsck/main.c
> index 6058c4d..885e2cf 100644
> --- a/fsck/main.c
> +++ b/fsck/main.c
> @@ -52,6 +52,15 @@ void defrag_usage()
>   exit(1);
>   }
>
> +void resize_usage()
> +{
> + MSG(0, "\nUsage: resize.f2fs [options] device\n");
> + MSG(0, "[options]:\n");
> + MSG(0, "  -d debug level [default:0]\n");
> + MSG(0, "  -t target sectors [default: device size]\n");
> + exit(1);
> +}
> +
>   void f2fs_parse_options(int argc, char *argv[])
>   {
>   int option = 0;
> @@ -203,6 +212,34 @@ void f2fs_parse_options(int argc, char *argv[])
>   }
>   ASSERT(ret >= 0);
>   }
> + } else if (!strcmp("resize.f2fs", prog)) {
> + const char *option_string = "d:t:";
> +
> + config.func = RESIZE;
> + while ((option = getopt(argc, argv, option_string)) != EOF) {
> + int ret = 0;
> +
> + switch (option) {
> + case 'd':
> + config.dbg_lv = atoi(optarg);
> + MSG(0, "Info: Debug level = %d\n",
> + config.dbg_lv);
> + break;
> + case 't':
> + if (strncmp(optarg, "0x", 2))
> + ret = sscanf(optarg, "%"PRIu64"",
> + _sectors);
> + else
> + ret = sscanf(optarg, "%"PRIx64"",
> + _sectors);
> + break;
> + default:
> + MSG(0, "\tError: Unknown option %c\n", option);
> + resize_usage();
> + break;
> + }
> + ASSERT(ret >= 0);
> + }
>   }
>
>   if ((optind + 1) != argc) {
> @@ -213,6 +250,8 @@ void f2fs_parse_options(int argc, char *argv[])
>   dump_usage();
>   else if (config.func == DEFRAG)
>   defrag_usage();
> + 

[f2fs-dev] [PATCH] fsck.f2fs: remove duplicated codes in sanity_check_raw_super

2016-04-25 Thread Junling Zheng
Remove duplicated codes in sanity_check_raw_super().

Signed-off-by: Junling Zheng 
---
 fsck/mount.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/fsck/mount.c b/fsck/mount.c
index 4bde179..f866c4f 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -376,10 +376,6 @@ int sanity_check_raw_super(struct f2fs_super_block *sb, 
u64 offset)
if (get_sb(log_blocks_per_seg) != 9)
return -1;
 
-   if (get_sb(log_sectorsize) > F2FS_MAX_LOG_SECTOR_SIZE ||
-   get_sb(log_sectorsize) < F2FS_MIN_LOG_SECTOR_SIZE)
-   return -1;
-
/* Currently, support 512/1024/2048/4096 bytes sector size */
if (get_sb(log_sectorsize) > F2FS_MAX_LOG_SECTOR_SIZE ||
get_sb(log_sectorsize) < F2FS_MIN_LOG_SECTOR_SIZE)
-- 
1.9.1


--
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 1/3] resize.f2fs: support to expand partition size

2016-04-25 Thread He YunLei
On 2016/4/26 10:17, Jaegeuk Kim wrote:
> Hello,
>
> ...
>
>>> +   /* ovp / free segments */
>>> +   set_cp(overprov_segment_count, config.new_overprovision);
>>> +   set_cp(rsvd_segment_count, config.new_reserved_segments);
>>
>> maybe something wrong here:
>>  set_cp(rsvd_segment_count, config.new_reserved_segments);
>>  set_cp(overprov_segment_count, (get_newsb(segment_count_main) -
>>  get_cp(rsvd_segment_count)) *
>>  config.new_overprovision / 100);
>>  set_cp(overprov_segment_count, get_cp(overprov_segment_count) +
>>  get_cp(rsvd_segment_count));
>>
>
> So, could you illustrate the point?
> The new_overprovision and new_reserved_segments were calculated from the 
> target
> partition size.
>
> Am I missing something?

hi, Kim

I test the resize and find something wrong with overprov_segment_count,
and I find its calculation is different with mkfs tool. So I copy the method of
calculation from mkfs tool.

Thanks,
>
> Thanks,
>
>>> +   free_segment_count = get_cp(free_segment_count);
>>> +   new_segment_count = get_newsb(segment_count_main) -
>>> +   get_sb(segment_count_main);
>>> +
>>> +   set_cp(free_segment_count, free_segment_count + new_segment_count);
>>> +   set_cp(user_block_count, ((get_sb(segment_count_main) -
>>> +   get_cp(overprov_segment_count)) * config.blks_per_seg));
>>> +
>>> +   if (is_set_ckpt_flags(cp, CP_ORPHAN_PRESENT_FLAG))
>>> +   orphan_blks = __start_sum_addr(sbi) - 1;
>>> +
>>> +   set_cp(cp_pack_start_sum, 1 + get_newsb(cp_payload));
>>> +   set_cp(cp_pack_total_block_count, 8 + orphan_blks + 
>>> get_newsb(cp_payload));
>>> +
>>> +   /* cur->segno - offset */
>>> +   for (i = 0; i < NO_CHECK_TYPE; i++) {
>>> +   if (i < CURSEG_HOT_NODE) {
>>> +   set_cp(cur_data_segno[i],
>>> +   CURSEG_I(sbi, i)->segno - offset);
>>> +   } else {
>>> +   int n = i - CURSEG_HOT_NODE;
>>> +
>>> +   set_cp(cur_node_segno[n],
>>> +   CURSEG_I(sbi, i)->segno - offset);
>>> +   }
>>> +   }
>>> +
>>> +   /* sit / nat ver bitmap bytesize */
>>> +   set_cp(sit_ver_bitmap_bytesize,
>>> +   ((get_newsb(segment_count_sit) / 2) <<
>>> +   get_newsb(log_blocks_per_seg)) / 8);
>>> +   set_cp(nat_ver_bitmap_bytesize,
>>> +   ((get_newsb(segment_count_nat) / 2) <<
>>> +   get_newsb(log_blocks_per_seg)) / 8);
>>> +
>>> +   memcpy(new_cp, cp, (unsigned char *)cp->sit_nat_version_bitmap -
>>> +   (unsigned char *)cp);
>>> +
>>> +   crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, new_cp, CHECKSUM_OFFSET);
>>> +   *((__le32 *)((unsigned char *)new_cp + CHECKSUM_OFFSET)) = 
>>> cpu_to_le32(crc);
>>> +
>>> +   /* Write a new checkpoint in the other set */
>>> +   new_cp_blk_no = old_cp_blk_no = get_sb(cp_blkaddr);
>>> +   if (sbi->cur_cp == 2)
>>> +   old_cp_blk_no += 1 << get_sb(log_blocks_per_seg);
>>> +   else
>>> +   new_cp_blk_no += 1 << get_sb(log_blocks_per_seg);
>>> +
>>> +   /* write first cp */
>>> +   ret = dev_write_block(new_cp, new_cp_blk_no++);
>>> +   ASSERT(ret >= 0);
>>> +
>>> +   memset(buf, 0, BLOCK_SZ);
>>> +   for (i = 0; i < get_newsb(cp_payload); i++) {
>>> +   ret = dev_write_block(buf, new_cp_blk_no++);
>>> +   ASSERT(ret >= 0);
>>> +   }
>>> +
>>> +   for (i = 0; i < orphan_blks; i++) {
>>> +   block_t orphan_blk_no = old_cp_blk_no + 1 + get_sb(cp_payload);
>>> +
>>> +   ret = dev_read_block(buf, orphan_blk_no++);
>>> +   ASSERT(ret >= 0);
>>> +
>>> +   ret = dev_write_block(buf, new_cp_blk_no++);
>>> +   ASSERT(ret >= 0);
>>> +   }
>>> +
>>> +   /* update summary blocks having nullified journal entries */
>>> +   for (i = 0; i < NO_CHECK_TYPE; i++) {
>>> +   struct curseg_info *curseg = CURSEG_I(sbi, i);
>>> +
>>> +   ret = dev_write_block(curseg->sum_blk, new_cp_blk_no++);
>>> +   ASSERT(ret >= 0);
>>> +   }
>>> +
>>> +   /* write the last cp */
>>> +   ret = dev_write_block(new_cp, new_cp_blk_no++);
>>> +   ASSERT(ret >= 0);
>>> +
>>> +   /* disable old checkpoint */
>>> +   memset(buf, 0, BLOCK_SZ);
>>> +   ret = dev_write_block(buf, old_cp_blk_no);
>>> +   ASSERT(ret >= 0);
>>> +
>>> +   free(buf);
>>> +   free(new_cp);
>>> +   DBG(0, "Info: Done to rebuild checkpoint blocks\n");
>>> +}
>>> +
>>> +static void rebuild_superblock(struct f2fs_sb_info *sbi,
>>> +   struct f2fs_super_block *new_sb)
>>> +{
>>> +   int index, ret;
>>> +   u_int8_t *buf;
>>> +
>>> +   buf = calloc(BLOCK_SZ, 1);
>>> +
>>> +   memcpy(buf + F2FS_SUPER_OFFSET, new_sb, sizeof(*new_sb));
>>> +   for (index = 0; index < 2; index++) {
>>> +   ret = dev_write_block(buf, index);
>>> +   

[f2fs-dev] [PATCH 1/3] resize.f2fs: support to expand partition size

2016-04-25 Thread Jaegeuk Kim
Now user can expand existing partition with resize.f2fs.
Currently, it doesn't support shrink an image.

For example,
 # resize.f2fs -t [# of sectors] [image]

Signed-off-by: Jaegeuk Kim 
---
 fsck/Makefile.am  |   4 +-
 fsck/f2fs.h   |   4 +-
 fsck/fsck.h   |   2 +
 fsck/main.c   |  64 ++
 fsck/resize.c | 578 ++
 include/f2fs_fs.h |  17 ++
 man/Makefile.am   |   2 +-
 man/defrag.f2fs.8 |   3 +-
 man/dump.f2fs.8   |   3 +-
 man/fsck.f2fs.8   |   3 +-
 man/mkfs.f2fs.8   |   3 +-
 man/resize.f2fs.8 |  49 +
 12 files changed, 724 insertions(+), 8 deletions(-)
 create mode 100644 fsck/resize.c
 create mode 100644 man/resize.f2fs.8

diff --git a/fsck/Makefile.am b/fsck/Makefile.am
index 73df884..3586625 100644
--- a/fsck/Makefile.am
+++ b/fsck/Makefile.am
@@ -3,9 +3,11 @@
 AM_CPPFLAGS = ${libuuid_CFLAGS} -I$(top_srcdir)/include
 AM_CFLAGS = -Wall
 sbin_PROGRAMS = fsck.f2fs
-fsck_f2fs_SOURCES = main.c fsck.c dump.c mount.c defrag.c f2fs.h fsck.h 
$(top_srcdir)/include/f2fs_fs.h
+fsck_f2fs_SOURCES = main.c fsck.c dump.c mount.c defrag.c f2fs.h fsck.h 
$(top_srcdir)/include/f2fs_fs.h\
+   resize.c
 fsck_f2fs_LDADD = ${libuuid_LIBS} $(top_builddir)/lib/libf2fs.la
 
 install-data-hook:
ln -sf fsck.f2fs $(DESTDIR)/$(sbindir)/dump.f2fs
ln -sf fsck.f2fs $(DESTDIR)/$(sbindir)/defrag.f2fs
+   ln -sf fsck.f2fs $(DESTDIR)/$(sbindir)/resize.f2fs
diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index a618b47..4b3c666 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -323,9 +323,9 @@ static inline block_t sum_blk_addr(struct f2fs_sb_info 
*sbi, int base, int type)
 #define segno_in_journal(jnl, i)(jnl->sit_j.entries[i].segno)
 
 #define SIT_ENTRY_OFFSET(sit_i, segno)  \
-   (segno % sit_i->sents_per_block)
+   ((segno) % sit_i->sents_per_block)
 #define SIT_BLOCK_OFFSET(sit_i, segno)  \
-   (segno / SIT_ENTRY_PER_BLOCK)
+   ((segno) / SIT_ENTRY_PER_BLOCK)
 #define TOTAL_SEGS(sbi) (SM_I(sbi)->main_segments)
 
 static inline bool IS_VALID_NID(struct f2fs_sb_info *sbi, u32 nid)
diff --git a/fsck/fsck.h b/fsck/fsck.h
index 5fc214e..db11b41 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -179,4 +179,6 @@ extern int dump_info_from_blkaddr(struct f2fs_sb_info *, 
u32);
 /* defrag.c */
 int f2fs_defragment(struct f2fs_sb_info *, u64, u64, u64, int);
 
+/* resize.c */
+int f2fs_resize(struct f2fs_sb_info *);
 #endif /* _FSCK_H_ */
diff --git a/fsck/main.c b/fsck/main.c
index 6058c4d..885e2cf 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -52,6 +52,15 @@ void defrag_usage()
exit(1);
 }
 
+void resize_usage()
+{
+   MSG(0, "\nUsage: resize.f2fs [options] device\n");
+   MSG(0, "[options]:\n");
+   MSG(0, "  -d debug level [default:0]\n");
+   MSG(0, "  -t target sectors [default: device size]\n");
+   exit(1);
+}
+
 void f2fs_parse_options(int argc, char *argv[])
 {
int option = 0;
@@ -203,6 +212,34 @@ void f2fs_parse_options(int argc, char *argv[])
}
ASSERT(ret >= 0);
}
+   } else if (!strcmp("resize.f2fs", prog)) {
+   const char *option_string = "d:t:";
+
+   config.func = RESIZE;
+   while ((option = getopt(argc, argv, option_string)) != EOF) {
+   int ret = 0;
+
+   switch (option) {
+   case 'd':
+   config.dbg_lv = atoi(optarg);
+   MSG(0, "Info: Debug level = %d\n",
+   config.dbg_lv);
+   break;
+   case 't':
+   if (strncmp(optarg, "0x", 2))
+   ret = sscanf(optarg, "%"PRIu64"",
+   _sectors);
+   else
+   ret = sscanf(optarg, "%"PRIx64"",
+   _sectors);
+   break;
+   default:
+   MSG(0, "\tError: Unknown option %c\n", option);
+   resize_usage();
+   break;
+   }
+   ASSERT(ret >= 0);
+   }
}
 
if ((optind + 1) != argc) {
@@ -213,6 +250,8 @@ void f2fs_parse_options(int argc, char *argv[])
dump_usage();
else if (config.func == DEFRAG)
defrag_usage();
+   else if (config.func == RESIZE)
+   resize_usage();
}
config.device_name = argv[optind];
 }
@@ -345,6 +384,27 @@ out_range:
return -1;
 }
 
+static int do_resize(struct 

[f2fs-dev] [PATCH 2/3] sload.f2fs: support loading files into partition directly

2016-04-25 Thread Jaegeuk Kim
This patch implements loading files into the existing partition.
For example,
 # sload.f2fs -f ./ /dev/sdb1

Then, all the directories and files will be loaded into /dev/sdb1.
By default, newly files should have inline_data and inline_xattr, if possible.

Signed-off-by: Hou Pengyang 
Signed-off-by: Liu Shuoran 
Signed-off-by: Jaegeuk Kim 
---
 README|   1 +
 configure.ac  |   1 +
 fsck/Makefile.am  |   6 +-
 fsck/defrag.c |   2 +-
 fsck/dir.c| 584 ++
 fsck/f2fs.h   |  77 ++-
 fsck/fsck.h   |  26 ++-
 fsck/main.c   |  56 ++
 fsck/mount.c  |  90 -
 fsck/node.c   | 250 +++
 fsck/node.h   | 101 ++
 fsck/segment.c| 220 
 fsck/sload.c  | 247 +++
 fsck/xattr.c  | 241 ++
 fsck/xattr.h  |  66 ++
 include/f2fs_fs.h |  18 +-
 man/Makefile.am   |   2 +-
 man/defrag.f2fs.8 |   3 +-
 man/dump.f2fs.8   |   3 +-
 man/fsck.f2fs.8   |   3 +-
 man/mkfs.f2fs.8   |   3 +-
 man/resize.f2fs.8 |   3 +-
 man/sload.f2fs.8  |  56 ++
 23 files changed, 2042 insertions(+), 17 deletions(-)
 create mode 100644 fsck/dir.c
 create mode 100644 fsck/node.c
 create mode 100644 fsck/node.h
 create mode 100644 fsck/segment.c
 create mode 100644 fsck/sload.c
 create mode 100644 fsck/xattr.c
 create mode 100644 fsck/xattr.h
 create mode 100644 man/sload.f2fs.8

diff --git a/README b/README
index 222cbc3..77d9b49 100644
--- a/README
+++ b/README
@@ -12,6 +12,7 @@ Your should install the following packages.
  - pkg-config
  - autoconf
  - libtool
+ - libselinux1-dev
 
 Initial compilation
 ---
diff --git a/configure.ac b/configure.ac
index 1f6ff5a..42df775 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,6 +54,7 @@ AC_PATH_PROG([LDCONFIG], [ldconfig],
 
 # Checks for libraries.
 PKG_CHECK_MODULES([libuuid], [uuid])
+PKG_CHECK_MODULES([libselinux], [libselinux])
 
 # Checks for header files.
 AC_CHECK_HEADERS([linux/fs.h fcntl.h mntent.h stdlib.h string.h \
diff --git a/fsck/Makefile.am b/fsck/Makefile.am
index 3586625..7abcd00 100644
--- a/fsck/Makefile.am
+++ b/fsck/Makefile.am
@@ -4,10 +4,12 @@ AM_CPPFLAGS = ${libuuid_CFLAGS} -I$(top_srcdir)/include
 AM_CFLAGS = -Wall
 sbin_PROGRAMS = fsck.f2fs
 fsck_f2fs_SOURCES = main.c fsck.c dump.c mount.c defrag.c f2fs.h fsck.h 
$(top_srcdir)/include/f2fs_fs.h\
-   resize.c
-fsck_f2fs_LDADD = ${libuuid_LIBS} $(top_builddir)/lib/libf2fs.la
+   resize.c
\
+   node.c segment.c dir.c sload.c xattr.c
+fsck_f2fs_LDADD = ${libselinux_LIBS} ${libuuid_LIBS} 
$(top_builddir)/lib/libf2fs.la
 
 install-data-hook:
ln -sf fsck.f2fs $(DESTDIR)/$(sbindir)/dump.f2fs
ln -sf fsck.f2fs $(DESTDIR)/$(sbindir)/defrag.f2fs
ln -sf fsck.f2fs $(DESTDIR)/$(sbindir)/resize.f2fs
+   ln -sf fsck.f2fs $(DESTDIR)/$(sbindir)/sload.f2fs
diff --git a/fsck/defrag.c b/fsck/defrag.c
index 7abc0bf..079e7a7 100644
--- a/fsck/defrag.c
+++ b/fsck/defrag.c
@@ -51,7 +51,7 @@ static int migrate_block(struct f2fs_sb_info *sbi, u64 from, 
u64 to)
update_data_blkaddr(sbi, le32_to_cpu(sum.nid),
le16_to_cpu(sum.ofs_in_node), to);
else
-   update_nat_blkaddr(sbi, le32_to_cpu(sum.nid), to);
+   update_nat_blkaddr(sbi, 0, le32_to_cpu(sum.nid), to);
 
DBG(0, "Migrate %s block %"PRIx64" -> %"PRIx64"\n",
IS_DATASEG(type) ? "data" : "node",
diff --git a/fsck/dir.c b/fsck/dir.c
new file mode 100644
index 000..18b79bd
--- /dev/null
+++ b/fsck/dir.c
@@ -0,0 +1,584 @@
+/**
+ * dir.c
+ *
+ * Many parts of codes are copied from Linux kernel/fs/f2fs.
+ *
+ * Copyright (C) 2015 Huawei Ltd.
+ * Witten by:
+ *   Hou Pengyang 
+ *   Liu Shuoran 
+ *   Jaegeuk Kim 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include "fsck.h"
+#include "node.h"
+
+static unsigned int dir_buckets(unsigned int level)
+{
+   if (level < MAX_DIR_HASH_DEPTH / 2)
+   return 1 << level;
+   else
+   return MAX_DIR_BUCKETS;
+}
+
+static unsigned int bucket_blocks(unsigned int level)
+{
+   if (level < MAX_DIR_HASH_DEPTH / 2)
+   return 2;
+   else
+   return 4;
+}
+
+static unsigned long dir_block_index(unsigned int level,
+   int dir_level, unsigned int idx)
+{
+   unsigned long i;
+   unsigned long bidx = 0;
+
+   for (i = 0; i < level; i++)
+   bidx += dir_buckets(i + dir_level) * 

[f2fs-dev] [PATCH 3/3] script: add simple test script

2016-04-25 Thread Jaegeuk Kim
This patch adds a script to test sload.f2fs, defrag.f2fs, and resize.f2fs.

Signed-off-by: Jaegeuk Kim 
---
 scripts/verify.sh | 137 ++
 1 file changed, 137 insertions(+)
 create mode 100755 scripts/verify.sh

diff --git a/scripts/verify.sh b/scripts/verify.sh
new file mode 100755
index 000..8a22a2d
--- /dev/null
+++ b/scripts/verify.sh
@@ -0,0 +1,137 @@
+#!/bin/bash
+
+IMG=../test.img
+TMP=/tmp/res
+XFSTESTS=~/xfstests
+TESTS="4 5 8 11 16 25 32 55 64"
+
+TARGET=./testdir
+MNT=/mnt/resize
+
+mkdir $TARGET 2>/dev/null
+mkdir $MNT 2>/dev/null
+
+umount $TARGET
+umount $MNT
+
+_check_out()
+{
+   if [ $1 -ne 0 ]; then
+   grep ASSERT $TMP
+   echo FAIL RETURN $1
+   exit
+   fi
+}
+
+_get_sec()
+{
+   echo $(($1*1024*1024*1024/512))
+}
+
+_mkfs()
+{
+   echo "== Initialize $1 GB "
+   mkfs.f2fs $IMG `_get_sec $1` | grep sectors
+}
+
+_mount()
+{
+   echo "== mount to $1 ="
+   mount -t f2fs -o loop,discard,inline_data,inline_xattr $IMG $1 2>&1
+   _check_out $?
+}
+
+_fsck()
+{
+   echo "== fsck.f2fs ==="
+   fsck.f2fs $IMG -t 2>&1 >$TMP
+   _check_out $?
+   grep FSCK $TMP
+}
+
+_fsstress()
+{
+   echo "== fsstress $1 ="
+   $XFSTESTS/ltp/fsstress -x "echo 3 > /proc/sys/vm/drop_caches && sleep 
1" -X 1 -r -f fsync=8 -f sync=0 -f write=8 -f dwrite=2 -f truncate=6 -f 
allocsp=0 -f bulkstat=0 -f bulkstat1=0 -f freesp=0 -f zero=1 -f collapse=1 -f 
insert=1 -f resvsp=0 -f unresvsp=0 -S t -p 10 -n $2 -d $1 >/dev/null
+}
+
+_resize()
+{
+   echo "== resize.f2fs $1 GB ==="
+   resize.f2fs -t `_get_sec $1` $IMG 2>&1 >$TMP
+   _check_out $?
+   _fsck
+}
+
+_resize_tests()
+{
+   for i in $TESTS
+   do
+   if [ $i -ge $1 ]; then
+   _resize $i
+   fi
+   done
+}
+
+_sload()
+{
+   echo "== sload $1 "
+   sload.f2fs -f $1 $IMG 2>&1
+   _check_out $?
+}
+
+from_mount()
+{
+   echo ""
+   echo "   $1 GB to $2 GB with $3 *** "
+   _mkfs $1
+   _mount $3
+   _fsstress $3 1
+   umount $3
+   _fsck
+   _resize_tests $2
+}
+
+from_sload()
+{
+   echo ""
+   echo "   $1 GB to $2 GB with $3 *** "
+
+   _mkfs $1
+   _sload $3
+   _fsck
+
+   _mount $MNT
+   _fsstress $MNT 1
+   umount $MNT
+   _fsck
+
+   _resize_tests $2
+
+   _mount $MNT
+   _fsstress $MNT 1
+   umount $MNT
+   _fsck
+}
+
+test_all()
+{
+   for i in $TESTS
+   do
+   for j in $TESTS
+   do
+   if [ $i -lt $j ]; then
+   $1 $i $j $2
+   fi
+   done
+   done
+}
+
+test_all from_sload ~/grub
+
+rm -rf $TARGET/*
+_fsstress $TARGET 5000
+test_all from_sload $TARGET
+rm -rf $TARGET 2>/dev/null
+
+test_all from_mount $MNT
-- 
2.6.3


--
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 3/7] f2fs: split sync_node_pages with fsync_node_pages

2016-04-25 Thread Jaegeuk Kim
This patch splits the existing sync_node_pages into (f)sync_node_pages.
The fsync_node_pages is used for f2fs_sync_file only.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/checkpoint.c |   2 +-
 fs/f2fs/f2fs.h   |   3 +-
 fs/f2fs/file.c   |   2 +-
 fs/f2fs/gc.c |   2 +-
 fs/f2fs/node.c   | 108 +--
 5 files changed, 84 insertions(+), 33 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index b92782f..bf040b5 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -892,7 +892,7 @@ retry_flush_nodes:
 
if (get_pages(sbi, F2FS_DIRTY_NODES)) {
up_write(>node_write);
-   err = sync_node_pages(sbi, 0, );
+   err = sync_node_pages(sbi, );
if (err) {
f2fs_unlock_all(sbi);
goto out;
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 3f15513..269abe5 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1784,7 +1784,8 @@ void ra_node_page(struct f2fs_sb_info *, nid_t);
 struct page *get_node_page(struct f2fs_sb_info *, pgoff_t);
 struct page *get_node_page_ra(struct page *, int);
 void sync_inode_page(struct dnode_of_data *);
-int sync_node_pages(struct f2fs_sb_info *, nid_t, struct writeback_control *);
+int fsync_node_pages(struct f2fs_sb_info *, nid_t, struct writeback_control *);
+int sync_node_pages(struct f2fs_sb_info *, struct writeback_control *);
 bool alloc_nid(struct f2fs_sb_info *, nid_t *);
 void alloc_nid_done(struct f2fs_sb_info *, nid_t);
 void alloc_nid_failed(struct f2fs_sb_info *, nid_t);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 7de90e6..3d53ee0 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -256,7 +256,7 @@ go_write:
goto out;
}
 sync_nodes:
-   sync_node_pages(sbi, ino, );
+   fsync_node_pages(sbi, ino, );
 
/* if cp_error was enabled, we should avoid infinite loop */
if (unlikely(f2fs_cp_error(sbi))) {
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index b0051a9..e820465 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -841,7 +841,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
.nr_to_write = LONG_MAX,
.for_reclaim = 0,
};
-   sync_node_pages(sbi, 0, );
+   sync_node_pages(sbi, );
} else {
f2fs_submit_merged_bio(sbi, DATA, WRITE);
}
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index cccee50..675b730 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1222,12 +1222,84 @@ iput_out:
iput(inode);
 }
 
-int sync_node_pages(struct f2fs_sb_info *sbi, nid_t ino,
+int fsync_node_pages(struct f2fs_sb_info *sbi, nid_t ino,
struct writeback_control *wbc)
 {
pgoff_t index, end;
struct pagevec pvec;
-   int step = ino ? 2 : 0;
+   int nwritten = 0;
+
+   pagevec_init(, 0);
+   index = 0;
+   end = ULONG_MAX;
+
+   while (index <= end) {
+   int i, nr_pages;
+   nr_pages = pagevec_lookup_tag(, NODE_MAPPING(sbi), ,
+   PAGECACHE_TAG_DIRTY,
+   min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
+   if (nr_pages == 0)
+   break;
+
+   for (i = 0; i < nr_pages; i++) {
+   struct page *page = pvec.pages[i];
+
+   if (unlikely(f2fs_cp_error(sbi))) {
+   pagevec_release();
+   return -EIO;
+   }
+
+   if (!IS_DNODE(page) || !is_cold_node(page))
+   continue;
+   if (ino_of_node(page) != ino)
+   continue;
+
+   lock_page(page);
+
+   if (unlikely(page->mapping != NODE_MAPPING(sbi))) {
+continue_unlock:
+   unlock_page(page);
+   continue;
+   }
+   if (ino_of_node(page) != ino)
+   goto continue_unlock;
+
+   if (!PageDirty(page)) {
+   /* someone wrote it for us */
+   goto continue_unlock;
+   }
+
+   f2fs_wait_on_page_writeback(page, NODE, true);
+   BUG_ON(PageWriteback(page));
+   if (!clear_page_dirty_for_io(page))
+   goto continue_unlock;
+
+   set_fsync_mark(page, 1);
+   if (IS_INODE(page))
+   set_dentry_mark(page,
+   need_dentry_mark(sbi, ino));
+   

[f2fs-dev] [PATCH 4/7] f2fs: report unwritten status in fsync_node_pages

2016-04-25 Thread Jaegeuk Kim
The fsync_node_pages should return pass or failure so that user could know
fsync is completed or not.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/file.c |  4 +++-
 fs/f2fs/node.c | 13 ++---
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 3d53ee0..60fd64c 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -256,7 +256,9 @@ go_write:
goto out;
}
 sync_nodes:
-   fsync_node_pages(sbi, ino, );
+   ret = fsync_node_pages(sbi, ino, );
+   if (ret)
+   goto out;
 
/* if cp_error was enabled, we should avoid infinite loop */
if (unlikely(f2fs_cp_error(sbi))) {
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 675b730..8a1e211 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1227,7 +1227,7 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, nid_t ino,
 {
pgoff_t index, end;
struct pagevec pvec;
-   int nwritten = 0;
+   int ret = 0;
 
pagevec_init(, 0);
index = 0;
@@ -1278,21 +1278,20 @@ continue_unlock:
if (IS_INODE(page))
set_dentry_mark(page,
need_dentry_mark(sbi, ino));
-   nwritten++;
 
-   if (NODE_MAPPING(sbi)->a_ops->writepage(page, wbc))
+   ret = NODE_MAPPING(sbi)->a_ops->writepage(page, wbc);
+   if (ret) {
unlock_page(page);
-
-   if (--wbc->nr_to_write == 0)
break;
+   }
}
pagevec_release();
cond_resched();
 
-   if (wbc->nr_to_write == 0)
+   if (ret)
break;
}
-   return nwritten;
+   return ret ? -EIO: 0;
 }
 
 int sync_node_pages(struct f2fs_sb_info *sbi, struct writeback_control *wbc)
-- 
2.6.3


--
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 5/7] f2fs: set fsync mark only for the last dnode

2016-04-25 Thread Jaegeuk Kim
In order to give atomic writes, we should consider power failure during
sync_node_pages in fsync.
So, this patch marks fsync flag only in the last dnode block.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/f2fs.h |   4 +-
 fs/f2fs/file.c |  14 +--
 fs/f2fs/node.c | 106 +
 fs/f2fs/recovery.c |   9 ++---
 4 files changed, 113 insertions(+), 20 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 269abe5..ca828b0 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -159,7 +159,6 @@ struct fsync_inode_entry {
struct inode *inode;/* vfs inode pointer */
block_t blkaddr;/* block address locating the last fsync */
block_t last_dentry;/* block address locating the last dentry */
-   block_t last_inode; /* block address locating the last inode */
 };
 
 #define nats_in_cursum(jnl)(le16_to_cpu(jnl->n_nats))
@@ -1784,7 +1783,8 @@ void ra_node_page(struct f2fs_sb_info *, nid_t);
 struct page *get_node_page(struct f2fs_sb_info *, pgoff_t);
 struct page *get_node_page_ra(struct page *, int);
 void sync_inode_page(struct dnode_of_data *);
-int fsync_node_pages(struct f2fs_sb_info *, nid_t, struct writeback_control *);
+int fsync_node_pages(struct f2fs_sb_info *, nid_t, struct writeback_control *,
+   bool);
 int sync_node_pages(struct f2fs_sb_info *, struct writeback_control *);
 bool alloc_nid(struct f2fs_sb_info *, nid_t *);
 void alloc_nid_done(struct f2fs_sb_info *, nid_t);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 60fd64c..dc47d5c 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -182,7 +182,8 @@ static void try_to_fix_pino(struct inode *inode)
}
 }
 
-int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,
+   int datasync, bool atomic)
 {
struct inode *inode = file->f_mapping->host;
struct f2fs_inode_info *fi = F2FS_I(inode);
@@ -256,7 +257,7 @@ go_write:
goto out;
}
 sync_nodes:
-   ret = fsync_node_pages(sbi, ino, );
+   ret = fsync_node_pages(sbi, ino, , atomic);
if (ret)
goto out;
 
@@ -290,6 +291,11 @@ out:
return ret;
 }
 
+int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+{
+   return f2fs_do_sync_file(file, start, end, datasync, false);
+}
+
 static pgoff_t __get_first_dirty_index(struct address_space *mapping,
pgoff_t pgofs, int whence)
 {
@@ -1407,7 +1413,7 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
}
}
 
-   ret = f2fs_sync_file(filp, 0, LLONG_MAX, 0);
+   ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true);
 err_out:
mnt_drop_write_file(filp);
return ret;
@@ -1465,7 +1471,7 @@ static int f2fs_ioc_abort_volatile_write(struct file 
*filp)
drop_inmem_pages(inode);
if (f2fs_is_volatile_file(inode)) {
clear_inode_flag(F2FS_I(inode), FI_VOLATILE_FILE);
-   ret = f2fs_sync_file(filp, 0, LLONG_MAX, 0);
+   ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true);
}
 
mnt_drop_write_file(filp);
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 8a1e211..de070a5 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1222,13 +1222,81 @@ iput_out:
iput(inode);
 }
 
+static struct page *last_fsync_dnode(struct f2fs_sb_info *sbi, nid_t ino)
+{
+   pgoff_t index, end;
+   struct pagevec pvec;
+   struct page *last_page = NULL;
+
+   pagevec_init(, 0);
+   index = 0;
+   end = ULONG_MAX;
+
+   while (index <= end) {
+   int i, nr_pages;
+   nr_pages = pagevec_lookup_tag(, NODE_MAPPING(sbi), ,
+   PAGECACHE_TAG_DIRTY,
+   min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
+   if (nr_pages == 0)
+   break;
+
+   for (i = 0; i < nr_pages; i++) {
+   struct page *page = pvec.pages[i];
+
+   if (unlikely(f2fs_cp_error(sbi))) {
+   f2fs_put_page(last_page, 0);
+   pagevec_release();
+   return ERR_PTR(-EIO);
+   }
+
+   if (!IS_DNODE(page) || !is_cold_node(page))
+   continue;
+   if (ino_of_node(page) != ino)
+   continue;
+
+   lock_page(page);
+
+   if (unlikely(page->mapping != NODE_MAPPING(sbi))) {
+continue_unlock:
+   unlock_page(page);
+   continue;
+ 

[f2fs-dev] [PATCH 1/7] f2fs: avoid needless lock for node pages when fsyncing a file

2016-04-25 Thread Jaegeuk Kim
When fsync is called, sync_node_pages finds a proper direct node pages to flush.
But, it locks unrelated direct node pages together unnecessarily.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/node.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 095fc2c..cccee50 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1272,10 +1272,14 @@ next_step:
 * we should not skip writing node pages.
 */
 lock_node:
-   if (ino && ino_of_node(page) == ino)
-   lock_page(page);
-   else if (!trylock_page(page))
+   if (ino) {
+   if (ino_of_node(page) == ino)
+   lock_page(page);
+   else
+   continue;
+   } else if (!trylock_page(page)) {
continue;
+   }
 
if (unlikely(page->mapping != NODE_MAPPING(sbi))) {
 continue_unlock:
-- 
2.6.3


--
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 6/7] f2fs: issue cache flush on direct IO

2016-04-25 Thread Jaegeuk Kim
Under direct IO path with O_(D)SYNC, it needs to set proper APPEND or UPDATE
flags, so taht f2fs_sync_file can make its data safe.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/data.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index e54489b..38ce5d6 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -673,6 +673,9 @@ next_block:
err = reserve_new_block();
} else {
err = __allocate_data_block();
+   if (!err)
+   set_inode_flag(F2FS_I(inode),
+   FI_APPEND_WRITE);
}
if (err)
goto sync_out;
@@ -1685,8 +1688,12 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct 
iov_iter *iter,
trace_f2fs_direct_IO_enter(inode, offset, count, iov_iter_rw(iter));
 
err = blockdev_direct_IO(iocb, inode, iter, offset, get_data_block_dio);
-   if (err < 0 && iov_iter_rw(iter) == WRITE)
-   f2fs_write_failed(mapping, offset + count);
+   if (iov_iter_rw(iter) == WRITE) {
+   if (err > 0)
+   set_inode_flag(F2FS_I(inode), FI_UPDATE_WRITE);
+   else if (err < 0)
+   f2fs_write_failed(mapping, offset + count);
+   }
 
trace_f2fs_direct_IO_exit(inode, offset, count, iov_iter_rw(iter), err);
 
-- 
2.6.3


--
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 7/7] f2fs: should check the remaining dentry bits

2016-04-25 Thread Jaegeuk Kim
Let's consider a race condition between f2fs_add_regular_entry and
find_target_dentry.

1.
- f2fs_add_regular_entry updated len: 24 first.
   |
Bits:  0 0 0 1
Lens: 24 0 0 3 (name: foo)
   |->
- find_target_dentry checks the first bit to find "foo", then ++pointer.

2.
- f2fs_add_regular_entry updates bits.
   |>|>|
Bits:  1 1 1 1
Lens: 24 0 0 3 (name: foo)
 |
- find_target_dentry is checking second bit, but it's len is zero, which
makes the process being terminated.

In this case, user can add additional dentry named "foo" accordingly.
This patch enables to check the remaining bits.

Signed-off-by: He YunLei 
Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/dir.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index e90380d..aed5e6d 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -149,9 +149,9 @@ struct f2fs_dir_entry *find_target_dentry(struct 
fscrypt_name *fname,
 
/* remain bug on condition */
if (unlikely(!de->name_len))
-   d->max = -1;
-
-   bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
+   bit_pos++;
+   else
+   bit_pos += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
}
 
de = NULL;
-- 
2.6.3


--
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 2/7] f2fs: avoid writing 0'th page in volatile writes

2016-04-25 Thread Jaegeuk Kim
The first page of volatile writes usually contains a sort of header information
which will be used for recovery.
(e.g., journal header of sqlite)

If this is written without other journal data, user needs to handle the stale
journal information.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/data.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index c29bcf4..e54489b 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1177,8 +1177,10 @@ write:
goto redirty_out;
if (f2fs_is_drop_cache(inode))
goto out;
-   if (f2fs_is_volatile_file(inode) && !wbc->for_reclaim &&
-   available_free_memory(sbi, BASE_CHECK))
+   /* we should not write 0'th page having journal header */
+   if (f2fs_is_volatile_file(inode) && (!page->index ||
+   (!wbc->for_reclaim &&
+   available_free_memory(sbi, BASE_CHECK
goto redirty_out;
 
/* Dentry blocks are controlled by checkpoint */
-- 
2.6.3


--
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel