2 * linux/fs/hpfs/namei.c
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
6 * adding & removing files & directories
8 #include <linux/sched.h>
11 static int hpfs_mkdir(struct inode
*dir
, struct dentry
*dentry
, int mode
)
13 const unsigned char *name
= dentry
->d_name
.name
;
14 unsigned len
= dentry
->d_name
.len
;
15 struct quad_buffer_head qbh0
;
16 struct buffer_head
*bh
;
17 struct hpfs_dirent
*de
;
24 struct hpfs_dirent dee
;
26 if ((err
= hpfs_chk_name(name
, &len
))) return err
==-ENOENT
? -EINVAL
: err
;
29 fnode
= hpfs_alloc_fnode(dir
->i_sb
, hpfs_i(dir
)->i_dno
, &fno
, &bh
);
32 dnode
= hpfs_alloc_dnode(dir
->i_sb
, fno
, &dno
, &qbh0
);
35 memset(&dee
, 0, sizeof dee
);
37 if (!(mode
& 0222)) dee
.read_only
= 1;
39 dee
.hidden
= name
[0] == '.';
40 dee
.fnode
= cpu_to_le32(fno
);
41 dee
.creation_date
= dee
.write_date
= dee
.read_date
= cpu_to_le32(gmt_to_local(dir
->i_sb
, get_seconds()));
42 result
= new_inode(dir
->i_sb
);
45 hpfs_init_inode(result
);
47 hpfs_i(result
)->i_parent_dir
= dir
->i_ino
;
48 hpfs_i(result
)->i_dno
= dno
;
49 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
));
50 result
->i_ctime
.tv_nsec
= 0;
51 result
->i_mtime
.tv_nsec
= 0;
52 result
->i_atime
.tv_nsec
= 0;
53 hpfs_i(result
)->i_ea_size
= 0;
54 result
->i_mode
|= S_IFDIR
;
55 result
->i_op
= &hpfs_dir_iops
;
56 result
->i_fop
= &hpfs_dir_ops
;
58 result
->i_size
= 2048;
61 result
->i_mode
&= ~0222;
63 r
= hpfs_add_dirent(dir
, name
, len
, &dee
);
71 memcpy(fnode
->name
, name
, len
> 15 ? 15 : len
);
72 fnode
->up
= cpu_to_le32(dir
->i_ino
);
74 fnode
->btree
.n_free_nodes
= 7;
75 fnode
->btree
.n_used_nodes
= 1;
76 fnode
->btree
.first_free
= cpu_to_le16(0x14);
77 fnode
->u
.external
[0].disk_secno
= cpu_to_le32(dno
);
78 fnode
->u
.external
[0].file_secno
= cpu_to_le32(-1);
79 dnode
->root_dnode
= 1;
80 dnode
->up
= cpu_to_le32(fno
);
81 de
= hpfs_add_de(dir
->i_sb
, dnode
, "\001\001", 2, 0);
82 de
->creation_date
= de
->write_date
= de
->read_date
= cpu_to_le32(gmt_to_local(dir
->i_sb
, get_seconds()));
83 if (!(mode
& 0222)) de
->read_only
= 1;
84 de
->first
= de
->directory
= 1;
85 /*de->hidden = de->system = 0;*/
86 de
->fnode
= cpu_to_le32(fno
);
87 mark_buffer_dirty(bh
);
89 hpfs_mark_4buffers_dirty(&qbh0
);
92 insert_inode_hash(result
);
94 if (result
->i_uid
!= current_fsuid() ||
95 result
->i_gid
!= current_fsgid() ||
96 result
->i_mode
!= (mode
| S_IFDIR
)) {
97 result
->i_uid
= current_fsuid();
98 result
->i_gid
= current_fsgid();
99 result
->i_mode
= mode
| S_IFDIR
;
100 hpfs_write_inode_nolock(result
);
102 d_instantiate(dentry
, result
);
103 hpfs_unlock(dir
->i_sb
);
109 hpfs_free_dnode(dir
->i_sb
, dno
);
112 hpfs_free_sectors(dir
->i_sb
, fno
, 1);
114 hpfs_unlock(dir
->i_sb
);
118 static int hpfs_create(struct inode
*dir
, struct dentry
*dentry
, int mode
, struct nameidata
*nd
)
120 const unsigned char *name
= dentry
->d_name
.name
;
121 unsigned len
= dentry
->d_name
.len
;
122 struct inode
*result
= NULL
;
123 struct buffer_head
*bh
;
127 struct hpfs_dirent dee
;
129 if ((err
= hpfs_chk_name(name
, &len
)))
130 return err
==-ENOENT
? -EINVAL
: err
;
131 hpfs_lock(dir
->i_sb
);
133 fnode
= hpfs_alloc_fnode(dir
->i_sb
, hpfs_i(dir
)->i_dno
, &fno
, &bh
);
136 memset(&dee
, 0, sizeof dee
);
137 if (!(mode
& 0222)) dee
.read_only
= 1;
139 dee
.hidden
= name
[0] == '.';
140 dee
.fnode
= cpu_to_le32(fno
);
141 dee
.creation_date
= dee
.write_date
= dee
.read_date
= cpu_to_le32(gmt_to_local(dir
->i_sb
, get_seconds()));
143 result
= new_inode(dir
->i_sb
);
147 hpfs_init_inode(result
);
149 result
->i_mode
|= S_IFREG
;
150 result
->i_mode
&= ~0111;
151 result
->i_op
= &hpfs_file_iops
;
152 result
->i_fop
= &hpfs_file_ops
;
153 set_nlink(result
, 1);
154 hpfs_i(result
)->i_parent_dir
= dir
->i_ino
;
155 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
));
156 result
->i_ctime
.tv_nsec
= 0;
157 result
->i_mtime
.tv_nsec
= 0;
158 result
->i_atime
.tv_nsec
= 0;
159 hpfs_i(result
)->i_ea_size
= 0;
161 result
->i_mode
&= ~0222;
162 result
->i_blocks
= 1;
164 result
->i_data
.a_ops
= &hpfs_aops
;
165 hpfs_i(result
)->mmu_private
= 0;
167 r
= hpfs_add_dirent(dir
, name
, len
, &dee
);
175 memcpy(fnode
->name
, name
, len
> 15 ? 15 : len
);
176 fnode
->up
= cpu_to_le32(dir
->i_ino
);
177 mark_buffer_dirty(bh
);
180 insert_inode_hash(result
);
182 if (result
->i_uid
!= current_fsuid() ||
183 result
->i_gid
!= current_fsgid() ||
184 result
->i_mode
!= (mode
| S_IFREG
)) {
185 result
->i_uid
= current_fsuid();
186 result
->i_gid
= current_fsgid();
187 result
->i_mode
= mode
| S_IFREG
;
188 hpfs_write_inode_nolock(result
);
190 d_instantiate(dentry
, result
);
191 hpfs_unlock(dir
->i_sb
);
198 hpfs_free_sectors(dir
->i_sb
, fno
, 1);
200 hpfs_unlock(dir
->i_sb
);
204 static int hpfs_mknod(struct inode
*dir
, struct dentry
*dentry
, int mode
, dev_t rdev
)
206 const unsigned char *name
= dentry
->d_name
.name
;
207 unsigned len
= dentry
->d_name
.len
;
208 struct buffer_head
*bh
;
212 struct hpfs_dirent dee
;
213 struct inode
*result
= NULL
;
215 if ((err
= hpfs_chk_name(name
, &len
))) return err
==-ENOENT
? -EINVAL
: err
;
216 if (hpfs_sb(dir
->i_sb
)->sb_eas
< 2) return -EPERM
;
217 if (!new_valid_dev(rdev
))
219 hpfs_lock(dir
->i_sb
);
221 fnode
= hpfs_alloc_fnode(dir
->i_sb
, hpfs_i(dir
)->i_dno
, &fno
, &bh
);
224 memset(&dee
, 0, sizeof dee
);
225 if (!(mode
& 0222)) dee
.read_only
= 1;
227 dee
.hidden
= name
[0] == '.';
228 dee
.fnode
= cpu_to_le32(fno
);
229 dee
.creation_date
= dee
.write_date
= dee
.read_date
= cpu_to_le32(gmt_to_local(dir
->i_sb
, get_seconds()));
231 result
= new_inode(dir
->i_sb
);
235 hpfs_init_inode(result
);
237 hpfs_i(result
)->i_parent_dir
= dir
->i_ino
;
238 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
));
239 result
->i_ctime
.tv_nsec
= 0;
240 result
->i_mtime
.tv_nsec
= 0;
241 result
->i_atime
.tv_nsec
= 0;
242 hpfs_i(result
)->i_ea_size
= 0;
243 result
->i_uid
= current_fsuid();
244 result
->i_gid
= current_fsgid();
245 set_nlink(result
, 1);
247 result
->i_blocks
= 1;
248 init_special_inode(result
, mode
, rdev
);
250 r
= hpfs_add_dirent(dir
, name
, len
, &dee
);
258 memcpy(fnode
->name
, name
, len
> 15 ? 15 : len
);
259 fnode
->up
= cpu_to_le32(dir
->i_ino
);
260 mark_buffer_dirty(bh
);
262 insert_inode_hash(result
);
264 hpfs_write_inode_nolock(result
);
265 d_instantiate(dentry
, result
);
267 hpfs_unlock(dir
->i_sb
);
273 hpfs_free_sectors(dir
->i_sb
, fno
, 1);
275 hpfs_unlock(dir
->i_sb
);
279 static int hpfs_symlink(struct inode
*dir
, struct dentry
*dentry
, const char *symlink
)
281 const unsigned char *name
= dentry
->d_name
.name
;
282 unsigned len
= dentry
->d_name
.len
;
283 struct buffer_head
*bh
;
287 struct hpfs_dirent dee
;
288 struct inode
*result
;
290 if ((err
= hpfs_chk_name(name
, &len
))) return err
==-ENOENT
? -EINVAL
: err
;
291 hpfs_lock(dir
->i_sb
);
292 if (hpfs_sb(dir
->i_sb
)->sb_eas
< 2) {
293 hpfs_unlock(dir
->i_sb
);
297 fnode
= hpfs_alloc_fnode(dir
->i_sb
, hpfs_i(dir
)->i_dno
, &fno
, &bh
);
300 memset(&dee
, 0, sizeof dee
);
302 dee
.hidden
= name
[0] == '.';
303 dee
.fnode
= cpu_to_le32(fno
);
304 dee
.creation_date
= dee
.write_date
= dee
.read_date
= cpu_to_le32(gmt_to_local(dir
->i_sb
, get_seconds()));
306 result
= new_inode(dir
->i_sb
);
310 hpfs_init_inode(result
);
311 hpfs_i(result
)->i_parent_dir
= dir
->i_ino
;
312 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
));
313 result
->i_ctime
.tv_nsec
= 0;
314 result
->i_mtime
.tv_nsec
= 0;
315 result
->i_atime
.tv_nsec
= 0;
316 hpfs_i(result
)->i_ea_size
= 0;
317 result
->i_mode
= S_IFLNK
| 0777;
318 result
->i_uid
= current_fsuid();
319 result
->i_gid
= current_fsgid();
320 result
->i_blocks
= 1;
321 set_nlink(result
, 1);
322 result
->i_size
= strlen(symlink
);
323 result
->i_op
= &page_symlink_inode_operations
;
324 result
->i_data
.a_ops
= &hpfs_symlink_aops
;
326 r
= hpfs_add_dirent(dir
, name
, len
, &dee
);
334 memcpy(fnode
->name
, name
, len
> 15 ? 15 : len
);
335 fnode
->up
= cpu_to_le32(dir
->i_ino
);
336 hpfs_set_ea(result
, fnode
, "SYMLINK", symlink
, strlen(symlink
));
337 mark_buffer_dirty(bh
);
340 insert_inode_hash(result
);
342 hpfs_write_inode_nolock(result
);
343 d_instantiate(dentry
, result
);
344 hpfs_unlock(dir
->i_sb
);
350 hpfs_free_sectors(dir
->i_sb
, fno
, 1);
352 hpfs_unlock(dir
->i_sb
);
356 static int hpfs_unlink(struct inode
*dir
, struct dentry
*dentry
)
358 const unsigned char *name
= dentry
->d_name
.name
;
359 unsigned len
= dentry
->d_name
.len
;
360 struct quad_buffer_head qbh
;
361 struct hpfs_dirent
*de
;
362 struct inode
*inode
= dentry
->d_inode
;
368 hpfs_lock(dir
->i_sb
);
369 hpfs_adjust_length(name
, &len
);
372 de
= map_dirent(dir
, hpfs_i(dir
)->i_dno
, name
, len
, &dno
, &qbh
);
384 r
= hpfs_remove_dirent(dir
, dno
, de
, &qbh
, 1);
387 hpfs_error(dir
->i_sb
, "there was error when removing dirent");
390 case 2: /* no space for deleting, try to truncate file */
396 dentry_unhash(dentry
);
397 if (!d_unhashed(dentry
)) {
398 hpfs_unlock(dir
->i_sb
);
401 if (generic_permission(inode
, MAY_WRITE
) ||
402 !S_ISREG(inode
->i_mode
) ||
403 get_write_access(inode
)) {
406 struct iattr newattrs
;
407 /*printk("HPFS: truncating file before delete.\n");*/
408 newattrs
.ia_size
= 0;
409 newattrs
.ia_valid
= ATTR_SIZE
| ATTR_CTIME
;
410 err
= notify_change(dentry
, &newattrs
);
411 put_write_access(inode
);
415 hpfs_unlock(dir
->i_sb
);
426 hpfs_unlock(dir
->i_sb
);
430 static int hpfs_rmdir(struct inode
*dir
, struct dentry
*dentry
)
432 const unsigned char *name
= dentry
->d_name
.name
;
433 unsigned len
= dentry
->d_name
.len
;
434 struct quad_buffer_head qbh
;
435 struct hpfs_dirent
*de
;
436 struct inode
*inode
= dentry
->d_inode
;
442 hpfs_adjust_length(name
, &len
);
443 hpfs_lock(dir
->i_sb
);
445 de
= map_dirent(dir
, hpfs_i(dir
)->i_dno
, name
, len
, &dno
, &qbh
);
457 hpfs_count_dnodes(dir
->i_sb
, hpfs_i(inode
)->i_dno
, NULL
, NULL
, &n_items
);
462 r
= hpfs_remove_dirent(dir
, dno
, de
, &qbh
, 1);
465 hpfs_error(dir
->i_sb
, "there was error when removing dirent");
480 hpfs_unlock(dir
->i_sb
);
484 static int hpfs_symlink_readpage(struct file
*file
, struct page
*page
)
486 char *link
= kmap(page
);
487 struct inode
*i
= page
->mapping
->host
;
489 struct buffer_head
*bh
;
494 if (!(fnode
= hpfs_map_fnode(i
->i_sb
, i
->i_ino
, &bh
)))
496 err
= hpfs_read_ea(i
->i_sb
, fnode
, "SYMLINK", link
, PAGE_SIZE
);
500 hpfs_unlock(i
->i_sb
);
501 SetPageUptodate(page
);
507 hpfs_unlock(i
->i_sb
);
514 const struct address_space_operations hpfs_symlink_aops
= {
515 .readpage
= hpfs_symlink_readpage
518 static int hpfs_rename(struct inode
*old_dir
, struct dentry
*old_dentry
,
519 struct inode
*new_dir
, struct dentry
*new_dentry
)
521 const unsigned char *old_name
= old_dentry
->d_name
.name
;
522 unsigned old_len
= old_dentry
->d_name
.len
;
523 const unsigned char *new_name
= new_dentry
->d_name
.name
;
524 unsigned new_len
= new_dentry
->d_name
.len
;
525 struct inode
*i
= old_dentry
->d_inode
;
526 struct inode
*new_inode
= new_dentry
->d_inode
;
527 struct quad_buffer_head qbh
, qbh1
;
528 struct hpfs_dirent
*dep
, *nde
;
529 struct hpfs_dirent de
;
532 struct buffer_head
*bh
;
536 if ((err
= hpfs_chk_name(new_name
, &new_len
))) return err
;
538 hpfs_adjust_length(old_name
, &old_len
);
541 /* order doesn't matter, due to VFS exclusion */
543 /* Erm? Moving over the empty non-busy directory is perfectly legal */
544 if (new_inode
&& S_ISDIR(new_inode
->i_mode
)) {
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");
555 de
.hidden
= new_name
[0] == '.';
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
);
563 memcpy(nde
->name
, new_name
, new_len
);
564 hpfs_mark_4buffers_dirty(&qbh1
);
568 hpfs_error(new_dir
->i_sb
, "hpfs_rename: could not find dirent");
572 err
= r
== 2 ? -ENOSPC
: r
== 1 ? -EFSERROR
: 0;
576 if (new_dir
== old_dir
) hpfs_brelse4(&qbh
);
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
);
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");
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
;
599 hpfs_i(i
)->i_parent_dir
= new_dir
->i_ino
;
600 if (S_ISDIR(i
->i_mode
)) {
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
);
613 hpfs_unlock(i
->i_sb
);
617 const struct inode_operations hpfs_dir_iops
=
619 .create
= hpfs_create
,
620 .lookup
= hpfs_lookup
,
621 .unlink
= hpfs_unlink
,
622 .symlink
= hpfs_symlink
,
626 .rename
= hpfs_rename
,
627 .setattr
= hpfs_setattr
,