xref: /openbmc/linux/fs/jfs/namei.c (revision 1da177e4)
1 /*
2  *   Copyright (C) International Business Machines Corp., 2000-2004
3  *   Portions Copyright (C) Christoph Hellwig, 2001-2002
4  *
5  *   This program is free software;  you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13  *   the GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program;  if not, write to the Free Software
17  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19 
20 #include <linux/fs.h>
21 #include <linux/ctype.h>
22 #include <linux/quotaops.h>
23 #include "jfs_incore.h"
24 #include "jfs_superblock.h"
25 #include "jfs_inode.h"
26 #include "jfs_dinode.h"
27 #include "jfs_dmap.h"
28 #include "jfs_unicode.h"
29 #include "jfs_metapage.h"
30 #include "jfs_xattr.h"
31 #include "jfs_acl.h"
32 #include "jfs_debug.h"
33 
34 extern struct inode_operations jfs_file_inode_operations;
35 extern struct inode_operations jfs_symlink_inode_operations;
36 extern struct file_operations jfs_file_operations;
37 extern struct address_space_operations jfs_aops;
38 
39 extern int jfs_fsync(struct file *, struct dentry *, int);
40 extern void jfs_truncate_nolock(struct inode *, loff_t);
41 extern int jfs_init_acl(struct inode *, struct inode *);
42 
43 /*
44  * forward references
45  */
46 struct inode_operations jfs_dir_inode_operations;
47 struct file_operations jfs_dir_operations;
48 struct dentry_operations jfs_ci_dentry_operations;
49 
50 static s64 commitZeroLink(tid_t, struct inode *);
51 
52 /*
53  * NAME:	jfs_create(dip, dentry, mode)
54  *
55  * FUNCTION:	create a regular file in the parent directory <dip>
56  *		with name = <from dentry> and mode = <mode>
57  *
58  * PARAMETER:	dip 	- parent directory vnode
59  *		dentry	- dentry of new file
60  *		mode	- create mode (rwxrwxrwx).
61  *		nd- nd struct
62  *
63  * RETURN:	Errors from subroutines
64  *
65  */
66 static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
67 		struct nameidata *nd)
68 {
69 	int rc = 0;
70 	tid_t tid;		/* transaction id */
71 	struct inode *ip = NULL;	/* child directory inode */
72 	ino_t ino;
73 	struct component_name dname;	/* child directory name */
74 	struct btstack btstack;
75 	struct inode *iplist[2];
76 	struct tblock *tblk;
77 
78 	jfs_info("jfs_create: dip:0x%p name:%s", dip, dentry->d_name.name);
79 
80 	/*
81 	 * search parent directory for entry/freespace
82 	 * (dtSearch() returns parent directory page pinned)
83 	 */
84 	if ((rc = get_UCSname(&dname, dentry)))
85 		goto out1;
86 
87 	/*
88 	 * Either iAlloc() or txBegin() may block.  Deadlock can occur if we
89 	 * block there while holding dtree page, so we allocate the inode &
90 	 * begin the transaction before we search the directory.
91 	 */
92 	ip = ialloc(dip, mode);
93 	if (ip == NULL) {
94 		rc = -ENOSPC;
95 		goto out2;
96 	}
97 
98 	tid = txBegin(dip->i_sb, 0);
99 
100 	down(&JFS_IP(dip)->commit_sem);
101 	down(&JFS_IP(ip)->commit_sem);
102 
103 	if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
104 		jfs_err("jfs_create: dtSearch returned %d", rc);
105 		goto out3;
106 	}
107 
108 	tblk = tid_to_tblock(tid);
109 	tblk->xflag |= COMMIT_CREATE;
110 	tblk->ino = ip->i_ino;
111 	tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
112 
113 	iplist[0] = dip;
114 	iplist[1] = ip;
115 
116 	/*
117 	 * initialize the child XAD tree root in-line in inode
118 	 */
119 	xtInitRoot(tid, ip);
120 
121 	/*
122 	 * create entry in parent directory for child directory
123 	 * (dtInsert() releases parent directory page)
124 	 */
125 	ino = ip->i_ino;
126 	if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
127 		if (rc == -EIO) {
128 			jfs_err("jfs_create: dtInsert returned -EIO");
129 			txAbort(tid, 1);	/* Marks Filesystem dirty */
130 		} else
131 			txAbort(tid, 0);	/* Filesystem full */
132 		goto out3;
133 	}
134 
135 	ip->i_op = &jfs_file_inode_operations;
136 	ip->i_fop = &jfs_file_operations;
137 	ip->i_mapping->a_ops = &jfs_aops;
138 
139 	insert_inode_hash(ip);
140 	mark_inode_dirty(ip);
141 
142 	dip->i_ctime = dip->i_mtime = CURRENT_TIME;
143 
144 	mark_inode_dirty(dip);
145 
146 	rc = txCommit(tid, 2, &iplist[0], 0);
147 
148       out3:
149 	txEnd(tid);
150 	up(&JFS_IP(dip)->commit_sem);
151 	up(&JFS_IP(ip)->commit_sem);
152 	if (rc) {
153 		ip->i_nlink = 0;
154 		iput(ip);
155 	} else
156 		d_instantiate(dentry, ip);
157 
158       out2:
159 	free_UCSname(&dname);
160 
161 #ifdef CONFIG_JFS_POSIX_ACL
162 	if (rc == 0)
163 		jfs_init_acl(ip, dip);
164 #endif
165 
166       out1:
167 
168 	jfs_info("jfs_create: rc:%d", rc);
169 	return rc;
170 }
171 
172 
173 /*
174  * NAME:	jfs_mkdir(dip, dentry, mode)
175  *
176  * FUNCTION:	create a child directory in the parent directory <dip>
177  *		with name = <from dentry> and mode = <mode>
178  *
179  * PARAMETER:	dip 	- parent directory vnode
180  *		dentry	- dentry of child directory
181  *		mode	- create mode (rwxrwxrwx).
182  *
183  * RETURN:	Errors from subroutines
184  *
185  * note:
186  * EACCESS: user needs search+write permission on the parent directory
187  */
188 static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
189 {
190 	int rc = 0;
191 	tid_t tid;		/* transaction id */
192 	struct inode *ip = NULL;	/* child directory inode */
193 	ino_t ino;
194 	struct component_name dname;	/* child directory name */
195 	struct btstack btstack;
196 	struct inode *iplist[2];
197 	struct tblock *tblk;
198 
199 	jfs_info("jfs_mkdir: dip:0x%p name:%s", dip, dentry->d_name.name);
200 
201 	/* link count overflow on parent directory ? */
202 	if (dip->i_nlink == JFS_LINK_MAX) {
203 		rc = -EMLINK;
204 		goto out1;
205 	}
206 
207 	/*
208 	 * search parent directory for entry/freespace
209 	 * (dtSearch() returns parent directory page pinned)
210 	 */
211 	if ((rc = get_UCSname(&dname, dentry)))
212 		goto out1;
213 
214 	/*
215 	 * Either iAlloc() or txBegin() may block.  Deadlock can occur if we
216 	 * block there while holding dtree page, so we allocate the inode &
217 	 * begin the transaction before we search the directory.
218 	 */
219 	ip = ialloc(dip, S_IFDIR | mode);
220 	if (ip == NULL) {
221 		rc = -ENOSPC;
222 		goto out2;
223 	}
224 
225 	tid = txBegin(dip->i_sb, 0);
226 
227 	down(&JFS_IP(dip)->commit_sem);
228 	down(&JFS_IP(ip)->commit_sem);
229 
230 	if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
231 		jfs_err("jfs_mkdir: dtSearch returned %d", rc);
232 		goto out3;
233 	}
234 
235 	tblk = tid_to_tblock(tid);
236 	tblk->xflag |= COMMIT_CREATE;
237 	tblk->ino = ip->i_ino;
238 	tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
239 
240 	iplist[0] = dip;
241 	iplist[1] = ip;
242 
243 	/*
244 	 * initialize the child directory in-line in inode
245 	 */
246 	dtInitRoot(tid, ip, dip->i_ino);
247 
248 	/*
249 	 * create entry in parent directory for child directory
250 	 * (dtInsert() releases parent directory page)
251 	 */
252 	ino = ip->i_ino;
253 	if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
254 		if (rc == -EIO) {
255 			jfs_err("jfs_mkdir: dtInsert returned -EIO");
256 			txAbort(tid, 1);	/* Marks Filesystem dirty */
257 		} else
258 			txAbort(tid, 0);	/* Filesystem full */
259 		goto out3;
260 	}
261 
262 	ip->i_nlink = 2;	/* for '.' */
263 	ip->i_op = &jfs_dir_inode_operations;
264 	ip->i_fop = &jfs_dir_operations;
265 
266 	insert_inode_hash(ip);
267 	mark_inode_dirty(ip);
268 
269 	/* update parent directory inode */
270 	dip->i_nlink++;		/* for '..' from child directory */
271 	dip->i_ctime = dip->i_mtime = CURRENT_TIME;
272 	mark_inode_dirty(dip);
273 
274 	rc = txCommit(tid, 2, &iplist[0], 0);
275 
276       out3:
277 	txEnd(tid);
278 	up(&JFS_IP(dip)->commit_sem);
279 	up(&JFS_IP(ip)->commit_sem);
280 	if (rc) {
281 		ip->i_nlink = 0;
282 		iput(ip);
283 	} else
284 		d_instantiate(dentry, ip);
285 
286       out2:
287 	free_UCSname(&dname);
288 
289 #ifdef CONFIG_JFS_POSIX_ACL
290 	if (rc == 0)
291 		jfs_init_acl(ip, dip);
292 #endif
293 
294       out1:
295 
296 	jfs_info("jfs_mkdir: rc:%d", rc);
297 	return rc;
298 }
299 
300 /*
301  * NAME:	jfs_rmdir(dip, dentry)
302  *
303  * FUNCTION:	remove a link to child directory
304  *
305  * PARAMETER:	dip 	- parent inode
306  *		dentry	- child directory dentry
307  *
308  * RETURN:	-EINVAL	- if name is . or ..
309  *		-EINVAL  - if . or .. exist but are invalid.
310  *		errors from subroutines
311  *
312  * note:
313  * if other threads have the directory open when the last link
314  * is removed, the "." and ".." entries, if present, are removed before
315  * rmdir() returns and no new entries may be created in the directory,
316  * but the directory is not removed until the last reference to
317  * the directory is released (cf.unlink() of regular file).
318  */
319 static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
320 {
321 	int rc;
322 	tid_t tid;		/* transaction id */
323 	struct inode *ip = dentry->d_inode;
324 	ino_t ino;
325 	struct component_name dname;
326 	struct inode *iplist[2];
327 	struct tblock *tblk;
328 
329 	jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name);
330 
331 	/* Init inode for quota operations. */
332 	DQUOT_INIT(ip);
333 
334 	/* directory must be empty to be removed */
335 	if (!dtEmpty(ip)) {
336 		rc = -ENOTEMPTY;
337 		goto out;
338 	}
339 
340 	if ((rc = get_UCSname(&dname, dentry))) {
341 		goto out;
342 	}
343 
344 	tid = txBegin(dip->i_sb, 0);
345 
346 	down(&JFS_IP(dip)->commit_sem);
347 	down(&JFS_IP(ip)->commit_sem);
348 
349 	iplist[0] = dip;
350 	iplist[1] = ip;
351 
352 	tblk = tid_to_tblock(tid);
353 	tblk->xflag |= COMMIT_DELETE;
354 	tblk->u.ip = ip;
355 
356 	/*
357 	 * delete the entry of target directory from parent directory
358 	 */
359 	ino = ip->i_ino;
360 	if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) {
361 		jfs_err("jfs_rmdir: dtDelete returned %d", rc);
362 		if (rc == -EIO)
363 			txAbort(tid, 1);
364 		txEnd(tid);
365 		up(&JFS_IP(dip)->commit_sem);
366 		up(&JFS_IP(ip)->commit_sem);
367 
368 		goto out2;
369 	}
370 
371 	/* update parent directory's link count corresponding
372 	 * to ".." entry of the target directory deleted
373 	 */
374 	dip->i_nlink--;
375 	dip->i_ctime = dip->i_mtime = CURRENT_TIME;
376 	mark_inode_dirty(dip);
377 
378 	/*
379 	 * OS/2 could have created EA and/or ACL
380 	 */
381 	/* free EA from both persistent and working map */
382 	if (JFS_IP(ip)->ea.flag & DXD_EXTENT) {
383 		/* free EA pages */
384 		txEA(tid, ip, &JFS_IP(ip)->ea, NULL);
385 	}
386 	JFS_IP(ip)->ea.flag = 0;
387 
388 	/* free ACL from both persistent and working map */
389 	if (JFS_IP(ip)->acl.flag & DXD_EXTENT) {
390 		/* free ACL pages */
391 		txEA(tid, ip, &JFS_IP(ip)->acl, NULL);
392 	}
393 	JFS_IP(ip)->acl.flag = 0;
394 
395 	/* mark the target directory as deleted */
396 	ip->i_nlink = 0;
397 	mark_inode_dirty(ip);
398 
399 	rc = txCommit(tid, 2, &iplist[0], 0);
400 
401 	txEnd(tid);
402 
403 	up(&JFS_IP(dip)->commit_sem);
404 	up(&JFS_IP(ip)->commit_sem);
405 
406 	/*
407 	 * Truncating the directory index table is not guaranteed.  It
408 	 * may need to be done iteratively
409 	 */
410 	if (test_cflag(COMMIT_Stale, dip)) {
411 		if (dip->i_size > 1)
412 			jfs_truncate_nolock(dip, 0);
413 
414 		clear_cflag(COMMIT_Stale, dip);
415 	}
416 
417       out2:
418 	free_UCSname(&dname);
419 
420       out:
421 	jfs_info("jfs_rmdir: rc:%d", rc);
422 	return rc;
423 }
424 
425 /*
426  * NAME:	jfs_unlink(dip, dentry)
427  *
428  * FUNCTION:	remove a link to object <vp> named by <name>
429  *		from parent directory <dvp>
430  *
431  * PARAMETER:	dip 	- inode of parent directory
432  *		dentry 	- dentry of object to be removed
433  *
434  * RETURN:	errors from subroutines
435  *
436  * note:
437  * temporary file: if one or more processes have the file open
438  * when the last link is removed, the link will be removed before
439  * unlink() returns, but the removal of the file contents will be
440  * postponed until all references to the files are closed.
441  *
442  * JFS does NOT support unlink() on directories.
443  *
444  */
445 static int jfs_unlink(struct inode *dip, struct dentry *dentry)
446 {
447 	int rc;
448 	tid_t tid;		/* transaction id */
449 	struct inode *ip = dentry->d_inode;
450 	ino_t ino;
451 	struct component_name dname;	/* object name */
452 	struct inode *iplist[2];
453 	struct tblock *tblk;
454 	s64 new_size = 0;
455 	int commit_flag;
456 
457 	jfs_info("jfs_unlink: dip:0x%p name:%s", dip, dentry->d_name.name);
458 
459 	/* Init inode for quota operations. */
460 	DQUOT_INIT(ip);
461 
462 	if ((rc = get_UCSname(&dname, dentry)))
463 		goto out;
464 
465 	IWRITE_LOCK(ip);
466 
467 	tid = txBegin(dip->i_sb, 0);
468 
469 	down(&JFS_IP(dip)->commit_sem);
470 	down(&JFS_IP(ip)->commit_sem);
471 
472 	iplist[0] = dip;
473 	iplist[1] = ip;
474 
475 	/*
476 	 * delete the entry of target file from parent directory
477 	 */
478 	ino = ip->i_ino;
479 	if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) {
480 		jfs_err("jfs_unlink: dtDelete returned %d", rc);
481 		if (rc == -EIO)
482 			txAbort(tid, 1);	/* Marks FS Dirty */
483 		txEnd(tid);
484 		up(&JFS_IP(dip)->commit_sem);
485 		up(&JFS_IP(ip)->commit_sem);
486 		IWRITE_UNLOCK(ip);
487 		goto out1;
488 	}
489 
490 	ASSERT(ip->i_nlink);
491 
492 	ip->i_ctime = dip->i_ctime = dip->i_mtime = CURRENT_TIME;
493 	mark_inode_dirty(dip);
494 
495 	/* update target's inode */
496 	ip->i_nlink--;
497 	mark_inode_dirty(ip);
498 
499 	/*
500 	 *      commit zero link count object
501 	 */
502 	if (ip->i_nlink == 0) {
503 		assert(!test_cflag(COMMIT_Nolink, ip));
504 		/* free block resources */
505 		if ((new_size = commitZeroLink(tid, ip)) < 0) {
506 			txAbort(tid, 1);	/* Marks FS Dirty */
507 			txEnd(tid);
508 			up(&JFS_IP(dip)->commit_sem);
509 			up(&JFS_IP(ip)->commit_sem);
510 			IWRITE_UNLOCK(ip);
511 			rc = new_size;
512 			goto out1;
513 		}
514 		tblk = tid_to_tblock(tid);
515 		tblk->xflag |= COMMIT_DELETE;
516 		tblk->u.ip = ip;
517 	}
518 
519 	/*
520 	 * Incomplete truncate of file data can
521 	 * result in timing problems unless we synchronously commit the
522 	 * transaction.
523 	 */
524 	if (new_size)
525 		commit_flag = COMMIT_SYNC;
526 	else
527 		commit_flag = 0;
528 
529 	/*
530 	 * If xtTruncate was incomplete, commit synchronously to avoid
531 	 * timing complications
532 	 */
533 	rc = txCommit(tid, 2, &iplist[0], commit_flag);
534 
535 	txEnd(tid);
536 
537 	up(&JFS_IP(dip)->commit_sem);
538 	up(&JFS_IP(ip)->commit_sem);
539 
540 
541 	while (new_size && (rc == 0)) {
542 		tid = txBegin(dip->i_sb, 0);
543 		down(&JFS_IP(ip)->commit_sem);
544 		new_size = xtTruncate_pmap(tid, ip, new_size);
545 		if (new_size < 0) {
546 			txAbort(tid, 1);	/* Marks FS Dirty */
547 			rc = new_size;
548 		} else
549 			rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC);
550 		txEnd(tid);
551 		up(&JFS_IP(ip)->commit_sem);
552 	}
553 
554 	if (ip->i_nlink == 0)
555 		set_cflag(COMMIT_Nolink, ip);
556 
557 	IWRITE_UNLOCK(ip);
558 
559 	/*
560 	 * Truncating the directory index table is not guaranteed.  It
561 	 * may need to be done iteratively
562 	 */
563 	if (test_cflag(COMMIT_Stale, dip)) {
564 		if (dip->i_size > 1)
565 			jfs_truncate_nolock(dip, 0);
566 
567 		clear_cflag(COMMIT_Stale, dip);
568 	}
569 
570       out1:
571 	free_UCSname(&dname);
572       out:
573 	jfs_info("jfs_unlink: rc:%d", rc);
574 	return rc;
575 }
576 
577 /*
578  * NAME:	commitZeroLink()
579  *
580  * FUNCTION:    for non-directory, called by jfs_remove(),
581  *		truncate a regular file, directory or symbolic
582  *		link to zero length. return 0 if type is not
583  *		one of these.
584  *
585  *		if the file is currently associated with a VM segment
586  *		only permanent disk and inode map resources are freed,
587  *		and neither the inode nor indirect blocks are modified
588  *		so that the resources can be later freed in the work
589  *		map by ctrunc1.
590  *		if there is no VM segment on entry, the resources are
591  *		freed in both work and permanent map.
592  *		(? for temporary file - memory object is cached even
593  *		after no reference:
594  *		reference count > 0 -   )
595  *
596  * PARAMETERS:	cd	- pointer to commit data structure.
597  *			  current inode is the one to truncate.
598  *
599  * RETURN:	Errors from subroutines
600  */
601 static s64 commitZeroLink(tid_t tid, struct inode *ip)
602 {
603 	int filetype;
604 	struct tblock *tblk;
605 
606 	jfs_info("commitZeroLink: tid = %d, ip = 0x%p", tid, ip);
607 
608 	filetype = ip->i_mode & S_IFMT;
609 	switch (filetype) {
610 	case S_IFREG:
611 		break;
612 	case S_IFLNK:
613 		/* fast symbolic link */
614 		if (ip->i_size < IDATASIZE) {
615 			ip->i_size = 0;
616 			return 0;
617 		}
618 		break;
619 	default:
620 		assert(filetype != S_IFDIR);
621 		return 0;
622 	}
623 
624 	set_cflag(COMMIT_Freewmap, ip);
625 
626 	/* mark transaction of block map update type */
627 	tblk = tid_to_tblock(tid);
628 	tblk->xflag |= COMMIT_PMAP;
629 
630 	/*
631 	 * free EA
632 	 */
633 	if (JFS_IP(ip)->ea.flag & DXD_EXTENT)
634 		/* acquire maplock on EA to be freed from block map */
635 		txEA(tid, ip, &JFS_IP(ip)->ea, NULL);
636 
637 	/*
638 	 * free ACL
639 	 */
640 	if (JFS_IP(ip)->acl.flag & DXD_EXTENT)
641 		/* acquire maplock on EA to be freed from block map */
642 		txEA(tid, ip, &JFS_IP(ip)->acl, NULL);
643 
644 	/*
645 	 * free xtree/data (truncate to zero length):
646 	 * free xtree/data pages from cache if COMMIT_PWMAP,
647 	 * free xtree/data blocks from persistent block map, and
648 	 * free xtree/data blocks from working block map if COMMIT_PWMAP;
649 	 */
650 	if (ip->i_size)
651 		return xtTruncate_pmap(tid, ip, 0);
652 
653 	return 0;
654 }
655 
656 
657 /*
658  * NAME:	freeZeroLink()
659  *
660  * FUNCTION:    for non-directory, called by iClose(),
661  *		free resources of a file from cache and WORKING map
662  *		for a file previously committed with zero link count
663  *		while associated with a pager object,
664  *
665  * PARAMETER:	ip	- pointer to inode of file.
666  *
667  * RETURN:	0 -ok
668  */
669 int freeZeroLink(struct inode *ip)
670 {
671 	int rc = 0;
672 	int type;
673 
674 	jfs_info("freeZeroLink: ip = 0x%p", ip);
675 
676 	/* return if not reg or symbolic link or if size is
677 	 * already ok.
678 	 */
679 	type = ip->i_mode & S_IFMT;
680 
681 	switch (type) {
682 	case S_IFREG:
683 		break;
684 	case S_IFLNK:
685 		/* if its contained in inode nothing to do */
686 		if (ip->i_size < IDATASIZE)
687 			return 0;
688 		break;
689 	default:
690 		return 0;
691 	}
692 
693 	/*
694 	 * free EA
695 	 */
696 	if (JFS_IP(ip)->ea.flag & DXD_EXTENT) {
697 		s64 xaddr = addressDXD(&JFS_IP(ip)->ea);
698 		int xlen = lengthDXD(&JFS_IP(ip)->ea);
699 		struct maplock maplock;	/* maplock for COMMIT_WMAP */
700 		struct pxd_lock *pxdlock;	/* maplock for COMMIT_WMAP */
701 
702 		/* free EA pages from cache */
703 		invalidate_dxd_metapages(ip, JFS_IP(ip)->ea);
704 
705 		/* free EA extent from working block map */
706 		maplock.index = 1;
707 		pxdlock = (struct pxd_lock *) & maplock;
708 		pxdlock->flag = mlckFREEPXD;
709 		PXDaddress(&pxdlock->pxd, xaddr);
710 		PXDlength(&pxdlock->pxd, xlen);
711 		txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
712 	}
713 
714 	/*
715 	 * free ACL
716 	 */
717 	if (JFS_IP(ip)->acl.flag & DXD_EXTENT) {
718 		s64 xaddr = addressDXD(&JFS_IP(ip)->acl);
719 		int xlen = lengthDXD(&JFS_IP(ip)->acl);
720 		struct maplock maplock;	/* maplock for COMMIT_WMAP */
721 		struct pxd_lock *pxdlock;	/* maplock for COMMIT_WMAP */
722 
723 		invalidate_dxd_metapages(ip, JFS_IP(ip)->acl);
724 
725 		/* free ACL extent from working block map */
726 		maplock.index = 1;
727 		pxdlock = (struct pxd_lock *) & maplock;
728 		pxdlock->flag = mlckFREEPXD;
729 		PXDaddress(&pxdlock->pxd, xaddr);
730 		PXDlength(&pxdlock->pxd, xlen);
731 		txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
732 	}
733 
734 	/*
735 	 * free xtree/data (truncate to zero length):
736 	 * free xtree/data pages from cache, and
737 	 * free xtree/data blocks from working block map;
738 	 */
739 	if (ip->i_size)
740 		rc = xtTruncate(0, ip, 0, COMMIT_WMAP);
741 
742 	return rc;
743 }
744 
745 /*
746  * NAME:	jfs_link(vp, dvp, name, crp)
747  *
748  * FUNCTION:	create a link to <vp> by the name = <name>
749  *		in the parent directory <dvp>
750  *
751  * PARAMETER:	vp 	- target object
752  *		dvp	- parent directory of new link
753  *		name	- name of new link to target object
754  *		crp	- credential
755  *
756  * RETURN:	Errors from subroutines
757  *
758  * note:
759  * JFS does NOT support link() on directories (to prevent circular
760  * path in the directory hierarchy);
761  * EPERM: the target object is a directory, and either the caller
762  * does not have appropriate privileges or the implementation prohibits
763  * using link() on directories [XPG4.2].
764  *
765  * JFS does NOT support links between file systems:
766  * EXDEV: target object and new link are on different file systems and
767  * implementation does not support links between file systems [XPG4.2].
768  */
769 static int jfs_link(struct dentry *old_dentry,
770 	     struct inode *dir, struct dentry *dentry)
771 {
772 	int rc;
773 	tid_t tid;
774 	struct inode *ip = old_dentry->d_inode;
775 	ino_t ino;
776 	struct component_name dname;
777 	struct btstack btstack;
778 	struct inode *iplist[2];
779 
780 	jfs_info("jfs_link: %s %s", old_dentry->d_name.name,
781 		 dentry->d_name.name);
782 
783 	if (ip->i_nlink == JFS_LINK_MAX)
784 		return -EMLINK;
785 
786 	if (ip->i_nlink == 0)
787 		return -ENOENT;
788 
789 	tid = txBegin(ip->i_sb, 0);
790 
791 	down(&JFS_IP(dir)->commit_sem);
792 	down(&JFS_IP(ip)->commit_sem);
793 
794 	/*
795 	 * scan parent directory for entry/freespace
796 	 */
797 	if ((rc = get_UCSname(&dname, dentry)))
798 		goto out;
799 
800 	if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE)))
801 		goto free_dname;
802 
803 	/*
804 	 * create entry for new link in parent directory
805 	 */
806 	ino = ip->i_ino;
807 	if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack)))
808 		goto free_dname;
809 
810 	/* update object inode */
811 	ip->i_nlink++;		/* for new link */
812 	ip->i_ctime = CURRENT_TIME;
813 	mark_inode_dirty(dir);
814 	atomic_inc(&ip->i_count);
815 
816 	iplist[0] = ip;
817 	iplist[1] = dir;
818 	rc = txCommit(tid, 2, &iplist[0], 0);
819 
820 	if (rc) {
821 		ip->i_nlink--;
822 		iput(ip);
823 	} else
824 		d_instantiate(dentry, ip);
825 
826       free_dname:
827 	free_UCSname(&dname);
828 
829       out:
830 	txEnd(tid);
831 
832 	up(&JFS_IP(dir)->commit_sem);
833 	up(&JFS_IP(ip)->commit_sem);
834 
835 	jfs_info("jfs_link: rc:%d", rc);
836 	return rc;
837 }
838 
839 /*
840  * NAME:	jfs_symlink(dip, dentry, name)
841  *
842  * FUNCTION:	creates a symbolic link to <symlink> by name <name>
843  *		        in directory <dip>
844  *
845  * PARAMETER:	dip	    - parent directory vnode
846  *		        dentry 	- dentry of symbolic link
847  *		        name    - the path name of the existing object
848  *			              that will be the source of the link
849  *
850  * RETURN:	errors from subroutines
851  *
852  * note:
853  * ENAMETOOLONG: pathname resolution of a symbolic link produced
854  * an intermediate result whose length exceeds PATH_MAX [XPG4.2]
855 */
856 
857 static int jfs_symlink(struct inode *dip, struct dentry *dentry,
858 		const char *name)
859 {
860 	int rc;
861 	tid_t tid;
862 	ino_t ino = 0;
863 	struct component_name dname;
864 	int ssize;		/* source pathname size */
865 	struct btstack btstack;
866 	struct inode *ip = dentry->d_inode;
867 	unchar *i_fastsymlink;
868 	s64 xlen = 0;
869 	int bmask = 0, xsize;
870 	s64 extent = 0, xaddr;
871 	struct metapage *mp;
872 	struct super_block *sb;
873 	struct tblock *tblk;
874 
875 	struct inode *iplist[2];
876 
877 	jfs_info("jfs_symlink: dip:0x%p name:%s", dip, name);
878 
879 	ssize = strlen(name) + 1;
880 
881 	/*
882 	 * search parent directory for entry/freespace
883 	 * (dtSearch() returns parent directory page pinned)
884 	 */
885 
886 	if ((rc = get_UCSname(&dname, dentry)))
887 		goto out1;
888 
889 	/*
890 	 * allocate on-disk/in-memory inode for symbolic link:
891 	 * (iAlloc() returns new, locked inode)
892 	 */
893 	ip = ialloc(dip, S_IFLNK | 0777);
894 	if (ip == NULL) {
895 		rc = -ENOSPC;
896 		goto out2;
897 	}
898 
899 	tid = txBegin(dip->i_sb, 0);
900 
901 	down(&JFS_IP(dip)->commit_sem);
902 	down(&JFS_IP(ip)->commit_sem);
903 
904 	tblk = tid_to_tblock(tid);
905 	tblk->xflag |= COMMIT_CREATE;
906 	tblk->ino = ip->i_ino;
907 	tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
908 
909 	/* fix symlink access permission
910 	 * (dir_create() ANDs in the u.u_cmask,
911 	 * but symlinks really need to be 777 access)
912 	 */
913 	ip->i_mode |= 0777;
914 
915 	/*
916 	 * write symbolic link target path name
917 	 */
918 	xtInitRoot(tid, ip);
919 
920 	/*
921 	 * write source path name inline in on-disk inode (fast symbolic link)
922 	 */
923 
924 	if (ssize <= IDATASIZE) {
925 		ip->i_op = &jfs_symlink_inode_operations;
926 
927 		i_fastsymlink = JFS_IP(ip)->i_inline;
928 		memcpy(i_fastsymlink, name, ssize);
929 		ip->i_size = ssize - 1;
930 
931 		/*
932 		 * if symlink is > 128 bytes, we don't have the space to
933 		 * store inline extended attributes
934 		 */
935 		if (ssize > sizeof (JFS_IP(ip)->i_inline))
936 			JFS_IP(ip)->mode2 &= ~INLINEEA;
937 
938 		jfs_info("jfs_symlink: fast symlink added  ssize:%d name:%s ",
939 			 ssize, name);
940 	}
941 	/*
942 	 * write source path name in a single extent
943 	 */
944 	else {
945 		jfs_info("jfs_symlink: allocate extent ip:0x%p", ip);
946 
947 		ip->i_op = &page_symlink_inode_operations;
948 		ip->i_mapping->a_ops = &jfs_aops;
949 
950 		/*
951 		 * even though the data of symlink object (source
952 		 * path name) is treated as non-journaled user data,
953 		 * it is read/written thru buffer cache for performance.
954 		 */
955 		sb = ip->i_sb;
956 		bmask = JFS_SBI(sb)->bsize - 1;
957 		xsize = (ssize + bmask) & ~bmask;
958 		xaddr = 0;
959 		xlen = xsize >> JFS_SBI(sb)->l2bsize;
960 		if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0))) {
961 			txAbort(tid, 0);
962 			rc = -ENOSPC;
963 			goto out3;
964 		}
965 		extent = xaddr;
966 		ip->i_size = ssize - 1;
967 		while (ssize) {
968 			/* This is kind of silly since PATH_MAX == 4K */
969 			int copy_size = min(ssize, PSIZE);
970 
971 			mp = get_metapage(ip, xaddr, PSIZE, 1);
972 
973 			if (mp == NULL) {
974 				xtTruncate(tid, ip, 0, COMMIT_PWMAP);
975 				rc = -EIO;
976 				txAbort(tid, 0);
977 				goto out3;
978 			}
979 			memcpy(mp->data, name, copy_size);
980 			flush_metapage(mp);
981 			ssize -= copy_size;
982 			name += copy_size;
983 			xaddr += JFS_SBI(sb)->nbperpage;
984 		}
985 	}
986 
987 	/*
988 	 * create entry for symbolic link in parent directory
989 	 */
990 	rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE);
991 	if (rc == 0) {
992 		ino = ip->i_ino;
993 		rc = dtInsert(tid, dip, &dname, &ino, &btstack);
994 	}
995 	if (rc) {
996 		if (xlen)
997 			xtTruncate(tid, ip, 0, COMMIT_PWMAP);
998 		txAbort(tid, 0);
999 		/* discard new inode */
1000 		goto out3;
1001 	}
1002 
1003 	insert_inode_hash(ip);
1004 	mark_inode_dirty(ip);
1005 
1006 	/*
1007 	 * commit update of parent directory and link object
1008 	 */
1009 
1010 	iplist[0] = dip;
1011 	iplist[1] = ip;
1012 	rc = txCommit(tid, 2, &iplist[0], 0);
1013 
1014       out3:
1015 	txEnd(tid);
1016 	up(&JFS_IP(dip)->commit_sem);
1017 	up(&JFS_IP(ip)->commit_sem);
1018 	if (rc) {
1019 		ip->i_nlink = 0;
1020 		iput(ip);
1021 	} else
1022 		d_instantiate(dentry, ip);
1023 
1024       out2:
1025 	free_UCSname(&dname);
1026 
1027 #ifdef CONFIG_JFS_POSIX_ACL
1028 	if (rc == 0)
1029 		jfs_init_acl(ip, dip);
1030 #endif
1031 
1032       out1:
1033 	jfs_info("jfs_symlink: rc:%d", rc);
1034 	return rc;
1035 }
1036 
1037 
1038 /*
1039  * NAME:        jfs_rename
1040  *
1041  * FUNCTION:    rename a file or directory
1042  */
1043 static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1044 	       struct inode *new_dir, struct dentry *new_dentry)
1045 {
1046 	struct btstack btstack;
1047 	ino_t ino;
1048 	struct component_name new_dname;
1049 	struct inode *new_ip;
1050 	struct component_name old_dname;
1051 	struct inode *old_ip;
1052 	int rc;
1053 	tid_t tid;
1054 	struct tlock *tlck;
1055 	struct dt_lock *dtlck;
1056 	struct lv *lv;
1057 	int ipcount;
1058 	struct inode *iplist[4];
1059 	struct tblock *tblk;
1060 	s64 new_size = 0;
1061 	int commit_flag;
1062 
1063 
1064 	jfs_info("jfs_rename: %s %s", old_dentry->d_name.name,
1065 		 new_dentry->d_name.name);
1066 
1067 	old_ip = old_dentry->d_inode;
1068 	new_ip = new_dentry->d_inode;
1069 
1070 	if ((rc = get_UCSname(&old_dname, old_dentry)))
1071 		goto out1;
1072 
1073 	if ((rc = get_UCSname(&new_dname, new_dentry)))
1074 		goto out2;
1075 
1076 	/*
1077 	 * Make sure source inode number is what we think it is
1078 	 */
1079 	rc = dtSearch(old_dir, &old_dname, &ino, &btstack, JFS_LOOKUP);
1080 	if (rc || (ino != old_ip->i_ino)) {
1081 		rc = -ENOENT;
1082 		goto out3;
1083 	}
1084 
1085 	/*
1086 	 * Make sure dest inode number (if any) is what we think it is
1087 	 */
1088 	rc = dtSearch(new_dir, &new_dname, &ino, &btstack, JFS_LOOKUP);
1089 	if (rc == 0) {
1090 		if ((new_ip == 0) || (ino != new_ip->i_ino)) {
1091 			rc = -ESTALE;
1092 			goto out3;
1093 		}
1094 	} else if (rc != -ENOENT)
1095 		goto out3;
1096 	else if (new_ip) {
1097 		/* no entry exists, but one was expected */
1098 		rc = -ESTALE;
1099 		goto out3;
1100 	}
1101 
1102 	if (S_ISDIR(old_ip->i_mode)) {
1103 		if (new_ip) {
1104 			if (!dtEmpty(new_ip)) {
1105 				rc = -ENOTEMPTY;
1106 				goto out3;
1107 			}
1108 		} else if ((new_dir != old_dir) &&
1109 			   (new_dir->i_nlink == JFS_LINK_MAX)) {
1110 			rc = -EMLINK;
1111 			goto out3;
1112 		}
1113 	} else if (new_ip) {
1114 		IWRITE_LOCK(new_ip);
1115 		/* Init inode for quota operations. */
1116 		DQUOT_INIT(new_ip);
1117 	}
1118 
1119 	/*
1120 	 * The real work starts here
1121 	 */
1122 	tid = txBegin(new_dir->i_sb, 0);
1123 
1124 	down(&JFS_IP(new_dir)->commit_sem);
1125 	down(&JFS_IP(old_ip)->commit_sem);
1126 	if (old_dir != new_dir)
1127 		down(&JFS_IP(old_dir)->commit_sem);
1128 
1129 	if (new_ip) {
1130 		down(&JFS_IP(new_ip)->commit_sem);
1131 		/*
1132 		 * Change existing directory entry to new inode number
1133 		 */
1134 		ino = new_ip->i_ino;
1135 		rc = dtModify(tid, new_dir, &new_dname, &ino,
1136 			      old_ip->i_ino, JFS_RENAME);
1137 		if (rc)
1138 			goto out4;
1139 		new_ip->i_nlink--;
1140 		if (S_ISDIR(new_ip->i_mode)) {
1141 			new_ip->i_nlink--;
1142 			if (new_ip->i_nlink) {
1143 				up(&JFS_IP(new_dir)->commit_sem);
1144 				up(&JFS_IP(old_ip)->commit_sem);
1145 				if (old_dir != new_dir)
1146 					up(&JFS_IP(old_dir)->commit_sem);
1147 				if (!S_ISDIR(old_ip->i_mode) && new_ip)
1148 					IWRITE_UNLOCK(new_ip);
1149 				jfs_error(new_ip->i_sb,
1150 					  "jfs_rename: new_ip->i_nlink != 0");
1151 				return -EIO;
1152 			}
1153 			tblk = tid_to_tblock(tid);
1154 			tblk->xflag |= COMMIT_DELETE;
1155 			tblk->u.ip = new_ip;
1156 		} else if (new_ip->i_nlink == 0) {
1157 			assert(!test_cflag(COMMIT_Nolink, new_ip));
1158 			/* free block resources */
1159 			if ((new_size = commitZeroLink(tid, new_ip)) < 0) {
1160 				txAbort(tid, 1);	/* Marks FS Dirty */
1161 				rc = new_size;
1162 				goto out4;
1163 			}
1164 			tblk = tid_to_tblock(tid);
1165 			tblk->xflag |= COMMIT_DELETE;
1166 			tblk->u.ip = new_ip;
1167 		} else {
1168 			new_ip->i_ctime = CURRENT_TIME;
1169 			mark_inode_dirty(new_ip);
1170 		}
1171 	} else {
1172 		/*
1173 		 * Add new directory entry
1174 		 */
1175 		rc = dtSearch(new_dir, &new_dname, &ino, &btstack,
1176 			      JFS_CREATE);
1177 		if (rc) {
1178 			jfs_err("jfs_rename didn't expect dtSearch to fail "
1179 				"w/rc = %d", rc);
1180 			goto out4;
1181 		}
1182 
1183 		ino = old_ip->i_ino;
1184 		rc = dtInsert(tid, new_dir, &new_dname, &ino, &btstack);
1185 		if (rc) {
1186 			if (rc == -EIO)
1187 				jfs_err("jfs_rename: dtInsert returned -EIO");
1188 			goto out4;
1189 		}
1190 		if (S_ISDIR(old_ip->i_mode))
1191 			new_dir->i_nlink++;
1192 	}
1193 	/*
1194 	 * Remove old directory entry
1195 	 */
1196 
1197 	ino = old_ip->i_ino;
1198 	rc = dtDelete(tid, old_dir, &old_dname, &ino, JFS_REMOVE);
1199 	if (rc) {
1200 		jfs_err("jfs_rename did not expect dtDelete to return rc = %d",
1201 			rc);
1202 		txAbort(tid, 1);	/* Marks Filesystem dirty */
1203 		goto out4;
1204 	}
1205 	if (S_ISDIR(old_ip->i_mode)) {
1206 		old_dir->i_nlink--;
1207 		if (old_dir != new_dir) {
1208 			/*
1209 			 * Change inode number of parent for moved directory
1210 			 */
1211 
1212 			JFS_IP(old_ip)->i_dtroot.header.idotdot =
1213 				cpu_to_le32(new_dir->i_ino);
1214 
1215 			/* Linelock header of dtree */
1216 			tlck = txLock(tid, old_ip,
1217 				    (struct metapage *) &JFS_IP(old_ip)->bxflag,
1218 				      tlckDTREE | tlckBTROOT | tlckRELINK);
1219 			dtlck = (struct dt_lock *) & tlck->lock;
1220 			ASSERT(dtlck->index == 0);
1221 			lv = & dtlck->lv[0];
1222 			lv->offset = 0;
1223 			lv->length = 1;
1224 			dtlck->index++;
1225 		}
1226 	}
1227 
1228 	/*
1229 	 * Update ctime on changed/moved inodes & mark dirty
1230 	 */
1231 	old_ip->i_ctime = CURRENT_TIME;
1232 	mark_inode_dirty(old_ip);
1233 
1234 	new_dir->i_ctime = new_dir->i_mtime = current_fs_time(new_dir->i_sb);
1235 	mark_inode_dirty(new_dir);
1236 
1237 	/* Build list of inodes modified by this transaction */
1238 	ipcount = 0;
1239 	iplist[ipcount++] = old_ip;
1240 	if (new_ip)
1241 		iplist[ipcount++] = new_ip;
1242 	iplist[ipcount++] = old_dir;
1243 
1244 	if (old_dir != new_dir) {
1245 		iplist[ipcount++] = new_dir;
1246 		old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
1247 		mark_inode_dirty(old_dir);
1248 	}
1249 
1250 	/*
1251 	 * Incomplete truncate of file data can
1252 	 * result in timing problems unless we synchronously commit the
1253 	 * transaction.
1254 	 */
1255 	if (new_size)
1256 		commit_flag = COMMIT_SYNC;
1257 	else
1258 		commit_flag = 0;
1259 
1260 	rc = txCommit(tid, ipcount, iplist, commit_flag);
1261 
1262       out4:
1263 	txEnd(tid);
1264 
1265 	up(&JFS_IP(new_dir)->commit_sem);
1266 	up(&JFS_IP(old_ip)->commit_sem);
1267 	if (old_dir != new_dir)
1268 		up(&JFS_IP(old_dir)->commit_sem);
1269 	if (new_ip)
1270 		up(&JFS_IP(new_ip)->commit_sem);
1271 
1272 	while (new_size && (rc == 0)) {
1273 		tid = txBegin(new_ip->i_sb, 0);
1274 		down(&JFS_IP(new_ip)->commit_sem);
1275 		new_size = xtTruncate_pmap(tid, new_ip, new_size);
1276 		if (new_size < 0) {
1277 			txAbort(tid, 1);
1278 			rc = new_size;
1279 		} else
1280 			rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
1281 		txEnd(tid);
1282 		up(&JFS_IP(new_ip)->commit_sem);
1283 	}
1284 	if (new_ip && (new_ip->i_nlink == 0))
1285 		set_cflag(COMMIT_Nolink, new_ip);
1286       out3:
1287 	free_UCSname(&new_dname);
1288       out2:
1289 	free_UCSname(&old_dname);
1290       out1:
1291 	if (new_ip && !S_ISDIR(new_ip->i_mode))
1292 		IWRITE_UNLOCK(new_ip);
1293 	/*
1294 	 * Truncating the directory index table is not guaranteed.  It
1295 	 * may need to be done iteratively
1296 	 */
1297 	if (test_cflag(COMMIT_Stale, old_dir)) {
1298 		if (old_dir->i_size > 1)
1299 			jfs_truncate_nolock(old_dir, 0);
1300 
1301 		clear_cflag(COMMIT_Stale, old_dir);
1302 	}
1303 
1304 	jfs_info("jfs_rename: returning %d", rc);
1305 	return rc;
1306 }
1307 
1308 
1309 /*
1310  * NAME:        jfs_mknod
1311  *
1312  * FUNCTION:    Create a special file (device)
1313  */
1314 static int jfs_mknod(struct inode *dir, struct dentry *dentry,
1315 		int mode, dev_t rdev)
1316 {
1317 	struct jfs_inode_info *jfs_ip;
1318 	struct btstack btstack;
1319 	struct component_name dname;
1320 	ino_t ino;
1321 	struct inode *ip;
1322 	struct inode *iplist[2];
1323 	int rc;
1324 	tid_t tid;
1325 	struct tblock *tblk;
1326 
1327 	if (!new_valid_dev(rdev))
1328 		return -EINVAL;
1329 
1330 	jfs_info("jfs_mknod: %s", dentry->d_name.name);
1331 
1332 	if ((rc = get_UCSname(&dname, dentry)))
1333 		goto out;
1334 
1335 	ip = ialloc(dir, mode);
1336 	if (ip == NULL) {
1337 		rc = -ENOSPC;
1338 		goto out1;
1339 	}
1340 	jfs_ip = JFS_IP(ip);
1341 
1342 	tid = txBegin(dir->i_sb, 0);
1343 
1344 	down(&JFS_IP(dir)->commit_sem);
1345 	down(&JFS_IP(ip)->commit_sem);
1346 
1347 	if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE)))
1348 		goto out3;
1349 
1350 	tblk = tid_to_tblock(tid);
1351 	tblk->xflag |= COMMIT_CREATE;
1352 	tblk->ino = ip->i_ino;
1353 	tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
1354 
1355 	ino = ip->i_ino;
1356 	if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack)))
1357 		goto out3;
1358 
1359 	ip->i_op = &jfs_file_inode_operations;
1360 	jfs_ip->dev = new_encode_dev(rdev);
1361 	init_special_inode(ip, ip->i_mode, rdev);
1362 
1363 	insert_inode_hash(ip);
1364 	mark_inode_dirty(ip);
1365 
1366 	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
1367 
1368 	mark_inode_dirty(dir);
1369 
1370 	iplist[0] = dir;
1371 	iplist[1] = ip;
1372 	rc = txCommit(tid, 2, iplist, 0);
1373 
1374       out3:
1375 	txEnd(tid);
1376 	up(&JFS_IP(ip)->commit_sem);
1377 	up(&JFS_IP(dir)->commit_sem);
1378 	if (rc) {
1379 		ip->i_nlink = 0;
1380 		iput(ip);
1381 	} else
1382 		d_instantiate(dentry, ip);
1383 
1384       out1:
1385 	free_UCSname(&dname);
1386 
1387 #ifdef CONFIG_JFS_POSIX_ACL
1388 	if (rc == 0)
1389 		jfs_init_acl(ip, dir);
1390 #endif
1391 
1392       out:
1393 	jfs_info("jfs_mknod: returning %d", rc);
1394 	return rc;
1395 }
1396 
1397 static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struct nameidata *nd)
1398 {
1399 	struct btstack btstack;
1400 	ino_t inum;
1401 	struct inode *ip;
1402 	struct component_name key;
1403 	const char *name = dentry->d_name.name;
1404 	int len = dentry->d_name.len;
1405 	int rc;
1406 
1407 	jfs_info("jfs_lookup: name = %s", name);
1408 
1409 
1410 	if ((name[0] == '.') && (len == 1))
1411 		inum = dip->i_ino;
1412 	else if (strcmp(name, "..") == 0)
1413 		inum = PARENT(dip);
1414 	else {
1415 		if ((rc = get_UCSname(&key, dentry)))
1416 			return ERR_PTR(rc);
1417 		rc = dtSearch(dip, &key, &inum, &btstack, JFS_LOOKUP);
1418 		free_UCSname(&key);
1419 		if (rc == -ENOENT) {
1420 			d_add(dentry, NULL);
1421 			return ERR_PTR(0);
1422 		} else if (rc) {
1423 			jfs_err("jfs_lookup: dtSearch returned %d", rc);
1424 			return ERR_PTR(rc);
1425 		}
1426 	}
1427 
1428 	ip = iget(dip->i_sb, inum);
1429 	if (ip == NULL || is_bad_inode(ip)) {
1430 		jfs_err("jfs_lookup: iget failed on inum %d", (uint) inum);
1431 		if (ip)
1432 			iput(ip);
1433 		return ERR_PTR(-EACCES);
1434 	}
1435 
1436 	if (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2)
1437 		dentry->d_op = &jfs_ci_dentry_operations;
1438 
1439 	dentry = d_splice_alias(ip, dentry);
1440 
1441 	if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2))
1442 		dentry->d_op = &jfs_ci_dentry_operations;
1443 
1444 	return dentry;
1445 }
1446 
1447 struct dentry *jfs_get_parent(struct dentry *dentry)
1448 {
1449 	struct super_block *sb = dentry->d_inode->i_sb;
1450 	struct dentry *parent = ERR_PTR(-ENOENT);
1451 	struct inode *inode;
1452 	unsigned long parent_ino;
1453 
1454 	parent_ino =
1455 		le32_to_cpu(JFS_IP(dentry->d_inode)->i_dtroot.header.idotdot);
1456 	inode = iget(sb, parent_ino);
1457 	if (inode) {
1458 		if (is_bad_inode(inode)) {
1459 			iput(inode);
1460 			parent = ERR_PTR(-EACCES);
1461 		} else {
1462 			parent = d_alloc_anon(inode);
1463 			if (!parent) {
1464 				parent = ERR_PTR(-ENOMEM);
1465 				iput(inode);
1466 			}
1467 		}
1468 	}
1469 
1470 	return parent;
1471 }
1472 
1473 struct inode_operations jfs_dir_inode_operations = {
1474 	.create		= jfs_create,
1475 	.lookup		= jfs_lookup,
1476 	.link		= jfs_link,
1477 	.unlink		= jfs_unlink,
1478 	.symlink	= jfs_symlink,
1479 	.mkdir		= jfs_mkdir,
1480 	.rmdir		= jfs_rmdir,
1481 	.mknod		= jfs_mknod,
1482 	.rename		= jfs_rename,
1483 	.setxattr	= jfs_setxattr,
1484 	.getxattr	= jfs_getxattr,
1485 	.listxattr	= jfs_listxattr,
1486 	.removexattr	= jfs_removexattr,
1487 #ifdef CONFIG_JFS_POSIX_ACL
1488 	.setattr	= jfs_setattr,
1489 	.permission	= jfs_permission,
1490 #endif
1491 };
1492 
1493 struct file_operations jfs_dir_operations = {
1494 	.read		= generic_read_dir,
1495 	.readdir	= jfs_readdir,
1496 	.fsync		= jfs_fsync,
1497 };
1498 
1499 static int jfs_ci_hash(struct dentry *dir, struct qstr *this)
1500 {
1501 	unsigned long hash;
1502 	int i;
1503 
1504 	hash = init_name_hash();
1505 	for (i=0; i < this->len; i++)
1506 		hash = partial_name_hash(tolower(this->name[i]), hash);
1507 	this->hash = end_name_hash(hash);
1508 
1509 	return 0;
1510 }
1511 
1512 static int jfs_ci_compare(struct dentry *dir, struct qstr *a, struct qstr *b)
1513 {
1514 	int i, result = 1;
1515 
1516 	if (a->len != b->len)
1517 		goto out;
1518 	for (i=0; i < a->len; i++) {
1519 		if (tolower(a->name[i]) != tolower(b->name[i]))
1520 			goto out;
1521 	}
1522 	result = 0;
1523 
1524 	/*
1525 	 * We want creates to preserve case.  A negative dentry, a, that
1526 	 * has a different case than b may cause a new entry to be created
1527 	 * with the wrong case.  Since we can't tell if a comes from a negative
1528 	 * dentry, we blindly replace it with b.  This should be harmless if
1529 	 * a is not a negative dentry.
1530 	 */
1531 	memcpy((unsigned char *)a->name, b->name, a->len);
1532 out:
1533 	return result;
1534 }
1535 
1536 struct dentry_operations jfs_ci_dentry_operations =
1537 {
1538 	.d_hash = jfs_ci_hash,
1539 	.d_compare = jfs_ci_compare,
1540 };
1541