]> arthur.barton.de Git - netatalk.git/commitdiff
move of_findname key from filename to dev, inode.
authordidg <didg>
Wed, 4 Sep 2002 17:28:08 +0000 (17:28 +0000)
committerdidg <didg>
Wed, 4 Sep 2002 17:28:08 +0000 (17:28 +0000)
etc/afpd/desktop.c
etc/afpd/file.c
etc/afpd/filedir.c
etc/afpd/fork.c
etc/afpd/fork.h
etc/afpd/ofork.c

index 864cf26aa66cd478c5ece445031654120be9df79..e3f138b70b858d171b2eaf83ba846d753dc3caba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: desktop.c,v 1.13 2002-05-29 18:02:59 jmarcus Exp $
+ * $Id: desktop.c,v 1.14 2002-09-04 17:28:08 didg Exp $
  *
  * See COPYRIGHT.
  */
@@ -717,7 +717,7 @@ int         ibuflen, *rbuflen;
     struct vol         *vol;
     struct dir         *dir;
     struct ofork        *of;
-    char               *path, *name;
+    char               *path, *name, *upath;
     int                        clen;
     u_int32_t           did;
     u_int16_t          vid;
@@ -747,13 +747,13 @@ int               ibuflen, *rbuflen;
 
     clen = (u_char)*ibuf++;
     clen = min( clen, 199 );
-
-    if ((*path == '\0') || !(of = of_findname(vol, curdir, path))) {
+    upath = mtoupath( vol, path );
+    if ((*path == '\0') || !(of = of_findname(vol, curdir, upath, NULL))) {
         memset(&ad, 0, sizeof(ad));
         adp = &ad;
     } else
         adp = of->of_ad;
-    if (ad_open( mtoupath( vol, path ), vol_noadouble(vol) |
+    if (ad_open( upath , vol_noadouble(vol) |
                  (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
                  O_RDWR|O_CREAT, 0666, adp) < 0 ) {
         return( AFPERR_ACCESS );
@@ -786,7 +786,7 @@ int         ibuflen, *rbuflen;
     struct vol         *vol;
     struct dir         *dir;
     struct ofork        *of;
-    char               *path;
+    char               *path, *upath;
     u_int32_t          did;
     u_int16_t          vid;
 
@@ -809,12 +809,14 @@ int               ibuflen, *rbuflen;
         return( AFPERR_NOOBJ );
     }
 
-    if ((*path == '\0') || !(of = of_findname(vol, curdir, path))) {
+
+    upath = mtoupath( vol, path );
+    if ((*path == '\0') || !(of = of_findname(vol, curdir, upath, NULL))) {
         memset(&ad, 0, sizeof(ad));
         adp = &ad;
     } else
         adp = of->of_ad;
-    if ( ad_open( mtoupath( vol, path ),
+    if ( ad_open( upath,
                   (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
                   O_RDONLY, 0666, adp) < 0 ) {
         return( AFPERR_NOITEM );
@@ -846,7 +848,7 @@ int         ibuflen, *rbuflen;
     struct vol         *vol;
     struct dir         *dir;
     struct ofork        *of;
-    char               *path;
+    char               *path, *upath;
     u_int32_t          did;
     u_int16_t          vid;
 
@@ -869,12 +871,14 @@ int               ibuflen, *rbuflen;
         return( AFPERR_NOOBJ );
     }
 
-    if ((*path == '\0') || !(of = of_findname(vol, curdir, path))) {
+    upath = mtoupath( vol, path );
+    if ((*path == '\0') || !(of = of_findname(vol, curdir, upath, NULL))) {
         memset(&ad, 0, sizeof(ad));
         adp = &ad;
     } else
         adp = of->of_ad;
-    if ( ad_open( mtoupath( vol, path ),
+
+    if ( ad_open( upath,
                   (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
                   O_RDWR, 0, adp) < 0 ) {
         switch ( errno ) {
index 6b5664a4260732beb892b80f2e6940bfb05f3917..85ab9e9a6f5706d6a3bf2a80c6acda2caabde312 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.53 2002-08-30 19:32:41 didg Exp $
+ * $Id: file.c,v 1.54 2002-09-04 17:28:08 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -374,7 +374,7 @@ int getfilparams(struct vol *vol,
 #endif /* DEBUG */
 
     upath = mtoupath(vol, path);
-    if ((of = of_findname(vol, dir, path))) {
+    if ((of = of_findname(vol, dir, upath, st))) {
         adp = of->of_ad;
        attrbits = ((of->of_ad->ad_df.adf_refcount > 0) ? ATTRBIT_DOPEN : 0);
        attrbits |= ((of->of_ad->ad_hf.adf_refcount > of->of_ad->ad_df.adf_refcount)? ATTRBIT_ROPEN : 0);
@@ -428,7 +428,7 @@ int         ibuflen, *rbuflen;
     char               *path, *upath;
     int                        creatf, did, openf, retvalue = AFP_OK;
     u_int16_t          vid;
-
+    int                 ret;
 #ifdef DEBUG
     LOG(log_info, logtype_afpd, "begin afp_createfile:");
 #endif /* DEBUG */
@@ -459,13 +459,12 @@ int               ibuflen, *rbuflen;
     }
 
     upath = mtoupath(vol, path);
-    {
-    int ret;
-        if (0 != (ret = check_name(vol, upath))) 
-            return  ret;
-    }
+    if (0 != (ret = check_name(vol, upath))) 
+       return  ret;
 
-    if ((of = of_findname(vol, curdir, path))) {
+    ret = stat(upath, &st);
+    /* if upath is deleted we already in trouble anyway */
+    if (!ret && (of = of_findname(vol, curdir, upath, &st))) {
         adp = of->of_ad;
     } else {
         memset(&ad, 0, sizeof(ad));
@@ -473,11 +472,11 @@ int               ibuflen, *rbuflen;
     }
     if ( creatf) {
         /* on a hard create, fail if file exists and is open */
-        if ((stat(upath, &st) == 0) && of)
+        if (!ret && of)
             return AFPERR_BUSY;
         openf = O_RDWR|O_CREAT|O_TRUNC;
     } else {
-       /* on a soft create, if the file is open then ad_open won't failed 
+       /* on a soft create, if the file is open then ad_open won't fail
           because open syscall is not called
        */
        if (of) {
@@ -615,7 +614,7 @@ int setfilparams(struct vol *vol,
 #endif /* DEBUG */
 
     upath = mtoupath(vol, path);
-    if ((of = of_findname(vol, curdir, path))) {
+    if ((of = of_findname(vol, curdir, upath, NULL))) {
         adp = of->of_ad;
     } else {
         memset(&ad, 0, sizeof(ad));
@@ -892,7 +891,7 @@ int         ibuflen, *rbuflen;
 {
     struct vol *vol;
     struct dir *dir;
-    char       *newname, *path, *p;
+    char       *newname, *path, *p, *upath;
     u_int32_t  sdid, ddid;
     int                plen, err, retvalue = AFP_OK;
     u_int16_t  svid, dvid;
@@ -933,7 +932,9 @@ int         ibuflen, *rbuflen;
      *      however, copyfile doesn't have any of that info,
      *      and locks need to stay coherent. as a result,
      *      we just balk if the file is opened already. */
-    if (of_findname(vol, curdir, path))
+
+    upath = mtoupath(vol, newname );
+    if (of_findname(vol, curdir, upath, NULL))
         return AFPERR_DENYCONF;
 
     newname = obj->newtmp;
@@ -976,7 +977,7 @@ int         ibuflen, *rbuflen;
         }
     }
 
-    if ( (err = copyfile(p, mtoupath(vol, newname ), newname,
+    if ( (err = copyfile(p, upath, newname,
                          vol_noadouble(vol))) < 0 ) {
         return err;
     }
@@ -1641,7 +1642,8 @@ int               ibuflen, *rbuflen;
     struct adouble     add;
     struct adouble     *adsp;
     struct adouble     *addp;
-    struct ofork       *opened;
+    struct ofork       *s_of;
+    struct ofork       *d_of;
     
 #ifdef CNID_DB
     int                 slen, dlen;
@@ -1699,9 +1701,9 @@ int               ibuflen, *rbuflen;
     }
     memset(&ads, 0, sizeof(ads));
     adsp = &ads;
-    if ((opened = of_findname(vol, curdir, path))) {
+    if ((s_of = of_findname(vol, curdir, upath, &srcst))) {
             /* reuse struct adouble so it won't break locks */
-            adsp = opened->of_ad;
+            adsp = s_of->of_ad;
     }
     /* save some stuff */
     sdir = curdir;
@@ -1749,10 +1751,16 @@ int             ibuflen, *rbuflen;
     }
     memset(&add, 0, sizeof(add));
     addp = &add;
-    if ((opened = of_findname(vol, curdir, path))) {
+    if ((d_of = of_findname(vol, curdir, upath, &destst))) {
             /* reuse struct adouble so it won't break locks */
-            addp = opened->of_ad;
+            addp = d_of->of_ad;
     }
+
+    /* they are not on the same device and at least one is open
+    */
+    if ((d_of || s_of)  && srcst.st_dev != destst.st_dev)
+        return AFPERR_MISC;
+    
 #ifdef CNID_DB
     /* look for destination id. */
     did = cnid_lookup(vol->v_db, &destst, curdir->d_did, upath,
@@ -1769,17 +1777,17 @@ int             ibuflen, *rbuflen;
     /* now, quickly rename the file. we error if we can't. */
     if ((err = renamefile(p, temp, temp, vol_noadouble(vol), adsp)) < 0)
         goto err_exchangefile;
-    of_rename(vol, sdir, spath, curdir, temp);
+    of_rename(vol, s_of, sdir, spath, curdir, temp);
 
     /* rename destination to source */
     if ((err = renamefile(upath, p, spath, vol_noadouble(vol), addp)) < 0)
         goto err_src_to_tmp;
-    of_rename(vol, curdir, path, sdir, spath);
+    of_rename(vol, d_of, curdir, path, sdir, spath);
 
     /* rename temp to destination */
     if ((err = renamefile(temp, upath, path, vol_noadouble(vol), adsp)) < 0)
         goto err_dest_to_src;
-    of_rename(vol, curdir, temp, curdir, path);
+    of_rename(vol, s_of, curdir, temp, curdir, path);
 
 #ifdef CNID_DB
     /* id's need switching. src -> dest and dest -> src. */
@@ -1827,17 +1835,17 @@ err_temp_to_dest:
 #endif
     /* rename dest to temp */
     renamefile(upath, temp, temp, vol_noadouble(vol), adsp);
-    of_rename(vol, curdir, upath, curdir, temp);
+    of_rename(vol, s_of, curdir, upath, curdir, temp);
 
 err_dest_to_src:
     /* rename source back to dest */
     renamefile(p, upath, path, vol_noadouble(vol), addp);
-    of_rename(vol, sdir, spath, curdir, path);
+    of_rename(vol, d_of, sdir, spath, curdir, path);
 
 err_src_to_tmp:
     /* rename temp back to source */
     renamefile(temp, p, spath, vol_noadouble(vol), adsp);
-    of_rename(vol, curdir, temp, sdir, spath);
+    of_rename(vol, s_of, curdir, temp, sdir, spath);
 
 err_exchangefile:
     return err;
index 7d690a9fdae4be2a08779ac409dab6e8070dc329..f8a61f5d1983650ad80dcfea33e322a698b01fd3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: filedir.c,v 1.28 2002-08-29 18:57:26 didg Exp $
+ * $Id: filedir.c,v 1.29 2002-09-04 17:28:08 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -384,7 +384,7 @@ int         isdir;
         id = cnid_get(vol->v_db, sdir->d_did, p, strlen(p));
 #endif /* CNID_DB */
         p = ctoupath( vol, sdir, oldname );
-        if ((opened = of_findname(vol, sdir, oldname))) {
+        if ((opened = of_findname(vol, sdir, p, NULL))) {
             /* reuse struct adouble so it won't break locks */
             adp = opened->of_ad;
         }
@@ -429,13 +429,12 @@ int         isdir;
         return AFPERR_EXIST;
 
     if ( !isdir ) {
-        if (of_findname(vol, curdir, newname)) {
+        if (of_findname(vol, curdir, upath, &st)) {
             rc = AFPERR_EXIST; /* was AFPERR_BUSY; */
-        } else if ((rc = renamefile( p, upath, newname,
-                                     vol_noadouble(vol), adp )) == AFP_OK) {
-            /* if it's still open, rename the ofork as well. */
-            rc = of_rename(vol, sdir, oldname, curdir, newname);
-
+        } else {
+            rc = renamefile( p, upath, newname,vol_noadouble(vol), adp );
+            if (rc == AFP_OK)
+                of_rename(vol, opened, sdir, oldname, curdir, newname);
         }
     } else {
         rc = renamedir(p, upath, sdir, curdir, newname, vol_noadouble(vol));
@@ -580,11 +579,12 @@ int               ibuflen, *rbuflen;
         return( AFPERR_NOOBJ );
     }
 
+    upath = mtoupath(vol, path );
     if ( *path == '\0' ) {
         rc = deletecurdir( vol, obj->oldtmp, AFPOBJ_TMPSIZ);
-    } else if (of_findname(vol, curdir, path)) {
+    } else if (of_findname(vol, curdir, upath, NULL)) {
         rc = AFPERR_BUSY;
-    } else if ((rc = deletefile( upath = mtoupath(vol, path ), 1)) == AFP_OK) {
+    } else if ((rc = deletefile( upath, 1)) == AFP_OK) {
 #ifdef CNID_DB /* get rid of entry */
         cnid_t id = cnid_get(vol->v_db, curdir->d_did, upath, strlen(upath));
         cnid_delete(vol->v_db, id);
index 4aaee8680e812dea5616c99d6a6e02d35c5fe8b2..28970c0ad26cd790a93fa4b2215c6cda837e041f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: fork.c,v 1.34 2002-08-29 18:57:26 didg Exp $
+ * $Id: fork.c,v 1.35 2002-09-04 17:28:08 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -235,7 +235,8 @@ int         ibuflen, *rbuflen;
     u_int32_t           did;
     u_int16_t          vid, bitmap, access, ofrefnum, attrbits = 0;
     char               fork, *path, *upath;
-    u_int16_t bshort;
+    struct stat         st;
+    u_int16_t           bshort;
 
     ibuf++;
     fork = *ibuf++;
@@ -281,6 +282,20 @@ int                ibuflen, *rbuflen;
     if (check_access(upath, access ) < 0) {
         return AFPERR_ACCESS;
     }
+
+    /* stat() data fork */
+    if (stat(upath, &st) < 0) {
+        switch ( errno ) {
+        case ENOENT:
+            return AFPERR_NOOBJ;
+        case EACCES:
+            return (access & OPENACC_WR) ? AFPERR_LOCK : AFPERR_ACCESS;
+        default:
+            LOG(log_error, logtype_afpd, "afp_openfork: ad_open: %s", strerror(errno) );
+            return AFPERR_PARAM;
+        }
+    }
+
     /* XXX: this probably isn't the best way to do this. the already
        open bits should really be set if the fork is opened by any
        program, not just this one. however, that's problematic to do
@@ -288,7 +303,7 @@ int         ibuflen, *rbuflen;
        ad_open so that we can keep file locks together.
        FIXME: add the fork we are opening? 
     */
-    if ((opened = of_findname(vol, curdir, path))) {
+    if ((opened = of_findname(vol, curdir, upath, &st))) {
         attrbits = ((opened->of_ad->ad_df.adf_refcount > 0) ? ATTRBIT_DOPEN : 0);
         attrbits |= ((opened->of_ad->ad_hf.adf_refcount > opened->of_ad->ad_df.adf_refcount)? ATTRBIT_ROPEN : 0);
                    
@@ -296,38 +311,30 @@ int               ibuflen, *rbuflen;
     }
 
     if (( ofork = of_alloc(vol, curdir, path, &ofrefnum, eid,
-                           adsame)) == NULL ) {
+                           adsame, &st)) == NULL ) {
         return( AFPERR_NFILE );
     }
 
+    ret = AFPERR_NOOBJ;
     if (access & OPENACC_WR) {
         /* try opening in read-write mode */
-        ret = AFPERR_NOOBJ;
         if (ad_open(upath, adflags, O_RDWR, 0, ofork->of_ad) < 0) {
             switch ( errno ) {
             case EROFS:
                 ret = AFPERR_VLOCK;
             case EACCES:
                 goto openfork_err;
-
                 break;
             case ENOENT:
-                {
-                    struct stat st;
-
-                    /* see if client asked for the data fork */
-                    if (fork == OPENFORK_DATA) {
-                        if (ad_open(upath, ADFLAGS_DF, O_RDWR, 0, ofork->of_ad) < 0) {
-                            goto openfork_err;
-                        }
-                        adflags = ADFLAGS_DF;
-
-                    } else if (stat(upath, &st) == 0) {
-                        /* here's the deal. we only try to create the resource
-                         * fork if the user wants to open it for write acess. */
-                        if (ad_open(upath, adflags, O_RDWR | O_CREAT, 0666, ofork->of_ad) < 0)
-                            goto openfork_err;
-                    } else
+                if (fork == OPENFORK_DATA) {
+                    if (ad_open(upath, ADFLAGS_DF, O_RDWR, 0, ofork->of_ad) < 0) {
+                        goto openfork_err;
+                    }
+                    adflags = ADFLAGS_DF;
+
+                    /* here's the deal. we only try to create the resource
+                    * fork if the user wants to open it for write acess. */
+                    if (ad_open(upath, adflags, O_RDWR | O_CREAT, 0666, ofork->of_ad) < 0)
                         goto openfork_err;
                 }
                 break;
@@ -363,19 +370,12 @@ int               ibuflen, *rbuflen;
                 adflags = ADFLAGS_DF;
                 break;
             case ENOENT:
-                {
-                    struct stat st;
-
-                    /* see if client asked for the data fork */
-                    if (fork == OPENFORK_DATA) {
-                        if (ad_open(upath, ADFLAGS_DF, O_RDONLY, 0, ofork->of_ad) < 0) {
-                            goto openfork_err;
-                        }
-                        adflags = ADFLAGS_DF;
-
-                    } else if (stat(upath, &st) != 0) {
+                /* see if client asked for the data fork */
+                if (fork == OPENFORK_DATA) {
+                    if (ad_open(upath, ADFLAGS_DF, O_RDONLY, 0, ofork->of_ad) < 0) {
                         goto openfork_err;
                     }
+                    adflags = ADFLAGS_DF;
                 }
                 break;
             case EMFILE :
index 90e0ed9c39f17ce5aedaf34563414640acbeebd6..d58389f497141d1ca129ade6f3eef667cec5562c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: fork.h,v 1.3 2001-12-03 05:03:38 jmarcus Exp $
+ * $Id: fork.h,v 1.4 2002-09-04 17:28:08 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
 #include "volume.h"
 #include "directory.h"
 
+struct file_key {
+    dev_t              dev;
+    ino_t              inode;
+};
+
 struct ofork {
     struct adouble     *of_ad;
     struct vol          *of_vol;
     struct dir         *of_dir;
     char               *of_name;
     int                 of_namelen;
+
     u_int16_t           of_refnum;
     int                 of_flags;
+
+    struct file_key     key;
     struct ofork        **prevp, *next;
     struct ofork        *of_d_prev, *of_d_next;
 };
@@ -47,12 +55,15 @@ struct ofork {
 /* in ofork.c */
 extern struct ofork *of_alloc    __P((struct vol *, struct dir *,
                                                       char *, u_int16_t *, const int,
-                                                      struct adouble *));
+                                                      struct adouble *,
+                                                      struct stat *));
 extern void         of_dealloc   __P((struct ofork *));
 extern struct ofork *of_find     __P((const u_int16_t));
 extern struct ofork *of_findname __P((const struct vol *, const struct dir *,
-                                                      const char *));
+                                                      const char *,
+                                                      struct stat *));
 extern int          of_rename    __P((const struct vol *,
+                                          struct ofork *,
                                           struct dir *, const char *,
                                           struct dir *, const char *));
 extern int          of_flush     __P((const struct vol *));
index 1f81bb9cf451c1ec688dee719e6b65d9aa63c497..bbc3aa77885d4a72b3abc412eba192e580b9fda2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: ofork.c,v 1.16 2002-06-17 11:40:11 didg Exp $
+ * $Id: ofork.c,v 1.17 2002-09-04 17:28:08 didg Exp $
  *
  * Copyright (c) 1996 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -24,7 +24,7 @@
 #include "directory.h"
 #include "fork.h"
 
-/* we need to have a hashed list of oforks (by name). just hash
+/* we need to have a hashed list of oforks (by dev inode). just hash
  * by first letter. */
 #define OFORK_HASHSIZE  64
 static struct ofork     *ofork_table[OFORK_HASHSIZE];
@@ -35,21 +35,22 @@ static u_short              lastrefnum = 0;
 
 
 /* OR some of each character for the hash*/
-static __inline__ unsigned long hashfn(const char *name)
+static __inline__ unsigned long hashfn(const struct file_key *key)
 {
     unsigned long i = 0;
-
+#if 0
     while (*name) {
         i = ((i << 4) | (8*sizeof(i) - 4)) ^ *name++;
     }
-    return i & (OFORK_HASHSIZE - 1);
+#endif    
+    return key->inode & (OFORK_HASHSIZE - 1);
 }
 
 static __inline__ void of_hash(struct ofork *of)
 {
     struct ofork **table;
 
-    table = &ofork_table[hashfn(of->of_name)];
+    table = &ofork_table[hashfn(&of->key)];
     if ((of->next = *table) != NULL)
         (*table)->prevp = &of->next;
     *table = of;
@@ -96,20 +97,24 @@ int of_flush(const struct vol *vol)
     return( 0 );
 }
 
-
-int of_rename(vol, olddir, oldpath, newdir, newpath)
+int of_rename(vol, s_of, olddir, oldpath, newdir, newpath)
 const struct vol *vol;
+struct ofork *s_of;
 struct dir *olddir, *newdir;
 const char *oldpath, *newpath;
 {
     struct ofork *of, *next, *d_ofork;
 
-    next = ofork_table[hashfn(oldpath)];
+    if (!s_of)
+        return AFP_OK;
+        
+    next = ofork_table[hashfn(&s_of->key)];
     while ((of = next)) {
         next = next->next; /* so we can unhash and still be all right. */
 
-        if ((vol == of->of_vol) && (olddir == of->of_dir) &&
-                (strcmp(of->of_name, oldpath) == 0)) {
+        if (vol == of->of_vol && olddir == of->of_dir &&
+                s_of->key.dev == of->key.dev && 
+                s_of->key.inode == of->key.inode ) {
             of_unhash(of);
             strncpy( of->of_name, newpath, of->of_namelen);
             of->of_d_prev->of_d_next = of->of_d_next;
@@ -137,13 +142,14 @@ const char *oldpath, *newpath;
 #define min(a,b)       ((a)<(b)?(a):(b))
 
 struct ofork *
-            of_alloc(vol, dir, path, ofrefnum, eid, ad)
-            struct vol          *vol;
-struct dir             *dir;
+            of_alloc(vol, dir, path, ofrefnum, eid, ad, st)
+struct vol      *vol;
+struct dir     *dir;
 char           *path;
-u_int16_t              *ofrefnum;
-const int           eid;
-struct adouble      *ad;
+u_int16_t      *ofrefnum;
+const int       eid;
+struct adouble  *ad;
+struct stat     *st;
 {
     struct ofork        *of, *d_ofork;
     u_int16_t          refnum, of_refnum;
@@ -234,8 +240,7 @@ struct adouble      *ad;
     /* here's the deal: we allocate enough for the standard mac file length.
      * in the future, we'll reallocate in fairly large jumps in case
      * of long unicode names */
-    if (( of->of_name =(char *)malloc(255 + 1)) ==
-            NULL ) {
+    if (( of->of_name =(char *)malloc(255 + 1)) == NULL ) {
         LOG(log_error, logtype_afpd, "of_alloc: malloc: %s", strerror(errno) );
         if (!ad)
             free(of->of_ad);
@@ -246,13 +251,14 @@ struct adouble      *ad;
     strncpy( of->of_name, path, of->of_namelen = 255 + 1);
     *ofrefnum = refnum;
     of->of_refnum = refnum;
-    of_hash(of);
-
+    of->key.dev = st->st_dev;
+    of->key.inode = st->st_ino;
     if (eid == ADEID_DFORK)
         of->of_flags = AFPFORK_DATA;
     else
         of->of_flags = AFPFORK_RSRC;
 
+    of_hash(of);
     return( of );
 }
 
@@ -265,29 +271,34 @@ struct ofork *of_find(const u_int16_t ofrefnum )
 }
 
 /* --------------------------
-   FIXME it doesn't work :-(
-   mac1 open file "test" with simple text 
-   mac2 rename "test" ==> "test1"
-   
-   now of_findname return NULL 
-   
-   
 */
 struct ofork *
-            of_findname(const struct vol *vol, const struct dir *dir, const char *name)
+            of_findname(const struct vol *vol, const struct dir *dir, const char *name,
+            struct stat *st)
 {
     struct ofork *of;
+    struct file_key key;
+    struct stat buffer;
+    char   *p;
+    
+    if (st == NULL) {
+        st = &buffer;
+        if (stat(name, st) < 0)
+            return NULL;
+    }
+    key.dev = st->st_dev;
+    key.inode = st->st_ino;
 
-    for (of = ofork_table[hashfn(name)]; of; of = of->next) {
-        if ((vol == of->of_vol) && (dir == of->of_dir) &&
-                (strcmp(of->of_name, name) == 0))
+    for (of = ofork_table[hashfn(&key)]; of; of = of->next) {
+        if (vol == of->of_vol && dir == of->of_dir &&
+                key.dev == of->key.dev && key.inode == of->key.inode ) {
             return of;
+        }
     }
 
     return NULL;
 }
 
-
 void of_dealloc( of )
 struct ofork   *of;
 {