1 /*
2 * linux/fs/hpfs/namei.c
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * adding & removing files & directories
7 */
8
9 #include <linux/string.h>
10 #include "hpfs_fn.h"
11
hpfs_mkdir(struct inode * dir,struct dentry * dentry,int mode)12 int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
13 {
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;
19 struct fnode *fnode;
20 struct dnode *dnode;
21 struct inode *result;
22 fnode_secno fno;
23 dnode_secno dno;
24 int r;
25 struct hpfs_dirent dee;
26 int err;
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);
31 dee.directory = 1;
32 if (!(mode & 0222)) dee.read_only = 1;
33 /*dee.archive = 0;*/
34 dee.hidden = name[0] == '.';
35 dee.fnode = fno;
36 dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, CURRENT_TIME);
37 hpfs_lock_inode(dir);
38 r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
39 if (r == 1) goto bail2;
40 if (r == -1) {
41 brelse(bh);
42 hpfs_brelse4(&qbh0);
43 hpfs_free_sectors(dir->i_sb, fno, 1);
44 hpfs_free_dnode(dir->i_sb, dno);
45 hpfs_unlock_inode(dir);
46 return -EEXIST;
47 }
48 fnode->len = len;
49 memcpy(fnode->name, name, len > 15 ? 15 : len);
50 fnode->up = dir->i_ino;
51 fnode->dirflag = 1;
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;
58 dnode->up = fno;
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;*/
64 de->fnode = fno;
65 mark_buffer_dirty(bh);
66 brelse(bh);
67 hpfs_mark_4buffers_dirty(&qbh0);
68 hpfs_brelse4(&qbh0);
69 dir->i_nlink++;
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);
83 }
84 d_instantiate(dentry, result);
85 }
86 hpfs_unlock_iget(dir->i_sb);
87 hpfs_unlock_inode(dir);
88 return 0;
89 bail2:
90 hpfs_brelse4(&qbh0);
91 hpfs_free_dnode(dir->i_sb, dno);
92 hpfs_unlock_inode(dir);
93 bail1:
94 brelse(bh);
95 hpfs_free_sectors(dir->i_sb, fno, 1);
96 bail:
97 return -ENOSPC;
98 }
99
hpfs_create(struct inode * dir,struct dentry * dentry,int mode)100 int hpfs_create(struct inode *dir, struct dentry *dentry, int mode)
101 {
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;
106 struct fnode *fnode;
107 fnode_secno fno;
108 int r;
109 struct hpfs_dirent dee;
110 int err;
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;
115 dee.archive = 1;
116 dee.hidden = name[0] == '.';
117 dee.fnode = fno;
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;
122 if (r == -1) {
123 brelse(bh);
124 hpfs_free_sectors(dir->i_sb, fno, 1);
125 hpfs_unlock_inode(dir);
126 return -EEXIST;
127 }
128 fnode->len = len;
129 memcpy(fnode->name, name, len > 15 ? 15 : len);
130 fnode->up = dir->i_ino;
131 mark_buffer_dirty(bh);
132 brelse(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) {
142 result->i_size = 0;
143 result->i_data.a_ops = &hpfs_aops;
144 result->u.hpfs_i.mmu_private = 0;
145 }
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);
153 }
154 d_instantiate(dentry, result);
155 }
156 hpfs_unlock_iget(dir->i_sb);
157 hpfs_unlock_inode(dir);
158 return 0;
159 bail1:
160 brelse(bh);
161 hpfs_free_sectors(dir->i_sb, fno, 1);
162 hpfs_unlock_inode(dir);
163 bail:
164 return -ENOSPC;
165 }
166
hpfs_mknod(struct inode * dir,struct dentry * dentry,int mode,int rdev)167 int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
168 {
169 const char *name = dentry->d_name.name;
170 unsigned len = dentry->d_name.len;
171 struct buffer_head *bh;
172 struct fnode *fnode;
173 fnode_secno fno;
174 int r;
175 struct hpfs_dirent dee;
176 struct inode *result = NULL;
177 int err;
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;
183 dee.archive = 1;
184 dee.hidden = name[0] == '.';
185 dee.fnode = fno;
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;
190 if (r == -1) {
191 brelse(bh);
192 hpfs_free_sectors(dir->i_sb, fno, 1);
193 hpfs_unlock_inode(dir);
194 return -EEXIST;
195 }
196 fnode->len = len;
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;
209 result->i_nlink = 1;
210 result->i_size = 0;
211 result->i_blocks = 1;
212 init_special_inode(result, mode, rdev);
213 hpfs_write_inode_nolock(result);
214 d_instantiate(dentry, result);
215 }
216 hpfs_unlock_iget(dir->i_sb);
217 hpfs_unlock_inode(dir);
218 brelse(bh);
219 return 0;
220 bail1:
221 brelse(bh);
222 hpfs_free_sectors(dir->i_sb, fno, 1);
223 hpfs_unlock_inode(dir);
224 bail:
225 return -ENOSPC;
226 }
227
228 extern struct address_space_operations hpfs_symlink_aops;
229
hpfs_symlink(struct inode * dir,struct dentry * dentry,const char * symlink)230 int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *symlink)
231 {
232 const char *name = dentry->d_name.name;
233 unsigned len = dentry->d_name.len;
234 struct buffer_head *bh;
235 struct fnode *fnode;
236 fnode_secno fno;
237 int r;
238 struct hpfs_dirent dee;
239 struct inode *result;
240 int err;
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);
245 dee.archive = 1;
246 dee.hidden = name[0] == '.';
247 dee.fnode = fno;
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;
252 if (r == -1) {
253 brelse(bh);
254 hpfs_free_sectors(dir->i_sb, fno, 1);
255 hpfs_unlock_inode(dir);
256 return -EEXIST;
257 }
258 fnode->len = len;
259 memcpy(fnode->name, name, len > 15 ? 15 : len);
260 fnode->up = dir->i_ino;
261 mark_buffer_dirty(bh);
262 brelse(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);
280 brelse(bh);
281 }
282 hpfs_write_inode_nolock(result);
283 d_instantiate(dentry, result);
284 }
285 hpfs_unlock_iget(dir->i_sb);
286 hpfs_unlock_inode(dir);
287 return 0;
288 bail1:
289 brelse(bh);
290 hpfs_free_sectors(dir->i_sb, fno, 1);
291 hpfs_unlock_inode(dir);
292 bail:
293 return -ENOSPC;
294 }
295
hpfs_unlink(struct inode * dir,struct dentry * dentry)296 int hpfs_unlink(struct inode *dir, struct dentry *dentry)
297 {
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;
303 dnode_secno dno;
304 fnode_secno fno;
305 int r;
306 int rep = 0;
307 hpfs_adjust_length((char *)name, &len);
308 again:
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);
312 return -ENOENT;
313 }
314 if (de->first) {
315 hpfs_brelse4(&qbh);
316 hpfs_unlock_2inodes(dir, inode);
317 return -EPERM;
318 }
319 if (de->directory) {
320 hpfs_brelse4(&qbh);
321 hpfs_unlock_2inodes(dir, inode);
322 return -EISDIR;
323 }
324 fno = de->fnode;
325 if ((r = hpfs_remove_dirent(dir, dno, de, &qbh, 1)) == 1) hpfs_error(dir->i_sb, "there was error when removing dirent");
326 if (r != 2) {
327 inode->i_nlink--;
328 hpfs_unlock_2inodes(dir, inode);
329 } else { /* no space for deleting, try to truncate file */
330 struct iattr newattrs;
331 int err;
332 hpfs_unlock_2inodes(dir, inode);
333 if (rep)
334 goto ret;
335 d_drop(dentry);
336 if (atomic_read(&dentry->d_count) > 1 ||
337 permission(inode, MAY_WRITE) ||
338 get_write_access(inode)) {
339 d_rehash(dentry);
340 goto ret;
341 }
342 /*printk("HPFS: truncating file before delete.\n");*/
343 down(&inode->i_sem);
344 newattrs.ia_size = 0;
345 newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
346 err = notify_change(dentry, &newattrs);
347 up(&inode->i_sem);
348 put_write_access(inode);
349 if (err)
350 goto ret;
351 rep = 1;
352 goto again;
353 }
354 ret:
355 return r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
356 }
357
hpfs_rmdir(struct inode * dir,struct dentry * dentry)358 int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
359 {
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;
365 dnode_secno dno;
366 fnode_secno fno;
367 int n_items = 0;
368 int r;
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);
373 return -ENOENT;
374 }
375 if (de->first) {
376 hpfs_brelse4(&qbh);
377 hpfs_unlock_2inodes(dir, inode);
378 return -EPERM;
379 }
380 if (!de->directory) {
381 hpfs_brelse4(&qbh);
382 hpfs_unlock_2inodes(dir, inode);
383 return -ENOTDIR;
384 }
385 hpfs_count_dnodes(dir->i_sb, inode->i_hpfs_dno, NULL, NULL, &n_items);
386 if (n_items) {
387 hpfs_brelse4(&qbh);
388 hpfs_unlock_2inodes(dir, inode);
389 return -ENOTEMPTY;
390 }
391 fno = de->fnode;
392 if ((r = hpfs_remove_dirent(dir, dno, de, &qbh, 1)) == 1)
393 hpfs_error(dir->i_sb, "there was error when removing dirent");
394 if (r != 2) {
395 dir->i_nlink--;
396 inode->i_nlink = 0;
397 hpfs_unlock_2inodes(dir, inode);
398 } else hpfs_unlock_2inodes(dir, inode);
399 return r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
400 }
401
hpfs_symlink_readpage(struct file * file,struct page * page)402 int hpfs_symlink_readpage(struct file *file, struct page *page)
403 {
404 char *link = kmap(page);
405 struct inode *i = page->mapping->host;
406 struct fnode *fnode;
407 struct buffer_head *bh;
408 int err;
409
410 err = -EIO;
411 lock_kernel();
412 if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh)))
413 goto fail;
414 err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE);
415 brelse(bh);
416 if (err)
417 goto fail;
418 unlock_kernel();
419 SetPageUptodate(page);
420 kunmap(page);
421 UnlockPage(page);
422 return 0;
423
424 fail:
425 unlock_kernel();
426 SetPageError(page);
427 kunmap(page);
428 UnlockPage(page);
429 return err;
430 }
431
hpfs_rename(struct inode * old_dir,struct dentry * old_dentry,struct inode * new_dir,struct dentry * new_dentry)432 int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
433 struct inode *new_dir, struct dentry *new_dentry)
434 {
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;
444 dnode_secno dno;
445 int r;
446 struct buffer_head *bh;
447 struct fnode *fnode;
448 int err;
449 if ((err = hpfs_chk_name((char *)new_name, &new_len))) return err;
450 err = 0;
451 hpfs_adjust_length((char *)old_name, &old_len);
452
453 hpfs_lock_3inodes(old_dir, new_dir, i);
454
455 /* Erm? Moving over the empty non-busy directory is perfectly legal */
456 if (new_inode && S_ISDIR(new_inode->i_mode)) {
457 err = -EINVAL;
458 goto end1;
459 }
460
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");
463 err = -ENOENT;
464 goto end1;
465 }
466 copy_de(&de, dep);
467 de.hidden = new_name[0] == '.';
468
469 if (new_inode) {
470 int r;
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;
474 copy_de(nde, &de);
475 memcpy(nde->name, new_name, new_len);
476 hpfs_mark_4buffers_dirty(&qbh1);
477 hpfs_brelse4(&qbh1);
478 goto end;
479 }
480 hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent");
481 err = -EFSERROR;
482 goto end1;
483 }
484 err = r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
485 goto end1;
486 }
487
488 if (new_dir == old_dir) hpfs_brelse4(&qbh);
489
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);
496 goto end1;
497 }
498
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");
503 err = -ENOENT;
504 goto end1;
505 }
506
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;
511 goto end1;
512 }
513 hpfs_unlock_creation(i->i_sb);
514
515 end:
516 i->i_hpfs_parent_dir = new_dir->i_ino;
517 if (S_ISDIR(i->i_mode)) {
518 new_dir->i_nlink++;
519 old_dir->i_nlink--;
520 }
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);
527 brelse(bh);
528 }
529 i->i_hpfs_conv = i->i_sb->s_hpfs_conv;
530 hpfs_decide_conv(i, (char *)new_name, new_len);
531 end1:
532 hpfs_unlock_3inodes(old_dir, new_dir, i);
533 return err;
534 }
535