Merge tag 'mmc-v5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
[linux-2.6-microblaze.git] / fs / exfat / dir.c
index 9167970..c452364 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/compat.h>
 #include <linux/bio.h>
 #include <linux/buffer_head.h>
 
@@ -146,7 +147,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
                                        0);
 
                        *uni_name.name = 0x0;
-                       exfat_get_uniname_from_ext_entry(sb, &dir, dentry,
+                       exfat_get_uniname_from_ext_entry(sb, &clu, i,
                                uni_name.name);
                        exfat_utf16_to_nls(sb, &uni_name,
                                dir_entry->namebuf.lfn,
@@ -306,6 +307,10 @@ const struct file_operations exfat_dir_operations = {
        .llseek         = generic_file_llseek,
        .read           = generic_read_dir,
        .iterate        = exfat_iterate,
+       .unlocked_ioctl = exfat_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = exfat_compat_ioctl,
+#endif
        .fsync          = exfat_file_fsync,
 };
 
@@ -315,7 +320,7 @@ int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu)
 
        exfat_chain_set(clu, EXFAT_EOF_CLUSTER, 0, ALLOC_NO_FAT_CHAIN);
 
-       ret = exfat_alloc_cluster(inode, 1, clu);
+       ret = exfat_alloc_cluster(inode, 1, clu, IS_DIRSYNC(inode));
        if (ret)
                return ret;
 
@@ -906,14 +911,19 @@ enum {
 };
 
 /*
- * return values:
- *   >= 0      : return dir entiry position with the name in dir
- *   -ENOENT   : entry with the name does not exist
- *   -EIO      : I/O error
+ * @ei:         inode info of parent directory
+ * @p_dir:      directory structure of parent directory
+ * @num_entries:entry size of p_uniname
+ * @hint_opt:   If p_uniname is found, filled with optimized dir/entry
+ *              for traversing cluster chain.
+ * @return:
+ *   >= 0:      file directory entry position where the name exists
+ *   -ENOENT:   entry with the name does not exist
+ *   -EIO:      I/O error
  */
 int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
                struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname,
-               int num_entries, unsigned int type)
+               int num_entries, unsigned int type, struct exfat_hint *hint_opt)
 {
        int i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0, len;
        int order, step, name_len = 0;
@@ -990,6 +1000,8 @@ rewind:
 
                        if (entry_type == TYPE_FILE || entry_type == TYPE_DIR) {
                                step = DIRENT_STEP_FILE;
+                               hint_opt->clu = clu.dir;
+                               hint_opt->eidx = i;
                                if (type == TYPE_ALL || type == entry_type) {
                                        num_ext = ep->dentry.file.num_ext;
                                        step = DIRENT_STEP_STRM;