fs: Use dquot_load_quota_inode() from filesystems
[linux-2.6-microblaze.git] / fs / f2fs / super.c
index f43befd..91745d5 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/f2fs_fs.h>
 #include <linux/sysfs.h>
 #include <linux/quota.h>
+#include <linux/unicode.h>
 
 #include "f2fs.h"
 #include "node.h"
@@ -222,6 +223,36 @@ void f2fs_printk(struct f2fs_sb_info *sbi, const char *fmt, ...)
        va_end(args);
 }
 
+#ifdef CONFIG_UNICODE
+static const struct f2fs_sb_encodings {
+       __u16 magic;
+       char *name;
+       char *version;
+} f2fs_sb_encoding_map[] = {
+       {F2FS_ENC_UTF8_12_1, "utf8", "12.1.0"},
+};
+
+static int f2fs_sb_read_encoding(const struct f2fs_super_block *sb,
+                                const struct f2fs_sb_encodings **encoding,
+                                __u16 *flags)
+{
+       __u16 magic = le16_to_cpu(sb->s_encoding);
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(f2fs_sb_encoding_map); i++)
+               if (magic == f2fs_sb_encoding_map[i].magic)
+                       break;
+
+       if (i >= ARRAY_SIZE(f2fs_sb_encoding_map))
+               return -EINVAL;
+
+       *encoding = &f2fs_sb_encoding_map[i];
+       *flags = le16_to_cpu(sb->s_encoding_flags);
+
+       return 0;
+}
+#endif
+
 static inline void limit_reserve_root(struct f2fs_sb_info *sbi)
 {
        block_t limit = min((sbi->user_block_count << 1) / 1000,
@@ -798,6 +829,13 @@ static int parse_options(struct super_block *sb, char *options)
                return -EINVAL;
        }
 #endif
+#ifndef CONFIG_UNICODE
+       if (f2fs_sb_has_casefold(sbi)) {
+               f2fs_err(sbi,
+                       "Filesystem with casefold feature cannot be mounted without CONFIG_UNICODE");
+               return -EINVAL;
+       }
+#endif
 
        if (F2FS_IO_SIZE_BITS(sbi) && !test_opt(sbi, LFS)) {
                f2fs_err(sbi, "Should set mode=lfs with %uKB-sized IO",
@@ -873,7 +911,21 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
 
 static int f2fs_drop_inode(struct inode *inode)
 {
+       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        int ret;
+
+       /*
+        * during filesystem shutdown, if checkpoint is disabled,
+        * drop useless meta/node dirty pages.
+        */
+       if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
+               if (inode->i_ino == F2FS_NODE_INO(sbi) ||
+                       inode->i_ino == F2FS_META_INO(sbi)) {
+                       trace_f2fs_drop_inode(inode, 1);
+                       return 1;
+               }
+       }
+
        /*
         * This is to avoid a deadlock condition like below.
         * writeback_single_inode(inode)
@@ -1091,6 +1143,9 @@ static void f2fs_put_super(struct super_block *sb)
        destroy_percpu_info(sbi);
        for (i = 0; i < NR_PAGE_TYPE; i++)
                kvfree(sbi->write_io[i]);
+#ifdef CONFIG_UNICODE
+       utf8_unload(sbi->s_encoding);
+#endif
        kvfree(sbi);
 }
 
@@ -1216,8 +1271,7 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf)
        else
                buf->f_bavail = 0;
 
-       avail_node_count = sbi->total_node_count - sbi->nquota_files -
-                                               F2FS_RESERVED_NODE_NUM;
+       avail_node_count = sbi->total_node_count - F2FS_RESERVED_NODE_NUM;
 
        if (avail_node_count > user_block_count) {
                buf->f_files = user_block_count;
@@ -1524,6 +1578,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
        bool need_stop_gc = false;
        bool no_extent_cache = !test_opt(sbi, EXTENT_CACHE);
        bool disable_checkpoint = test_opt(sbi, DISABLE_CHECKPOINT);
+       bool no_io_align = !F2FS_IO_ALIGNED(sbi);
        bool checkpoint_changed;
 #ifdef CONFIG_QUOTA
        int i, j;
@@ -1603,6 +1658,12 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
                goto restore_opts;
        }
 
+       if (no_io_align == !!F2FS_IO_ALIGNED(sbi)) {
+               err = -EINVAL;
+               f2fs_warn(sbi, "switch io_bits option is not allowed");
+               goto restore_opts;
+       }
+
        if ((*flags & SB_RDONLY) && test_opt(sbi, DISABLE_CHECKPOINT)) {
                err = -EINVAL;
                f2fs_warn(sbi, "disabling checkpoint not compatible with read-only");
@@ -1871,7 +1932,7 @@ static int f2fs_quota_enable(struct super_block *sb, int type, int format_id,
 
        /* Don't account quota for quota files to avoid recursion */
        qf_inode->i_flags |= S_NOQUOTA;
-       err = dquot_enable(qf_inode, type, format_id, flags);
+       err = dquot_load_quota_inode(qf_inode, type, format_id, flags);
        iput(qf_inode);
        return err;
 }
@@ -1981,6 +2042,12 @@ static int f2fs_quota_on(struct super_block *sb, int type, int format_id,
        struct inode *inode;
        int err;
 
+       /* if quota sysfile exists, deny enabling quota with specific file */
+       if (f2fs_sb_has_quota_ino(F2FS_SB(sb))) {
+               f2fs_err(F2FS_SB(sb), "quota sysfile already exists");
+               return -EBUSY;
+       }
+
        err = f2fs_quota_sync(sb, type);
        if (err)
                return err;
@@ -2000,7 +2067,7 @@ static int f2fs_quota_on(struct super_block *sb, int type, int format_id,
        return 0;
 }
 
-static int f2fs_quota_off(struct super_block *sb, int type)
+static int __f2fs_quota_off(struct super_block *sb, int type)
 {
        struct inode *inode = sb_dqopt(sb)->files[type];
        int err;
@@ -2026,13 +2093,30 @@ out_put:
        return err;
 }
 
+static int f2fs_quota_off(struct super_block *sb, int type)
+{
+       struct f2fs_sb_info *sbi = F2FS_SB(sb);
+       int err;
+
+       err = __f2fs_quota_off(sb, type);
+
+       /*
+        * quotactl can shutdown journalled quota, result in inconsistence
+        * between quota record and fs data by following updates, tag the
+        * flag to let fsck be aware of it.
+        */
+       if (is_journalled_quota(sbi))
+               set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
+       return err;
+}
+
 void f2fs_quota_off_umount(struct super_block *sb)
 {
        int type;
        int err;
 
        for (type = 0; type < MAXQUOTAS; type++) {
-               err = f2fs_quota_off(sb, type);
+               err = __f2fs_quota_off(sb, type);
                if (err) {
                        int ret = dquot_quota_off(sb, type);
 
@@ -2617,8 +2701,7 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
        }
 
        valid_node_count = le32_to_cpu(ckpt->valid_node_count);
-       avail_node_count = sbi->total_node_count - sbi->nquota_files -
-                                               F2FS_RESERVED_NODE_NUM;
+       avail_node_count = sbi->total_node_count - F2FS_RESERVED_NODE_NUM;
        if (valid_node_count > avail_node_count) {
                f2fs_err(sbi, "Wrong valid_node_count: %u, avail_node_count: %u",
                         valid_node_count, avail_node_count);
@@ -2657,10 +2740,10 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
                }
        }
        for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) {
-               for (j = i; j < NR_CURSEG_DATA_TYPE; j++) {
+               for (j = 0; j < NR_CURSEG_DATA_TYPE; j++) {
                        if (le32_to_cpu(ckpt->cur_node_segno[i]) ==
                                le32_to_cpu(ckpt->cur_data_segno[j])) {
-                               f2fs_err(sbi, "Data segment (%u) and Data segment (%u) has the same segno: %u",
+                               f2fs_err(sbi, "Node segment (%u) and Data segment (%u) has the same segno: %u",
                                         i, j,
                                         le32_to_cpu(ckpt->cur_node_segno[i]));
                                return 1;
@@ -3033,6 +3116,53 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
        return 0;
 }
 
+static int f2fs_setup_casefold(struct f2fs_sb_info *sbi)
+{
+#ifdef CONFIG_UNICODE
+       if (f2fs_sb_has_casefold(sbi) && !sbi->s_encoding) {
+               const struct f2fs_sb_encodings *encoding_info;
+               struct unicode_map *encoding;
+               __u16 encoding_flags;
+
+               if (f2fs_sb_has_encrypt(sbi)) {
+                       f2fs_err(sbi,
+                               "Can't mount with encoding and encryption");
+                       return -EINVAL;
+               }
+
+               if (f2fs_sb_read_encoding(sbi->raw_super, &encoding_info,
+                                         &encoding_flags)) {
+                       f2fs_err(sbi,
+                                "Encoding requested by superblock is unknown");
+                       return -EINVAL;
+               }
+
+               encoding = utf8_load(encoding_info->version);
+               if (IS_ERR(encoding)) {
+                       f2fs_err(sbi,
+                                "can't mount with superblock charset: %s-%s "
+                                "not supported by the kernel. flags: 0x%x.",
+                                encoding_info->name, encoding_info->version,
+                                encoding_flags);
+                       return PTR_ERR(encoding);
+               }
+               f2fs_info(sbi, "Using encoding defined by superblock: "
+                        "%s-%s with flags 0x%hx", encoding_info->name,
+                        encoding_info->version?:"\b", encoding_flags);
+
+               sbi->s_encoding = encoding;
+               sbi->s_encoding_flags = encoding_flags;
+               sbi->sb->s_d_op = &f2fs_dentry_ops;
+       }
+#else
+       if (f2fs_sb_has_casefold(sbi)) {
+               f2fs_err(sbi, "Filesystem with casefold feature cannot be mounted without CONFIG_UNICODE");
+               return -EINVAL;
+       }
+#endif
+       return 0;
+}
+
 static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi)
 {
        struct f2fs_sm_info *sm_i = SM_I(sbi);
@@ -3129,6 +3259,10 @@ try_onemore:
                                le32_to_cpu(raw_super->log_blocksize);
        sb->s_max_links = F2FS_LINK_MAX;
 
+       err = f2fs_setup_casefold(sbi);
+       if (err)
+               goto free_options;
+
 #ifdef CONFIG_QUOTA
        sb->dq_op = &f2fs_quota_operations;
        sb->s_qcop = &f2fs_quotactl_ops;
@@ -3207,7 +3341,7 @@ try_onemore:
        if (err)
                goto free_bio_info;
 
-       if (F2FS_IO_SIZE(sbi) > 1) {
+       if (F2FS_IO_ALIGNED(sbi)) {
                sbi->write_io_dummy =
                        mempool_create_page_pool(2 * (F2FS_IO_SIZE(sbi) - 1), 0);
                if (!sbi->write_io_dummy) {
@@ -3482,6 +3616,10 @@ free_percpu:
 free_bio_info:
        for (i = 0; i < NR_PAGE_TYPE; i++)
                kvfree(sbi->write_io[i]);
+
+#ifdef CONFIG_UNICODE
+       utf8_unload(sbi->s_encoding);
+#endif
 free_options:
 #ifdef CONFIG_QUOTA
        for (i = 0; i < MAXQUOTAS; i++)