Index: trunk/Nebulous/lib/Nebulous/Server.pm
===================================================================
--- trunk/Nebulous/lib/Nebulous/Server.pm	(revision 16354)
+++ trunk/Nebulous/lib/Nebulous/Server.pm	(revision 16565)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004  Joshua Hoblitt
 #
-# $Id: Server.pm,v 1.52 2008-02-07 22:18:51 jhoblitt Exp $
+# $Id: Server.pm,v 1.53 2008-02-21 23:20:39 jhoblitt Exp $
 
 package Nebulous::Server;
@@ -13,5 +13,8 @@
 
 use DBI;
+use Digest::SHA1 qw( sha1_hex );
 use File::ExtAttr qw( setfattr );
+use File::Path;
+use File::Spec;
 use Log::Log4perl;
 use Nebulous::Server::Config;
@@ -23,4 +26,6 @@
 
 __PACKAGE__->mk_accessors(qw( log sql config ));
+
+use constant SUBPATH_DEPTH => 3;
 
 sub new {
@@ -1229,12 +1234,16 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
-
-    my ($storage_filename);
-    my ($uri);
-    eval {
-        $storage_filename = $self->_generate_storage_filename($key, $ins_id);
-        # XXX put a hook for directory hashing here
-        $uri = URI::file->new("$vol_path/$storage_filename");
+    my $db  = $self->db;
+
+    my $uri;
+    eval {
+        my $storage_path = $self->_generate_storage_path($key, $vol_path);
+        my $storage_filename = $self->_generate_storage_filename($key, $ins_id);
+        unless (-d $storage_path) {
+            mkpath($storage_path)
+                or die "can't create storage path: $storage_path";
+        }
+        my $fqpn = File::Spec->catfile($storage_path, $storage_filename);
+        $uri = URI::file->new($fqpn);
         $log->debug("generated uri $uri");
         $self->_create_empty_file($uri->file);
@@ -1291,4 +1300,19 @@
 
 
+sub _generate_storage_path
+{
+    my $self = shift;
+
+    my ($key, $vol_path) = @_;
+
+    # taken and modified from Cache::File::cache_file_path()
+    # Copyright (C) 2003-2006 Chris Leishman.  All Rights Reserved.
+    my $shakey = sha1_hex($key);
+    my (@path) = unpack('A2' x SUBPATH_DEPTH, $shakey);
+
+    return File::Spec->catdir($vol_path, @path);
+}
+
+
 sub DESTROY
 {
