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