Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  linux/fs/hpfs/namei.c
0004  *
0005  *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
0006  *
0007  *  adding & removing files & directories
0008  */
0009 #include <linux/sched.h>
0010 #include "hpfs_fn.h"
0011 
0012 static void hpfs_update_directory_times(struct inode *dir)
0013 {
0014     time64_t t = local_to_gmt(dir->i_sb, local_get_seconds(dir->i_sb));
0015     if (t == dir->i_mtime.tv_sec &&
0016         t == dir->i_ctime.tv_sec)
0017         return;
0018     dir->i_mtime.tv_sec = dir->i_ctime.tv_sec = t;
0019     dir->i_mtime.tv_nsec = dir->i_ctime.tv_nsec = 0;
0020     hpfs_write_inode_nolock(dir);
0021 }
0022 
0023 static int hpfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
0024               struct dentry *dentry, umode_t mode)
0025 {
0026     const unsigned char *name = dentry->d_name.name;
0027     unsigned len = dentry->d_name.len;
0028     struct quad_buffer_head qbh0;
0029     struct buffer_head *bh;
0030     struct hpfs_dirent *de;
0031     struct fnode *fnode;
0032     struct dnode *dnode;
0033     struct inode *result;
0034     fnode_secno fno;
0035     dnode_secno dno;
0036     int r;
0037     struct hpfs_dirent dee;
0038     int err;
0039     if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
0040     hpfs_lock(dir->i_sb);
0041     err = -ENOSPC;
0042     fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
0043     if (!fnode)
0044         goto bail;
0045     dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0);
0046     if (!dnode)
0047         goto bail1;
0048     memset(&dee, 0, sizeof dee);
0049     dee.directory = 1;
0050     if (!(mode & 0222)) dee.read_only = 1;
0051     /*dee.archive = 0;*/
0052     dee.hidden = name[0] == '.';
0053     dee.fnode = cpu_to_le32(fno);
0054     dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
0055     result = new_inode(dir->i_sb);
0056     if (!result)
0057         goto bail2;
0058     hpfs_init_inode(result);
0059     result->i_ino = fno;
0060     hpfs_i(result)->i_parent_dir = dir->i_ino;
0061     hpfs_i(result)->i_dno = dno;
0062     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));
0063     result->i_ctime.tv_nsec = 0; 
0064     result->i_mtime.tv_nsec = 0; 
0065     result->i_atime.tv_nsec = 0; 
0066     hpfs_i(result)->i_ea_size = 0;
0067     result->i_mode |= S_IFDIR;
0068     result->i_op = &hpfs_dir_iops;
0069     result->i_fop = &hpfs_dir_ops;
0070     result->i_blocks = 4;
0071     result->i_size = 2048;
0072     set_nlink(result, 2);
0073     if (dee.read_only)
0074         result->i_mode &= ~0222;
0075 
0076     r = hpfs_add_dirent(dir, name, len, &dee);
0077     if (r == 1)
0078         goto bail3;
0079     if (r == -1) {
0080         err = -EEXIST;
0081         goto bail3;
0082     }
0083     fnode->len = len;
0084     memcpy(fnode->name, name, len > 15 ? 15 : len);
0085     fnode->up = cpu_to_le32(dir->i_ino);
0086     fnode->flags |= FNODE_dir;
0087     fnode->btree.n_free_nodes = 7;
0088     fnode->btree.n_used_nodes = 1;
0089     fnode->btree.first_free = cpu_to_le16(0x14);
0090     fnode->u.external[0].disk_secno = cpu_to_le32(dno);
0091     fnode->u.external[0].file_secno = cpu_to_le32(-1);
0092     dnode->root_dnode = 1;
0093     dnode->up = cpu_to_le32(fno);
0094     de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0);
0095     de->creation_date = de->write_date = de->read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
0096     if (!(mode & 0222)) de->read_only = 1;
0097     de->first = de->directory = 1;
0098     /*de->hidden = de->system = 0;*/
0099     de->fnode = cpu_to_le32(fno);
0100     mark_buffer_dirty(bh);
0101     brelse(bh);
0102     hpfs_mark_4buffers_dirty(&qbh0);
0103     hpfs_brelse4(&qbh0);
0104     inc_nlink(dir);
0105     insert_inode_hash(result);
0106 
0107     if (!uid_eq(result->i_uid, current_fsuid()) ||
0108         !gid_eq(result->i_gid, current_fsgid()) ||
0109         result->i_mode != (mode | S_IFDIR)) {
0110         result->i_uid = current_fsuid();
0111         result->i_gid = current_fsgid();
0112         result->i_mode = mode | S_IFDIR;
0113         hpfs_write_inode_nolock(result);
0114     }
0115     hpfs_update_directory_times(dir);
0116     d_instantiate(dentry, result);
0117     hpfs_unlock(dir->i_sb);
0118     return 0;
0119 bail3:
0120     iput(result);
0121 bail2:
0122     hpfs_brelse4(&qbh0);
0123     hpfs_free_dnode(dir->i_sb, dno);
0124 bail1:
0125     brelse(bh);
0126     hpfs_free_sectors(dir->i_sb, fno, 1);
0127 bail:
0128     hpfs_unlock(dir->i_sb);
0129     return err;
0130 }
0131 
0132 static int hpfs_create(struct user_namespace *mnt_userns, struct inode *dir,
0133                struct dentry *dentry, umode_t mode, bool excl)
0134 {
0135     const unsigned char *name = dentry->d_name.name;
0136     unsigned len = dentry->d_name.len;
0137     struct inode *result = NULL;
0138     struct buffer_head *bh;
0139     struct fnode *fnode;
0140     fnode_secno fno;
0141     int r;
0142     struct hpfs_dirent dee;
0143     int err;
0144     if ((err = hpfs_chk_name(name, &len)))
0145         return err==-ENOENT ? -EINVAL : err;
0146     hpfs_lock(dir->i_sb);
0147     err = -ENOSPC;
0148     fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
0149     if (!fnode)
0150         goto bail;
0151     memset(&dee, 0, sizeof dee);
0152     if (!(mode & 0222)) dee.read_only = 1;
0153     dee.archive = 1;
0154     dee.hidden = name[0] == '.';
0155     dee.fnode = cpu_to_le32(fno);
0156     dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
0157 
0158     result = new_inode(dir->i_sb);
0159     if (!result)
0160         goto bail1;
0161     
0162     hpfs_init_inode(result);
0163     result->i_ino = fno;
0164     result->i_mode |= S_IFREG;
0165     result->i_mode &= ~0111;
0166     result->i_op = &hpfs_file_iops;
0167     result->i_fop = &hpfs_file_ops;
0168     set_nlink(result, 1);
0169     hpfs_i(result)->i_parent_dir = dir->i_ino;
0170     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));
0171     result->i_ctime.tv_nsec = 0;
0172     result->i_mtime.tv_nsec = 0;
0173     result->i_atime.tv_nsec = 0;
0174     hpfs_i(result)->i_ea_size = 0;
0175     if (dee.read_only)
0176         result->i_mode &= ~0222;
0177     result->i_blocks = 1;
0178     result->i_size = 0;
0179     result->i_data.a_ops = &hpfs_aops;
0180     hpfs_i(result)->mmu_private = 0;
0181 
0182     r = hpfs_add_dirent(dir, name, len, &dee);
0183     if (r == 1)
0184         goto bail2;
0185     if (r == -1) {
0186         err = -EEXIST;
0187         goto bail2;
0188     }
0189     fnode->len = len;
0190     memcpy(fnode->name, name, len > 15 ? 15 : len);
0191     fnode->up = cpu_to_le32(dir->i_ino);
0192     mark_buffer_dirty(bh);
0193     brelse(bh);
0194 
0195     insert_inode_hash(result);
0196 
0197     if (!uid_eq(result->i_uid, current_fsuid()) ||
0198         !gid_eq(result->i_gid, current_fsgid()) ||
0199         result->i_mode != (mode | S_IFREG)) {
0200         result->i_uid = current_fsuid();
0201         result->i_gid = current_fsgid();
0202         result->i_mode = mode | S_IFREG;
0203         hpfs_write_inode_nolock(result);
0204     }
0205     hpfs_update_directory_times(dir);
0206     d_instantiate(dentry, result);
0207     hpfs_unlock(dir->i_sb);
0208     return 0;
0209 
0210 bail2:
0211     iput(result);
0212 bail1:
0213     brelse(bh);
0214     hpfs_free_sectors(dir->i_sb, fno, 1);
0215 bail:
0216     hpfs_unlock(dir->i_sb);
0217     return err;
0218 }
0219 
0220 static int hpfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
0221               struct dentry *dentry, umode_t mode, dev_t rdev)
0222 {
0223     const unsigned char *name = dentry->d_name.name;
0224     unsigned len = dentry->d_name.len;
0225     struct buffer_head *bh;
0226     struct fnode *fnode;
0227     fnode_secno fno;
0228     int r;
0229     struct hpfs_dirent dee;
0230     struct inode *result = NULL;
0231     int err;
0232     if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
0233     if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM;
0234     hpfs_lock(dir->i_sb);
0235     err = -ENOSPC;
0236     fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
0237     if (!fnode)
0238         goto bail;
0239     memset(&dee, 0, sizeof dee);
0240     if (!(mode & 0222)) dee.read_only = 1;
0241     dee.archive = 1;
0242     dee.hidden = name[0] == '.';
0243     dee.fnode = cpu_to_le32(fno);
0244     dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
0245 
0246     result = new_inode(dir->i_sb);
0247     if (!result)
0248         goto bail1;
0249 
0250     hpfs_init_inode(result);
0251     result->i_ino = fno;
0252     hpfs_i(result)->i_parent_dir = dir->i_ino;
0253     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));
0254     result->i_ctime.tv_nsec = 0;
0255     result->i_mtime.tv_nsec = 0;
0256     result->i_atime.tv_nsec = 0;
0257     hpfs_i(result)->i_ea_size = 0;
0258     result->i_uid = current_fsuid();
0259     result->i_gid = current_fsgid();
0260     set_nlink(result, 1);
0261     result->i_size = 0;
0262     result->i_blocks = 1;
0263     init_special_inode(result, mode, rdev);
0264 
0265     r = hpfs_add_dirent(dir, name, len, &dee);
0266     if (r == 1)
0267         goto bail2;
0268     if (r == -1) {
0269         err = -EEXIST;
0270         goto bail2;
0271     }
0272     fnode->len = len;
0273     memcpy(fnode->name, name, len > 15 ? 15 : len);
0274     fnode->up = cpu_to_le32(dir->i_ino);
0275     mark_buffer_dirty(bh);
0276 
0277     insert_inode_hash(result);
0278 
0279     hpfs_write_inode_nolock(result);
0280     hpfs_update_directory_times(dir);
0281     d_instantiate(dentry, result);
0282     brelse(bh);
0283     hpfs_unlock(dir->i_sb);
0284     return 0;
0285 bail2:
0286     iput(result);
0287 bail1:
0288     brelse(bh);
0289     hpfs_free_sectors(dir->i_sb, fno, 1);
0290 bail:
0291     hpfs_unlock(dir->i_sb);
0292     return err;
0293 }
0294 
0295 static int hpfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
0296             struct dentry *dentry, const char *symlink)
0297 {
0298     const unsigned char *name = dentry->d_name.name;
0299     unsigned len = dentry->d_name.len;
0300     struct buffer_head *bh;
0301     struct fnode *fnode;
0302     fnode_secno fno;
0303     int r;
0304     struct hpfs_dirent dee;
0305     struct inode *result;
0306     int err;
0307     if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
0308     hpfs_lock(dir->i_sb);
0309     if (hpfs_sb(dir->i_sb)->sb_eas < 2) {
0310         hpfs_unlock(dir->i_sb);
0311         return -EPERM;
0312     }
0313     err = -ENOSPC;
0314     fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
0315     if (!fnode)
0316         goto bail;
0317     memset(&dee, 0, sizeof dee);
0318     dee.archive = 1;
0319     dee.hidden = name[0] == '.';
0320     dee.fnode = cpu_to_le32(fno);
0321     dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
0322 
0323     result = new_inode(dir->i_sb);
0324     if (!result)
0325         goto bail1;
0326     result->i_ino = fno;
0327     hpfs_init_inode(result);
0328     hpfs_i(result)->i_parent_dir = dir->i_ino;
0329     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));
0330     result->i_ctime.tv_nsec = 0;
0331     result->i_mtime.tv_nsec = 0;
0332     result->i_atime.tv_nsec = 0;
0333     hpfs_i(result)->i_ea_size = 0;
0334     result->i_mode = S_IFLNK | 0777;
0335     result->i_uid = current_fsuid();
0336     result->i_gid = current_fsgid();
0337     result->i_blocks = 1;
0338     set_nlink(result, 1);
0339     result->i_size = strlen(symlink);
0340     inode_nohighmem(result);
0341     result->i_op = &page_symlink_inode_operations;
0342     result->i_data.a_ops = &hpfs_symlink_aops;
0343 
0344     r = hpfs_add_dirent(dir, name, len, &dee);
0345     if (r == 1)
0346         goto bail2;
0347     if (r == -1) {
0348         err = -EEXIST;
0349         goto bail2;
0350     }
0351     fnode->len = len;
0352     memcpy(fnode->name, name, len > 15 ? 15 : len);
0353     fnode->up = cpu_to_le32(dir->i_ino);
0354     hpfs_set_ea(result, fnode, "SYMLINK", symlink, strlen(symlink));
0355     mark_buffer_dirty(bh);
0356     brelse(bh);
0357 
0358     insert_inode_hash(result);
0359 
0360     hpfs_write_inode_nolock(result);
0361     hpfs_update_directory_times(dir);
0362     d_instantiate(dentry, result);
0363     hpfs_unlock(dir->i_sb);
0364     return 0;
0365 bail2:
0366     iput(result);
0367 bail1:
0368     brelse(bh);
0369     hpfs_free_sectors(dir->i_sb, fno, 1);
0370 bail:
0371     hpfs_unlock(dir->i_sb);
0372     return err;
0373 }
0374 
0375 static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
0376 {
0377     const unsigned char *name = dentry->d_name.name;
0378     unsigned len = dentry->d_name.len;
0379     struct quad_buffer_head qbh;
0380     struct hpfs_dirent *de;
0381     struct inode *inode = d_inode(dentry);
0382     dnode_secno dno;
0383     int r;
0384     int err;
0385 
0386     hpfs_lock(dir->i_sb);
0387     hpfs_adjust_length(name, &len);
0388 
0389     err = -ENOENT;
0390     de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
0391     if (!de)
0392         goto out;
0393 
0394     err = -EPERM;
0395     if (de->first)
0396         goto out1;
0397 
0398     err = -EISDIR;
0399     if (de->directory)
0400         goto out1;
0401 
0402     r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
0403     switch (r) {
0404     case 1:
0405         hpfs_error(dir->i_sb, "there was error when removing dirent");
0406         err = -EFSERROR;
0407         break;
0408     case 2:     /* no space for deleting */
0409         err = -ENOSPC;
0410         break;
0411     default:
0412         drop_nlink(inode);
0413         err = 0;
0414     }
0415     goto out;
0416 
0417 out1:
0418     hpfs_brelse4(&qbh);
0419 out:
0420     if (!err)
0421         hpfs_update_directory_times(dir);
0422     hpfs_unlock(dir->i_sb);
0423     return err;
0424 }
0425 
0426 static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
0427 {
0428     const unsigned char *name = dentry->d_name.name;
0429     unsigned len = dentry->d_name.len;
0430     struct quad_buffer_head qbh;
0431     struct hpfs_dirent *de;
0432     struct inode *inode = d_inode(dentry);
0433     dnode_secno dno;
0434     int n_items = 0;
0435     int err;
0436     int r;
0437 
0438     hpfs_adjust_length(name, &len);
0439     hpfs_lock(dir->i_sb);
0440     err = -ENOENT;
0441     de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
0442     if (!de)
0443         goto out;
0444 
0445     err = -EPERM;
0446     if (de->first)
0447         goto out1;
0448 
0449     err = -ENOTDIR;
0450     if (!de->directory)
0451         goto out1;
0452 
0453     hpfs_count_dnodes(dir->i_sb, hpfs_i(inode)->i_dno, NULL, NULL, &n_items);
0454     err = -ENOTEMPTY;
0455     if (n_items)
0456         goto out1;
0457 
0458     r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
0459     switch (r) {
0460     case 1:
0461         hpfs_error(dir->i_sb, "there was error when removing dirent");
0462         err = -EFSERROR;
0463         break;
0464     case 2:
0465         err = -ENOSPC;
0466         break;
0467     default:
0468         drop_nlink(dir);
0469         clear_nlink(inode);
0470         err = 0;
0471     }
0472     goto out;
0473 out1:
0474     hpfs_brelse4(&qbh);
0475 out:
0476     if (!err)
0477         hpfs_update_directory_times(dir);
0478     hpfs_unlock(dir->i_sb);
0479     return err;
0480 }
0481 
0482 static int hpfs_symlink_read_folio(struct file *file, struct folio *folio)
0483 {
0484     struct page *page = &folio->page;
0485     char *link = page_address(page);
0486     struct inode *i = page->mapping->host;
0487     struct fnode *fnode;
0488     struct buffer_head *bh;
0489     int err;
0490 
0491     err = -EIO;
0492     hpfs_lock(i->i_sb);
0493     if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh)))
0494         goto fail;
0495     err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE);
0496     brelse(bh);
0497     if (err)
0498         goto fail;
0499     hpfs_unlock(i->i_sb);
0500     SetPageUptodate(page);
0501     unlock_page(page);
0502     return 0;
0503 
0504 fail:
0505     hpfs_unlock(i->i_sb);
0506     SetPageError(page);
0507     unlock_page(page);
0508     return err;
0509 }
0510 
0511 const struct address_space_operations hpfs_symlink_aops = {
0512     .read_folio = hpfs_symlink_read_folio
0513 };
0514 
0515 static int hpfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
0516                struct dentry *old_dentry, struct inode *new_dir,
0517                struct dentry *new_dentry, unsigned int flags)
0518 {
0519     const unsigned char *old_name = old_dentry->d_name.name;
0520     unsigned old_len = old_dentry->d_name.len;
0521     const unsigned char *new_name = new_dentry->d_name.name;
0522     unsigned new_len = new_dentry->d_name.len;
0523     struct inode *i = d_inode(old_dentry);
0524     struct inode *new_inode = d_inode(new_dentry);
0525     struct quad_buffer_head qbh, qbh1;
0526     struct hpfs_dirent *dep, *nde;
0527     struct hpfs_dirent de;
0528     dnode_secno dno;
0529     int r;
0530     struct buffer_head *bh;
0531     struct fnode *fnode;
0532     int err;
0533 
0534     if (flags & ~RENAME_NOREPLACE)
0535         return -EINVAL;
0536 
0537     if ((err = hpfs_chk_name(new_name, &new_len))) return err;
0538     err = 0;
0539     hpfs_adjust_length(old_name, &old_len);
0540 
0541     hpfs_lock(i->i_sb);
0542     /* order doesn't matter, due to VFS exclusion */
0543     
0544     /* Erm? Moving over the empty non-busy directory is perfectly legal */
0545     if (new_inode && S_ISDIR(new_inode->i_mode)) {
0546         err = -EINVAL;
0547         goto end1;
0548     }
0549 
0550     if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
0551         hpfs_error(i->i_sb, "lookup succeeded but map dirent failed");
0552         err = -ENOENT;
0553         goto end1;
0554     }
0555     copy_de(&de, dep);
0556     de.hidden = new_name[0] == '.';
0557 
0558     if (new_inode) {
0559         int r;
0560         if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) {
0561             if ((nde = map_dirent(new_dir, hpfs_i(new_dir)->i_dno, new_name, new_len, NULL, &qbh1))) {
0562                 clear_nlink(new_inode);
0563                 copy_de(nde, &de);
0564                 memcpy(nde->name, new_name, new_len);
0565                 hpfs_mark_4buffers_dirty(&qbh1);
0566                 hpfs_brelse4(&qbh1);
0567                 goto end;
0568             }
0569             hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent");
0570             err = -EFSERROR;
0571             goto end1;
0572         }
0573         err = -ENOSPC;
0574         goto end1;
0575     }
0576 
0577     if (new_dir == old_dir) hpfs_brelse4(&qbh);
0578 
0579     if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de))) {
0580         if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!");
0581         err = r == 1 ? -ENOSPC : -EFSERROR;
0582         if (new_dir != old_dir) hpfs_brelse4(&qbh);
0583         goto end1;
0584     }
0585     
0586     if (new_dir == old_dir)
0587         if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
0588             hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2");
0589             err = -ENOENT;
0590             goto end1;
0591         }
0592 
0593     if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) {
0594         hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent");
0595         err = r == 2 ? -ENOSPC : -EFSERROR;
0596         goto end1;
0597     }
0598 
0599 end:
0600     hpfs_i(i)->i_parent_dir = new_dir->i_ino;
0601     if (S_ISDIR(i->i_mode)) {
0602         inc_nlink(new_dir);
0603         drop_nlink(old_dir);
0604     }
0605     if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) {
0606         fnode->up = cpu_to_le32(new_dir->i_ino);
0607         fnode->len = new_len;
0608         memcpy(fnode->name, new_name, new_len>15?15:new_len);
0609         if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len);
0610         mark_buffer_dirty(bh);
0611         brelse(bh);
0612     }
0613 end1:
0614     if (!err) {
0615         hpfs_update_directory_times(old_dir);
0616         hpfs_update_directory_times(new_dir);
0617     }
0618     hpfs_unlock(i->i_sb);
0619     return err;
0620 }
0621 
0622 const struct inode_operations hpfs_dir_iops =
0623 {
0624     .create     = hpfs_create,
0625     .lookup     = hpfs_lookup,
0626     .unlink     = hpfs_unlink,
0627     .symlink    = hpfs_symlink,
0628     .mkdir      = hpfs_mkdir,
0629     .rmdir      = hpfs_rmdir,
0630     .mknod      = hpfs_mknod,
0631     .rename     = hpfs_rename,
0632     .setattr    = hpfs_setattr,
0633 };