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        inode_nohighmem(result);
 336        result->i_op = &page_symlink_inode_operations;
 337        result->i_data.a_ops = &hpfs_symlink_aops;
 338
 339        r = hpfs_add_dirent(dir, name, len, &dee);
 340        if (r == 1)
 341                goto bail2;
 342        if (r == -1) {
 343                err = -EEXIST;
 344                goto bail2;
 345        }
 346        fnode->len = len;
 347        memcpy(fnode->name, name, len > 15 ? 15 : len);
 348        fnode->up = cpu_to_le32(dir->i_ino);
 349        hpfs_set_ea(result, fnode, "SYMLINK", symlink, strlen(symlink));
 350        mark_buffer_dirty(bh);
 351        brelse(bh);
 352
 353        insert_inode_hash(result);
 354
 355        hpfs_write_inode_nolock(result);
 356        hpfs_update_directory_times(dir);
 357        d_instantiate(dentry, result);
 358        hpfs_unlock(dir->i_sb);
 359        return 0;
 360bail2:
 361        iput(result);
 362bail1:
 363        brelse(bh);
 364        hpfs_free_sectors(dir->i_sb, fno, 1);
 365bail:
 366        hpfs_unlock(dir->i_sb);
 367        return err;
 368}
 369
 370static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
 371{
 372        const unsigned 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 = d_inode(dentry);
 377        dnode_secno dno;
 378        int r;
 379        int err;
 380
 381        hpfs_lock(dir->i_sb);
 382        hpfs_adjust_length(name, &len);
 383
 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 */
 404                err = -ENOSPC;
 405                break;
 406        default:
 407                drop_nlink(inode);
 408                err = 0;
 409        }
 410        goto out;
 411
 412out1:
 413        hpfs_brelse4(&qbh);
 414out:
 415        if (!err)
 416                hpfs_update_directory_times(dir);
 417        hpfs_unlock(dir->i_sb);
 418        return err;
 419}
 420
 421static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
 422{
 423        const unsigned char *name = dentry->d_name.name;
 424        unsigned len = dentry->d_name.len;
 425        struct quad_buffer_head qbh;
 426        struct hpfs_dirent *de;
 427        struct inode *inode = d_inode(dentry);
 428        dnode_secno dno;
 429        int n_items = 0;
 430        int err;
 431        int r;
 432
 433        hpfs_adjust_length(name, &len);
 434        hpfs_lock(dir->i_sb);
 435        err = -ENOENT;
 436        de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
 437        if (!de)
 438                goto out;
 439
 440        err = -EPERM;
 441        if (de->first)
 442                goto out1;
 443
 444        err = -ENOTDIR;
 445        if (!de->directory)
 446                goto out1;
 447
 448        hpfs_count_dnodes(dir->i_sb, hpfs_i(inode)->i_dno, NULL, NULL, &n_items);
 449        err = -ENOTEMPTY;
 450        if (n_items)
 451                goto out1;
 452
 453        r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
 454        switch (r) {
 455        case 1:
 456                hpfs_error(dir->i_sb, "there was error when removing dirent");
 457                err = -EFSERROR;
 458                break;
 459        case 2:
 460                err = -ENOSPC;
 461                break;
 462        default:
 463                drop_nlink(dir);
 464                clear_nlink(inode);
 465                err = 0;
 466        }
 467        goto out;
 468out1:
 469        hpfs_brelse4(&qbh);
 470out:
 471        if (!err)
 472                hpfs_update_directory_times(dir);
 473        hpfs_unlock(dir->i_sb);
 474        return err;
 475}
 476
 477static int hpfs_symlink_readpage(struct file *file, struct page *page)
 478{
 479        char *link = page_address(page);
 480        struct inode *i = page->mapping->host;
 481        struct fnode *fnode;
 482        struct buffer_head *bh;
 483        int err;
 484
 485        err = -EIO;
 486        hpfs_lock(i->i_sb);
 487        if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh)))
 488                goto fail;
 489        err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE);
 490        brelse(bh);
 491        if (err)
 492                goto fail;
 493        hpfs_unlock(i->i_sb);
 494        SetPageUptodate(page);
 495        unlock_page(page);
 496        return 0;
 497
 498fail:
 499        hpfs_unlock(i->i_sb);
 500        SetPageError(page);
 501        unlock_page(page);
 502        return err;
 503}
 504
 505const struct address_space_operations hpfs_symlink_aops = {
 506        .readpage       = hpfs_symlink_readpage
 507};
 508        
 509static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 510                       struct inode *new_dir, struct dentry *new_dentry,
 511                       unsigned int flags)
 512{
 513        const unsigned char *old_name = old_dentry->d_name.name;
 514        unsigned old_len = old_dentry->d_name.len;
 515        const unsigned char *new_name = new_dentry->d_name.name;
 516        unsigned new_len = new_dentry->d_name.len;
 517        struct inode *i = d_inode(old_dentry);
 518        struct inode *new_inode = d_inode(new_dentry);
 519        struct quad_buffer_head qbh, qbh1;
 520        struct hpfs_dirent *dep, *nde;
 521        struct hpfs_dirent de;
 522        dnode_secno dno;
 523        int r;
 524        struct buffer_head *bh;
 525        struct fnode *fnode;
 526        int err;
 527
 528        if (flags & ~RENAME_NOREPLACE)
 529                return -EINVAL;
 530
 531        if ((err = hpfs_chk_name(new_name, &new_len))) return err;
 532        err = 0;
 533        hpfs_adjust_length(old_name, &old_len);
 534
 535        hpfs_lock(i->i_sb);
 536        /* order doesn't matter, due to VFS exclusion */
 537        
 538        /* Erm? Moving over the empty non-busy directory is perfectly legal */
 539        if (new_inode && S_ISDIR(new_inode->i_mode)) {
 540                err = -EINVAL;
 541                goto end1;
 542        }
 543
 544        if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
 545                hpfs_error(i->i_sb, "lookup succeeded but map dirent failed");
 546                err = -ENOENT;
 547                goto end1;
 548        }
 549        copy_de(&de, dep);
 550        de.hidden = new_name[0] == '.';
 551
 552        if (new_inode) {
 553                int r;
 554                if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) {
 555                        if ((nde = map_dirent(new_dir, hpfs_i(new_dir)->i_dno, new_name, new_len, NULL, &qbh1))) {
 556                                clear_nlink(new_inode);
 557                                copy_de(nde, &de);
 558                                memcpy(nde->name, new_name, new_len);
 559                                hpfs_mark_4buffers_dirty(&qbh1);
 560                                hpfs_brelse4(&qbh1);
 561                                goto end;
 562                        }
 563                        hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent");
 564                        err = -EFSERROR;
 565                        goto end1;
 566                }
 567                err = r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
 568                goto end1;
 569        }
 570
 571        if (new_dir == old_dir) hpfs_brelse4(&qbh);
 572
 573        if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de))) {
 574                if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!");
 575                err = r == 1 ? -ENOSPC : -EFSERROR;
 576                if (new_dir != old_dir) hpfs_brelse4(&qbh);
 577                goto end1;
 578        }
 579        
 580        if (new_dir == old_dir)
 581                if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
 582                        hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2");
 583                        err = -ENOENT;
 584                        goto end1;
 585                }
 586
 587        if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) {
 588                hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent");
 589                err = r == 2 ? -ENOSPC : -EFSERROR;
 590                goto end1;
 591        }
 592
 593end:
 594        hpfs_i(i)->i_parent_dir = new_dir->i_ino;
 595        if (S_ISDIR(i->i_mode)) {
 596                inc_nlink(new_dir);
 597                drop_nlink(old_dir);
 598        }
 599        if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) {
 600                fnode->up = cpu_to_le32(new_dir->i_ino);
 601                fnode->len = new_len;
 602                memcpy(fnode->name, new_name, new_len>15?15:new_len);
 603                if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len);
 604                mark_buffer_dirty(bh);
 605                brelse(bh);
 606        }
 607end1:
 608        if (!err) {
 609                hpfs_update_directory_times(old_dir);
 610                hpfs_update_directory_times(new_dir);
 611        }
 612        hpfs_unlock(i->i_sb);
 613        return err;
 614}
 615
 616const struct inode_operations hpfs_dir_iops =
 617{
 618        .create         = hpfs_create,
 619        .lookup         = hpfs_lookup,
 620        .unlink         = hpfs_unlink,
 621        .symlink        = hpfs_symlink,
 622        .mkdir          = hpfs_mkdir,
 623        .rmdir          = hpfs_rmdir,
 624        .mknod          = hpfs_mknod,
 625        .rename         = hpfs_rename,
 626        .setattr        = hpfs_setattr,
 627};
 628