0001
0002
0003
0004
0005
0006
0007
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
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
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:
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
0543
0544
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 };