]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/fat/dir.c
Merge branch 'v28-range-hrtimers-for-linus-v2' of git://git.kernel.org/pub/scm/linux...
[linux-2.6-omap-h63xx.git] / fs / fat / dir.c
index 96a1cad30da477bcee8cdc7cae58d1aa0c012f24..bae1c3292522eddbb744bcf6e6f84bc56da349e3 100644 (file)
@@ -481,11 +481,11 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent,
        unsigned short opt_shortname = sbi->options.shortname;
        int isvfat = sbi->options.isvfat;
        int nocase = sbi->options.nocase;
-       const char *fill_name;
+       const char *fill_name = NULL;
        unsigned long inum;
        unsigned long lpos, dummy, *furrfu = &lpos;
        loff_t cpos;
-       int chi, chl, i, i2, j, last, last_u, dotoffset = 0, fill_len;
+       int chi, chl, i, i2, j, last, last_u, dotoffset = 0, fill_len = 0;
        int ret = 0;
 
        lock_super(sb);
@@ -516,8 +516,11 @@ get_new:
                goto end_of_dir;
 parse_record:
        nr_slots = 0;
-       /* Check for long filename entry */
-       if (isvfat) {
+       /*
+        * Check for long filename entry, but if short_only, we don't
+        * need to parse long filename.
+        */
+       if (isvfat && !short_only) {
                if (de->name[0] == DELETED_FLAG)
                        goto record_end;
                if (de->attr != ATTR_EXT && (de->attr & ATTR_VOLUME))
@@ -542,6 +545,18 @@ parse_record:
                        goto parse_record;
                else if (status == PARSE_EOF)
                        goto end_of_dir;
+
+               if (nr_slots) {
+                       void *longname = unicode + FAT_MAX_UNI_CHARS;
+                       int size = PATH_MAX - FAT_MAX_UNI_SIZE;
+                       int len = fat_uni_to_x8(sbi, unicode, longname, size);
+
+                       fill_name = longname;
+                       fill_len = len;
+                       /* !both && !short_only, so we don't need shortname. */
+                       if (!both)
+                               goto start_filldir;
+               }
        }
 
        if (sbi->options.dotsOK) {
@@ -608,6 +623,26 @@ parse_record:
        i = last + dotoffset;
        j = last_u;
 
+       if (isvfat) {
+               bufuname[j] = 0x0000;
+               i = fat_uni_to_x8(sbi, bufuname, bufname, sizeof(bufname));
+       }
+       if (nr_slots) {
+               /* hack for fat_ioctl_filldir() */
+               struct fat_ioctl_filldir_callback *p = dirent;
+
+               p->longname = fill_name;
+               p->long_len = fill_len;
+               p->shortname = bufname;
+               p->short_len = i;
+               fill_name = NULL;
+               fill_len = 0;
+       } else {
+               fill_name = bufname;
+               fill_len = i;
+       }
+
+start_filldir:
        lpos = cpos - (nr_slots + 1) * sizeof(struct msdos_dir_entry);
        if (!memcmp(de->name, MSDOS_DOT, MSDOS_NAME))
                inum = inode->i_ino;
@@ -623,34 +658,6 @@ parse_record:
                        inum = iunique(sb, MSDOS_ROOT_INO);
        }
 
-       if (isvfat) {
-               bufuname[j] = 0x0000;
-               i = fat_uni_to_x8(sbi, bufuname, bufname, sizeof(bufname));
-       }
-
-       fill_name = bufname;
-       fill_len = i;
-       if (!short_only && nr_slots) {
-               void *longname = unicode + FAT_MAX_UNI_CHARS;
-               int long_len, size = PATH_MAX - FAT_MAX_UNI_SIZE;
-
-               long_len = fat_uni_to_x8(sbi, unicode, longname, size);
-
-               if (!both) {
-                       fill_name = longname;
-                       fill_len = long_len;
-               } else {
-                       /* hack for fat_ioctl_filldir() */
-                       struct fat_ioctl_filldir_callback *p = dirent;
-
-                       p->longname = longname;
-                       p->long_len = long_len;
-                       p->shortname = bufname;
-                       p->short_len = i;
-                       fill_name = NULL;
-                       fill_len = 0;
-               }
-       }
        if (filldir(dirent, fill_name, fill_len, *furrfu, inum,
                    (de->attr & ATTR_DIR) ? DT_DIR : DT_REG) < 0)
                goto fill_failed;
@@ -832,6 +839,7 @@ const struct file_operations fat_dir_operations = {
        .compat_ioctl   = fat_compat_dir_ioctl,
 #endif
        .fsync          = file_fsync,
+       .llseek         = generic_file_llseek,
 };
 
 static int fat_get_short_entry(struct inode *dir, loff_t *pos,
@@ -1094,7 +1102,7 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec *ts)
                goto error_free;
        }
 
-       fat_date_unix2dos(ts->tv_sec, &time, &date);
+       fat_date_unix2dos(ts->tv_sec, &time, &date, sbi->options.tz_utc);
 
        de = (struct msdos_dir_entry *)bhs[0]->b_data;
        /* filling the new directory slots ("." and ".." entries) */