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