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