2 * linux/fs/hpfs/namei.c
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
6 * adding & removing files & directories
9 #include <linux/string.h>
12 int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
14 const char *name = dentry->d_name.name;
15 unsigned len = dentry->d_name.len;
16 struct quad_buffer_head qbh0;
17 struct buffer_head *bh;
18 struct hpfs_dirent *de;
25 struct hpfs_dirent dee;
27 if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
28 if (!(fnode = hpfs_alloc_fnode(dir->i_sb, dir->i_hpfs_dno, &fno, &bh))) goto bail;
29 if (!(dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0, 1))) goto bail1;
30 memset(&dee, 0, sizeof dee);
32 if (!(mode & 0222)) dee.read_only = 1;
34 dee.hidden = name[0] == '.';
36 dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, CURRENT_TIME);
38 r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
39 if (r == 1) goto bail2;
43 hpfs_free_sectors(dir->i_sb, fno, 1);
44 hpfs_free_dnode(dir->i_sb, dno);
45 hpfs_unlock_inode(dir);
49 memcpy(fnode->name, name, len > 15 ? 15 : len);
50 fnode->up = dir->i_ino;
52 fnode->btree.n_free_nodes = 7;
53 fnode->btree.n_used_nodes = 1;
54 fnode->btree.first_free = 0x14;
55 fnode->u.external[0].disk_secno = dno;
56 fnode->u.external[0].file_secno = -1;
57 dnode->root_dnode = 1;
59 de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0);
60 de->creation_date = de->write_date = de->read_date = gmt_to_local(dir->i_sb, CURRENT_TIME);
61 if (!(mode & 0222)) de->read_only = 1;
62 de->first = de->directory = 1;
63 /*de->hidden = de->system = 0;*/
65 mark_buffer_dirty(bh);
67 hpfs_mark_4buffers_dirty(&qbh0);
70 hpfs_lock_iget(dir->i_sb, 1);
71 if ((result = iget(dir->i_sb, fno))) {
72 result->i_hpfs_parent_dir = dir->i_ino;
73 result->i_ctime = result->i_mtime = result->i_atime = local_to_gmt(dir->i_sb, dee.creation_date);
74 result->i_hpfs_ea_size = 0;
75 if (dee.read_only) result->i_mode &= ~0222;
76 if (result->i_uid != current->fsuid ||
77 result->i_gid != current->fsgid ||
78 result->i_mode != (mode | S_IFDIR)) {
79 result->i_uid = current->fsuid;
80 result->i_gid = current->fsgid;
81 result->i_mode = mode | S_IFDIR;
82 hpfs_write_inode_nolock(result);
84 d_instantiate(dentry, result);
86 hpfs_unlock_iget(dir->i_sb);
87 hpfs_unlock_inode(dir);
91 hpfs_free_dnode(dir->i_sb, dno);
92 hpfs_unlock_inode(dir);
95 hpfs_free_sectors(dir->i_sb, fno, 1);
100 int hpfs_create(struct inode *dir, struct dentry *dentry, int mode)
102 const char *name = dentry->d_name.name;
103 unsigned len = dentry->d_name.len;
104 struct inode *result = NULL;
105 struct buffer_head *bh;
109 struct hpfs_dirent dee;
111 if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
112 if (!(fnode = hpfs_alloc_fnode(dir->i_sb, dir->i_hpfs_dno, &fno, &bh))) goto bail;
113 memset(&dee, 0, sizeof dee);
114 if (!(mode & 0222)) dee.read_only = 1;
116 dee.hidden = name[0] == '.';
118 dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, CURRENT_TIME);
119 hpfs_lock_inode(dir);
120 r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
121 if (r == 1) goto bail1;
124 hpfs_free_sectors(dir->i_sb, fno, 1);
125 hpfs_unlock_inode(dir);
129 memcpy(fnode->name, name, len > 15 ? 15 : len);
130 fnode->up = dir->i_ino;
131 mark_buffer_dirty(bh);
133 hpfs_lock_iget(dir->i_sb, 2);
134 if ((result = iget(dir->i_sb, fno))) {
135 hpfs_decide_conv(result, (char *)name, len);
136 result->i_hpfs_parent_dir = dir->i_ino;
137 result->i_ctime = result->i_mtime = result->i_atime = local_to_gmt(dir->i_sb, dee.creation_date);
138 result->i_hpfs_ea_size = 0;
139 if (dee.read_only) result->i_mode &= ~0222;
140 if (result->i_blocks == -1) result->i_blocks = 1;
141 if (result->i_size == -1) {
143 result->i_data.a_ops = &hpfs_aops;
144 result->u.hpfs_i.mmu_private = 0;
146 if (result->i_uid != current->fsuid ||
147 result->i_gid != current->fsgid ||
148 result->i_mode != (mode | S_IFREG)) {
149 result->i_uid = current->fsuid;
150 result->i_gid = current->fsgid;
151 result->i_mode = mode | S_IFREG;
152 hpfs_write_inode_nolock(result);
154 d_instantiate(dentry, result);
156 hpfs_unlock_iget(dir->i_sb);
157 hpfs_unlock_inode(dir);
161 hpfs_free_sectors(dir->i_sb, fno, 1);
162 hpfs_unlock_inode(dir);
167 int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
169 const char *name = dentry->d_name.name;
170 unsigned len = dentry->d_name.len;
171 struct buffer_head *bh;
175 struct hpfs_dirent dee;
176 struct inode *result = NULL;
178 if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
179 if (dir->i_sb->s_hpfs_eas < 2) return -EPERM;
180 if (!(fnode = hpfs_alloc_fnode(dir->i_sb, dir->i_hpfs_dno, &fno, &bh))) goto bail;
181 memset(&dee, 0, sizeof dee);
182 if (!(mode & 0222)) dee.read_only = 1;
184 dee.hidden = name[0] == '.';
186 dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, CURRENT_TIME);
187 hpfs_lock_inode(dir);
188 r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
189 if (r == 1) goto bail1;
192 hpfs_free_sectors(dir->i_sb, fno, 1);
193 hpfs_unlock_inode(dir);
197 memcpy(fnode->name, name, len > 15 ? 15 : len);
198 fnode->up = dir->i_ino;
199 mark_buffer_dirty(bh);
200 hpfs_lock_iget(dir->i_sb, 2);
201 if ((result = iget(dir->i_sb, fno))) {
202 result->i_hpfs_parent_dir = dir->i_ino;
203 result->i_ctime = result->i_mtime = result->i_atime = local_to_gmt(dir->i_sb, dee.creation_date);
204 result->i_hpfs_ea_size = 0;
205 /*if (result->i_blocks == -1) result->i_blocks = 1;
206 if (result->i_size == -1) result->i_size = 0;*/
207 result->i_uid = current->fsuid;
208 result->i_gid = current->fsgid;
211 result->i_blocks = 1;
212 init_special_inode(result, mode, rdev);
213 hpfs_write_inode_nolock(result);
214 d_instantiate(dentry, result);
216 hpfs_unlock_iget(dir->i_sb);
217 hpfs_unlock_inode(dir);
222 hpfs_free_sectors(dir->i_sb, fno, 1);
223 hpfs_unlock_inode(dir);
228 extern struct address_space_operations hpfs_symlink_aops;
230 int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *symlink)
232 const char *name = dentry->d_name.name;
233 unsigned len = dentry->d_name.len;
234 struct buffer_head *bh;
238 struct hpfs_dirent dee;
239 struct inode *result;
241 if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
242 if (dir->i_sb->s_hpfs_eas < 2) return -EPERM;
243 if (!(fnode = hpfs_alloc_fnode(dir->i_sb, dir->i_hpfs_dno, &fno, &bh))) goto bail;
244 memset(&dee, 0, sizeof dee);
246 dee.hidden = name[0] == '.';
248 dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, CURRENT_TIME);
249 hpfs_lock_inode(dir);
250 r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
251 if (r == 1) goto bail1;
254 hpfs_free_sectors(dir->i_sb, fno, 1);
255 hpfs_unlock_inode(dir);
259 memcpy(fnode->name, name, len > 15 ? 15 : len);
260 fnode->up = dir->i_ino;
261 mark_buffer_dirty(bh);
263 hpfs_lock_iget(dir->i_sb, 2);
264 if ((result = iget(dir->i_sb, fno))) {
265 result->i_hpfs_parent_dir = dir->i_ino;
266 result->i_ctime = result->i_mtime = result->i_atime = local_to_gmt(dir->i_sb, dee.creation_date);
267 result->i_hpfs_ea_size = 0;
268 /*if (result->i_blocks == -1) result->i_blocks = 1;
269 if (result->i_size == -1) result->i_size = 0;*/
270 result->i_mode = S_IFLNK | 0777;
271 result->i_uid = current->fsuid;
272 result->i_gid = current->fsgid;
273 result->i_blocks = 1;
274 result->i_size = strlen(symlink);
275 result->i_op = &page_symlink_inode_operations;
276 result->i_data.a_ops = &hpfs_symlink_aops;
277 if ((fnode = hpfs_map_fnode(dir->i_sb, fno, &bh))) {
278 hpfs_set_ea(result, fnode, "SYMLINK", (char *)symlink, strlen(symlink));
279 mark_buffer_dirty(bh);
282 hpfs_write_inode_nolock(result);
283 d_instantiate(dentry, result);
285 hpfs_unlock_iget(dir->i_sb);
286 hpfs_unlock_inode(dir);
290 hpfs_free_sectors(dir->i_sb, fno, 1);
291 hpfs_unlock_inode(dir);
296 int hpfs_unlink(struct inode *dir, struct dentry *dentry)
298 const char *name = dentry->d_name.name;
299 unsigned len = dentry->d_name.len;
300 struct quad_buffer_head qbh;
301 struct hpfs_dirent *de;
302 struct inode *inode = dentry->d_inode;
307 hpfs_adjust_length((char *)name, &len);
309 hpfs_lock_2inodes(dir, inode);
310 if (!(de = map_dirent(dir, dir->i_hpfs_dno, (char *)name, len, &dno, &qbh))) {
311 hpfs_unlock_2inodes(dir, inode);
316 hpfs_unlock_2inodes(dir, inode);
321 hpfs_unlock_2inodes(dir, inode);
325 if ((r = hpfs_remove_dirent(dir, dno, de, &qbh, 1)) == 1) hpfs_error(dir->i_sb, "there was error when removing dirent");
328 hpfs_unlock_2inodes(dir, inode);
329 } else { /* no space for deleting, try to truncate file */
330 struct iattr newattrs;
332 hpfs_unlock_2inodes(dir, inode);
336 if (atomic_read(&dentry->d_count) > 1 ||
337 permission(inode, MAY_WRITE) ||
338 get_write_access(inode)) {
342 /*printk("HPFS: truncating file before delete.\n");*/
344 newattrs.ia_size = 0;
345 newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
346 err = notify_change(dentry, &newattrs);
348 put_write_access(inode);
355 return r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
358 int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
360 const char *name = dentry->d_name.name;
361 unsigned len = dentry->d_name.len;
362 struct quad_buffer_head qbh;
363 struct hpfs_dirent *de;
364 struct inode *inode = dentry->d_inode;
369 hpfs_adjust_length((char *)name, &len);
370 hpfs_lock_2inodes(dir, inode);
371 if (!(de = map_dirent(dir, dir->i_hpfs_dno, (char *)name, len, &dno, &qbh))) {
372 hpfs_unlock_2inodes(dir, inode);
377 hpfs_unlock_2inodes(dir, inode);
380 if (!de->directory) {
382 hpfs_unlock_2inodes(dir, inode);
385 hpfs_count_dnodes(dir->i_sb, inode->i_hpfs_dno, NULL, NULL, &n_items);
388 hpfs_unlock_2inodes(dir, inode);
392 if ((r = hpfs_remove_dirent(dir, dno, de, &qbh, 1)) == 1)
393 hpfs_error(dir->i_sb, "there was error when removing dirent");
397 hpfs_unlock_2inodes(dir, inode);
398 } else hpfs_unlock_2inodes(dir, inode);
399 return r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
402 int hpfs_symlink_readpage(struct file *file, struct page *page)
404 char *link = kmap(page);
405 struct inode *i = page->mapping->host;
407 struct buffer_head *bh;
412 if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh)))
414 err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE);
419 SetPageUptodate(page);
432 int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
433 struct inode *new_dir, struct dentry *new_dentry)
435 char *old_name = (char *)old_dentry->d_name.name;
436 int old_len = old_dentry->d_name.len;
437 char *new_name = (char *)new_dentry->d_name.name;
438 int new_len = new_dentry->d_name.len;
439 struct inode *i = old_dentry->d_inode;
440 struct inode *new_inode = new_dentry->d_inode;
441 struct quad_buffer_head qbh, qbh1;
442 struct hpfs_dirent *dep, *nde;
443 struct hpfs_dirent de;
446 struct buffer_head *bh;
449 if ((err = hpfs_chk_name((char *)new_name, &new_len))) return err;
451 hpfs_adjust_length((char *)old_name, &old_len);
453 hpfs_lock_3inodes(old_dir, new_dir, i);
455 /* Erm? Moving over the empty non-busy directory is perfectly legal */
456 if (new_inode && S_ISDIR(new_inode->i_mode)) {
461 if (!(dep = map_dirent(old_dir, old_dir->i_hpfs_dno, (char *)old_name, old_len, &dno, &qbh))) {
462 hpfs_error(i->i_sb, "lookup succeeded but map dirent failed");
467 de.hidden = new_name[0] == '.';
471 if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) {
472 if ((nde = map_dirent(new_dir, new_dir->i_hpfs_dno, (char *)new_name, new_len, NULL, &qbh1))) {
473 new_inode->i_nlink = 0;
475 memcpy(nde->name, new_name, new_len);
476 hpfs_mark_4buffers_dirty(&qbh1);
480 hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent");
484 err = r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
488 if (new_dir == old_dir) hpfs_brelse4(&qbh);
490 hpfs_lock_creation(i->i_sb);
491 if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de, 1))) {
492 hpfs_unlock_creation(i->i_sb);
493 if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!");
494 err = r == 1 ? -ENOSPC : -EFSERROR;
495 if (new_dir != old_dir) hpfs_brelse4(&qbh);
499 if (new_dir == old_dir)
500 if (!(dep = map_dirent(old_dir, old_dir->i_hpfs_dno, (char *)old_name, old_len, &dno, &qbh))) {
501 hpfs_unlock_creation(i->i_sb);
502 hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2");
507 if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) {
508 hpfs_unlock_creation(i->i_sb);
509 hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent");
510 err = r == 2 ? -ENOSPC : -EFSERROR;
513 hpfs_unlock_creation(i->i_sb);
516 i->i_hpfs_parent_dir = new_dir->i_ino;
517 if (S_ISDIR(i->i_mode)) {
521 if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) {
522 fnode->up = new_dir->i_ino;
523 fnode->len = new_len;
524 memcpy(fnode->name, new_name, new_len>15?15:new_len);
525 if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len);
526 mark_buffer_dirty(bh);
529 i->i_hpfs_conv = i->i_sb->s_hpfs_conv;
530 hpfs_decide_conv(i, (char *)new_name, new_len);
532 hpfs_unlock_3inodes(old_dir, new_dir, i);