[f2fs-dev] [RFC 2/5] f2fs: Handle inline data read and write

2013-06-03 Thread Huajun Li
Hook inline data read/write in address space operations.

Signed-off-by: Huajun Li huajun...@intel.com
Signed-off-by: Haicheng Li haicheng...@linux.intel.com
---
 fs/f2fs/data.c |   78 ++--
 fs/f2fs/file.c |9 +--
 2 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 93917e3..bac25f3 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -64,6 +64,23 @@ int reserve_new_block(struct dnode_of_data *dn)
return 0;
 }
 
+int f2fs_reserve_block(struct inode *inode, pgoff_t index)
+{
+   int err;
+   struct dnode_of_data dn;
+
+   set_new_dnode(dn, inode, NULL, NULL, 0);
+   err = get_dnode_of_data(dn, index, ALLOC_NODE);
+   if (err)
+   return err;
+   if (dn.data_blkaddr == NULL_ADDR)
+   err = reserve_new_block(dn);
+
+   f2fs_put_dnode(dn);
+
+   return err;
+}
+
 static int check_extent_cache(struct inode *inode, pgoff_t pgofs,
struct buffer_head *bh_result)
 {
@@ -461,13 +478,28 @@ static int get_data_block_ro(struct inode *inode, 
sector_t iblock,
 
 static int f2fs_read_data_page(struct file *file, struct page *page)
 {
-   return mpage_readpage(page, get_data_block_ro);
+   int ret;
+   struct inode *inode = file-f_mapping-host;
+
+   /* If the file has inline data, try to read it directlly */
+   if (f2fs_has_inline_data(inode))
+   ret = f2fs_read_inline_data_page(inode, page);
+   else
+   ret = mpage_readpage(page, get_data_block_ro);
+
+   return ret;
 }
 
 static int f2fs_read_data_pages(struct file *file,
struct address_space *mapping,
struct list_head *pages, unsigned nr_pages)
 {
+   struct inode *inode = file-f_mapping-host;
+
+   /* If the file has inline data, skip readpages */
+   if (f2fs_has_inline_data(inode))
+   return 0;
+
return mpage_readpages(mapping, pages, nr_pages, get_data_block_ro);
 }
 
@@ -517,7 +549,7 @@ static int f2fs_write_data_page(struct page *page,
loff_t i_size = i_size_read(inode);
const pgoff_t end_index = ((unsigned long long) i_size)
 PAGE_CACHE_SHIFT;
-   unsigned offset;
+   unsigned offset = 0;
bool need_balance_fs = false;
int err = 0;
 
@@ -551,7 +583,16 @@ write:
err = do_write_data_page(page);
} else {
int ilock = mutex_lock_op(sbi);
+
+#ifdef CONFIG_F2FS_INLINE_DATA
+   if (i_size = MAX_INLINE_DATA)
+   err = f2fs_write_inline_data(inode, page, offset);
+   else
+   err = do_write_data_page(page);
+#else
err = do_write_data_page(page);
+#endif
+
mutex_unlock_op(sbi, ilock);
need_balance_fs = true;
}
@@ -643,6 +684,25 @@ repeat:
return -ENOMEM;
*pagep = page;
 
+#ifdef CONFIG_F2FS_INLINE_DATA
+   if ((pos + len) = MAX_INLINE_DATA) {
+   set_inode_dyn_flag(F2FS_I(inode), F2FS_INLINE_DATA_ATTEMPT);
+   goto inline_data;
+   } else if (f2fs_has_inline_data(inode)) {
+   err = f2fs_convert_inline_data(page, inode, flags);
+   if (err)
+   return err;
+   } else if (f2fs_inline_data_attempt(inode)) {
+   clear_inode_dyn_flag(F2FS_I(inode), F2FS_INLINE_DATA_ATTEMPT);
+
+   ilock = mutex_lock_op(sbi);
+   err = f2fs_reserve_block(inode, 0);
+   if (err)
+   goto err;
+   mutex_unlock_op(sbi, ilock);
+   }
+#endif
+
ilock = mutex_lock_op(sbi);
 
set_new_dnode(dn, inode, NULL, NULL, 0);
@@ -659,6 +719,7 @@ repeat:
 
mutex_unlock_op(sbi, ilock);
 
+inline_data:
if ((len == PAGE_CACHE_SIZE) || PageUptodate(page))
return 0;
 
@@ -674,7 +735,16 @@ repeat:
if (dn.data_blkaddr == NEW_ADDR) {
zero_user_segment(page, 0, PAGE_CACHE_SIZE);
} else {
+#ifdef CONFIG_F2FS_INLINE_DATA
+   if ((pos + len) = MAX_INLINE_DATA)
+   err = f2fs_read_inline_data_page(inode, page);
+   else
+   err = f2fs_readpage(sbi, page,
+   dn.data_blkaddr, READ_SYNC);
+#else
err = f2fs_readpage(sbi, page, dn.data_blkaddr, READ_SYNC);
+#endif
+
if (err)
return err;
lock_page(page);
@@ -707,6 +777,10 @@ static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb,
if (rw == WRITE)
return 0;
 
+   /* Let buffer I/O handle the inline data case. */
+   if (f2fs_has_inline_data(inode))
+   return 0;
+
/* Needs synchronization with the 

[f2fs-dev] [RFC 4/5] f2fs: Add Kconfig interface for inline data support

2013-06-03 Thread Huajun Li
From: Haicheng Li haicheng...@linux.intel.com

Add Kconfig interface for inline data support, and update Makefile to
compile new added source file.

Signed-off-by: Haicheng Li haicheng...@linux.intel.com
Signed-off-by: Huajun Li huajun...@intel.com
---
 fs/f2fs/Kconfig  |   10 ++
 fs/f2fs/Makefile |1 +
 2 files changed, 11 insertions(+)

diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig
index fd27e7e..75da2e4 100644
--- a/fs/f2fs/Kconfig
+++ b/fs/f2fs/Kconfig
@@ -51,3 +51,13 @@ config F2FS_FS_POSIX_ACL
  Linux website http://acl.bestbits.at/.
 
  If you don't know what Access Control Lists are, say N
+
+config F2FS_INLINE_DATA
+   bool F2FS inline data support
+   depends on F2FS_FS
+   default y
+   help
+ Inline data support is an optimization of F2FS data space management,
+ which utilizes the unused space within f2fs inode to keep real data.
+
+ If unsure, say N.
diff --git a/fs/f2fs/Makefile b/fs/f2fs/Makefile
index 27a0820..e1ff7b8 100644
--- a/fs/f2fs/Makefile
+++ b/fs/f2fs/Makefile
@@ -5,3 +5,4 @@ f2fs-y  += checkpoint.o gc.o data.o node.o segment.o 
recovery.o
 f2fs-$(CONFIG_F2FS_STAT_FS) += debug.o
 f2fs-$(CONFIG_F2FS_FS_XATTR) += xattr.o
 f2fs-$(CONFIG_F2FS_FS_POSIX_ACL) += acl.o
+f2fs-$(CONFIG_F2FS_INLINE_DATA) += inline.o
-- 
1.7.9.5


--
Get 100% visibility into Java/.NET code with AppDynamics Lite
It's a free troubleshooting tool designed for production
Get down to code-level detail for bottlenecks, with 2% overhead.
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap2
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [RFC 3/5] f2fs: Key functions to handle inline data

2013-06-03 Thread Huajun Li
Functions to implement inline data read/write, and move inline data to
normal data block when file size exceeds inline data limitation.

Signed-off-by: Huajun Li huajun...@intel.com
Signed-off-by: Haicheng Li haicheng...@linux.intel.com
---
 fs/f2fs/inline.c |  152 ++
 1 file changed, 152 insertions(+)
 create mode 100644 fs/f2fs/inline.c

diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
new file mode 100644
index 000..a2aa056
--- /dev/null
+++ b/fs/f2fs/inline.c
@@ -0,0 +1,152 @@
+/*
+ * fs/f2fs/inline.c
+ *
+ * Copyright (c) 2013, Intel Corporation.
+ * Authors:
+ *  Huajun Li huajun...@intel.com
+ *  Haicheng Li haicheng...@intel.com
+ *
+ * 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 linux/fs.h
+#include linux/f2fs_fs.h
+
+#include f2fs.h
+
+void f2fs_clear_inode_inline_flag(struct f2fs_inode *raw_inode)
+{
+   raw_inode-i_reserved = ~F2FS_INODE_INLINE_DATA;
+}
+
+void f2fs_set_inode_inline_flag(struct f2fs_inode *raw_inode)
+{
+   raw_inode-i_reserved |= F2FS_INODE_INLINE_DATA;
+}
+
+int f2fs_inline_data_attempt(struct inode *inode)
+{
+   return is_inode_dyn_flag_set(F2FS_I(inode), F2FS_INLINE_DATA_ATTEMPT);
+}
+
+int f2fs_has_inline_data(struct inode *inode)
+{
+   return is_inode_dyn_flag_set(F2FS_I(inode), F2FS_INLINE_DATA_FL);
+}
+
+static int f2fs_read_inline_data(struct inode *inode, struct page *page)
+{
+   void *src_addr, *dst_addr;
+   loff_t size = i_size_read(inode);
+   struct page *ipage = get_node_page(F2FS_SB(inode-i_sb), inode-i_ino);
+
+   if (IS_ERR(ipage))
+   return PTR_ERR(ipage);
+
+   src_addr = page_address(ipage);
+   dst_addr = page_address(page);
+
+   memcpy(dst_addr, src_addr + INLINE_DATA_OFFSET, size);
+   zero_user_segment(page, INLINE_DATA_OFFSET + size, PAGE_CACHE_SIZE);
+   SetPageUptodate(page);
+
+   f2fs_put_page(ipage, 1);
+
+   return 0;
+}
+
+int f2fs_read_inline_data_page(struct inode *inode, struct page *page)
+{
+   int ret = 0;
+
+   if (!page-index) {
+   ret = f2fs_read_inline_data(inode, page);
+   } else if (!PageUptodate(page)) {
+   zero_user_segment(page, 0, PAGE_CACHE_SIZE);
+   SetPageUptodate(page);
+   }
+
+   unlock_page(page);
+
+   return ret;
+}
+
+int f2fs_convert_inline_data(struct page *p,
+struct inode *inode, unsigned flags)
+{
+   int err;
+   int ilock;
+   loff_t size;
+   struct page *page, *ipage;
+   void *src_addr, *dst_addr;
+   struct f2fs_sb_info *sbi = F2FS_SB(inode-i_sb);
+
+   if (!p-index)
+   page = p;
+   else
+   page = grab_cache_page_write_begin(inode-i_mapping, 0, flags);
+
+   if (IS_ERR(page))
+   return PTR_ERR(page);
+
+   ipage = get_node_page(sbi, inode-i_ino);
+   if (IS_ERR(ipage)) {
+   f2fs_put_page(page, 1);
+   return PTR_ERR(ipage);
+   }
+
+   src_addr = page_address(ipage);
+   dst_addr = page_address(page);
+
+   size = i_size_read(inode);
+   memcpy(dst_addr, src_addr + INLINE_DATA_OFFSET, size);
+   zero_user_segment(ipage, INLINE_DATA_OFFSET,
+ INLINE_DATA_OFFSET + MAX_INLINE_DATA);
+   clear_inode_dyn_flag(F2FS_I(inode), F2FS_INLINE_DATA_FL);
+   set_page_dirty(ipage);
+   f2fs_put_page(ipage, 1);
+
+   if (!p-index) {
+   SetPageUptodate(page);
+   } else {
+   ilock = mutex_lock_op(sbi);
+   err = f2fs_reserve_block(inode, 0);
+   if (err)
+   goto err;
+   mutex_unlock_op(sbi, ilock);
+
+   set_page_dirty(page);
+   f2fs_put_page(page, 1);
+   }
+
+   return 0;
+
+err:
+   mutex_unlock_op(sbi, ilock);
+   f2fs_put_page(page, 1);
+   return err;
+}
+
+int f2fs_write_inline_data(struct inode *inode,
+  struct page *page, unsigned size)
+{
+   void *src_addr, *dst_addr;
+   struct f2fs_sb_info *sbi = F2FS_SB(inode-i_sb);
+   struct page *ipage = get_node_page(sbi, inode-i_ino);
+
+   if (IS_ERR(ipage))
+   return PTR_ERR(ipage);
+
+   src_addr = page_address(page);
+   dst_addr = page_address(ipage);
+
+   memcpy(dst_addr + INLINE_DATA_OFFSET, src_addr, size);
+   clear_inode_dyn_flag(F2FS_I(inode), F2FS_INLINE_DATA_ATTEMPT);
+   if (!f2fs_has_inline_data(inode))
+   set_inode_dyn_flag(F2FS_I(inode), F2FS_INLINE_DATA_FL);
+   set_page_dirty(ipage);
+   f2fs_put_page(ipage, 1);
+
+   return 0;
+}
-- 
1.7.9.5


--
Get 100% visibility into Java/.NET code with 

[f2fs-dev] [RFC 1/5] f2fs: Add helper functions and flag to support inline data

2013-06-03 Thread Huajun Li
From: Haicheng Li haicheng...@linux.intel.com

Add a new flag i_dyn_flags to struct f2fs_inode_info to indicate whether
the inode has inline data, and sync the flag with raw inode while update
file.

Signed-off-by: Haicheng Li haicheng...@linux.intel.com
Signed-off-by: Huajun Li huajun...@intel.com
---
 fs/f2fs/f2fs.h  |   70 +++
 fs/f2fs/inode.c |8 ++
 include/linux/f2fs_fs.h |5 
 3 files changed, 83 insertions(+)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 40b137a..9382f76 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -162,6 +162,7 @@ struct f2fs_inode_info {
umode_t i_acl_mode; /* keep file acl mode temporarily */
 
/* Use below internally in f2fs*/
+   unsigned long i_dyn_flags;  /* use to mark dynamic features */
unsigned long flags;/* use to pass per-file flags */
atomic_t dirty_dents;   /* # of dirty dentry pages */
f2fs_hash_t chash;  /* hash value of given file name */
@@ -170,6 +171,14 @@ struct f2fs_inode_info {
struct extent_info ext; /* in-memory extent cache entry */
 };
 
+/*
+ * Flags on f2fs_inode_info.i_dyn_flags
+ *
+ * These can change much more often than i_flags.
+ */
+#define F2FS_INLINE_DATA_FL   (0x0001) /* Data stored in inode block */
+#define F2FS_INLINE_DATA_ATTEMPT  (0x0002) /* Data stored in inode block */
+
 static inline void get_extent_info(struct extent_info *ext,
struct f2fs_extent i_ext)
 {
@@ -877,6 +886,21 @@ static inline void clear_inode_flag(struct f2fs_inode_info 
*fi, int flag)
clear_bit(flag, fi-flags);
 }
 
+static inline void set_inode_dyn_flag(struct f2fs_inode_info *fi, int flag)
+{
+   set_bit(flag, fi-i_dyn_flags);
+}
+
+static inline int is_inode_dyn_flag_set(struct f2fs_inode_info *fi, int flag)
+{
+   return test_bit(flag, fi-i_dyn_flags);
+}
+
+static inline void clear_inode_dyn_flag(struct f2fs_inode_info *fi, int flag)
+{
+   clear_bit(flag, fi-i_dyn_flags);
+}
+
 static inline void set_acl_inode(struct f2fs_inode_info *fi, umode_t mode)
 {
fi-i_acl_mode = mode;
@@ -1042,6 +1066,7 @@ void destroy_checkpoint_caches(void);
  * data.c
  */
 int reserve_new_block(struct dnode_of_data *);
+int f2fs_reserve_block(struct inode *, pgoff_t);
 void update_extent_cache(block_t, struct dnode_of_data *);
 struct page *find_data_page(struct inode *, pgoff_t, bool);
 struct page *get_lock_data_page(struct inode *, pgoff_t);
@@ -1144,6 +1169,51 @@ static inline void __init f2fs_create_root_stats(void) { 
}
 static inline void f2fs_destroy_root_stats(void) { }
 #endif
 
+/*
+ * inline.c
+ */
+#ifdef CONFIG_F2FS_INLINE_DATA
+#define MAX_INLINE_DATA(sizeof(__le32) * (ADDRS_PER_INODE + 5))
+#define INLINE_DATA_OFFSET (PAGE_CACHE_SIZE - sizeof(struct node_footer)\
+   - MAX_INLINE_DATA)
+
+void f2fs_clear_inode_inline_flag(struct f2fs_inode *);
+void f2fs_set_inode_inline_flag(struct f2fs_inode *);
+int f2fs_inline_data_attempt(struct inode *);
+int f2fs_has_inline_data(struct inode *);
+int f2fs_read_inline_data_page(struct inode *, struct page *);
+int f2fs_convert_inline_data(struct page *, struct inode *, unsigned);
+int f2fs_write_inline_data(struct inode *, struct page *, unsigned int);
+#else
+static inline void
+f2fs_clear_inode_inline_flag(struct f2fs_inode *raw_inode) { }
+static inline void
+f2fs_set_inode_inline_flag(struct f2fs_inode *raw_inode) { }
+int f2fs_inline_data_attempt(struct inode *inode)
+{
+   return 0;
+}
+static inline int f2fs_has_inline_data(struct inode *inode)
+{
+   return 0;
+}
+static inline int f2fs_read_inline_data_page(struct inode *inode,
+   struct page *page)
+{
+   return 0;
+}
+static inline int f2fs_convert_inline_data(struct page *page,
+  struct inode *inode, unsigned flags)
+{
+   return 0;
+}
+static inline int f2fs_write_inline_data(struct inode *inode,
+struct page *page, unsigned size)
+{
+   return 0;
+}
+#endif
+
 extern const struct file_operations f2fs_dir_operations;
 extern const struct file_operations f2fs_file_operations;
 extern const struct inode_operations f2fs_file_inode_operations;
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index b44a4c1..1d7b0b5 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -84,6 +84,9 @@ static int do_read_inode(struct inode *inode)
fi-flags = 0;
fi-i_advise = ri-i_advise;
fi-i_pino = le32_to_cpu(ri-i_pino);
+   if (ri-i_reserved  F2FS_INODE_INLINE_DATA)
+   set_inode_dyn_flag(fi, F2FS_INLINE_DATA_FL);
+
get_extent_info(fi-ext, ri-i_ext);
f2fs_put_page(node_page, 1);
return 0;
@@ -177,6 +180,11 @@ void update_inode(struct inode *inode, struct 

Re: [f2fs-dev] [RFC 5/5] f2fs: add tracepoints to debug inline data operations

2013-06-03 Thread Steven Rostedt
On Mon, 2013-06-03 at 18:04 +0800, Huajun Li wrote:
 From: Haicheng Li haicheng...@linux.intel.com
 
 Add tracepoints for: f2fs_read_inline_data(), f2fs_convert_inline_data(),
 f2fs_write_inline_data().
 
 Cc: Steven Rostedt rost...@goodmis.org
 Signed-off-by: Haicheng Li haicheng...@linux.intel.com
 Signed-off-by: Huajun Li huajun...@intel.com
 ---
  fs/f2fs/inline.c|4 +++
  include/trace/events/f2fs.h |   69 
 +++
  2 files changed, 73 insertions(+)
 
 diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
 index a2aa056..9ec66e5 100644
 --- a/fs/f2fs/inline.c
 +++ b/fs/f2fs/inline.c
 @@ -14,6 +14,7 @@
  #include linux/f2fs_fs.h
  
  #include f2fs.h
 +#include trace/events/f2fs.h
  
  void f2fs_clear_inode_inline_flag(struct f2fs_inode *raw_inode)
  {
 @@ -44,6 +45,7 @@ static int f2fs_read_inline_data(struct inode *inode, 
 struct page *page)
   if (IS_ERR(ipage))
   return PTR_ERR(ipage);
  
 + trace_f2fs_read_inline_data(inode, page);
   src_addr = page_address(ipage);
   dst_addr = page_address(page);
  
 @@ -107,6 +109,7 @@ int f2fs_convert_inline_data(struct page *p,
   set_page_dirty(ipage);
   f2fs_put_page(ipage, 1);
  
 + trace_f2fs_convert_inline_data(inode, page);
   if (!p-index) {
   SetPageUptodate(page);
   } else {
 @@ -138,6 +141,7 @@ int f2fs_write_inline_data(struct inode *inode,
   if (IS_ERR(ipage))
   return PTR_ERR(ipage);
  
 + trace_f2fs_write_inline_data(inode, page);
   src_addr = page_address(page);
   dst_addr = page_address(ipage);
  
 diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
 index 52ae548..bc7a84e 100644
 --- a/include/trace/events/f2fs.h
 +++ b/include/trace/events/f2fs.h
 @@ -676,6 +676,75 @@ TRACE_EVENT(f2fs_write_checkpoint,
   __entry-msg)
  );
  
 +TRACE_EVENT(f2fs_read_inline_data,
 +
 + TP_PROTO(struct inode *inode, struct page *page),
 +
 + TP_ARGS(inode, page),
 +
 + TP_STRUCT__entry(
 + __field(dev_t,  dev)
 + __field(ino_t,  ino)
 + __field(pgoff_t, index)
 + ),
 +
 + TP_fast_assign(
 + __entry-dev= inode-i_sb-s_dev;
 + __entry-ino= inode-i_ino;
 + __entry-index  = page-index;
 + ),
 +
 + TP_printk(dev = (%d,%d), ino = %lu, index = %lu,
 + show_dev_ino(__entry),
 + (unsigned long)__entry-index)
 +);
 +
 +TRACE_EVENT(f2fs_convert_inline_data,
 +
 + TP_PROTO(struct inode *inode, struct page *page),
 +
 + TP_ARGS(inode, page),
 +
 + TP_STRUCT__entry(
 + __field(dev_t,  dev)
 + __field(ino_t,  ino)
 + __field(pgoff_t, index)
 + ),
 +
 + TP_fast_assign(
 + __entry-dev= inode-i_sb-s_dev;
 + __entry-ino= inode-i_ino;
 + __entry-index  = page-index;
 + ),
 +
 + TP_printk(dev = (%d,%d), ino = %lu, index = %lu,
 + show_dev_ino(__entry),
 + (unsigned long)__entry-index)
 +);
 +
 +TRACE_EVENT(f2fs_write_inline_data,
 +
 + TP_PROTO(struct inode *inode, struct page *page),
 +
 + TP_ARGS(inode, page),
 +
 + TP_STRUCT__entry(
 + __field(dev_t,  dev)
 + __field(ino_t,  ino)
 + __field(pgoff_t, index)
 + ),
 +
 + TP_fast_assign(
 + __entry-dev= inode-i_sb-s_dev;
 + __entry-ino= inode-i_ino;
 + __entry-index  = page-index;
 + ),
 +
 + TP_printk(dev = (%d,%d), ino = %lu, index = %lu,
 + show_dev_ino(__entry),
 + (unsigned long)__entry-index)
 +);

Can you convert the above to use DECLARE_EVENT_CLASS() and
DEFINE_EVENT(), as the above three are basically the same. You'll save a
few K in text by doing so.

Thanks,

-- Steve



 +
  #endif /* _TRACE_F2FS_H */
  
   /* This part must be outside protection */



--
Get 100% visibility into Java/.NET code with AppDynamics Lite
It's a free troubleshooting tool designed for production
Get down to code-level detail for bottlenecks, with 2% overhead.
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap2
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [RFC 0/5] Enable f2fs support inline data

2013-06-03 Thread Jaegeuk Kim
Hi,

This feature is one of my todo items. ;)
Thank you for the contribution.

Before reviewing the below code intensively, we need to check the
following issues.

- deadlock conditions
- FS consistency
- recovery routine

Could you check one more time?
Thanks again,

2013-06-03 (월), 18:04 +0800, Huajun Li:
 f2fs inode is so large, small files can be stored directly in the inode,
 rather than just storing a single block address and storing the data 
 elsewhere.
 
 This RFC patch set is just to enable f2fs support inline data: files less than
 about 3.6K can be stored directly in inode block.
 
 TODO: make small dirs inline too.
 
 
 Haicheng Li (3):
   f2fs: Add helper functions and flag to support inline data
   f2fs: Add interface for inline data support
   f2fs: add tracepoints to debug inline data operations
 
 Huajun Li (2):
   f2fs: Handle inline data read and write
   f2fs: Key functions to handle inline data
 
  fs/f2fs/Kconfig |   10 +++
  fs/f2fs/Makefile|1 +
  fs/f2fs/data.c  |   78 +-
  fs/f2fs/f2fs.h  |   70 +++
  fs/f2fs/file.c  |9 ++-
  fs/f2fs/inline.c|  156 
 +++
  fs/f2fs/inode.c |8 +++
  include/linux/f2fs_fs.h |5 ++
  include/trace/events/f2fs.h |   69 +++
  9 files changed, 402 insertions(+), 4 deletions(-)
  create mode 100644 fs/f2fs/inline.c
 

-- 
Jaegeuk Kim
Samsung


signature.asc
Description: This is a digitally signed message part
--
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j___
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/2] f2fs: add remount_fs callback support

2013-06-03 Thread Gu Zheng
On 06/01/2013 03:20 PM, Namjae Jeon wrote:

 From: Namjae Jeon namjae.j...@samsung.com
 
 Add the f2fs_remount function call which will be used
 during the filesystem remounting. This function
 will help us to change the mount options specific to
 f2fs.
 
 Also modify the f2fs background_gc mount option, which
 will allow the user to dynamically trun on/off the
 garbage collection in f2fs based on the background_gc
 value. If background_gc=0, Garbage collection will
 be turned off  if background_gc=1, Garbage collection
 will be truned on.


Hi Namjae,
  I think splitting these two changes into single ones seems better.
Refer to the inline comments.

Thanks,
Gu

 
 By default the garbage collection is on in f2fs.
 
 Signed-off-by: Namjae Jeon namjae.j...@samsung.com
 Signed-off-by: Pankaj Kumar pankaj...@samsung.com

 ---
  Documentation/filesystems/f2fs.txt |8 +-
  fs/f2fs/super.c|  223 
 +++-
  2 files changed, 148 insertions(+), 83 deletions(-)
 
 diff --git a/Documentation/filesystems/f2fs.txt 
 b/Documentation/filesystems/f2fs.txt
 index bd3c56c..6a036ce 100644
 --- a/Documentation/filesystems/f2fs.txt
 +++ b/Documentation/filesystems/f2fs.txt
 @@ -98,8 +98,12 @@ Cleaning Overhead
  MOUNT OPTIONS
  
 
  
 -background_gc_off  Turn off cleaning operations, namely garbage 
 collection,
 -triggered in background when I/O subsystem is idle.
 +background_gc=%u   Turn on/off cleaning operations, namely garbage 
 collection,
 +   triggered in background when I/O subsystem is idle. If
 +   background_gc=1, it will turn on the garbage 
 collection 
 +   if background_gc=0, garbage collection will be truned 
 off.
 +   Default value for this option is 1. So garbage 
 collection
 +   is on by default.
  disable_roll_forward   Disable the roll-forward recovery routine
  discardIssue discard/TRIM commands when a segment is cleaned.
  no_heapDisable heap-style segment allocation which finds free
 diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
 index 3ac305d..bcd68aa 100644
 --- a/fs/f2fs/super.c
 +++ b/fs/f2fs/super.c
 @@ -34,7 +34,7 @@
  static struct kmem_cache *f2fs_inode_cachep;
  
  enum {
 - Opt_gc_background_off,
 + Opt_gc_background,
   Opt_disable_roll_forward,
   Opt_discard,
   Opt_noheap,
 @@ -46,7 +46,7 @@ enum {
  };
  
  static match_table_t f2fs_tokens = {
 - {Opt_gc_background_off, background_gc_off},
 + {Opt_gc_background, background_gc=%u},
   {Opt_disable_roll_forward, disable_roll_forward},
   {Opt_discard, discard},
   {Opt_noheap, no_heap},
 @@ -76,6 +76,86 @@ static void init_once(void *foo)
   inode_init_once(fi-vfs_inode);
  }
  
 +static int parse_options(struct super_block *sb, struct f2fs_sb_info *sbi,
 + char *options)
 +{
 + substring_t args[MAX_OPT_ARGS];
 + char *p;
 + int arg = 0;
 +
 + if (!options)
 + return 0;
 +
 + while ((p = strsep(options, ,)) != NULL) {
 + int token;
 + if (!*p)
 + continue;
 + /*
 +  * Initialize args struct so we know whether arg was
 +  * found; some options take optional arguments.
 +  */
 + args[0].to = args[0].from = NULL;
 + token = match_token(p, f2fs_tokens, args);
 +
 + switch (token) {
 + case Opt_gc_background:
 + if (args-from  match_int(args, arg))
 + return -EINVAL;
 + if (arg != 0  arg != 1)
 + return -EINVAL;
 + if (arg == 0)
 + clear_opt(sbi, BG_GC);
 + else
 + set_opt(sbi, BG_GC);
 + break;
 + case Opt_disable_roll_forward:
 + set_opt(sbi, DISABLE_ROLL_FORWARD);
 + break;
 + case Opt_discard:
 + set_opt(sbi, DISCARD);
 + break;
 + case Opt_noheap:
 + set_opt(sbi, NOHEAP);
 + break;
 +#ifdef CONFIG_F2FS_FS_XATTR
 + case Opt_nouser_xattr:
 + clear_opt(sbi, XATTR_USER);
 + break;
 +#else
 + case Opt_nouser_xattr:
 + f2fs_msg(sb, KERN_INFO,
 + nouser_xattr options not supported);
 + break;
 +#endif
 +#ifdef CONFIG_F2FS_FS_POSIX_ACL
 + case Opt_noacl:
 + clear_opt(sbi, POSIX_ACL);
 + break;
 +#else
 + case Opt_noacl:
 + f2fs_msg(sb, 

Re: [f2fs-dev] [RFC 0/5] Enable f2fs support inline data

2013-06-03 Thread Namjae Jeon
Hi. Huajun.

I agree jaegeuk's opinion.
Additionally, It is better that you describe the effect in change-log
when this feature is added to f2fs.
e.g.
1. how much space is saved when storing kernel-tree(small files) ?
2. small files creation performance test.
3. file look-up performance test.
4. other performance tools 's result.

Thanks.

2013/6/4 Jaegeuk Kim jaegeuk@samsung.com:
 Hi,

 This feature is one of my todo items. ;)
 Thank you for the contribution.

 Before reviewing the below code intensively, we need to check the
 following issues.

 - deadlock conditions
 - FS consistency
 - recovery routine

 Could you check one more time?
 Thanks again,

 2013-06-03 (월), 18:04 +0800, Huajun Li:
 f2fs inode is so large, small files can be stored directly in the inode,
 rather than just storing a single block address and storing the data 
 elsewhere.

 This RFC patch set is just to enable f2fs support inline data: files less 
 than
 about 3.6K can be stored directly in inode block.

 TODO: make small dirs inline too.


 Haicheng Li (3):
   f2fs: Add helper functions and flag to support inline data
   f2fs: Add interface for inline data support
   f2fs: add tracepoints to debug inline data operations

 Huajun Li (2):
   f2fs: Handle inline data read and write
   f2fs: Key functions to handle inline data

  fs/f2fs/Kconfig |   10 +++
  fs/f2fs/Makefile|1 +
  fs/f2fs/data.c  |   78 +-
  fs/f2fs/f2fs.h  |   70 +++
  fs/f2fs/file.c  |9 ++-
  fs/f2fs/inline.c|  156 
 +++
  fs/f2fs/inode.c |8 +++
  include/linux/f2fs_fs.h |5 ++
  include/trace/events/f2fs.h |   69 +++
  9 files changed, 402 insertions(+), 4 deletions(-)
  create mode 100644 fs/f2fs/inline.c


 --
 Jaegeuk Kim
 Samsung

--
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel