Linux Audio

Check our new training course

Loading...
v4.10.11
 
  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#include <linux/sched.h>
  9#include "hpfs_fn.h"
 10
 11static void hpfs_update_directory_times(struct inode *dir)
 12{
 13	time_t t = get_seconds();
 14	if (t == dir->i_mtime.tv_sec &&
 15	    t == dir->i_ctime.tv_sec)
 16		return;
 17	dir->i_mtime.tv_sec = dir->i_ctime.tv_sec = t;
 18	dir->i_mtime.tv_nsec = dir->i_ctime.tv_nsec = 0;
 19	hpfs_write_inode_nolock(dir);
 20}
 21
 22static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 
 23{
 24	const unsigned char *name = dentry->d_name.name;
 25	unsigned len = dentry->d_name.len;
 26	struct quad_buffer_head qbh0;
 27	struct buffer_head *bh;
 28	struct hpfs_dirent *de;
 29	struct fnode *fnode;
 30	struct dnode *dnode;
 31	struct inode *result;
 32	fnode_secno fno;
 33	dnode_secno dno;
 34	int r;
 35	struct hpfs_dirent dee;
 36	int err;
 37	if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
 38	hpfs_lock(dir->i_sb);
 39	err = -ENOSPC;
 40	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
 41	if (!fnode)
 42		goto bail;
 43	dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0);
 44	if (!dnode)
 45		goto bail1;
 46	memset(&dee, 0, sizeof dee);
 47	dee.directory = 1;
 48	if (!(mode & 0222)) dee.read_only = 1;
 49	/*dee.archive = 0;*/
 50	dee.hidden = name[0] == '.';
 51	dee.fnode = cpu_to_le32(fno);
 52	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds()));
 53	result = new_inode(dir->i_sb);
 54	if (!result)
 55		goto bail2;
 56	hpfs_init_inode(result);
 57	result->i_ino = fno;
 58	hpfs_i(result)->i_parent_dir = dir->i_ino;
 59	hpfs_i(result)->i_dno = dno;
 60	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));
 61	result->i_ctime.tv_nsec = 0; 
 62	result->i_mtime.tv_nsec = 0; 
 63	result->i_atime.tv_nsec = 0; 
 64	hpfs_i(result)->i_ea_size = 0;
 65	result->i_mode |= S_IFDIR;
 66	result->i_op = &hpfs_dir_iops;
 67	result->i_fop = &hpfs_dir_ops;
 68	result->i_blocks = 4;
 69	result->i_size = 2048;
 70	set_nlink(result, 2);
 71	if (dee.read_only)
 72		result->i_mode &= ~0222;
 73
 74	r = hpfs_add_dirent(dir, name, len, &dee);
 75	if (r == 1)
 76		goto bail3;
 77	if (r == -1) {
 78		err = -EEXIST;
 79		goto bail3;
 80	}
 81	fnode->len = len;
 82	memcpy(fnode->name, name, len > 15 ? 15 : len);
 83	fnode->up = cpu_to_le32(dir->i_ino);
 84	fnode->flags |= FNODE_dir;
 85	fnode->btree.n_free_nodes = 7;
 86	fnode->btree.n_used_nodes = 1;
 87	fnode->btree.first_free = cpu_to_le16(0x14);
 88	fnode->u.external[0].disk_secno = cpu_to_le32(dno);
 89	fnode->u.external[0].file_secno = cpu_to_le32(-1);
 90	dnode->root_dnode = 1;
 91	dnode->up = cpu_to_le32(fno);
 92	de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0);
 93	de->creation_date = de->write_date = de->read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds()));
 94	if (!(mode & 0222)) de->read_only = 1;
 95	de->first = de->directory = 1;
 96	/*de->hidden = de->system = 0;*/
 97	de->fnode = cpu_to_le32(fno);
 98	mark_buffer_dirty(bh);
 99	brelse(bh);
100	hpfs_mark_4buffers_dirty(&qbh0);
101	hpfs_brelse4(&qbh0);
102	inc_nlink(dir);
103	insert_inode_hash(result);
104
105	if (!uid_eq(result->i_uid, current_fsuid()) ||
106	    !gid_eq(result->i_gid, current_fsgid()) ||
107	    result->i_mode != (mode | S_IFDIR)) {
108		result->i_uid = current_fsuid();
109		result->i_gid = current_fsgid();
110		result->i_mode = mode | S_IFDIR;
111		hpfs_write_inode_nolock(result);
112	}
113	hpfs_update_directory_times(dir);
114	d_instantiate(dentry, result);
115	hpfs_unlock(dir->i_sb);
116	return 0;
117bail3:
118	iput(result);
119bail2:
120	hpfs_brelse4(&qbh0);
121	hpfs_free_dnode(dir->i_sb, dno);
122bail1:
123	brelse(bh);
124	hpfs_free_sectors(dir->i_sb, fno, 1);
125bail:
126	hpfs_unlock(dir->i_sb);
127	return err;
128}
129
130static int hpfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl)
 
131{
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;
136	struct fnode *fnode;
137	fnode_secno fno;
138	int r;
139	struct hpfs_dirent dee;
140	int err;
141	if ((err = hpfs_chk_name(name, &len)))
142		return err==-ENOENT ? -EINVAL : err;
143	hpfs_lock(dir->i_sb);
144	err = -ENOSPC;
145	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
146	if (!fnode)
147		goto bail;
148	memset(&dee, 0, sizeof dee);
149	if (!(mode & 0222)) dee.read_only = 1;
150	dee.archive = 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(gmt_to_local(dir->i_sb, get_seconds()));
154
155	result = new_inode(dir->i_sb);
156	if (!result)
157		goto bail1;
158	
159	hpfs_init_inode(result);
160	result->i_ino = fno;
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	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));
168	result->i_ctime.tv_nsec = 0;
169	result->i_mtime.tv_nsec = 0;
170	result->i_atime.tv_nsec = 0;
171	hpfs_i(result)->i_ea_size = 0;
172	if (dee.read_only)
173		result->i_mode &= ~0222;
174	result->i_blocks = 1;
175	result->i_size = 0;
176	result->i_data.a_ops = &hpfs_aops;
177	hpfs_i(result)->mmu_private = 0;
178
179	r = hpfs_add_dirent(dir, name, len, &dee);
180	if (r == 1)
181		goto bail2;
182	if (r == -1) {
183		err = -EEXIST;
184		goto bail2;
185	}
186	fnode->len = len;
187	memcpy(fnode->name, name, len > 15 ? 15 : len);
188	fnode->up = cpu_to_le32(dir->i_ino);
189	mark_buffer_dirty(bh);
190	brelse(bh);
191
192	insert_inode_hash(result);
193
194	if (!uid_eq(result->i_uid, current_fsuid()) ||
195	    !gid_eq(result->i_gid, current_fsgid()) ||
196	    result->i_mode != (mode | S_IFREG)) {
197		result->i_uid = current_fsuid();
198		result->i_gid = current_fsgid();
199		result->i_mode = mode | S_IFREG;
200		hpfs_write_inode_nolock(result);
201	}
202	hpfs_update_directory_times(dir);
203	d_instantiate(dentry, result);
204	hpfs_unlock(dir->i_sb);
205	return 0;
206
207bail2:
208	iput(result);
209bail1:
210	brelse(bh);
211	hpfs_free_sectors(dir->i_sb, fno, 1);
212bail:
213	hpfs_unlock(dir->i_sb);
214	return err;
215}
216
217static int hpfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev)
 
218{
219	const unsigned char *name = dentry->d_name.name;
220	unsigned len = dentry->d_name.len;
221	struct buffer_head *bh;
222	struct fnode *fnode;
223	fnode_secno fno;
224	int r;
225	struct hpfs_dirent dee;
226	struct inode *result = NULL;
227	int err;
228	if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
229	if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM;
230	hpfs_lock(dir->i_sb);
231	err = -ENOSPC;
232	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
233	if (!fnode)
234		goto bail;
235	memset(&dee, 0, sizeof dee);
236	if (!(mode & 0222)) dee.read_only = 1;
237	dee.archive = 1;
238	dee.hidden = name[0] == '.';
239	dee.fnode = cpu_to_le32(fno);
240	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds()));
241
242	result = new_inode(dir->i_sb);
243	if (!result)
244		goto bail1;
245
246	hpfs_init_inode(result);
247	result->i_ino = fno;
248	hpfs_i(result)->i_parent_dir = dir->i_ino;
249	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));
250	result->i_ctime.tv_nsec = 0;
251	result->i_mtime.tv_nsec = 0;
252	result->i_atime.tv_nsec = 0;
253	hpfs_i(result)->i_ea_size = 0;
254	result->i_uid = current_fsuid();
255	result->i_gid = current_fsgid();
256	set_nlink(result, 1);
257	result->i_size = 0;
258	result->i_blocks = 1;
259	init_special_inode(result, mode, rdev);
260
261	r = hpfs_add_dirent(dir, name, len, &dee);
262	if (r == 1)
263		goto bail2;
264	if (r == -1) {
265		err = -EEXIST;
266		goto bail2;
267	}
268	fnode->len = len;
269	memcpy(fnode->name, name, len > 15 ? 15 : len);
270	fnode->up = cpu_to_le32(dir->i_ino);
271	mark_buffer_dirty(bh);
272
273	insert_inode_hash(result);
274
275	hpfs_write_inode_nolock(result);
276	hpfs_update_directory_times(dir);
277	d_instantiate(dentry, result);
278	brelse(bh);
279	hpfs_unlock(dir->i_sb);
280	return 0;
281bail2:
282	iput(result);
283bail1:
284	brelse(bh);
285	hpfs_free_sectors(dir->i_sb, fno, 1);
286bail:
287	hpfs_unlock(dir->i_sb);
288	return err;
289}
290
291static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *symlink)
 
292{
293	const unsigned char *name = dentry->d_name.name;
294	unsigned len = dentry->d_name.len;
295	struct buffer_head *bh;
296	struct fnode *fnode;
297	fnode_secno fno;
298	int r;
299	struct hpfs_dirent dee;
300	struct inode *result;
301	int err;
302	if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
303	hpfs_lock(dir->i_sb);
304	if (hpfs_sb(dir->i_sb)->sb_eas < 2) {
305		hpfs_unlock(dir->i_sb);
306		return -EPERM;
307	}
308	err = -ENOSPC;
309	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
310	if (!fnode)
311		goto bail;
312	memset(&dee, 0, sizeof dee);
313	dee.archive = 1;
314	dee.hidden = name[0] == '.';
315	dee.fnode = cpu_to_le32(fno);
316	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds()));
317
318	result = new_inode(dir->i_sb);
319	if (!result)
320		goto bail1;
321	result->i_ino = fno;
322	hpfs_init_inode(result);
323	hpfs_i(result)->i_parent_dir = dir->i_ino;
324	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));
325	result->i_ctime.tv_nsec = 0;
326	result->i_mtime.tv_nsec = 0;
327	result->i_atime.tv_nsec = 0;
328	hpfs_i(result)->i_ea_size = 0;
329	result->i_mode = S_IFLNK | 0777;
330	result->i_uid = current_fsuid();
331	result->i_gid = current_fsgid();
332	result->i_blocks = 1;
333	set_nlink(result, 1);
334	result->i_size = strlen(symlink);
335	inode_nohighmem(result);
336	result->i_op = &page_symlink_inode_operations;
337	result->i_data.a_ops = &hpfs_symlink_aops;
338
339	r = hpfs_add_dirent(dir, name, len, &dee);
340	if (r == 1)
341		goto bail2;
342	if (r == -1) {
343		err = -EEXIST;
344		goto bail2;
345	}
346	fnode->len = len;
347	memcpy(fnode->name, name, len > 15 ? 15 : len);
348	fnode->up = cpu_to_le32(dir->i_ino);
349	hpfs_set_ea(result, fnode, "SYMLINK", symlink, strlen(symlink));
350	mark_buffer_dirty(bh);
351	brelse(bh);
352
353	insert_inode_hash(result);
354
355	hpfs_write_inode_nolock(result);
356	hpfs_update_directory_times(dir);
357	d_instantiate(dentry, result);
358	hpfs_unlock(dir->i_sb);
359	return 0;
360bail2:
361	iput(result);
362bail1:
363	brelse(bh);
364	hpfs_free_sectors(dir->i_sb, fno, 1);
365bail:
366	hpfs_unlock(dir->i_sb);
367	return err;
368}
369
370static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
371{
372	const unsigned char *name = dentry->d_name.name;
373	unsigned len = dentry->d_name.len;
374	struct quad_buffer_head qbh;
375	struct hpfs_dirent *de;
376	struct inode *inode = d_inode(dentry);
377	dnode_secno dno;
378	int r;
379	int err;
380
381	hpfs_lock(dir->i_sb);
382	hpfs_adjust_length(name, &len);
383
384	err = -ENOENT;
385	de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
386	if (!de)
387		goto out;
388
389	err = -EPERM;
390	if (de->first)
391		goto out1;
392
393	err = -EISDIR;
394	if (de->directory)
395		goto out1;
396
397	r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
398	switch (r) {
399	case 1:
400		hpfs_error(dir->i_sb, "there was error when removing dirent");
401		err = -EFSERROR;
402		break;
403	case 2:		/* no space for deleting */
404		err = -ENOSPC;
405		break;
406	default:
407		drop_nlink(inode);
408		err = 0;
409	}
410	goto out;
411
412out1:
413	hpfs_brelse4(&qbh);
414out:
415	if (!err)
416		hpfs_update_directory_times(dir);
417	hpfs_unlock(dir->i_sb);
418	return err;
419}
420
421static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
422{
423	const unsigned char *name = dentry->d_name.name;
424	unsigned len = dentry->d_name.len;
425	struct quad_buffer_head qbh;
426	struct hpfs_dirent *de;
427	struct inode *inode = d_inode(dentry);
428	dnode_secno dno;
429	int n_items = 0;
430	int err;
431	int r;
432
433	hpfs_adjust_length(name, &len);
434	hpfs_lock(dir->i_sb);
435	err = -ENOENT;
436	de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
437	if (!de)
438		goto out;
439
440	err = -EPERM;
441	if (de->first)
442		goto out1;
443
444	err = -ENOTDIR;
445	if (!de->directory)
446		goto out1;
447
448	hpfs_count_dnodes(dir->i_sb, hpfs_i(inode)->i_dno, NULL, NULL, &n_items);
449	err = -ENOTEMPTY;
450	if (n_items)
451		goto out1;
452
453	r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
454	switch (r) {
455	case 1:
456		hpfs_error(dir->i_sb, "there was error when removing dirent");
457		err = -EFSERROR;
458		break;
459	case 2:
460		err = -ENOSPC;
461		break;
462	default:
463		drop_nlink(dir);
464		clear_nlink(inode);
465		err = 0;
466	}
467	goto out;
468out1:
469	hpfs_brelse4(&qbh);
470out:
471	if (!err)
472		hpfs_update_directory_times(dir);
473	hpfs_unlock(dir->i_sb);
474	return err;
475}
476
477static int hpfs_symlink_readpage(struct file *file, struct page *page)
478{
 
479	char *link = page_address(page);
480	struct inode *i = page->mapping->host;
481	struct fnode *fnode;
482	struct buffer_head *bh;
483	int err;
484
485	err = -EIO;
486	hpfs_lock(i->i_sb);
487	if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh)))
488		goto fail;
489	err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE);
490	brelse(bh);
491	if (err)
492		goto fail;
493	hpfs_unlock(i->i_sb);
494	SetPageUptodate(page);
495	unlock_page(page);
496	return 0;
497
498fail:
499	hpfs_unlock(i->i_sb);
500	SetPageError(page);
501	unlock_page(page);
502	return err;
503}
504
505const struct address_space_operations hpfs_symlink_aops = {
506	.readpage	= hpfs_symlink_readpage
507};
508	
509static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
510		       struct inode *new_dir, struct dentry *new_dentry,
511		       unsigned int flags)
512{
513	const unsigned char *old_name = old_dentry->d_name.name;
514	unsigned old_len = old_dentry->d_name.len;
515	const unsigned char *new_name = new_dentry->d_name.name;
516	unsigned new_len = new_dentry->d_name.len;
517	struct inode *i = d_inode(old_dentry);
518	struct inode *new_inode = d_inode(new_dentry);
519	struct quad_buffer_head qbh, qbh1;
520	struct hpfs_dirent *dep, *nde;
521	struct hpfs_dirent de;
522	dnode_secno dno;
523	int r;
524	struct buffer_head *bh;
525	struct fnode *fnode;
526	int err;
527
528	if (flags & ~RENAME_NOREPLACE)
529		return -EINVAL;
530
531	if ((err = hpfs_chk_name(new_name, &new_len))) return err;
532	err = 0;
533	hpfs_adjust_length(old_name, &old_len);
534
535	hpfs_lock(i->i_sb);
536	/* order doesn't matter, due to VFS exclusion */
537	
538	/* Erm? Moving over the empty non-busy directory is perfectly legal */
539	if (new_inode && S_ISDIR(new_inode->i_mode)) {
540		err = -EINVAL;
541		goto end1;
542	}
543
544	if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
545		hpfs_error(i->i_sb, "lookup succeeded but map dirent failed");
546		err = -ENOENT;
547		goto end1;
548	}
549	copy_de(&de, dep);
550	de.hidden = new_name[0] == '.';
551
552	if (new_inode) {
553		int r;
554		if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) {
555			if ((nde = map_dirent(new_dir, hpfs_i(new_dir)->i_dno, new_name, new_len, NULL, &qbh1))) {
556				clear_nlink(new_inode);
557				copy_de(nde, &de);
558				memcpy(nde->name, new_name, new_len);
559				hpfs_mark_4buffers_dirty(&qbh1);
560				hpfs_brelse4(&qbh1);
561				goto end;
562			}
563			hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent");
564			err = -EFSERROR;
565			goto end1;
566		}
567		err = r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
568		goto end1;
569	}
570
571	if (new_dir == old_dir) hpfs_brelse4(&qbh);
572
573	if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de))) {
574		if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!");
575		err = r == 1 ? -ENOSPC : -EFSERROR;
576		if (new_dir != old_dir) hpfs_brelse4(&qbh);
577		goto end1;
578	}
579	
580	if (new_dir == old_dir)
581		if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
582			hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2");
583			err = -ENOENT;
584			goto end1;
585		}
586
587	if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) {
588		hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent");
589		err = r == 2 ? -ENOSPC : -EFSERROR;
590		goto end1;
591	}
592
593end:
594	hpfs_i(i)->i_parent_dir = new_dir->i_ino;
595	if (S_ISDIR(i->i_mode)) {
596		inc_nlink(new_dir);
597		drop_nlink(old_dir);
598	}
599	if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) {
600		fnode->up = cpu_to_le32(new_dir->i_ino);
601		fnode->len = new_len;
602		memcpy(fnode->name, new_name, new_len>15?15:new_len);
603		if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len);
604		mark_buffer_dirty(bh);
605		brelse(bh);
606	}
607end1:
608	if (!err) {
609		hpfs_update_directory_times(old_dir);
610		hpfs_update_directory_times(new_dir);
611	}
612	hpfs_unlock(i->i_sb);
613	return err;
614}
615
616const struct inode_operations hpfs_dir_iops =
617{
618	.create		= hpfs_create,
619	.lookup		= hpfs_lookup,
620	.unlink		= hpfs_unlink,
621	.symlink	= hpfs_symlink,
622	.mkdir		= hpfs_mkdir,
623	.rmdir		= hpfs_rmdir,
624	.mknod		= hpfs_mknod,
625	.rename		= hpfs_rename,
626	.setattr	= hpfs_setattr,
627};
v6.2
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 *  linux/fs/hpfs/namei.c
  4 *
  5 *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
  6 *
  7 *  adding & removing files & directories
  8 */
  9#include <linux/sched.h>
 10#include "hpfs_fn.h"
 11
 12static void hpfs_update_directory_times(struct inode *dir)
 13{
 14	time64_t t = local_to_gmt(dir->i_sb, local_get_seconds(dir->i_sb));
 15	if (t == dir->i_mtime.tv_sec &&
 16	    t == dir->i_ctime.tv_sec)
 17		return;
 18	dir->i_mtime.tv_sec = dir->i_ctime.tv_sec = t;
 19	dir->i_mtime.tv_nsec = dir->i_ctime.tv_nsec = 0;
 20	hpfs_write_inode_nolock(dir);
 21}
 22
 23static int hpfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
 24		      struct dentry *dentry, umode_t mode)
 25{
 26	const unsigned char *name = dentry->d_name.name;
 27	unsigned len = dentry->d_name.len;
 28	struct quad_buffer_head qbh0;
 29	struct buffer_head *bh;
 30	struct hpfs_dirent *de;
 31	struct fnode *fnode;
 32	struct dnode *dnode;
 33	struct inode *result;
 34	fnode_secno fno;
 35	dnode_secno dno;
 36	int r;
 37	struct hpfs_dirent dee;
 38	int err;
 39	if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
 40	hpfs_lock(dir->i_sb);
 41	err = -ENOSPC;
 42	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
 43	if (!fnode)
 44		goto bail;
 45	dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0);
 46	if (!dnode)
 47		goto bail1;
 48	memset(&dee, 0, sizeof dee);
 49	dee.directory = 1;
 50	if (!(mode & 0222)) dee.read_only = 1;
 51	/*dee.archive = 0;*/
 52	dee.hidden = name[0] == '.';
 53	dee.fnode = cpu_to_le32(fno);
 54	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
 55	result = new_inode(dir->i_sb);
 56	if (!result)
 57		goto bail2;
 58	hpfs_init_inode(result);
 59	result->i_ino = fno;
 60	hpfs_i(result)->i_parent_dir = dir->i_ino;
 61	hpfs_i(result)->i_dno = dno;
 62	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));
 63	result->i_ctime.tv_nsec = 0; 
 64	result->i_mtime.tv_nsec = 0; 
 65	result->i_atime.tv_nsec = 0; 
 66	hpfs_i(result)->i_ea_size = 0;
 67	result->i_mode |= S_IFDIR;
 68	result->i_op = &hpfs_dir_iops;
 69	result->i_fop = &hpfs_dir_ops;
 70	result->i_blocks = 4;
 71	result->i_size = 2048;
 72	set_nlink(result, 2);
 73	if (dee.read_only)
 74		result->i_mode &= ~0222;
 75
 76	r = hpfs_add_dirent(dir, name, len, &dee);
 77	if (r == 1)
 78		goto bail3;
 79	if (r == -1) {
 80		err = -EEXIST;
 81		goto bail3;
 82	}
 83	fnode->len = len;
 84	memcpy(fnode->name, name, len > 15 ? 15 : len);
 85	fnode->up = cpu_to_le32(dir->i_ino);
 86	fnode->flags |= FNODE_dir;
 87	fnode->btree.n_free_nodes = 7;
 88	fnode->btree.n_used_nodes = 1;
 89	fnode->btree.first_free = cpu_to_le16(0x14);
 90	fnode->u.external[0].disk_secno = cpu_to_le32(dno);
 91	fnode->u.external[0].file_secno = cpu_to_le32(-1);
 92	dnode->root_dnode = 1;
 93	dnode->up = cpu_to_le32(fno);
 94	de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0);
 95	de->creation_date = de->write_date = de->read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
 96	if (!(mode & 0222)) de->read_only = 1;
 97	de->first = de->directory = 1;
 98	/*de->hidden = de->system = 0;*/
 99	de->fnode = cpu_to_le32(fno);
100	mark_buffer_dirty(bh);
101	brelse(bh);
102	hpfs_mark_4buffers_dirty(&qbh0);
103	hpfs_brelse4(&qbh0);
104	inc_nlink(dir);
105	insert_inode_hash(result);
106
107	if (!uid_eq(result->i_uid, current_fsuid()) ||
108	    !gid_eq(result->i_gid, current_fsgid()) ||
109	    result->i_mode != (mode | S_IFDIR)) {
110		result->i_uid = current_fsuid();
111		result->i_gid = current_fsgid();
112		result->i_mode = mode | S_IFDIR;
113		hpfs_write_inode_nolock(result);
114	}
115	hpfs_update_directory_times(dir);
116	d_instantiate(dentry, result);
117	hpfs_unlock(dir->i_sb);
118	return 0;
119bail3:
120	iput(result);
121bail2:
122	hpfs_brelse4(&qbh0);
123	hpfs_free_dnode(dir->i_sb, dno);
124bail1:
125	brelse(bh);
126	hpfs_free_sectors(dir->i_sb, fno, 1);
127bail:
128	hpfs_unlock(dir->i_sb);
129	return err;
130}
131
132static int hpfs_create(struct user_namespace *mnt_userns, struct inode *dir,
133		       struct dentry *dentry, umode_t mode, bool excl)
134{
135	const unsigned char *name = dentry->d_name.name;
136	unsigned len = dentry->d_name.len;
137	struct inode *result = NULL;
138	struct buffer_head *bh;
139	struct fnode *fnode;
140	fnode_secno fno;
141	int r;
142	struct hpfs_dirent dee;
143	int err;
144	if ((err = hpfs_chk_name(name, &len)))
145		return err==-ENOENT ? -EINVAL : err;
146	hpfs_lock(dir->i_sb);
147	err = -ENOSPC;
148	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
149	if (!fnode)
150		goto bail;
151	memset(&dee, 0, sizeof dee);
152	if (!(mode & 0222)) dee.read_only = 1;
153	dee.archive = 1;
154	dee.hidden = name[0] == '.';
155	dee.fnode = cpu_to_le32(fno);
156	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
157
158	result = new_inode(dir->i_sb);
159	if (!result)
160		goto bail1;
161	
162	hpfs_init_inode(result);
163	result->i_ino = fno;
164	result->i_mode |= S_IFREG;
165	result->i_mode &= ~0111;
166	result->i_op = &hpfs_file_iops;
167	result->i_fop = &hpfs_file_ops;
168	set_nlink(result, 1);
169	hpfs_i(result)->i_parent_dir = dir->i_ino;
170	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));
171	result->i_ctime.tv_nsec = 0;
172	result->i_mtime.tv_nsec = 0;
173	result->i_atime.tv_nsec = 0;
174	hpfs_i(result)->i_ea_size = 0;
175	if (dee.read_only)
176		result->i_mode &= ~0222;
177	result->i_blocks = 1;
178	result->i_size = 0;
179	result->i_data.a_ops = &hpfs_aops;
180	hpfs_i(result)->mmu_private = 0;
181
182	r = hpfs_add_dirent(dir, name, len, &dee);
183	if (r == 1)
184		goto bail2;
185	if (r == -1) {
186		err = -EEXIST;
187		goto bail2;
188	}
189	fnode->len = len;
190	memcpy(fnode->name, name, len > 15 ? 15 : len);
191	fnode->up = cpu_to_le32(dir->i_ino);
192	mark_buffer_dirty(bh);
193	brelse(bh);
194
195	insert_inode_hash(result);
196
197	if (!uid_eq(result->i_uid, current_fsuid()) ||
198	    !gid_eq(result->i_gid, current_fsgid()) ||
199	    result->i_mode != (mode | S_IFREG)) {
200		result->i_uid = current_fsuid();
201		result->i_gid = current_fsgid();
202		result->i_mode = mode | S_IFREG;
203		hpfs_write_inode_nolock(result);
204	}
205	hpfs_update_directory_times(dir);
206	d_instantiate(dentry, result);
207	hpfs_unlock(dir->i_sb);
208	return 0;
209
210bail2:
211	iput(result);
212bail1:
213	brelse(bh);
214	hpfs_free_sectors(dir->i_sb, fno, 1);
215bail:
216	hpfs_unlock(dir->i_sb);
217	return err;
218}
219
220static int hpfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
221		      struct dentry *dentry, umode_t mode, dev_t rdev)
222{
223	const unsigned char *name = dentry->d_name.name;
224	unsigned len = dentry->d_name.len;
225	struct buffer_head *bh;
226	struct fnode *fnode;
227	fnode_secno fno;
228	int r;
229	struct hpfs_dirent dee;
230	struct inode *result = NULL;
231	int err;
232	if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
233	if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM;
234	hpfs_lock(dir->i_sb);
235	err = -ENOSPC;
236	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
237	if (!fnode)
238		goto bail;
239	memset(&dee, 0, sizeof dee);
240	if (!(mode & 0222)) dee.read_only = 1;
241	dee.archive = 1;
242	dee.hidden = name[0] == '.';
243	dee.fnode = cpu_to_le32(fno);
244	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
245
246	result = new_inode(dir->i_sb);
247	if (!result)
248		goto bail1;
249
250	hpfs_init_inode(result);
251	result->i_ino = fno;
252	hpfs_i(result)->i_parent_dir = dir->i_ino;
253	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));
254	result->i_ctime.tv_nsec = 0;
255	result->i_mtime.tv_nsec = 0;
256	result->i_atime.tv_nsec = 0;
257	hpfs_i(result)->i_ea_size = 0;
258	result->i_uid = current_fsuid();
259	result->i_gid = current_fsgid();
260	set_nlink(result, 1);
261	result->i_size = 0;
262	result->i_blocks = 1;
263	init_special_inode(result, mode, rdev);
264
265	r = hpfs_add_dirent(dir, name, len, &dee);
266	if (r == 1)
267		goto bail2;
268	if (r == -1) {
269		err = -EEXIST;
270		goto bail2;
271	}
272	fnode->len = len;
273	memcpy(fnode->name, name, len > 15 ? 15 : len);
274	fnode->up = cpu_to_le32(dir->i_ino);
275	mark_buffer_dirty(bh);
276
277	insert_inode_hash(result);
278
279	hpfs_write_inode_nolock(result);
280	hpfs_update_directory_times(dir);
281	d_instantiate(dentry, result);
282	brelse(bh);
283	hpfs_unlock(dir->i_sb);
284	return 0;
285bail2:
286	iput(result);
287bail1:
288	brelse(bh);
289	hpfs_free_sectors(dir->i_sb, fno, 1);
290bail:
291	hpfs_unlock(dir->i_sb);
292	return err;
293}
294
295static int hpfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
296			struct dentry *dentry, const char *symlink)
297{
298	const unsigned char *name = dentry->d_name.name;
299	unsigned len = dentry->d_name.len;
300	struct buffer_head *bh;
301	struct fnode *fnode;
302	fnode_secno fno;
303	int r;
304	struct hpfs_dirent dee;
305	struct inode *result;
306	int err;
307	if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err;
308	hpfs_lock(dir->i_sb);
309	if (hpfs_sb(dir->i_sb)->sb_eas < 2) {
310		hpfs_unlock(dir->i_sb);
311		return -EPERM;
312	}
313	err = -ENOSPC;
314	fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
315	if (!fnode)
316		goto bail;
317	memset(&dee, 0, sizeof dee);
318	dee.archive = 1;
319	dee.hidden = name[0] == '.';
320	dee.fnode = cpu_to_le32(fno);
321	dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
322
323	result = new_inode(dir->i_sb);
324	if (!result)
325		goto bail1;
326	result->i_ino = fno;
327	hpfs_init_inode(result);
328	hpfs_i(result)->i_parent_dir = dir->i_ino;
329	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));
330	result->i_ctime.tv_nsec = 0;
331	result->i_mtime.tv_nsec = 0;
332	result->i_atime.tv_nsec = 0;
333	hpfs_i(result)->i_ea_size = 0;
334	result->i_mode = S_IFLNK | 0777;
335	result->i_uid = current_fsuid();
336	result->i_gid = current_fsgid();
337	result->i_blocks = 1;
338	set_nlink(result, 1);
339	result->i_size = strlen(symlink);
340	inode_nohighmem(result);
341	result->i_op = &page_symlink_inode_operations;
342	result->i_data.a_ops = &hpfs_symlink_aops;
343
344	r = hpfs_add_dirent(dir, name, len, &dee);
345	if (r == 1)
346		goto bail2;
347	if (r == -1) {
348		err = -EEXIST;
349		goto bail2;
350	}
351	fnode->len = len;
352	memcpy(fnode->name, name, len > 15 ? 15 : len);
353	fnode->up = cpu_to_le32(dir->i_ino);
354	hpfs_set_ea(result, fnode, "SYMLINK", symlink, strlen(symlink));
355	mark_buffer_dirty(bh);
356	brelse(bh);
357
358	insert_inode_hash(result);
359
360	hpfs_write_inode_nolock(result);
361	hpfs_update_directory_times(dir);
362	d_instantiate(dentry, result);
363	hpfs_unlock(dir->i_sb);
364	return 0;
365bail2:
366	iput(result);
367bail1:
368	brelse(bh);
369	hpfs_free_sectors(dir->i_sb, fno, 1);
370bail:
371	hpfs_unlock(dir->i_sb);
372	return err;
373}
374
375static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
376{
377	const unsigned char *name = dentry->d_name.name;
378	unsigned len = dentry->d_name.len;
379	struct quad_buffer_head qbh;
380	struct hpfs_dirent *de;
381	struct inode *inode = d_inode(dentry);
382	dnode_secno dno;
383	int r;
384	int err;
385
386	hpfs_lock(dir->i_sb);
387	hpfs_adjust_length(name, &len);
388
389	err = -ENOENT;
390	de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
391	if (!de)
392		goto out;
393
394	err = -EPERM;
395	if (de->first)
396		goto out1;
397
398	err = -EISDIR;
399	if (de->directory)
400		goto out1;
401
402	r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
403	switch (r) {
404	case 1:
405		hpfs_error(dir->i_sb, "there was error when removing dirent");
406		err = -EFSERROR;
407		break;
408	case 2:		/* no space for deleting */
409		err = -ENOSPC;
410		break;
411	default:
412		drop_nlink(inode);
413		err = 0;
414	}
415	goto out;
416
417out1:
418	hpfs_brelse4(&qbh);
419out:
420	if (!err)
421		hpfs_update_directory_times(dir);
422	hpfs_unlock(dir->i_sb);
423	return err;
424}
425
426static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
427{
428	const unsigned char *name = dentry->d_name.name;
429	unsigned len = dentry->d_name.len;
430	struct quad_buffer_head qbh;
431	struct hpfs_dirent *de;
432	struct inode *inode = d_inode(dentry);
433	dnode_secno dno;
434	int n_items = 0;
435	int err;
436	int r;
437
438	hpfs_adjust_length(name, &len);
439	hpfs_lock(dir->i_sb);
440	err = -ENOENT;
441	de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh);
442	if (!de)
443		goto out;
444
445	err = -EPERM;
446	if (de->first)
447		goto out1;
448
449	err = -ENOTDIR;
450	if (!de->directory)
451		goto out1;
452
453	hpfs_count_dnodes(dir->i_sb, hpfs_i(inode)->i_dno, NULL, NULL, &n_items);
454	err = -ENOTEMPTY;
455	if (n_items)
456		goto out1;
457
458	r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
459	switch (r) {
460	case 1:
461		hpfs_error(dir->i_sb, "there was error when removing dirent");
462		err = -EFSERROR;
463		break;
464	case 2:
465		err = -ENOSPC;
466		break;
467	default:
468		drop_nlink(dir);
469		clear_nlink(inode);
470		err = 0;
471	}
472	goto out;
473out1:
474	hpfs_brelse4(&qbh);
475out:
476	if (!err)
477		hpfs_update_directory_times(dir);
478	hpfs_unlock(dir->i_sb);
479	return err;
480}
481
482static int hpfs_symlink_read_folio(struct file *file, struct folio *folio)
483{
484	struct page *page = &folio->page;
485	char *link = page_address(page);
486	struct inode *i = page->mapping->host;
487	struct fnode *fnode;
488	struct buffer_head *bh;
489	int err;
490
491	err = -EIO;
492	hpfs_lock(i->i_sb);
493	if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh)))
494		goto fail;
495	err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE);
496	brelse(bh);
497	if (err)
498		goto fail;
499	hpfs_unlock(i->i_sb);
500	SetPageUptodate(page);
501	unlock_page(page);
502	return 0;
503
504fail:
505	hpfs_unlock(i->i_sb);
506	SetPageError(page);
507	unlock_page(page);
508	return err;
509}
510
511const struct address_space_operations hpfs_symlink_aops = {
512	.read_folio	= hpfs_symlink_read_folio
513};
514
515static int hpfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
516		       struct dentry *old_dentry, struct inode *new_dir,
517		       struct dentry *new_dentry, unsigned int flags)
518{
519	const unsigned char *old_name = old_dentry->d_name.name;
520	unsigned old_len = old_dentry->d_name.len;
521	const unsigned char *new_name = new_dentry->d_name.name;
522	unsigned new_len = new_dentry->d_name.len;
523	struct inode *i = d_inode(old_dentry);
524	struct inode *new_inode = d_inode(new_dentry);
525	struct quad_buffer_head qbh, qbh1;
526	struct hpfs_dirent *dep, *nde;
527	struct hpfs_dirent de;
528	dnode_secno dno;
529	int r;
530	struct buffer_head *bh;
531	struct fnode *fnode;
532	int err;
533
534	if (flags & ~RENAME_NOREPLACE)
535		return -EINVAL;
536
537	if ((err = hpfs_chk_name(new_name, &new_len))) return err;
538	err = 0;
539	hpfs_adjust_length(old_name, &old_len);
540
541	hpfs_lock(i->i_sb);
542	/* order doesn't matter, due to VFS exclusion */
543	
544	/* Erm? Moving over the empty non-busy directory is perfectly legal */
545	if (new_inode && S_ISDIR(new_inode->i_mode)) {
546		err = -EINVAL;
547		goto end1;
548	}
549
550	if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
551		hpfs_error(i->i_sb, "lookup succeeded but map dirent failed");
552		err = -ENOENT;
553		goto end1;
554	}
555	copy_de(&de, dep);
556	de.hidden = new_name[0] == '.';
557
558	if (new_inode) {
559		int r;
560		if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) {
561			if ((nde = map_dirent(new_dir, hpfs_i(new_dir)->i_dno, new_name, new_len, NULL, &qbh1))) {
562				clear_nlink(new_inode);
563				copy_de(nde, &de);
564				memcpy(nde->name, new_name, new_len);
565				hpfs_mark_4buffers_dirty(&qbh1);
566				hpfs_brelse4(&qbh1);
567				goto end;
568			}
569			hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent");
570			err = -EFSERROR;
571			goto end1;
572		}
573		err = -ENOSPC;
574		goto end1;
575	}
576
577	if (new_dir == old_dir) hpfs_brelse4(&qbh);
578
579	if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de))) {
580		if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!");
581		err = r == 1 ? -ENOSPC : -EFSERROR;
582		if (new_dir != old_dir) hpfs_brelse4(&qbh);
583		goto end1;
584	}
585	
586	if (new_dir == old_dir)
587		if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) {
588			hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2");
589			err = -ENOENT;
590			goto end1;
591		}
592
593	if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) {
594		hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent");
595		err = r == 2 ? -ENOSPC : -EFSERROR;
596		goto end1;
597	}
598
599end:
600	hpfs_i(i)->i_parent_dir = new_dir->i_ino;
601	if (S_ISDIR(i->i_mode)) {
602		inc_nlink(new_dir);
603		drop_nlink(old_dir);
604	}
605	if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) {
606		fnode->up = cpu_to_le32(new_dir->i_ino);
607		fnode->len = new_len;
608		memcpy(fnode->name, new_name, new_len>15?15:new_len);
609		if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len);
610		mark_buffer_dirty(bh);
611		brelse(bh);
612	}
613end1:
614	if (!err) {
615		hpfs_update_directory_times(old_dir);
616		hpfs_update_directory_times(new_dir);
617	}
618	hpfs_unlock(i->i_sb);
619	return err;
620}
621
622const struct inode_operations hpfs_dir_iops =
623{
624	.create		= hpfs_create,
625	.lookup		= hpfs_lookup,
626	.unlink		= hpfs_unlink,
627	.symlink	= hpfs_symlink,
628	.mkdir		= hpfs_mkdir,
629	.rmdir		= hpfs_rmdir,
630	.mknod		= hpfs_mknod,
631	.rename		= hpfs_rename,
632	.setattr	= hpfs_setattr,
633};