]> git.saurik.com Git - apple/hfs.git/commitdiff
hfs-116.10.tar.gz mac-os-x-1022 v116.10
authorApple <opensource@apple.com>
Fri, 25 Oct 2002 19:51:46 +0000 (19:51 +0000)
committerApple <opensource@apple.com>
Fri, 25 Oct 2002 19:51:46 +0000 (19:51 +0000)
hfs_util/Info.plist
hfs_util/InfoPlist.strings
hfs_util/Makefile
hfs_util/Makefile.postamble
hfs_util/PB.project
hfs_util/hfsutil_jnl.c [new file with mode: 0644]
hfs_util/hfsutil_main.c

index 26b938c8a382585577f1a611a94874c736739e0f..f794579543f78113a7e4fa3716c09eefcc453044 100644 (file)
        <key>CFBundlePackageType</key>
        <string>fs  </string>
        <key>CFBundleShortVersionString</key>
        <key>CFBundlePackageType</key>
        <string>fs  </string>
        <key>CFBundleShortVersionString</key>
-       <string>1.1</string>
+       <string>1.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.1</string>
+       <string>1.2</string>
        <key>FSMediaTypes</key>
        <dict>
                <key>Apple_HFS</key>
        <key>FSMediaTypes</key>
        <dict>
                <key>Apple_HFS</key>
                        <key>FSVerificationExecutable</key>
                        <string>../../../../../../sbin/fsck_hfs</string>
                </dict>
                        <key>FSVerificationExecutable</key>
                        <string>../../../../../../sbin/fsck_hfs</string>
                </dict>
+               <key>Journaled HFS+</key>
+               <dict>
+                       <key>FSFormatArguments</key>
+                       <string>-J</string>
+                       <key>FSFormatContentMask</key>
+                       <string>Apple_HFS</string>
+                       <key>FSFormatExecutable</key>
+                       <string>../../../../../../sbin/newfs_hfs</string>
+                       <key>FSFormatMinimumSize</key>
+                       <integer>4194304</integer>
+                       <key>FSMountArguments</key>
+                       <string></string>
+                       <key>FSMountExecutable</key>
+                       <string>../../../../../../sbin/mount_hfs</string>
+                       <key>FSName</key>
+                       <string>Mac OS Extended (Journaled)</string>
+                       <key>FSRepairArguments</key>
+                       <string>-y</string>
+                       <key>FSRepairExecutable</key>
+                       <string>../../../../../../sbin/fsck_hfs</string>
+                       <key>FSVerificationArguments</key>
+                       <string>-fn</string>
+                       <key>FSVerificationExecutable</key>
+                       <string>../../../../../../sbin/fsck_hfs</string>
+               </dict>
                <key>HFS+</key>
                <dict>
                        <key>FSFormatArguments</key>
                <key>HFS+</key>
                <dict>
                        <key>FSFormatArguments</key>
                        <key>FSRepairExecutable</key>
                        <string>../../../../../../sbin/fsck_hfs</string>
                        <key>FSVerificationArguments</key>
                        <key>FSRepairExecutable</key>
                        <string>../../../../../../sbin/fsck_hfs</string>
                        <key>FSVerificationArguments</key>
-                       <string>-n</string>
+                       <string>-fn</string>
                        <key>FSVerificationExecutable</key>
                        <string>../../../../../../sbin/fsck_hfs</string>
                </dict>
                        <key>FSVerificationExecutable</key>
                        <string>../../../../../../sbin/fsck_hfs</string>
                </dict>
index 5a09ea5e1cc29f1b3d42158a2966bb70026f9aaa..a108b2068012fd4c5130f89bf1d32bbd36a278b0 100644 (file)
                        <key>FSName</key>
                        <string>Mac OS Extended</string>
                </dict>
                        <key>FSName</key>
                        <string>Mac OS Extended</string>
                </dict>
+               <key>Journaled HFS+</key>
+               <dict>
+                       <key>FSName</key>
+                       <string>Mac OS Extended (Journaled)</string>
+               </dict>
        </dict>
 </dict>
 </plist>
        </dict>
 </dict>
 </plist>
index e8bcb61e15fdfc21dce8fa42303626bdb452c889..25e7f9077f3f4160f626bd83e36b55fe0b028f67 100644 (file)
@@ -12,7 +12,7 @@ NAME = hfs.util
 PROJECTVERSION = 2.8
 PROJECT_TYPE = Tool
 
 PROJECTVERSION = 2.8
 PROJECT_TYPE = Tool
 
-CFILES = hfsutil_main.c
+CFILES = hfsutil_main.c hfsutil_jnl.c
 
 OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\
             hfs_CD.fs.tiff hfs_CD.openfs.tiff hfs_FD.fs.tiff\
 
 OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\
             hfs_CD.fs.tiff hfs_CD.openfs.tiff hfs_FD.fs.tiff\
index 4b80f133847756188f62b7bf0b39a35bcb73464a..001327f636867d7df03c5e60173e04b9907d1bb8 100644 (file)
@@ -80,7 +80,7 @@ INSTALL_AS_USER = root
         # User/group ownership 
 #INSTALL_AS_GROUP = wheel
         # (probably want to set both of these) 
         # User/group ownership 
 #INSTALL_AS_GROUP = wheel
         # (probably want to set both of these) 
-INSTALL_PERMISSIONS = 4555
+#INSTALL_PERMISSIONS = 4555
         # If set, 'install' chmod's executable to this
 
 
         # If set, 'install' chmod's executable to this
 
 
index b2c82cb26c5be00f20dd7226863de8ab9f08ef6b..146a30e9b6c5aac87f52de51e5031e82c66cabe8 100644 (file)
@@ -8,7 +8,7 @@
         FRAMEWORKSEARCH = (); 
         H_FILES = (); 
         M_FILES = (); 
         FRAMEWORKSEARCH = (); 
         H_FILES = (); 
         M_FILES = (); 
-        OTHER_LINKED = (hfsutil_main.c); 
+        OTHER_LINKED = (hfsutil_main.c hfsutil_jnl.c); 
         OTHER_SOURCES = (
             Makefile.preamble, 
             Makefile, 
         OTHER_SOURCES = (
             Makefile.preamble, 
             Makefile, 
diff --git a/hfs_util/hfsutil_jnl.c b/hfs_util/hfsutil_jnl.c
new file mode 100644 (file)
index 0000000..c4b6b6e
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 1999-2001 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ Copyright (c) 2002 Apple Computer, Inc.
+ All Rights Reserved.
+
+ This file contains the routine to make an HFS+ volume journaled
+ and a corresponding routine to turn it off.
+ */
+
+#include <sys/types.h>
+#include <sys/attr.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/sysctl.h>
+#include <sys/resource.h>
+#include <sys/vmmeter.h>
+#include <sys/mount.h>
+#include <sys/wait.h>
+
+#include <dev/disk.h>
+#include <sys/loadable_fs.h>
+#include <hfs/hfs_format.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <architecture/byte_order.h>
+
+//
+// Secret HFS sysctl's to instruct it to turn
+// journaling on/off for a volume.
+//
+#define HFS_BECOME_JOURNALED   0x082969
+#define HFS_BECOME_UNJOURNALED 0x031272
+
+
+/* getattrlist buffers start with an extra length field */
+struct ExtentsAttrBuf {
+       unsigned long   infoLength;
+       HFSPlusExtentRecord     extents;
+};
+typedef struct ExtentsAttrBuf ExtentsAttrBuf;
+
+
+
+#define kIsInvisible 0x4000
+
+/*
+ * Generic Finder file/dir data
+ */
+struct FinderInfo {
+       u_int32_t       opaque_1[2];
+       u_int16_t       fdFlags;        /* Finder flags */
+       int16_t         opaque_2[11];
+};
+typedef struct FinderInfo FinderInfo;
+
+/* getattrlist buffers start with an extra length field */
+struct FinderAttrBuf {
+       unsigned long   infoLength;
+       FinderInfo      finderInfo;
+};
+typedef struct FinderAttrBuf FinderAttrBuf;
+
+
+int hide_file(const char * file)
+{
+    struct attrlist alist = {0};
+    FinderAttrBuf finderInfoBuf = {0};
+    int result;
+    
+    alist.bitmapcount = ATTR_BIT_MAP_COUNT;
+    alist.commonattr = ATTR_CMN_FNDRINFO;
+
+    result = getattrlist(file, &alist, &finderInfoBuf, sizeof(finderInfoBuf), 0);
+    if (result) {
+               return (errno);
+       }
+       
+    if (finderInfoBuf.finderInfo.fdFlags & kIsInvisible) {
+               printf("hide: %s is alreadly invisible\n", file);
+               return (0);
+    }
+
+    finderInfoBuf.finderInfo.fdFlags |= kIsInvisible;
+
+    result = setattrlist(file, &alist, &finderInfoBuf.finderInfo, sizeof(FinderInfo), 0);
+    
+    return (result == -1 ? errno : result);
+}
+
+int
+get_start_block(const char *file)
+{
+    struct attrlist alist = {0};
+    ExtentsAttrBuf extentsbuf = {0};
+
+    alist.bitmapcount = ATTR_BIT_MAP_COUNT;
+    alist.fileattr = ATTR_FILE_DATAEXTENTS;
+
+    if (getattrlist(file, &alist, &extentsbuf, sizeof(extentsbuf), 0)) {
+               fprintf(stderr, "could not get attrlist for %s (%s)", file, strerror(errno));
+               return -1;
+    }
+
+    if (extentsbuf.extents[1].startBlock != 0) {
+               fprintf(stderr, "Journal File not contiguous!\n");
+               return -1;
+    }
+
+    return extentsbuf.extents[0].startBlock;
+}
+
+static const char *journal_fname = ".journal";
+static const char *jib_fname = ".journal_info_block";
+
+int
+DoMakeJournaled(char *volname, int jsize)
+{
+    int              fd, i, block_size, journal_size = 8*1024*1024;
+    char            *buf;
+    int              ret;
+    fstore_t         fst;
+    int              jstart_block, jinfo_block, sysctl_info[8];
+    JournalInfoBlock jib;
+       struct statfs    sfs;
+       static char      tmpname[MAXPATHLEN];
+
+       if (jsize != 0) {
+               journal_size = jsize;
+       }
+
+       if (statfs(volname, &sfs) != 0) {
+               fprintf(stderr, "Can't stat volume %s (%s).\n", volname, strerror(errno));
+               return 10;
+       }
+
+       // Make sure that we're HFS+.  First we check the fstypename.
+       // If that's ok then we try to create a symlink (which won't
+       // work on plain hfs volumes but will work on hfs+ volumes).
+       //
+       sprintf(tmpname, "%s/is_vol_hfs_plus", volname);
+       if (strcmp(sfs.f_fstypename, "hfs") != 0 ||
+               ((ret = symlink(tmpname, tmpname)) != 0 && errno == ENOTSUP)) {
+               fprintf(stderr, "%s is not an HFS+ volume.  Journaling only works on HFS+ volumes.\n",
+                               volname);
+               return 10;
+       }
+       unlink(tmpname);
+
+       if (sfs.f_flags & MNT_JOURNALED) {
+               fprintf(stderr, "Volume %s is already journaled.\n", volname);
+               return 1;
+       }
+
+    if (chdir(volname) != 0) {
+               fprintf(stderr, "Can't locate volume %s to make it journaled (%s).\n",
+                               volname, strerror(errno));
+               return 10;
+       }
+
+    fd = open(journal_fname, O_CREAT|O_TRUNC|O_RDWR, 000);
+    if (fd < 0) {
+               fprintf(stderr, "Can't create journal file on volume %s (%s)\n",
+                               volname, strerror(errno));
+               return 5;
+    }
+
+       // make sure that it has no r/w/x privs (only could happen if
+       // the file already existed since open() doesn't reset the mode
+       // bits).
+       //
+       fchmod(fd, 0);
+
+    block_size = sfs.f_bsize;
+    if ((journal_size % block_size) != 0) {
+               fprintf(stderr, "Journal size %dk is not a multiple of volume %s block size (%d).\n",
+                               journal_size/1024, volname, block_size);
+               close(fd);
+               unlink(journal_fname);
+               return 5;
+    }
+
+    memset(&fst, 0, sizeof(fst));
+    fst.fst_flags   = F_ALLOCATECONTIG|F_ALLOCATEALL;
+    fst.fst_length  = journal_size;
+    fst.fst_posmode = F_PEOFPOSMODE;
+    
+    ret = fcntl(fd, F_PREALLOCATE, &fst);
+    if (ret < 0) {
+               fprintf(stderr, "Pre-allocating the journal file failed on volume %s (%s)\n",
+                               volname, strerror(errno));
+               fprintf(stderr, "Try using a smaller (%d k) journal size\n", journal_size/2/1024);
+               close(fd);
+               unlink(journal_fname);
+               return 10;
+    }
+
+    printf("Allocated %lldK for journal file.\n", fst.fst_bytesalloc/1024LL);
+    buf = (char *)calloc(block_size, 1);
+    if (buf) {
+               for(i=0; i < journal_size/block_size; i++) {
+                       ret = write(fd, buf, block_size);
+                       if (ret != block_size) {
+                               break;
+                       }
+               }
+               
+               if (i*block_size != journal_size) {
+                       fprintf(stderr, "Failed to write %dk to journal on volume %s (%s)\n",
+                                       journal_size/1024, volname, strerror(errno));
+               }
+    } else {
+               printf("Could not allocate memory to write to the journal on volume %s (%s)\n",
+                          volname, strerror(errno));
+    }
+
+    fsync(fd);
+    close(fd);
+    hide_file(journal_fname);
+
+    jstart_block = get_start_block(journal_fname);
+
+    memset(&jib, 0, sizeof(jib));
+    jib.flags  = kJIJournalInFSMask;
+    jib.offset = (off_t)jstart_block * (off_t)block_size;
+    jib.size   = (off_t)journal_size;
+
+    fd = open(jib_fname, O_CREAT|O_TRUNC|O_RDWR, 000);
+    if (fd < 0) {
+               fprintf(stderr, "Could not create journal info block file on volume %s (%s)\n",
+                               volname, strerror(errno));
+               unlink(journal_fname);
+               return 5;
+    }
+    
+    memcpy(buf, &jib, sizeof(jib));
+    if (write(fd, buf, block_size) != block_size) {
+               fprintf(stderr, "Failed to write journal info block on volume %s (%s)!\n",
+                               volname, strerror(errno));
+               unlink(journal_fname);
+               return 10;
+    }
+
+    fsync(fd);
+    close(fd);
+    hide_file(jib_fname);
+
+    jinfo_block = get_start_block(jib_fname);
+
+
+    //
+    // Now make the volume journaled!
+    //
+    memset(sysctl_info, 0, sizeof(sysctl_info));
+    sysctl_info[0] = CTL_VFS;
+    sysctl_info[1] = sfs.f_fsid.val[1];
+    sysctl_info[2] = HFS_BECOME_JOURNALED;
+    sysctl_info[3] = jinfo_block;
+    sysctl_info[4] = jstart_block;
+    sysctl_info[5] = journal_size;
+     
+    //printf("fs type: 0x%x\n", sysctl_info[1]);
+    //printf("jinfo block : 0x%x\n", jinfo_block);
+    //printf("jstart block: 0x%x\n", jstart_block);
+    //printf("journal size: 0x%x\n", journal_size);
+
+    ret = sysctl((void *)sysctl_info, 6, NULL, NULL, NULL, 0);
+    if (ret != 0) {
+               fprintf(stderr, "Failed to make volume %s journaled (%s)\n",
+                               volname, strerror(errno));
+               unlink(journal_fname);
+               unlink(jib_fname);
+               return 20;
+    }
+
+       return 0;
+}
+
+
+int
+DoUnJournal(char *volname)
+{
+       int           result;
+    int           sysctl_info[8];
+       struct statfs sfs;
+       char          jbuf[MAXPATHLEN];
+       
+       if (statfs(volname, &sfs) != 0) {
+               fprintf(stderr, "Can't stat volume %s (%s).\n", volname, strerror(errno));
+               return 10;
+       }
+
+       if ((sfs.f_flags & MNT_JOURNALED) == 0) {
+               fprintf(stderr, "Volume %s is not journaled.\n", volname);
+               return 1;
+       }
+
+       if (chdir(volname) != 0) {
+               fprintf(stderr, "Can't locate volume %s to turn off journaling (%s).\n",
+                               volname, strerror(errno));
+               return 10;
+       }
+       
+       memset(sysctl_info, 0, sizeof(sysctl_info));
+       sysctl_info[0] = CTL_VFS;
+       sysctl_info[1] = sfs.f_fsid.val[1];
+       sysctl_info[2] = HFS_BECOME_UNJOURNALED;
+       
+       result = sysctl((void *)sysctl_info, 6, NULL, NULL, NULL, 0);
+       if (result != 0) {
+               fprintf(stderr, "Failed to make volume %s UN-journaled (%s)\n",
+                               volname, strerror(errno));
+               return 20;
+       }
+
+       sprintf(jbuf, "%s/%s", volname, journal_fname);
+       if (unlink(jbuf) != 0) {
+               fprintf(stderr, "Failed to remove the journal %s (%s)\n",
+                               jbuf, strerror(errno));
+       }
+
+       sprintf(jbuf, "%s/%s", volname, jib_fname);
+       if (unlink(jbuf) != 0) {
+               fprintf(stderr, "Failed to remove the journal info block %s (%s)\n",
+                               jbuf, strerror(errno));
+       }
+
+       printf("Journaling disabled on %s\n", volname);
+           
+       return 0;
+}
index a9f2f355bc643dcecc7759a23a8d260fd198883c..e500d0602e84b0dc8f36302870909142b4d3bcfd 100644 (file)
@@ -52,6 +52,7 @@
 #include <sys/loadable_fs.h>
 #include <hfs/hfs_format.h>
 
 #include <sys/loadable_fs.h>
 #include <hfs/hfs_format.h>
 
+#include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <pwd.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <pwd.h>
 #define FSUC_SETUUID 's'
 #endif
 
 #define FSUC_SETUUID 's'
 #endif
 
+#ifndef FSUC_MKJNL
+#define FSUC_MKJNL   'J'
+#endif
+
+#ifndef FSUC_UNJNL
+#define FSUC_UNJNL   'U'
+#endif
 
 
 /* **************************************** L O C A L S ******************************************* */
 
 
 /* **************************************** L O C A L S ******************************************* */
@@ -113,6 +121,8 @@ char gIgnorePermissionsOption[] = "noperm";
 
 boolean_t gIsEjectable = 0;
 
 
 boolean_t gIsEjectable = 0;
 
+int gJournalSize = 0;
+
 #define AUTO_ADOPT_FIXED 1
 #define AUTO_ENTER_FIXED 0
 
 #define AUTO_ADOPT_FIXED 1
 #define AUTO_ENTER_FIXED 0
 
@@ -154,6 +164,10 @@ static int DoGetUUIDKey( const char * theDeviceNamePtr );
 static int     DoChangeUUIDKey( const char * theDeviceNamePtr );
 static int     DoAdopt( const char * theDeviceNamePtr );
 static int     DoDisown( const char * theDeviceNamePtr );
 static int     DoChangeUUIDKey( const char * theDeviceNamePtr );
 static int     DoAdopt( const char * theDeviceNamePtr );
 static int     DoDisown( const char * theDeviceNamePtr );
+
+extern int  DoMakeJournaled( const char * volNamePtr, int journalSize );  // XXXdbg
+extern int  DoUnJournal( const char * volNamePtr );      // XXXdbg
+
 static int     ParseArgs( int argc, const char * argv[], const char ** actionPtr, const char ** mountPointPtr, boolean_t * isEjectablePtr, boolean_t * isLockedPtr, boolean_t * isSetuidPtr, boolean_t * isDevPtr );
 
 static int     GetVolumeUUID(const char *deviceNamePtr, VolumeUUID *volumeUUIDPtr, boolean_t generate);
 static int     ParseArgs( int argc, const char * argv[], const char ** actionPtr, const char ** mountPointPtr, boolean_t * isEjectablePtr, boolean_t * isLockedPtr, boolean_t * isSetuidPtr, boolean_t * isDevPtr );
 
 static int     GetVolumeUUID(const char *deviceNamePtr, VolumeUUID *volumeUUIDPtr, boolean_t generate);
@@ -245,6 +259,7 @@ int main (int argc, const char *argv[])
 
     result = seteuid( 0 );
     if ( result ) {
 
     result = seteuid( 0 );
     if ( result ) {
+               fprintf(stderr, "You must be root to run %s.\n", argv[0]);
         result = FSUR_INVAL;
         goto AllDone;
     }
         result = FSUR_INVAL;
         goto AllDone;
     }
@@ -278,6 +293,18 @@ int main (int argc, const char *argv[])
                case FSUC_DISOWN:
                        result = DoDisown( blockDeviceName );
                        break;
                case FSUC_DISOWN:
                        result = DoDisown( blockDeviceName );
                        break;
+
+               case FSUC_MKJNL:
+                       if (gJournalSize) {
+                               result = DoMakeJournaled( argv[3], gJournalSize );
+                       } else {
+                               result = DoMakeJournaled( argv[2], gJournalSize );
+                       }
+                       break;
+
+               case FSUC_UNJNL:
+                       result = DoUnJournal( argv[2] );
+                       break;
                        
         default:
             /* should never get here since ParseArgs should handle this situation */
                        
         default:
             /* should never get here since ParseArgs should handle this situation */
@@ -760,6 +787,19 @@ Err_Return:
 }
 
 
 }
 
 
+static int
+get_multiplier(char c)
+{
+       if (tolower(c) == 'k') {
+               return 1024;
+       } else if (tolower(c) == 'm') {
+               return 1024 * 1024;
+       } else if (tolower(c) == 'g') {
+               return 1024 * 1024 * 1024;
+       } 
+
+       return 1;
+}
 
 /* **************************************** ParseArgs ********************************************
 Purpose -
 
 /* **************************************** ParseArgs ********************************************
 Purpose -
@@ -805,7 +845,7 @@ ParseArgs(int argc, const char *argv[], const char ** actionPtr,
           boolean_t * isLockedPtr, boolean_t * isSetuidPtr, boolean_t * isDevPtr)
 {
     int                        result = FSUR_INVAL;
           boolean_t * isLockedPtr, boolean_t * isSetuidPtr, boolean_t * isDevPtr)
 {
     int                        result = FSUR_INVAL;
-    int                        deviceLength;
+    int                        deviceLength, doLengthCheck = 1;
     int                        index;
     int                mounting = 0;
 
     int                        index;
     int                mounting = 0;
 
@@ -865,6 +905,26 @@ ParseArgs(int argc, const char *argv[], const char ** actionPtr,
                        index = 0;
                        break;
                
                        index = 0;
                        break;
                
+               // XXXdbg
+               case FSUC_MKJNL:
+                       index = 0;
+                       doLengthCheck = 0;
+                       if (isdigit(argv[2][0])) {
+                               char *ptr;
+                               gJournalSize = strtoul(argv[2], &ptr, 0);
+                               if (ptr) {
+                                       gJournalSize *= get_multiplier(*ptr);
+                               }
+                               return 0;
+                       }
+                       break;
+
+               case FSUC_UNJNL:
+                       index = 0;
+                       doLengthCheck = 0;
+                       break;
+               // XXXdbg
+
         default:
             DoDisplayUsage( argv );
             goto Return;
         default:
             DoDisplayUsage( argv );
             goto Return;
@@ -873,7 +933,7 @@ ParseArgs(int argc, const char *argv[], const char ** actionPtr,
 
     /* Make sure device (argv[2]) is something reasonable */
     deviceLength = strlen( argv[2] );
 
     /* Make sure device (argv[2]) is something reasonable */
     deviceLength = strlen( argv[2] );
-    if ( deviceLength < 3 || deviceLength > NAME_MAX ) {
+    if ( doLengthCheck && (deviceLength < 3 || deviceLength > NAME_MAX) ) {
         DoDisplayUsage( argv );
         goto Return;
     }
         DoDisplayUsage( argv );
         goto Return;
     }
@@ -950,8 +1010,12 @@ DoDisplayUsage(const char *argv[])
     printf("       -%c (Set UUID Key)\n", FSUC_SETUUID);
 #endif HFS_UUID_SUPPORT
     printf("       -%c (Adopt permissions)\n", FSUC_ADOPT);
     printf("       -%c (Set UUID Key)\n", FSUC_SETUUID);
 #endif HFS_UUID_SUPPORT
     printf("       -%c (Adopt permissions)\n", FSUC_ADOPT);
+       printf("       -%c (Make a volume journaled)\n", FSUC_MKJNL);
+       printf("       -%c (Turn off journaling on a volume)\n", FSUC_UNJNL);
     printf("device_arg:\n");
     printf("       device we are acting upon (for example, 'disk0s2')\n");
     printf("device_arg:\n");
     printf("       device we are acting upon (for example, 'disk0s2')\n");
+    printf("       if '-%c' or '-%c' is specified, this should be the\n", FSUC_MKJNL, FSUC_UNJNL);
+       printf("       name of the volume we to act on (for example, '/Volumes/foo' or '/')\n");
     printf("mount_point_arg:\n");
     printf("       required for Mount and Force Mount \n");
     printf("Flags:\n");
     printf("mount_point_arg:\n");
     printf("       required for Mount and Force Mount \n");
     printf("Flags:\n");