1 // SPDX-License-Identifier: GPL-2.0
3 * linux/fs/hpfs/namei.c
5 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
7 * adding & removing files & directories
9 #include <linux/sched.h>
12 static void hpfs_update_directory_times(struct inode
*dir
)
14 time64_t t
= local_to_gmt(dir
->i_sb
, local_get_seconds(dir
->i_sb
));
15 if (t
== inode_get_mtime_sec(dir
) &&
16 t
== inode_get_ctime_sec(dir
))
18 inode_set_mtime_to_ts(dir
, inode_set_ctime(dir
, t
, 0));
19 hpfs_write_inode_nolock(dir
);
22 static int hpfs_mkdir(struct mnt_idmap
*idmap
, struct inode
*dir
,
23 struct dentry
*dentry
, umode_t mode
)
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
;
36 struct hpfs_dirent dee
;
38 if ((err
= hpfs_chk_name(name
, &len
))) return err
==-ENOENT
? -EINVAL
: err
;
41 fnode
= hpfs_alloc_fnode(dir
->i_sb
, hpfs_i(dir
)->i_dno
, &fno
, &bh
);
44 dnode
= hpfs_alloc_dnode(dir
->i_sb
, fno
, &dno
, &qbh0
);
47 memset(&dee
, 0, sizeof dee
);
49 if (!(mode
& 0222)) dee
.read_only
= 1;
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(local_get_seconds(dir
->i_sb
));
54 result
= new_inode(dir
->i_sb
);
57 hpfs_init_inode(result
);
59 hpfs_i(result
)->i_parent_dir
= dir
->i_ino
;
60 hpfs_i(result
)->i_dno
= dno
;
61 inode_set_mtime_to_ts(result
,
62 inode_set_atime_to_ts(result
, inode_set_ctime(result
, local_to_gmt(dir
->i_sb
, le32_to_cpu(dee
.creation_date
)), 0)));
63 hpfs_i(result
)->i_ea_size
= 0;
64 result
->i_mode
|= S_IFDIR
;
65 result
->i_op
= &hpfs_dir_iops
;
66 result
->i_fop
= &hpfs_dir_ops
;
68 result
->i_size
= 2048;
71 result
->i_mode
&= ~0222;
73 r
= hpfs_add_dirent(dir
, name
, len
, &dee
);
81 memcpy(fnode
->name
, name
, len
> 15 ? 15 : len
);
82 fnode
->up
= cpu_to_le32(dir
->i_ino
);
83 fnode
->flags
|= FNODE_dir
;
84 fnode
->btree
.n_free_nodes
= 7;
85 fnode
->btree
.n_used_nodes
= 1;
86 fnode
->btree
.first_free
= cpu_to_le16(0x14);
87 fnode
->u
.external
[0].disk_secno
= cpu_to_le32(dno
);
88 fnode
->u
.external
[0].file_secno
= cpu_to_le32(-1);
89 dnode
->root_dnode
= 1;
90 dnode
->up
= cpu_to_le32(fno
);
91 de
= hpfs_add_de(dir
->i_sb
, dnode
, "\001\001", 2, 0);
92 de
->creation_date
= de
->write_date
= de
->read_date
= cpu_to_le32(local_get_seconds(dir
->i_sb
));
93 if (!(mode
& 0222)) de
->read_only
= 1;
94 de
->first
= de
->directory
= 1;
95 /*de->hidden = de->system = 0;*/
96 de
->fnode
= cpu_to_le32(fno
);
97 mark_buffer_dirty(bh
);
99 hpfs_mark_4buffers_dirty(&qbh0
);
102 insert_inode_hash(result
);
104 if (!uid_eq(result
->i_uid
, current_fsuid()) ||
105 !gid_eq(result
->i_gid
, current_fsgid()) ||
106 result
->i_mode
!= (mode
| S_IFDIR
)) {
107 result
->i_uid
= current_fsuid();
108 result
->i_gid
= current_fsgid();
109 result
->i_mode
= mode
| S_IFDIR
;
110 hpfs_write_inode_nolock(result
);
112 hpfs_update_directory_times(dir
);
113 d_instantiate(dentry
, result
);
114 hpfs_unlock(dir
->i_sb
);
120 hpfs_free_dnode(dir
->i_sb
, dno
);
123 hpfs_free_sectors(dir
->i_sb
, fno
, 1);
125 hpfs_unlock(dir
->i_sb
);
129 static int hpfs_create(struct mnt_idmap
*idmap
, struct inode
*dir
,
130 struct dentry
*dentry
, umode_t mode
, bool excl
)
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
;
139 struct hpfs_dirent dee
;
141 if ((err
= hpfs_chk_name(name
, &len
)))
142 return err
==-ENOENT
? -EINVAL
: err
;
143 hpfs_lock(dir
->i_sb
);
145 fnode
= hpfs_alloc_fnode(dir
->i_sb
, hpfs_i(dir
)->i_dno
, &fno
, &bh
);
148 memset(&dee
, 0, sizeof dee
);
149 if (!(mode
& 0222)) dee
.read_only
= 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(local_get_seconds(dir
->i_sb
));
155 result
= new_inode(dir
->i_sb
);
159 hpfs_init_inode(result
);
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 inode_set_mtime_to_ts(result
,
168 inode_set_atime_to_ts(result
, inode_set_ctime(result
, local_to_gmt(dir
->i_sb
, le32_to_cpu(dee
.creation_date
)), 0)));
169 hpfs_i(result
)->i_ea_size
= 0;
171 result
->i_mode
&= ~0222;
172 result
->i_blocks
= 1;
174 result
->i_data
.a_ops
= &hpfs_aops
;
175 hpfs_i(result
)->mmu_private
= 0;
177 r
= hpfs_add_dirent(dir
, name
, len
, &dee
);
185 memcpy(fnode
->name
, name
, len
> 15 ? 15 : len
);
186 fnode
->up
= cpu_to_le32(dir
->i_ino
);
187 mark_buffer_dirty(bh
);
190 insert_inode_hash(result
);
192 if (!uid_eq(result
->i_uid
, current_fsuid()) ||
193 !gid_eq(result
->i_gid
, current_fsgid()) ||
194 result
->i_mode
!= (mode
| S_IFREG
)) {
195 result
->i_uid
= current_fsuid();
196 result
->i_gid
= current_fsgid();
197 result
->i_mode
= mode
| S_IFREG
;
198 hpfs_write_inode_nolock(result
);
200 hpfs_update_directory_times(dir
);
201 d_instantiate(dentry
, result
);
202 hpfs_unlock(dir
->i_sb
);
209 hpfs_free_sectors(dir
->i_sb
, fno
, 1);
211 hpfs_unlock(dir
->i_sb
);
215 static int hpfs_mknod(struct mnt_idmap
*idmap
, struct inode
*dir
,
216 struct dentry
*dentry
, umode_t mode
, dev_t rdev
)
218 const unsigned char *name
= dentry
->d_name
.name
;
219 unsigned len
= dentry
->d_name
.len
;
220 struct buffer_head
*bh
;
224 struct hpfs_dirent dee
;
225 struct inode
*result
= NULL
;
227 if ((err
= hpfs_chk_name(name
, &len
))) return err
==-ENOENT
? -EINVAL
: err
;
228 if (hpfs_sb(dir
->i_sb
)->sb_eas
< 2) return -EPERM
;
229 hpfs_lock(dir
->i_sb
);
231 fnode
= hpfs_alloc_fnode(dir
->i_sb
, hpfs_i(dir
)->i_dno
, &fno
, &bh
);
234 memset(&dee
, 0, sizeof dee
);
235 if (!(mode
& 0222)) dee
.read_only
= 1;
237 dee
.hidden
= name
[0] == '.';
238 dee
.fnode
= cpu_to_le32(fno
);
239 dee
.creation_date
= dee
.write_date
= dee
.read_date
= cpu_to_le32(local_get_seconds(dir
->i_sb
));
241 result
= new_inode(dir
->i_sb
);
245 hpfs_init_inode(result
);
247 hpfs_i(result
)->i_parent_dir
= dir
->i_ino
;
248 inode_set_mtime_to_ts(result
,
249 inode_set_atime_to_ts(result
, inode_set_ctime(result
, local_to_gmt(dir
->i_sb
, le32_to_cpu(dee
.creation_date
)), 0)));
250 hpfs_i(result
)->i_ea_size
= 0;
251 result
->i_uid
= current_fsuid();
252 result
->i_gid
= current_fsgid();
253 set_nlink(result
, 1);
255 result
->i_blocks
= 1;
256 init_special_inode(result
, mode
, rdev
);
258 r
= hpfs_add_dirent(dir
, name
, len
, &dee
);
266 memcpy(fnode
->name
, name
, len
> 15 ? 15 : len
);
267 fnode
->up
= cpu_to_le32(dir
->i_ino
);
268 mark_buffer_dirty(bh
);
270 insert_inode_hash(result
);
272 hpfs_write_inode_nolock(result
);
273 hpfs_update_directory_times(dir
);
274 d_instantiate(dentry
, result
);
276 hpfs_unlock(dir
->i_sb
);
282 hpfs_free_sectors(dir
->i_sb
, fno
, 1);
284 hpfs_unlock(dir
->i_sb
);
288 static int hpfs_symlink(struct mnt_idmap
*idmap
, struct inode
*dir
,
289 struct dentry
*dentry
, const char *symlink
)
291 const unsigned char *name
= dentry
->d_name
.name
;
292 unsigned len
= dentry
->d_name
.len
;
293 struct buffer_head
*bh
;
297 struct hpfs_dirent dee
;
298 struct inode
*result
;
300 if ((err
= hpfs_chk_name(name
, &len
))) return err
==-ENOENT
? -EINVAL
: err
;
301 hpfs_lock(dir
->i_sb
);
302 if (hpfs_sb(dir
->i_sb
)->sb_eas
< 2) {
303 hpfs_unlock(dir
->i_sb
);
307 fnode
= hpfs_alloc_fnode(dir
->i_sb
, hpfs_i(dir
)->i_dno
, &fno
, &bh
);
310 memset(&dee
, 0, sizeof dee
);
312 dee
.hidden
= name
[0] == '.';
313 dee
.fnode
= cpu_to_le32(fno
);
314 dee
.creation_date
= dee
.write_date
= dee
.read_date
= cpu_to_le32(local_get_seconds(dir
->i_sb
));
316 result
= new_inode(dir
->i_sb
);
320 hpfs_init_inode(result
);
321 hpfs_i(result
)->i_parent_dir
= dir
->i_ino
;
322 inode_set_mtime_to_ts(result
,
323 inode_set_atime_to_ts(result
, inode_set_ctime(result
, local_to_gmt(dir
->i_sb
, le32_to_cpu(dee
.creation_date
)), 0)));
324 hpfs_i(result
)->i_ea_size
= 0;
325 result
->i_mode
= S_IFLNK
| 0777;
326 result
->i_uid
= current_fsuid();
327 result
->i_gid
= current_fsgid();
328 result
->i_blocks
= 1;
329 set_nlink(result
, 1);
330 result
->i_size
= strlen(symlink
);
331 inode_nohighmem(result
);
332 result
->i_op
= &page_symlink_inode_operations
;
333 result
->i_data
.a_ops
= &hpfs_symlink_aops
;
335 r
= hpfs_add_dirent(dir
, name
, len
, &dee
);
343 memcpy(fnode
->name
, name
, len
> 15 ? 15 : len
);
344 fnode
->up
= cpu_to_le32(dir
->i_ino
);
345 hpfs_set_ea(result
, fnode
, "SYMLINK", symlink
, strlen(symlink
));
346 mark_buffer_dirty(bh
);
349 insert_inode_hash(result
);
351 hpfs_write_inode_nolock(result
);
352 hpfs_update_directory_times(dir
);
353 d_instantiate(dentry
, result
);
354 hpfs_unlock(dir
->i_sb
);
360 hpfs_free_sectors(dir
->i_sb
, fno
, 1);
362 hpfs_unlock(dir
->i_sb
);
366 static int hpfs_unlink(struct inode
*dir
, struct dentry
*dentry
)
368 const unsigned char *name
= dentry
->d_name
.name
;
369 unsigned len
= dentry
->d_name
.len
;
370 struct quad_buffer_head qbh
;
371 struct hpfs_dirent
*de
;
372 struct inode
*inode
= d_inode(dentry
);
377 hpfs_lock(dir
->i_sb
);
378 hpfs_adjust_length(name
, &len
);
381 de
= map_dirent(dir
, hpfs_i(dir
)->i_dno
, name
, len
, &dno
, &qbh
);
393 r
= hpfs_remove_dirent(dir
, dno
, de
, &qbh
, 1);
396 hpfs_error(dir
->i_sb
, "there was error when removing dirent");
399 case 2: /* no space for deleting */
412 hpfs_update_directory_times(dir
);
413 hpfs_unlock(dir
->i_sb
);
417 static int hpfs_rmdir(struct inode
*dir
, struct dentry
*dentry
)
419 const unsigned char *name
= dentry
->d_name
.name
;
420 unsigned len
= dentry
->d_name
.len
;
421 struct quad_buffer_head qbh
;
422 struct hpfs_dirent
*de
;
423 struct inode
*inode
= d_inode(dentry
);
429 hpfs_adjust_length(name
, &len
);
430 hpfs_lock(dir
->i_sb
);
432 de
= map_dirent(dir
, hpfs_i(dir
)->i_dno
, name
, len
, &dno
, &qbh
);
444 hpfs_count_dnodes(dir
->i_sb
, hpfs_i(inode
)->i_dno
, NULL
, NULL
, &n_items
);
449 r
= hpfs_remove_dirent(dir
, dno
, de
, &qbh
, 1);
452 hpfs_error(dir
->i_sb
, "there was error when removing dirent");
468 hpfs_update_directory_times(dir
);
469 hpfs_unlock(dir
->i_sb
);
473 static int hpfs_symlink_read_folio(struct file
*file
, struct folio
*folio
)
475 char *link
= folio_address(folio
);
476 struct inode
*i
= folio
->mapping
->host
;
478 struct buffer_head
*bh
;
483 if (!(fnode
= hpfs_map_fnode(i
->i_sb
, i
->i_ino
, &bh
)))
485 err
= hpfs_read_ea(i
->i_sb
, fnode
, "SYMLINK", link
, PAGE_SIZE
);
488 hpfs_unlock(i
->i_sb
);
489 folio_end_read(folio
, err
== 0);
493 const struct address_space_operations hpfs_symlink_aops
= {
494 .read_folio
= hpfs_symlink_read_folio
497 static int hpfs_rename(struct mnt_idmap
*idmap
, struct inode
*old_dir
,
498 struct dentry
*old_dentry
, struct inode
*new_dir
,
499 struct dentry
*new_dentry
, unsigned int flags
)
501 const unsigned char *old_name
= old_dentry
->d_name
.name
;
502 unsigned old_len
= old_dentry
->d_name
.len
;
503 const unsigned char *new_name
= new_dentry
->d_name
.name
;
504 unsigned new_len
= new_dentry
->d_name
.len
;
505 struct inode
*i
= d_inode(old_dentry
);
506 struct inode
*new_inode
= d_inode(new_dentry
);
507 struct quad_buffer_head qbh
, qbh1
;
508 struct hpfs_dirent
*dep
, *nde
;
509 struct hpfs_dirent de
;
512 struct buffer_head
*bh
;
516 if (flags
& ~RENAME_NOREPLACE
)
519 if ((err
= hpfs_chk_name(new_name
, &new_len
))) return err
;
521 hpfs_adjust_length(old_name
, &old_len
);
524 /* order doesn't matter, due to VFS exclusion */
526 /* Erm? Moving over the empty non-busy directory is perfectly legal */
527 if (new_inode
&& S_ISDIR(new_inode
->i_mode
)) {
532 if (!(dep
= map_dirent(old_dir
, hpfs_i(old_dir
)->i_dno
, old_name
, old_len
, &dno
, &qbh
))) {
533 hpfs_error(i
->i_sb
, "lookup succeeded but map dirent failed");
538 de
.hidden
= new_name
[0] == '.';
542 if ((r
= hpfs_remove_dirent(old_dir
, dno
, dep
, &qbh
, 1)) != 2) {
543 if ((nde
= map_dirent(new_dir
, hpfs_i(new_dir
)->i_dno
, new_name
, new_len
, NULL
, &qbh1
))) {
544 clear_nlink(new_inode
);
546 memcpy(nde
->name
, new_name
, new_len
);
547 hpfs_mark_4buffers_dirty(&qbh1
);
551 hpfs_error(new_dir
->i_sb
, "hpfs_rename: could not find dirent");
559 if (new_dir
== old_dir
) hpfs_brelse4(&qbh
);
561 if ((r
= hpfs_add_dirent(new_dir
, new_name
, new_len
, &de
))) {
562 if (r
== -1) hpfs_error(new_dir
->i_sb
, "hpfs_rename: dirent already exists!");
563 err
= r
== 1 ? -ENOSPC
: -EFSERROR
;
564 if (new_dir
!= old_dir
) hpfs_brelse4(&qbh
);
568 if (new_dir
== old_dir
)
569 if (!(dep
= map_dirent(old_dir
, hpfs_i(old_dir
)->i_dno
, old_name
, old_len
, &dno
, &qbh
))) {
570 hpfs_error(i
->i_sb
, "lookup succeeded but map dirent failed at #2");
575 if ((r
= hpfs_remove_dirent(old_dir
, dno
, dep
, &qbh
, 0))) {
576 hpfs_error(i
->i_sb
, "hpfs_rename: could not remove dirent");
577 err
= r
== 2 ? -ENOSPC
: -EFSERROR
;
582 hpfs_i(i
)->i_parent_dir
= new_dir
->i_ino
;
583 if (S_ISDIR(i
->i_mode
)) {
587 if ((fnode
= hpfs_map_fnode(i
->i_sb
, i
->i_ino
, &bh
))) {
588 fnode
->up
= cpu_to_le32(new_dir
->i_ino
);
589 fnode
->len
= new_len
;
590 memcpy(fnode
->name
, new_name
, new_len
>15?15:new_len
);
591 if (new_len
< 15) memset(&fnode
->name
[new_len
], 0, 15 - new_len
);
592 mark_buffer_dirty(bh
);
597 hpfs_update_directory_times(old_dir
);
598 hpfs_update_directory_times(new_dir
);
600 hpfs_unlock(i
->i_sb
);
604 const struct inode_operations hpfs_dir_iops
=
606 .create
= hpfs_create
,
607 .lookup
= hpfs_lookup
,
608 .unlink
= hpfs_unlink
,
609 .symlink
= hpfs_symlink
,
613 .rename
= hpfs_rename
,
614 .setattr
= hpfs_setattr
,