Section 12.11. Comparing Mac OS X File Systems


12.11. Comparing Mac OS X File Systems

Now that we have looked at details of HFS+ and overviews of commonly available file systems on Mac OS X (in Chapter 11), let us compare key features and interfaces supported by all these file systems. We will use the getattrlist() system call to display a given volume's capabilities.

int getattrlist(     const char      *path,        // path of a file system object on the volume     struct attrlist *attrList,    // a populated attribute list structure     void            *attrBuf,     // buffer for receiving attributes     size_t           attrBufSize, // size of the buffer     unsigned long    options);    // any options


The call returns attributes in a caller-provided buffer whose format depends on the specific attribute or attributes being retrieved. However, the buffer always begins with an unsigned long value that specifies the size of the returned attributes (including this size value) in bytes. In the case of volume attributes, the size value is followed by a vol_capabilities_attr_t data structure, which consists of two arrays of bitmaps: the valid array and the capabilities array. We will deal with only two elements of each array: the one at index VOL_CAPABILITIES_FORMAT (which contains information about volume format features) and the other at index VOL_CAPABILITIES_INTERFACES (which contains information about interfaces provided by the volume format). If a bit is set in a valid bitmap, it means the volume format implementation recognizes that bit. If the same bit is also set in the corresponding capabilities bitmap, it means the volume provides that capability.

typedef u_int32_t vol_capabilities_set_t[4]; #define VOL_CAPABILITIES_FORMAT     0 #define VOL_CAPABILITIES_INTERFACES 1 #define VOL_CAPABILITIES_RESERVED1  2 #define VOL_CAPABILITIES_RESERVED2  3 typedef struct vol_capabilities_attr {     vol_capabilities_set_t capabilities;     vol_capabilities_set_t valid; } vol_capabilities_attr_t;


Figure 1234 shows the source for a program that retrieves and displays a volume's capabilitiesboth features and interfaces.

Figure 1234. Querying a volume's capabilities

// getattrlist_volinfo.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/attr.h> #define PROGNAME "getattrlist_volinfo" // getattrlist() returns volume capabilities in this attribute buffer format typedef struct {     unsigned long           size;     vol_capabilities_attr_t attributes; } volinfo_buf_t; // for pretty-printing convenience typedef struct {     u_int32_t   bits;     const char *name; } bits_name_t; #define BITS_NAME(bits) { bits, #bits } // map feature availability bits to names bits_name_t vol_capabilities_format[] = {     BITS_NAME(VOL_CAP_FMT_2TB_FILESIZE),     BITS_NAME(VOL_CAP_FMT_CASE_PRESERVING),     BITS_NAME(VOL_CAP_FMT_CASE_SENSITIVE),     BITS_NAME(VOL_CAP_FMT_FAST_STATFS),     BITS_NAME(VOL_CAP_FMT_HARDLINKS),     BITS_NAME(VOL_CAP_FMT_JOURNAL),     BITS_NAME(VOL_CAP_FMT_JOURNAL_ACTIVE),     BITS_NAME(VOL_CAP_FMT_NO_ROOT_TIMES),     BITS_NAME(VOL_CAP_FMT_PERSISTENTOBJECTIDS),     BITS_NAME(VOL_CAP_FMT_SYMBOLICLINKS),     BITS_NAME(VOL_CAP_FMT_SPARSE_FILES),     BITS_NAME(VOL_CAP_FMT_ZERO_RUNS), }; #define VOL_CAP_FMT_SZ (sizeof(vol_capabilities_format)/sizeof(bits_name_t)) // map interface availability bits to names bits_name_t vol_capabilities_interfaces[] = {     BITS_NAME(VOL_CAP_INT_ADVLOCK),     BITS_NAME(VOL_CAP_INT_ALLOCATE),     BITS_NAME(VOL_CAP_INT_ATTRLIST),     BITS_NAME(VOL_CAP_INT_COPYFILE),     BITS_NAME(VOL_CAP_INT_EXCHANGEDATA),     BITS_NAME(VOL_CAP_INT_EXTENDED_SECURITY),     BITS_NAME(VOL_CAP_INT_FLOCK),     BITS_NAME(VOL_CAP_INT_NFSEXPORT),     BITS_NAME(VOL_CAP_INT_READDIRATTR),     BITS_NAME(VOL_CAP_INT_SEARCHFS),     BITS_NAME(VOL_CAP_INT_USERACCESS),     BITS_NAME(VOL_CAP_INT_VOL_RENAME), }; #define VOL_CAP_INT_SZ (sizeof(vol_capabilities_interfaces)/sizeof(bits_name_t)) void print_volume_capabilities(volinfo_buf_t *volinfo_buf,                           bits_name_t   *bits_names,                           ssize_t        size,                           u_int32_t      index) {     u_int32_t capabilities = volinfo_buf->attributes.capabilities[index];     u_int32_t valid        = volinfo_buf->attributes.valid[index];     int i;     for (i = 0; i < size; i++)         if ((bits_names[i].bits & valid) && (bits_names[i].bits & capabilities))             printf("%s\n", bits_names[i].name);     printf("\n"); } int main(int argc, char **argv) {     volinfo_buf_t   volinfo_buf;     struct attrlist attrlist;     if (argc != 2) {         fprintf(stderr, "usage: %s <volume path>\n", PROGNAME);         exit(1);     }     // populate the ingoing attribute list structure     attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;    // always set to this constant     attrlist.reserved    = 0;                     // reserved field zeroed     attrlist.commonattr  = 0;                     // we don't want ATTR_CMN_*     attrlist.volattr     = ATTR_VOL_CAPABILITIES; // we want these attributes     attrlist.dirattr     = 0;                     // we don't want ATTR_DIR_*     attrlist.fileattr    = 0;                     // we don't want ATTR_FILE_*     attrlist.forkattr    = 0;                     // we don't want ATTR_FORK_*     if (getattrlist(argv[1], &attrlist, &volinfo_buf, sizeof(volinfo_buf), 0)) {         perror("getattrlist");         exit(1);     }     print_volume_capabilities(&volinfo_buf,                               (bits_name_t *)&vol_capabilities_format,                               VOL_CAP_FMT_SZ, VOL_CAPABILITIES_FORMAT);     print_volume_capabilities(&volinfo_buf,                               (bits_name_t *)&vol_capabilities_interfaces,                               VOL_CAP_INT_SZ, VOL_CAPABILITIES_INTERFACES);     exit(0); } $ gcc -Wall -o getattrlist_volinfo getattrlist_volinfo.c $ getattrlist_volinfo / # an HFS+ volume VOL_CAP_FMT_2TB_FILESIZE VOL_CAP_FMT_CASE_PRESERVING VOL_CAP_FMT_FAST_STATFS VOL_CAP_FMT_HARDLINKS VOL_CAP_FMT_JOURNAL VOL_CAP_FMT_JOURNAL_ACTIVE VOL_CAP_FMT_PERSISTENTOBJECTIDS VOL_CAP_FMT_SYMBOLICLINKS VOL_CAP_INT_ADVLOCK VOL_CAP_INT_ALLOCATE VOL_CAP_INT_ATTRLIST VOL_CAP_INT_EXCHANGEDATA VOL_CAP_INT_EXTENDED_SECURITY VOL_CAP_INT_FLOCK VOL_CAP_INT_NFSEXPORT VOL_CAP_INT_READDIRATTR VOL_CAP_INT_SEARCHFS VOL_CAP_INT_VOL_RENAME $

The program output in Figure 1233 shows the volume capabilities supported by an HFS+ volume on Mac OS X. Let us look at the meanings of the various feature and interface bits that may be reported by getattrlist() for a volume. The following is an overview of the feature bits.

  • VOL_CAP_FMT_2TB_FILESIZE supports a maximum file size of at least 2TB, provided sufficient storage is available.

  • VOL_CAP_FMT_CASE_PRESERVING preserves the case of a file system object name when writing the name to disk but otherwise does not use case sensitivity. In particular, name comparisons are case-insensitive.

  • VOL_CAP_FMT_CASE_SENSITIVE uses case sensitivity at all times when dealing with file system object names.

  • VOL_CAP_FMT_FAST_STATFS provides a statfs() system call implementation that is fast enough to not require caching of its results by higher layers of the operating system. Typically, a volume format with this capability will provide its own caching of statfs() data. If this capability is missing, the information must typically be retrieved from the storage medium (which could be across the network) every time statfs() is called.

  • VOL_CAP_FMT_HARDLINKS natively supports hard links.

  • VOL_CAP_FMT_JOURNAL supports journaling, although journaling may not be enabled.

  • VOL_CAP_FMT_JOURNAL_ACTIVE indicates that the volume has journaling enabled. This is not really a capability bit but a status bit.

  • VOL_CAP_FMT_NO_ROOT_TIMES does not store times for the root directory reliably.

  • VOL_CAP_FMT_PERSISTENTOBJECTIDS has persistent object identifiers that can be used for looking up file system objects. As we saw in Section 11.7.19, Mac OS X provides the volume file system (volfs) for performing such lookups on volumes that support this capability.

  • VOL_CAP_FMT_SPARSE_FILES supports files with "holes"that is, the logical size of a file can be greater than the sum of the physical blocks it occupies on disk (see also Section 11.7.6). Specifically, blocks that have never been written are not allocated on disk, leading to space savings and possibly better performance for such files (if the file system would otherwise explicitly zero-fill the unused blocks on disk; see VOL_CAP_FMT_ZERO_RUNS).

  • VOL_CAP_FMT_SYMBOLICLINKS natively supports symbolic links. Note that although FAT32 does not support symbolic links natively, the Mac OS X implementation of FAT32 emulates symbolic links using regular files.

  • VOL_CAP_FMT_ZERO_RUNS indicates that the volume can dynamically substitute zeroes while reading a file's blocks that have been allocated but never written. Normally, such blocks are zero-filled on the disk by the file system. This capability is similar to sparse files in that there will be no I/O for the unwritten parts of a file, but it is dissimilar in that the corresponding blocks will still be allocated on disk.

Table 124 shows which features are supported by commonly used volume formats on Mac OS X.

Table 124. Features Supported by Common Volume Formats on Mac OS X

Feature

HFS+

UFS

HFS

NTFS

FAT32

AFP

SMB

NFS

WebDAV

2TB_FILESIZE

    

 

 

CASE_PRESERVING

  

 

CASE_SENSITIVE


(HFSX)

       

FAST_STATFS

 

HARDLINKS

 

   

 

JOURNAL

        

NO_ROOT_TIMES

    

 

  

PERSISTENTOBJECTIDS

 

  

   

SPARSE_FILES

 

 

     

SYMBOLICLINKS

   

 

ZERO_RUNS

         


The following is an overview of the interface bits that may be reported by getattrlist() for a volume.

  • VOL_CAP_INT_ADVLOCK provides POSIX-style byte-range, advisory-mode locking. As we saw in Section 9.18.10, the Mac OS X VFS layer provides an implementation of advisory locking, which a local file system may choose to use. Alternatively, a file system can implement locking itself or may not support locking at all. As Table 125 shows, HFS+, HFS, and UFS use VFS-layer locking, whereas FAT32 and SMB implement their own. In the case of NFS, locking is courtesy of the lock daemon.

    Table 125. Interfaces Supported by Common File System Implementations on Mac OS X

    Interface

    HFS+

    UFS

    HFS

    FAT32

    AFP

    SMB

    NFS

    ADVLOCK


    (VFS)


    (VFS)


    (VFS)

     


    (lock daemon)

    ALLOCATE

     

        

    ATTRLIST

     

     

      

    COPYFILE

        

      

    EXCHANGEDATA

     

     

      

    EXTENDED_SECURITY

          

    FLOCK


    (VFS)


    (VFS)


    (VFS)

     


    (lock daemon)

    NFSEXPORT

        

    READDIRATTR

     

     

      

    SEARCHFS

     

     

      

    USERACCESS

           

    VOL_RENAME

        


  • VOL_CAP_INT_ALLOCATE implements the F_PREALLOCATE file control operation, which allows the caller to preallocate storage space for a given file.

  • VOL_CAP_INT_ATTRLIST implements the setattrlist() and getattrlist() system calls.

  • VOL_CAP_INT_COPYFILE implements the copyfile() system call. Originally meant for the Apple Filing Protocol (AFP), copyfile() is used to copy a file system object along with some or all of its metadata, such as ACLs and other extended attributes. Note that the system library provides a user-space implementation of a copyfile() function that does not use the system call. The function also flattens out metadata into external files on volumes that do not support that metadata natively.

  • VOL_CAP_INT_EXCHANGEDATA implements the exchangedata() system call.

  • VOL_CAP_INT_EXTENDED_SECURITY implements extended security (i.e., ACLs).

  • VOL_CAP_INT_FLOCK provides whole-file, advisory-mode locking through the flock(2) system call. The note about VFS-level locking in the description of VOL_CAP_INT_ADVLOCK also applies here.

  • VOL_CAP_INT_NFSEXPORT indicates that the volume allows its contents to be exported via NFS.

  • VOL_CAP_INT_READDIRATTR implements the readdirattr() system call.

  • VOL_CAP_INT_SEARCHFS implements the searchfs() system call.

  • VOL_CAP_INT_USERACCESS is obsolete in Mac OS X 10.4.

  • VOL_CAP_INT_VOL_RENAME indicates that the volume name can be changed through the setattrlist() system call.




Mac OS X Internals. A Systems Approach
Mac OS X Internals: A Systems Approach
ISBN: 0321278542
EAN: 2147483647
Year: 2006
Pages: 161
Authors: Amit Singh

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net