Skip to content
  • Sougata Santra's avatar
    hfsplus: remove hfsplus_file_lookup() · d74a054f
    Sougata Santra authored
    HFS+ resource fork lookup breaks opendir() library function.  Since
    opendir first calls open() with O_DIRECTORY flag set.  O_DIRECTORY means
    "refuse to open if not a directory".  The open system call in the kernel
    does a check for inode->i_op->lookup and returns -ENOTDIR.  So if
    hfsplus_file_lookup is set it allows opendir() for plain files.
    
    Also resource fork lookup in HFS+ does not work.  Since it is never
    invoked after VFS permission checking.  It will always return with
    -EACCES.
    
    When we call opendir() on a file, it does not return NULL.  opendir()
    library call is based on open with O_DIRECTORY flag passed and then
    layered on top of getdents() system call.  O_DIRECTORY means "refuse to
    open if not a directory".
    
    The open() system call in the kernel does a check for: do_sys_open()
    -->..--> can_lookup() i.e it only checks inode->i_op->lookup and returns
    ENOTDIR if this function pointer is not set.
    
    In OSX, we can open "file/rsrc" to get the resource fork of "file".  This
    behavior is emulated inside hfsplus on Linux, which means that to some
    degree every file acts like a directory.  That is the reason lookup()
    inode operations is supported for files, and it is possible to do a lookup
    on this specific name.  As a result of this open succeeds without
    returning ENOTDIR for HFS+
    
    Please see the LKML discussion thread on this issue:
    http://marc.info/?l=linux-fsdevel&m=122823343730412&w=2
    
    I tried to test file/rsrc lookup in HFS+ driver and the feature does not
    work.  From OSX:
    
    $ touch test
    $ echo "1234" > test/..namedfork/rsrc
    $ ls -l test..namedfork/rsrc
    --rw-r--r-- 1 tuxera staff 5 10 dec 12:59 test/..namedfork/rsrc
    
    [sougata@ultrabook tmp]$ id
    uid=1000(sougata) gid=1000(sougata) groups=1000(sougata),5(tty),18(dialout),1001(vboxusers)
    
    [sougata@ultrabook tmp]$ mount
    /dev/sdb1 on /mnt/tmp type hfsplus (rw,relatime,umask=0,uid=1000,gid=1000,nls=utf8)
    
    [sougata@ultrabook tmp]$ ls -l test/rsrc
    ls: cannot access test/rsrc: Permission denied
    
    According to this LKML thread it is expected behavior.
    
    http://marc.info/?t=121139033800008&r=1&w=4
    
    
    
    I guess now that permission checking happens in vfs generic_permission() ?
     So it turns out that even though the lookup() inode_operation exists for
    HFS+ files.  It cannot really get invoked ?.  So if we can disable this
    feature to make opendir() work for HFS+.
    
    Signed-off-by: default avatarSougata Santra <sougata@tuxera.com>
    Acked-by: default avatarChristoph Hellwig <hch@lst.de>
    Cc: Vyacheslav Dubeyko <slava@dubeyko.com>
    Cc: Anton Altaparmakov <aia21@cam.ac.uk>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    d74a054f