Linux Audio

Check our new training course

Buildroot integration, development and maintenance

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