Merge tag 'for-rc-adfs' of git://git.armlinux.org.uk/~rmk/linux-arm
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 6 Jun 2019 18:02:54 +0000 (11:02 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 6 Jun 2019 18:02:54 +0000 (11:02 -0700)
Pull ADFS cleanups/fixes from Russell King:
 "As a result of some of Al Viro's great work, here are a few cleanups
  with fixes for adfs:

   - factor out filename comparison, so we can be sure that
     adfs_compare() (used for namei compare) and adfs_match() (used for
     lookup) have the same behaviour.

   - factor out filename lowering (which is not the same as tolower()
     which will lower top-bit-set characters) to ensure that we have the
     same behaviour when comparing filenames as when we hash them.

   - factor out the object fixups, so we are applying all fixups to
     directory objects in the same way, independent of the disk format.

   - factor out the object name fixup (into the previously factored out
     function) to ensure that filenames are appropriately translated -
     for example, adfs allows '/' in filenames, which being the Unix
     path separator, need to be translated to a different character,
     which is normally '.' (DOS 8.3 filenames represent the . as a / on
     adfs, so this is the expected reverse translation.)

   - remove filename truncation; Al asked about this and apparently the
     decision is to remove it. In any case, adfs's truncation was buggy,
     so this rids us of that bug by removing the truncation feature.

   - we now have only one location which adds the "filetype" suffix to
     the filename, so there's no point that code being out of line.

   - since we translate '/' into '.', an adfs filename of "/" or "//"
     would end up being translated to "." and ".." which have special
     meanings. In this case, change the first character to "^" to avoid
     these special directory names being abused"

* tag 'for-rc-adfs' of git://git.armlinux.org.uk/~rmk/linux-arm:
  fs/adfs: fix filename fixup handling for "/" and "//" names
  fs/adfs: move append_filetype_suffix() into adfs_object_fixup()
  fs/adfs: remove truncated filename hashing
  fs/adfs: factor out filename fixup
  fs/adfs: factor out object fixups
  fs/adfs: factor out filename case lowering
  fs/adfs: factor out filename comparison

1  2 
fs/adfs/dir_f.c

diff --combined fs/adfs/dir_f.c
index 382c9d7ad375be6df5ce6e96e00138257fada9d9,033884541a632ccfbc0928d39cb5358826a312e0..693f69ed3de3e3917c03212f02d0b5ad922d72a8
@@@ -24,11 -24,8 +24,11 @@@ static inline unsigned int adfs_readval
  
        switch (len) {
        case 4:         val |= p[3] << 24;
 +                      /* fall through */
        case 3:         val |= p[2] << 16;
 +                      /* fall through */
        case 2:         val |= p[1] << 8;
 +                      /* fall through */
        default:        val |= p[0];
        }
        return val;
@@@ -38,30 -35,12 +38,15 @@@ static inline void adfs_writeval(unsign
  {
        switch (len) {
        case 4:         p[3] = val >> 24;
 +                      /* fall through */
        case 3:         p[2] = val >> 16;
 +                      /* fall through */
        case 2:         p[1] = val >> 8;
 +                      /* fall through */
        default:        p[0] = val;
        }
  }
  
- static inline int adfs_readname(char *buf, char *ptr, int maxlen)
- {
-       char *old_buf = buf;
-       while ((unsigned char)*ptr >= ' ' && maxlen--) {
-               if (*ptr == '/')
-                       *buf++ = '.';
-               else
-                       *buf++ = *ptr;
-               ptr++;
-       }
-       return buf - old_buf;
- }
  #define ror13(v) ((v >> 13) | (v << 19))
  
  #define dir_u8(idx)                           \
@@@ -216,29 -195,23 +201,23 @@@ static inline voi
  adfs_dir2obj(struct adfs_dir *dir, struct object_info *obj,
        struct adfs_direntry *de)
  {
-       obj->name_len = adfs_readname(obj->name, de->dirobname, ADFS_F_NAME_LEN);
+       unsigned int name_len;
+       for (name_len = 0; name_len < ADFS_F_NAME_LEN; name_len++) {
+               if (de->dirobname[name_len] < ' ')
+                       break;
+               obj->name[name_len] = de->dirobname[name_len];
+       }
+       obj->name_len = name_len;
        obj->file_id  = adfs_readval(de->dirinddiscadd, 3);
        obj->loadaddr = adfs_readval(de->dirload, 4);
        obj->execaddr = adfs_readval(de->direxec, 4);
        obj->size     = adfs_readval(de->dirlen,  4);
        obj->attr     = de->newdiratts;
-       obj->filetype = -1;
  
-       /*
-        * object is a file and is filetyped and timestamped?
-        * RISC OS 12-bit filetype is stored in load_address[19:8]
-        */
-       if ((0 == (obj->attr & ADFS_NDA_DIRECTORY)) &&
-               (0xfff00000 == (0xfff00000 & obj->loadaddr))) {
-               obj->filetype = (__u16) ((0x000fff00 & obj->loadaddr) >> 8);
-               /* optionally append the ,xyz hex filetype suffix */
-               if (ADFS_SB(dir->sb)->s_ftsuffix)
-                       obj->name_len +=
-                               append_filetype_suffix(
-                                       &obj->name[obj->name_len],
-                                       obj->filetype);
-       }
+       adfs_object_fixup(dir, obj);
  }
  
  /*