linux/fs/hpfs/namei.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/hpfs/namei.c
   3 *
   4 *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
   5 *
   6 *  adding & removing files & directories
   7 */
   8#include <linux/sched.h>
   9#include "hpfs_fn.h"
  10
  11static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
  12{
  13        const char *name = dentry->d_name.name;
  14        unsigned len = dentry->d_name.len;
  15        struct quad_buffer_head qbh0;
  16        struct buffer_head *bh;
  17        struct hpfs_dirent *de;
  18        struct fnode *fnode;
  19        struct dnode *dnode;
  20        struct inode *result;
  21        fnode_secno fno;
  22        dnode_secno dno;
  23        int r;
  24        struct hpfs_dirent dee;
  25        int err;
  26        if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
  27        lock_kernel();
  28        err = -ENOSPC;
  29        fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
  30        if (!fnode)
  31                goto bail;
  32        dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0, 1);
  33        if (!dnode)
  34                goto bail1;
  35        memset(&dee, 0, sizeof dee);
  36        dee.directory = 1;
  37        if (!(mode & 0222)) dee.read_only = 1;
  38        /*dee.archive = 0;*/
  39        dee.hidden = name[0] == '.';
  40        dee.fnode = fno;
  41        dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds());
  42        result = new_inode(dir->i_sb);
  43        if (!result)
  44                goto bail2;
  45        hpfs_init_inode(result);
  46        result->i_ino = fno;
  47        hpfs_i(result)->i_parent_dir = dir->i_ino;
  48        hpfs_i(result)->i_dno = dno;
  49        result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date);
  50        result->i_ctime.tv_nsec = 0; 
  51        result->i_mtime.tv_nsec = 0; 
  52        result->i_atime.tv_nsec = 0; 
  53        hpfs_i(result)->i_ea_size = 0;
  54        result->i_mode |= S_IFDIR;
  55        result->i_op = &hpfs_dir_iops;
  56        result->i_fop = &hpfs_dir_ops;
  57        result->i_blocks = 4;
  58        result->i_size = 2048;
  59        result->i_nlink = 2;
  60        if (dee.read_only)
  61                result->i_mode &= ~0222;
  62
  63        mutex_lock(&hpfs_i(dir)->i_mutex);
  64        r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
  65        if (r == 1)
  66                goto bail3;
  67        if (r == -1) {
  68                err = -EEXIST;
  69                goto bail3;
  70        }
  71        fnode->len = len;
  72        memcpy(fnode->name, name, len > 15 ? 15 : len);
  73        fnode->up = dir->i_ino;
  74        fnode->dirflag = 1;
  75        fnode->btree.n_free_nodes = 7;
  76        fnode->btree.n_used_nodes = 1;
  77        fnode->btree.first_free = 0x14;
  78        fnode->u.external[0].disk_secno = dno;
  79        fnode->u.external[0].file_secno = -1;
  80        dnode->root_dnode = 1;
  81        dnode->up = fno;
  82        de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0);
  83        de->creation_date = de->write_date = de->read_date = gmt_to_local(dir->i_sb, get_seconds());
  84        if (!(mode & 0222)) de->read_only = 1;
  85        de->first = de->directory = 1;
  86        /*de->hidden = de->system = 0;*/
  87        de->fnode = fno;
  88        mark_buffer_dirty(bh);
  89        brelse(bh);
  90        hpfs_mark_4buffers_dirty(&qbh0);
  91        hpfs_brelse4(&qbh0);
  92        inc_nlink(dir);
  93        insert_inode_hash(result);
  94
  95        if (result->i_uid != current->fsuid ||
  96            result->i_gid != current->fsgid ||
  97            result->i_mode != (mode | S_IFDIR)) {
  98                result->i_uid = current->fsuid;
  99                result->i_gid = current->fsgid;
 100                result->i_mode = mode | S_IFDIR;
 101                hpfs_write_inode_nolock(result);
 102        }
 103        d_instantiate(dentry, result);
 104        mutex_unlock(&hpfs_i(dir)->i_mutex);
 105        unlock_kernel();
 106        return 0;
 107bail3:
 108        mutex_unlock(&hpfs_i(dir)->i_mutex);
 109        iput(result);
 110bail2:
 111        hpfs_brelse4(&qbh0);
 112        hpfs_free_dnode(dir->i_sb, dno);
 113bail1:
 114        brelse(bh);
 115        hpfs_free_sectors(dir->i_sb, fno, 1);
 116bail:
 117        unlock_kernel();
 118        return err;
 119}
 120
 121static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
 122{
 123        const char *name = dentry->d_name.name;
 124        unsigned len = dentry->d_name.len;
 125        struct inode *result = NULL;
 126        struct buffer_head *bh;
 127        struct fnode *fnode;
 128        fnode_secno fno;
 129        int r;
 130        struct hpfs_dirent dee;
 131        int err;
 132        if ((err = hpfs_chk_name((char *)name, &len)))
 133                return err==-ENOENT ? -EINVAL : err;
 134        lock_kernel();
 135        err = -ENOSPC;
 136        fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
 137        if (!fnode)
 138                goto bail;
 139        memset(&dee, 0, sizeof dee);
 140        if (!(mode & 0222)) dee.read_only = 1;
 141        dee.archive = 1;
 142        dee.hidden = name[0] == '.';
 143        dee.fnode = fno;
 144        dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds());
 145
 146        result = new_inode(dir->i_sb);
 147        if (!result)
 148                goto bail1;
 149        
 150        hpfs_init_inode(result);
 151        result->i_ino = fno;
 152        result->i_mode |= S_IFREG;
 153        result->i_mode &= ~0111;
 154        result->i_op = &hpfs_file_iops;
 155        result->i_fop = &hpfs_file_ops;
 156        result->i_nlink = 1;
 157        hpfs_decide_conv(result, (char *)name, len);
 158        hpfs_i(result)->i_parent_dir = dir->i_ino;
 159        result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date);
 160        result->i_ctime.tv_nsec = 0;
 161        result->i_mtime.tv_nsec = 0;
 162        result->i_atime.tv_nsec = 0;
 163        hpfs_i(result)->i_ea_size = 0;
 164        if (dee.read_only)
 165                result->i_mode &= ~0222;
 166        result->i_blocks = 1;
 167        result->i_size = 0;
 168        result->i_data.a_ops = &hpfs_aops;
 169        hpfs_i(result)->mmu_private = 0;
 170
 171        mutex_lock(&hpfs_i(dir)->i_mutex);
 172        r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
 173        if (r == 1)
 174                goto bail2;
 175        if (r == -1) {
 176                err = -EEXIST;
 177                goto bail2;
 178        }
 179        fnode->len = len;
 180        memcpy(fnode->name, name, len > 15 ? 15 : len);
 181        fnode->up = dir->i_ino;
 182        mark_buffer_dirty(bh);
 183        brelse(bh);
 184
 185        insert_inode_hash(result);
 186
 187        if (result->i_uid != current->fsuid ||
 188            result->i_gid != current->fsgid ||
 189            result->i_mode != (mode | S_IFREG)) {
 190                result->i_uid = current->fsuid;
 191                result->i_gid = current->fsgid;
 192                result->i_mode = mode | S_IFREG;
 193                hpfs_write_inode_nolock(result);
 194        }
 195        d_instantiate(dentry, result);
 196        mutex_unlock(&hpfs_i(dir)->i_mutex);
 197        unlock_kernel();
 198        return 0;
 199
 200bail2:
 201        mutex_unlock(&hpfs_i(dir)->i_mutex);
 202        iput(result);
 203bail1:
 204        brelse(bh);
 205        hpfs_free_sectors(dir->i_sb, fno, 1);
 206bail:
 207        unlock_kernel();
 208        return err;
 209}
 210
 211static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
 212{
 213        const char *name = dentry->d_name.name;
 214        unsigned len = dentry->d_name.len;
 215        struct buffer_head *bh;
 216        struct fnode *fnode;
 217        fnode_secno fno;
 218        int r;
 219        struct hpfs_dirent dee;
 220        struct inode *result = NULL;
 221        int err;
 222        if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
 223        if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM;
 224        if (!new_valid_dev(rdev))
 225                return -EINVAL;
 226        lock_kernel();
 227        err = -ENOSPC;
 228        fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
 229        if (!fnode)
 230                goto bail;
 231        memset(&dee, 0, sizeof dee);
 232        if (!(mode & 0222)) dee.read_only = 1;
 233        dee.archive = 1;
 234        dee.hidden = name[0] == '.';
 235        dee.fnode = fno;
 236        dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds());
 237
 238        result = new_inode(dir->i_sb);
 239        if (!result)
 240                goto bail1;
 241
 242        hpfs_init_inode(result);
 243        result->i_ino = fno;
 244        hpfs_i(result)->i_parent_dir = dir->i_ino;
 245        result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date);
 246        result->i_ctime.tv_nsec = 0;
 247        result->i_mtime.tv_nsec = 0;
 248        result->i_atime.tv_nsec = 0;
 249        hpfs_i(result)->i_ea_size = 0;
 250        result->i_uid = current->fsuid;
 251        result->i_gid = current->fsgid;
 252        result->i_nlink = 1;
 253        result->i_size = 0;
 254        result->i_blocks = 1;
 255        init_special_inode(result, mode, rdev);
 256
 257        mutex_lock(&hpfs_i(dir)->i_mutex);
 258        r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
 259        if (r == 1)
 260                goto bail2;
 261        if (r == -1) {
 262                err = -EEXIST;
 263                goto bail2;
 264        }
 265        fnode->len = len;
 266        memcpy(fnode->name, name, len > 15 ? 15 : len);
 267        fnode->up = dir->i_ino;
 268        mark_buffer_dirty(bh);
 269
 270        insert_inode_hash(result);
 271
 272        hpfs_write_inode_nolock(result);
 273        d_instantiate(dentry, result);
 274        mutex_unlock(&hpfs_i(dir)->i_mutex);
 275        brelse(bh);
 276        unlock_kernel();
 277        return 0;
 278bail2:
 279        mutex_unlock(&hpfs_i(dir)->i_mutex);
 280        iput(result);
 281bail1:
 282        brelse(bh);
 283        hpfs_free_sectors(dir->i_sb, fno, 1);
 284bail:
 285        unlock_kernel();
 286        return err;
 287}
 288
 289static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *symlink)
 290{
 291        const char *name = dentry->d_name.name;
 292        unsigned len = dentry->d_name.len;
 293        struct buffer_head *bh;
 294        struct fnode *fnode;
 295        fnode_secno fno;
 296        int r;
 297        struct hpfs_dirent dee;
 298        struct inode *result;
 299        int err;
 300        if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
 301        lock_kernel();
 302        if (hpfs_sb(dir->i_sb)->sb_eas < 2) {
 303                unlock_kernel();
 304                return -EPERM;
 305        }
 306        err = -ENOSPC;
 307        fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
 308        if (!fnode)
 309                goto bail;
 310        memset(&dee, 0, sizeof dee);
 311        dee.archive = 1;
 312        dee.hidden = name[0] == '.';
 313        dee.fnode = fno;
 314        dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds());
 315
 316        result = new_inode(dir->i_sb);
 317        if (!result)
 318                goto bail1;
 319        result->i_ino = fno;
 320        hpfs_init_inode(result);
 321        hpfs_i(result)->i_parent_dir = dir->i_ino;
 322        result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date);
 323        result->i_ctime.tv_nsec = 0;
 324        result->i_mtime.tv_nsec = 0;
 325        result->i_atime.tv_nsec = 0;
 326        hpfs_i(result)->i_ea_size = 0;
 327        result->i_mode = S_IFLNK | 0777;
 328        result->i_uid = current->fsuid;
 329        result->i_gid = current->fsgid;
 330        result->i_blocks = 1;
 331        result->i_nlink = 1;
 332        result->i_size = strlen(symlink);
 333        result->i_op = &page_symlink_inode_operations;
 334        result->i_data.a_ops = &hpfs_symlink_aops;
 335
 336        mutex_lock(&hpfs_i(dir)->i_mutex);
 337        r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
 338        if (r == 1)
 339                goto bail2;
 340        if (r == -1) {
 341                err = -EEXIST;
 342                goto bail2;
 343        }
 344        fnode->len = len;
 345        memcpy(fnode->name, name, len > 15 ? 15 : len);
 346        fnode->up = dir->i_ino;
 347        hpfs_set_ea(result, fnode, "SYMLINK", (char *)symlink, strlen(symlink));
 348        mark_buffer_dirty(bh);
 349        brelse(bh);
 350
 351        insert_inode_hash(result);
 352
 353        hpfs_write_inode_nolock(result);
 354        d_instantiate(dentry, result);
 355        mutex_unlock(&hpfs_i(dir)->i_mutex);
 356        unlock_kernel();
 357        return 0;
 358bail2:
 359        mutex_unlock(&hpfs_i(dir)->i_mutex);
 360        iput(result);
 361bail1:
 362        brelse(bh);
 363        hpfs_free_sectors(dir->i_sb, fno, 1);
 364bail:
 365        unlock_kernel();
 366        return err;
 367}
 368
 369static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
 370{
 371        const char *name = dentry->d_name.name;
 372        unsigned len = dentry->d_name.len;
 373        struct quad_buffer_head qbh;
 374        struct hpfs_dirent *de;
 375        struct inode *inode = dentry->d_inode;
 376        dnode_secno dno;
 377        fnode_secno fno;
 378        int r;
 379        int rep = 0;
 380        int err;
 381
 382        lock_kernel();
 383        hpfs_adjust_length((char *)name, &len);
 384again:
 385        mutex_lock(&hpfs_i(inode)->i_parent_mutex);
 386        mutex_lock(&hpfs_i(dir)->i_mutex);
 387        err = -ENOENT;
 388        de = map_dirent(dir, hpfs_i(dir)->i_dno, (char *)name, len, &dno, &qbh);
 389        if (!de)
 390                goto out;
 391
 392        err = -EPERM;
 393        if (de->first)
 394                goto out1;
 395
 396        err = -EISDIR;
 397        if (de->directory)
 398                goto out1;
 399
 400        fno = de->fnode;
 401        r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
 402        switch (r) {
 403        case 1:
 404                hpfs_error(dir->i_sb, "there was error when removing dirent");
 405                err = -EFSERROR;
 406                break;
 407        case 2:         /* no space for deleting, try to truncate file */
 408
 409                err = -ENOSPC;
 410                if (rep++)
 411                        break;
 412
 413                mutex_unlock(&hpfs_i(dir)->i_mutex);
 414                mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
 415                d_drop(dentry);
 416                spin_lock(&dentry->d_lock);
 417                if (atomic_read(&dentry->d_count) > 1 ||
 418                    permission(inode, MAY_WRITE, NULL) ||
 419                    !S_ISREG(inode->i_mode) ||
 420                    get_write_access(inode)) {
 421                        spin_unlock(&dentry->d_lock);
 422                        d_rehash(dentry);
 423                } else {
 424                        struct iattr newattrs;
 425                        spin_unlock(&dentry->d_lock);
 426                        /*printk("HPFS: truncating file before delete.\n");*/
 427                        newattrs.ia_size = 0;
 428                        newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
 429                        err = notify_change(dentry, &newattrs);
 430                        put_write_access(inode);
 431                        if (!err)
 432                                goto again;
 433                }
 434                unlock_kernel();
 435                return -ENOSPC;
 436        default:
 437                drop_nlink(inode);
 438                err = 0;
 439        }
 440        goto out;
 441
 442out1:
 443        hpfs_brelse4(&qbh);
 444out:
 445        mutex_unlock(&hpfs_i(dir)->i_mutex);
 446        mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
 447        unlock_kernel();
 448        return err;
 449}
 450
 451static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
 452{
 453        const char *name = dentry->d_name.name;
 454        unsigned len = dentry->d_name.len;
 455        struct quad_buffer_head qbh;
 456        struct hpfs_dirent *de;
 457        struct inode *inode = dentry->d_inode;
 458        dnode_secno dno;
 459        fnode_secno fno;
 460        int n_items = 0;
 461        int err;
 462        int r;
 463
 464        hpfs_adjust_length((char *)name, &len);
 465        lock_kernel();
 466        mutex_lock(&hpfs_i(inode)->i_parent_mutex);
 467        mutex_lock(&hpfs_i(dir)->i_mutex);
 468        err = -ENOENT;
 469        de = map_dirent(dir, hpfs_i(dir)->i_dno, (char *)name, len, &dno, &qbh);
 470        if (!de)
 471                goto out;
 472
 473        err = -EPERM;
 474        if (de->first)
 475                goto out1;
 476
 477        err = -ENOTDIR;
 478        if (!de->directory)
 479                goto out1;
 480
 481        hpfs_count_dnodes(dir->i_sb, hpfs_i(inode)->i_dno, NULL, NULL, &n_items);
 482        err = -ENOTEMPTY;
 483        if (n_items)
 484                goto out1;
 485
 486        fno = de->fnode;
 487        r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
 488        switch (r) {
 489        case 1:
 490                hpfs_error(dir->i_sb, "there was error when removing dirent");
 491                err = -EFSERROR;
 492                break;
 493        case 2:
 494                err = -ENOSPC;
 495                break;
 496        default:
 497                drop_nlink(dir);
 498                clear_nlink(inode);
 499                err = 0;
 500        }
 501        goto out;
 502out1:
 503        hpfs_brelse4(&qbh);
 504out:
 505        mutex_unlock(&hpfs_i(dir)->i_mutex);
 506        mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
 507        unlock_kernel();
 508        return err;
 509}
 510
 511static int hpfs_symlink_readpage(struct file *file, struct page *page)
 512{
 513        char *link = kmap(page);
 514        struct inode *i = page->mapping->host;
 515        struct fnode *fnode;
 516        struct buffer_head *bh;
 517        int err;
 518
 519        err = -EIO;
 520        lock_kernel();
 521        if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh)))
 522                goto fail;
 523        err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE);
 524        brelse(bh);
 525        if (err)
 526                goto fail;
 527        unlock_kernel();
 528        SetPageUptodate(page);
 529        kunmap(page);
 530        unlock_page(page);
 531        return 0;
 532
 533fail:
 534        unlock_kernel();
 535        SetPageError(page);
 536        kunmap(page);
 537        unlock_page(page);
 538        return err;
 539}
 540
 541const struct address_space_operations hpfs_symlink_aops = {
 542        .readpage       = hpfs_symlink_readpage
 543};
 544        
 545static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 546                struct inode *new_dir, struct dentry *new_dentry)
 547{
 548        char *old_name = (char *)old_dentry->d_name.name;
 549        int old_len = old_dentry->d_name.len;
 550        char *new_name = (char *)new_dentry->d_name.name;
 551        int new_len = new_dentry->d_name.len;
 552        struct inode *i = old_dentry->d_inode;
 553        struct inode *new_inode = new_dentry->d_inode;
 554        struct quad_buffer_head qbh, qbh1;
 555        struct hpfs_dirent *dep, *nde;
 556        struct hpfs_dirent de;
 557        dnode_secno dno;
 558        int r;
 559        struct buffer_head *bh;
 560        struct fnode *fnode;
 561        int err;
 562        if ((err = hpfs_chk_name((char *)new_name, &new_len))) return err;
 563        err = 0;
 564        hpfs_adjust_length((char *)old_name, &old_len);
 565
 566        lock_kernel();
 567        /* order doesn't matter, due to VFS exclusion */
 568        mutex_lock(&hpfs_i(i)->i_parent_mutex);
 569        if (new_inode)
 570                mutex_lock(&hpfs_i(new_inode)->i_parent_mutex);
 571        mutex_lock(&hpfs_i(old_dir)->i_mutex);
 572        if (new_dir != old_dir)
 573                mutex_lock(&hpfs_i(new_dir)->i_mutex);
 574        
 575        /* Erm? Moving over the empty non-busy directory is perfectly legal */
 576        if (new_inode && S_ISDIR(new_inode->i_mode)) {
 577                err = -EINVAL;
 578                goto end1;
 579        }
 580
 581        if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, (char *)old_name, old_len, &dno, &qbh))) {
 582                hpfs_error(i->i_sb, "lookup succeeded but map dirent failed");
 583                err = -ENOENT;
 584                goto end1;
 585        }
 586        copy_de(&de, dep);
 587        de.hidden = new_name[0] == '.';
 588
 589        if (new_inode) {
 590                int r;
 591                if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) {
 592                        if ((nde = map_dirent(new_dir, hpfs_i(new_dir)->i_dno, (char *)new_name, new_len, NULL, &qbh1))) {
 593                                clear_nlink(new_inode);
 594                                copy_de(nde, &de);
 595                                memcpy(nde->name, new_name, new_len);
 596                                hpfs_mark_4buffers_dirty(&qbh1);
 597                                hpfs_brelse4(&qbh1);
 598                                goto end;
 599                        }
 600                        hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent");
 601                        err = -EFSERROR;
 602                        goto end1;
 603                }
 604                err = r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
 605                goto end1;
 606        }
 607
 608        if (new_dir == old_dir) hpfs_brelse4(&qbh);
 609
 610        hpfs_lock_creation(i->i_sb);
 611        if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de, 1))) {
 612                hpfs_unlock_creation(i->i_sb);
 613                if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!");
 614                err = r == 1 ? -ENOSPC : -EFSERROR;
 615                if (new_dir != old_dir) hpfs_brelse4(&qbh);
 616                goto end1;
 617        }
 618        
 619        if (new_dir == old_dir)
 620                if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, (char *)old_name, old_len, &dno, &qbh))) {
 621                        hpfs_unlock_creation(i->i_sb);
 622                        hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2");
 623                        err = -ENOENT;
 624                        goto end1;
 625                }
 626
 627        if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) {
 628                hpfs_unlock_creation(i->i_sb);
 629                hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent");
 630                err = r == 2 ? -ENOSPC : -EFSERROR;
 631                goto end1;
 632        }
 633        hpfs_unlock_creation(i->i_sb);
 634        
 635        end:
 636        hpfs_i(i)->i_parent_dir = new_dir->i_ino;
 637        if (S_ISDIR(i->i_mode)) {
 638                inc_nlink(new_dir);
 639                drop_nlink(old_dir);
 640        }
 641        if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) {
 642                fnode->up = new_dir->i_ino;
 643                fnode->len = new_len;
 644                memcpy(fnode->name, new_name, new_len>15?15:new_len);
 645                if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len);
 646                mark_buffer_dirty(bh);
 647                brelse(bh);
 648        }
 649        hpfs_i(i)->i_conv = hpfs_sb(i->i_sb)->sb_conv;
 650        hpfs_decide_conv(i, (char *)new_name, new_len);
 651end1:
 652        if (old_dir != new_dir)
 653                mutex_unlock(&hpfs_i(new_dir)->i_mutex);
 654        mutex_unlock(&hpfs_i(old_dir)->i_mutex);
 655        mutex_unlock(&hpfs_i(i)->i_parent_mutex);
 656        if (new_inode)
 657                mutex_unlock(&hpfs_i(new_inode)->i_parent_mutex);
 658        unlock_kernel();
 659        return err;
 660}
 661
 662const struct inode_operations hpfs_dir_iops =
 663{
 664        .create         = hpfs_create,
 665        .lookup         = hpfs_lookup,
 666        .unlink         = hpfs_unlink,
 667        .symlink        = hpfs_symlink,
 668        .mkdir          = hpfs_mkdir,
 669        .rmdir          = hpfs_rmdir,
 670        .mknod          = hpfs_mknod,
 671        .rename         = hpfs_rename,
 672        .setattr        = hpfs_notify_change,
 673};
 674