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