Merge branch 'f2fs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs into dev
authorJaegeuk Kim <jaegeuk.kim@samsung.com>
Mon, 11 Feb 2013 22:17:20 +0000 (07:17 +0900)
committerJaegeuk Kim <jaegeuk.kim@samsung.com>
Mon, 11 Feb 2013 22:17:20 +0000 (07:17 +0900)
Pull f2fs cleanup patches from Al Viro:

f2fs: get rid of fake on-stack dentries
f2fs: switch init_inode_metadata() to passing parent and name separately
f2fs: switch new_inode_page() from dentry to qstr
f2fs: init_dent_inode() should take qstr

Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Conflicts:
fs/f2fs/recovery.c

1  2 
fs/f2fs/dir.c
fs/f2fs/f2fs.h
fs/f2fs/node.c
fs/f2fs/recovery.c

diff --combined fs/f2fs/dir.c
@@@ -265,7 -265,7 +265,7 @@@ void f2fs_set_link(struct inode *dir, s
        mutex_unlock_op(sbi, DENTRY_OPS);
  }
  
- void init_dent_inode(struct dentry *dentry, struct page *ipage)
+ void init_dent_inode(const struct qstr *name, struct page *ipage)
  {
        struct f2fs_node *rn;
  
  
        wait_on_page_writeback(ipage);
  
-       /* copy dentry info. to this inode page */
+       /* copy name info. to this inode page */
        rn = (struct f2fs_node *)page_address(ipage);
-       rn->i.i_namelen = cpu_to_le32(dentry->d_name.len);
-       memcpy(rn->i.i_name, dentry->d_name.name, dentry->d_name.len);
+       rn->i.i_namelen = cpu_to_le32(name->len);
+       memcpy(rn->i.i_name, name->name, name->len);
        set_page_dirty(ipage);
  }
  
- static int init_inode_metadata(struct inode *inode, struct dentry *dentry)
+ static int init_inode_metadata(struct inode *inode,
+               struct inode *dir, const struct qstr *name)
  {
-       struct inode *dir = dentry->d_parent->d_inode;
        if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) {
                int err;
-               err = new_inode_page(inode, dentry);
+               err = new_inode_page(inode, name);
                if (err)
                        return err;
  
                if (IS_ERR(ipage))
                        return PTR_ERR(ipage);
                set_cold_node(inode, ipage);
-               init_dent_inode(dentry, ipage);
+               init_dent_inode(name, ipage);
                f2fs_put_page(ipage, 1);
        }
        if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) {
@@@ -371,7 -370,7 +370,7 @@@ next
        goto next;
  }
  
- int f2fs_add_link(struct dentry *dentry, struct inode *inode)
+ int __f2fs_add_link(struct inode *dir, const struct qstr *name, struct inode *inode)
  {
        unsigned int bit_pos;
        unsigned int level;
        f2fs_hash_t dentry_hash;
        struct f2fs_dir_entry *de;
        unsigned int nbucket, nblock;
-       struct inode *dir = dentry->d_parent->d_inode;
        struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
-       const char *name = dentry->d_name.name;
-       size_t namelen = dentry->d_name.len;
+       size_t namelen = name->len;
        struct page *dentry_page = NULL;
        struct f2fs_dentry_block *dentry_blk = NULL;
        int slots = GET_DENTRY_SLOTS(namelen);
        int err = 0;
        int i;
  
-       dentry_hash = f2fs_dentry_hash(name, dentry->d_name.len);
+       dentry_hash = f2fs_dentry_hash(name->name, name->len);
        level = 0;
        current_depth = F2FS_I(dir)->i_current_depth;
        if (F2FS_I(dir)->chash == dentry_hash) {
@@@ -433,7 -430,7 +430,7 @@@ start
        ++level;
        goto start;
  add_dentry:
-       err = init_inode_metadata(inode, dentry);
+       err = init_inode_metadata(inode, dir, name);
        if (err)
                goto fail;
  
        de = &dentry_blk->dentry[bit_pos];
        de->hash_code = dentry_hash;
        de->name_len = cpu_to_le16(namelen);
-       memcpy(dentry_blk->filename[bit_pos], name, namelen);
+       memcpy(dentry_blk->filename[bit_pos], name->name, name->len);
        de->ino = cpu_to_le32(inode->i_ino);
        set_de_type(de, inode);
        for (i = 0; i < slots; i++)
@@@ -503,7 -500,7 +500,7 @@@ void f2fs_delete_entry(struct f2fs_dir_
        }
  
        if (inode) {
 -              inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 +              inode->i_ctime = CURRENT_TIME;
                drop_nlink(inode);
                if (S_ISDIR(inode->i_mode)) {
                        drop_nlink(inode);
diff --combined fs/f2fs/f2fs.h
@@@ -104,20 -104,6 +104,20 @@@ static inline int update_sits_in_cursum
  }
  
  /*
 + * ioctl commands
 + */
 +#define F2FS_IOC_GETFLAGS               FS_IOC_GETFLAGS
 +#define F2FS_IOC_SETFLAGS               FS_IOC_SETFLAGS
 +
 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
 +/*
 + * ioctl commands in 32 bit emulation
 + */
 +#define F2FS_IOC32_GETFLAGS             FS_IOC32_GETFLAGS
 +#define F2FS_IOC32_SETFLAGS             FS_IOC32_SETFLAGS
 +#endif
 +
 +/*
   * For INODE and NODE manager
   */
  #define XATTR_NODE_OFFSET     (-1)    /*
@@@ -155,7 -141,7 +155,7 @@@ struct f2fs_inode_info 
  
        /* Use below internally in f2fs*/
        unsigned long flags;            /* use to pass per-file flags */
 -      unsigned long long data_version;/* lastes version of data for fsync */
 +      unsigned long long data_version;/* latest version of data for fsync */
        atomic_t dirty_dents;           /* # of dirty dentry pages */
        f2fs_hash_t chash;              /* hash value of given file name */
        unsigned int clevel;            /* maximum level of given file name */
@@@ -225,11 -211,11 +225,11 @@@ struct dnode_of_data 
  static inline void set_new_dnode(struct dnode_of_data *dn, struct inode *inode,
                struct page *ipage, struct page *npage, nid_t nid)
  {
 +      memset(dn, 0, sizeof(*dn));
        dn->inode = inode;
        dn->inode_page = ipage;
        dn->node_page = npage;
        dn->nid = nid;
 -      dn->inode_page_locked = 0;
  }
  
  /*
@@@ -587,14 -573,6 +587,14 @@@ static inline int get_pages(struct f2fs
        return atomic_read(&sbi->nr_pages[count_type]);
  }
  
 +static inline int get_blocktype_secs(struct f2fs_sb_info *sbi, int block_type)
 +{
 +      unsigned int pages_per_sec = sbi->segs_per_sec *
 +                                      (1 << sbi->log_blocks_per_seg);
 +      return ((get_pages(sbi, block_type) + pages_per_sec - 1)
 +                      >> sbi->log_blocks_per_seg) / sbi->segs_per_sec;
 +}
 +
  static inline block_t valid_user_blocks(struct f2fs_sb_info *sbi)
  {
        block_t ret;
@@@ -864,12 -842,12 +864,12 @@@ void f2fs_truncate(struct inode *)
  int f2fs_setattr(struct dentry *, struct iattr *);
  int truncate_hole(struct inode *, pgoff_t, pgoff_t);
  long f2fs_ioctl(struct file *, unsigned int, unsigned long);
 +long f2fs_compat_ioctl(struct file *, unsigned int, unsigned long);
  
  /*
   * inode.c
   */
  void f2fs_set_inode_flags(struct inode *);
 -struct inode *f2fs_iget_nowait(struct super_block *, unsigned long);
  struct inode *f2fs_iget(struct super_block *, unsigned long);
  void update_inode(struct inode *, struct page *);
  int f2fs_write_inode(struct inode *, struct writeback_control *);
@@@ -889,18 -867,22 +889,24 @@@ struct f2fs_dir_entry *f2fs_parent_dir(
  ino_t f2fs_inode_by_name(struct inode *, struct qstr *);
  void f2fs_set_link(struct inode *, struct f2fs_dir_entry *,
                                struct page *, struct inode *);
- void init_dent_inode(struct dentry *, struct page *);
- int f2fs_add_link(struct dentry *, struct inode *);
+ void init_dent_inode(const struct qstr *, struct page *);
+ int __f2fs_add_link(struct inode *, const struct qstr *, struct inode *);
  void f2fs_delete_entry(struct f2fs_dir_entry *, struct page *, struct inode *);
  int f2fs_make_empty(struct inode *, struct inode *);
  bool f2fs_empty_dir(struct inode *);
  
+ static inline int f2fs_add_link(struct dentry *dentry, struct inode *inode)
+ {
+       return __f2fs_add_link(dentry->d_parent->d_inode, &dentry->d_name,
+                               inode);
+ }
  /*
   * super.c
   */
  int f2fs_sync_fs(struct super_block *, int);
 +extern __printf(3, 4)
 +void f2fs_msg(struct super_block *, const char *, const char *, ...);
  
  /*
   * hash.c
@@@ -918,7 -900,7 +924,7 @@@ void get_node_info(struct f2fs_sb_info 
  int get_dnode_of_data(struct dnode_of_data *, pgoff_t, int);
  int truncate_inode_blocks(struct inode *, pgoff_t);
  int remove_inode_page(struct inode *);
- int new_inode_page(struct inode *, struct dentry *);
+ int new_inode_page(struct inode *, const struct qstr *);
  struct page *new_node_page(struct dnode_of_data *, unsigned int);
  void ra_node_page(struct f2fs_sb_info *, nid_t);
  struct page *get_node_page(struct f2fs_sb_info *, pgoff_t);
@@@ -936,7 -918,7 +942,7 @@@ int restore_node_summary(struct f2fs_sb
  void flush_nat_entries(struct f2fs_sb_info *);
  int build_node_manager(struct f2fs_sb_info *);
  void destroy_node_manager(struct f2fs_sb_info *);
 -int create_node_manager_caches(void);
 +int __init create_node_manager_caches(void);
  void destroy_node_manager_caches(void);
  
  /*
@@@ -951,7 -933,8 +957,7 @@@ void allocate_new_segments(struct f2fs_
  struct page *get_sum_page(struct f2fs_sb_info *, unsigned int);
  struct bio *f2fs_bio_alloc(struct block_device *, int);
  void f2fs_submit_bio(struct f2fs_sb_info *, enum page_type, bool sync);
 -int write_meta_page(struct f2fs_sb_info *, struct page *,
 -                                      struct writeback_control *);
 +void write_meta_page(struct f2fs_sb_info *, struct page *);
  void write_node_page(struct f2fs_sb_info *, struct page *, unsigned int,
                                        block_t, block_t *);
  void write_data_page(struct inode *, struct page *, struct dnode_of_data*,
@@@ -984,9 -967,10 +990,9 @@@ int get_valid_checkpoint(struct f2fs_sb
  void set_dirty_dir_page(struct inode *, struct page *);
  void remove_dirty_dir_inode(struct inode *);
  void sync_dirty_dir_inodes(struct f2fs_sb_info *);
 -void block_operations(struct f2fs_sb_info *);
 -void write_checkpoint(struct f2fs_sb_info *, bool, bool);
 +void write_checkpoint(struct f2fs_sb_info *, bool);
  void init_orphan_info(struct f2fs_sb_info *);
 -int create_checkpoint_caches(void);
 +int __init create_checkpoint_caches(void);
  void destroy_checkpoint_caches(void);
  
  /*
@@@ -1006,9 -990,9 +1012,9 @@@ int do_write_data_page(struct page *)
  int start_gc_thread(struct f2fs_sb_info *);
  void stop_gc_thread(struct f2fs_sb_info *);
  block_t start_bidx_of_node(unsigned int);
 -int f2fs_gc(struct f2fs_sb_info *, int);
 +int f2fs_gc(struct f2fs_sb_info *);
  void build_gc_manager(struct f2fs_sb_info *);
 -int create_gc_caches(void);
 +int __init create_gc_caches(void);
  void destroy_gc_caches(void);
  
  /*
@@@ -1080,8 -1064,7 +1086,8 @@@ struct f2fs_stat_info 
  
  int f2fs_build_stats(struct f2fs_sb_info *);
  void f2fs_destroy_stats(struct f2fs_sb_info *);
 -void destroy_root_stats(void);
 +void __init f2fs_create_root_stats(void);
 +void f2fs_destroy_root_stats(void);
  #else
  #define stat_inc_call_count(si)
  #define stat_inc_seg_count(si, type)
  
  static inline int f2fs_build_stats(struct f2fs_sb_info *sbi) { return 0; }
  static inline void f2fs_destroy_stats(struct f2fs_sb_info *sbi) { }
 -static inline void destroy_root_stats(void) { }
 +static inline void __init f2fs_create_root_stats(void) { }
 +static inline void f2fs_destroy_root_stats(void) { }
  #endif
  
  extern const struct file_operations f2fs_dir_operations;
diff --combined fs/f2fs/node.c
@@@ -104,7 -104,7 +104,7 @@@ static void ra_nat_pages(struct f2fs_sb
                        f2fs_put_page(page, 1);
                        continue;
                }
 -              page_cache_release(page);
 +              f2fs_put_page(page, 0);
        }
  }
  
@@@ -780,7 -780,7 +780,7 @@@ int remove_inode_page(struct inode *ino
        return 0;
  }
  
- int new_inode_page(struct inode *inode, struct dentry *dentry)
+ int new_inode_page(struct inode *inode, const struct qstr *name)
  {
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
        struct page *page;
        set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino);
        mutex_lock_op(sbi, NODE_NEW);
        page = new_node_page(&dn, 0);
-       init_dent_inode(dentry, page);
+       init_dent_inode(name, page);
        mutex_unlock_op(sbi, NODE_NEW);
        if (IS_ERR(page))
                return PTR_ERR(page);
@@@ -874,11 -874,15 +874,11 @@@ void ra_node_page(struct f2fs_sb_info *
                return;
  
        if (read_node_page(apage, READA))
 -              goto unlock_out;
 +              unlock_page(apage);
  
 -      page_cache_release(apage);
 -      return;
 -
 -unlock_out:
 -      unlock_page(apage);
  release_out:
 -      page_cache_release(apage);
 +      f2fs_put_page(apage, 0);
 +      return;
  }
  
  struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid)
@@@ -1120,12 -1124,6 +1120,12 @@@ static int f2fs_write_node_page(struct 
        return 0;
  }
  
 +/*
 + * It is very important to gather dirty pages and write at once, so that we can
 + * submit a big bio without interfering other data writes.
 + * Be default, 512 pages (2MB), a segment size, is quite reasonable.
 + */
 +#define COLLECT_DIRTY_NODES   512
  static int f2fs_write_node_pages(struct address_space *mapping,
                            struct writeback_control *wbc)
  {
        struct block_device *bdev = sbi->sb->s_bdev;
        long nr_to_write = wbc->nr_to_write;
  
 -      if (wbc->for_kupdate)
 -              return 0;
 -
 -      if (get_pages(sbi, F2FS_DIRTY_NODES) == 0)
 -              return 0;
 -
 +      /* First check balancing cached NAT entries */
        if (try_to_free_nats(sbi, NAT_ENTRY_PER_BLOCK)) {
 -              write_checkpoint(sbi, false, false);
 +              write_checkpoint(sbi, false);
                return 0;
        }
  
 +      /* collect a number of dirty node pages and write together */
 +      if (get_pages(sbi, F2FS_DIRTY_NODES) < COLLECT_DIRTY_NODES)
 +              return 0;
 +
        /* if mounting is failed, skip writing node pages */
        wbc->nr_to_write = bio_get_nr_vecs(bdev);
        sync_node_pages(sbi, 0, wbc);
@@@ -1733,7 -1732,7 +1733,7 @@@ void destroy_node_manager(struct f2fs_s
        kfree(nm_i);
  }
  
 -int create_node_manager_caches(void)
 +int __init create_node_manager_caches(void)
  {
        nat_entry_slab = f2fs_kmem_cache_create("nat_entry",
                        sizeof(struct nat_entry), NULL);
diff --combined fs/f2fs/recovery.c
@@@ -42,7 -42,7 +42,7 @@@ static int recover_dentry(struct page *
  {
        struct f2fs_node *raw_node = (struct f2fs_node *)kmap(ipage);
        struct f2fs_inode *raw_inode = &(raw_node->i);
-       struct dentry dent, parent;
+       struct qstr name;
        struct f2fs_dir_entry *de;
        struct page *page;
        struct inode *dir;
                goto out;
        }
  
-       parent.d_inode = dir;
-       dent.d_parent = &parent;
-       dent.d_name.len = le32_to_cpu(raw_inode->i_namelen);
-       dent.d_name.name = raw_inode->i_name;
+       name.len = le32_to_cpu(raw_inode->i_namelen);
+       name.name = raw_inode->i_name;
  
-       de = f2fs_find_entry(dir, &dent.d_name, &page);
+       de = f2fs_find_entry(dir, &name, &page);
        if (de) {
                kunmap(page);
                f2fs_put_page(page, 0);
        } else {
-               err = f2fs_add_link(&dent, inode);
 -              __f2fs_add_link(dir, &name, inode);
++              err = __f2fs_add_link(dir, &name, inode);
        }
        iput(dir);
  out:
@@@ -151,6 -149,7 +149,6 @@@ static int find_fsync_dnodes(struct f2f
                                goto out;
                        }
  
 -                      INIT_LIST_HEAD(&entry->list);
                        list_add_tail(&entry->list, head);
                        entry->blkaddr = blkaddr;
                }
@@@ -173,9 -172,10 +171,9 @@@ out
  static void destroy_fsync_dnodes(struct f2fs_sb_info *sbi,
                                        struct list_head *head)
  {
 -      struct list_head *this;
 -      struct fsync_inode_entry *entry;
 -      list_for_each(this, head) {
 -              entry = list_entry(this, struct fsync_inode_entry, list);
 +      struct fsync_inode_entry *entry, *tmp;
 +
 +      list_for_each_entry_safe(entry, tmp, head, list) {
                iput(entry->inode);
                list_del(&entry->list);
                kmem_cache_free(fsync_entry_slab, entry);
@@@ -226,7 -226,7 +224,7 @@@ static void check_index_in_prev_nodes(s
        f2fs_put_page(node_page, 1);
  
        /* Deallocate previous index in the node page */
 -      inode = f2fs_iget_nowait(sbi->sb, ino);
 +      inode = f2fs_iget(sbi->sb, ino);
        if (IS_ERR(inode))
                return;
  
@@@ -373,5 -373,5 +371,5 @@@ void recover_fsync_data(struct f2fs_sb_
  out:
        destroy_fsync_dnodes(sbi, &inode_list);
        kmem_cache_destroy(fsync_entry_slab);
 -      write_checkpoint(sbi, false, false);
 +      write_checkpoint(sbi, false);
  }