jFYI(1, ("jfs_create: dip:0x%p name:%s\n", dip, dentry->d_name.name));
- IWRITE_LOCK(dip);
-
/*
* search parent directory for entry/freespace
* (dtSearch() returns parent directory page pinned)
tid = txBegin(dip->i_sb, 0);
+ down(&JFS_IP(dip)->commit_sem);
+ down(&JFS_IP(ip)->commit_sem);
+
if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
jERROR(1, ("jfs_create: dtSearch returned %d\n", rc));
- ip->i_nlink = 0;
- iput(ip);
- txEnd(tid);
- goto out2;
+ goto out3;
}
tblk = tid_to_tblock(tid);
ino = ip->i_ino;
if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
jERROR(1, ("jfs_create: dtInsert returned %d\n", rc));
- /* discard new inode */
- ip->i_nlink = 0;
- iput(ip);
-
if (rc == EIO)
txAbort(tid, 1); /* Marks Filesystem dirty */
else
txAbort(tid, 0); /* Filesystem full */
- txEnd(tid);
- goto out2;
+ goto out3;
}
ip->i_op = &jfs_file_inode_operations;
mark_inode_dirty(dip);
rc = txCommit(tid, 2, &iplist[0], 0);
+
+ out3:
txEnd(tid);
+ up(&JFS_IP(dip)->commit_sem);
+ up(&JFS_IP(ip)->commit_sem);
+ if (rc) {
+ ip->i_nlink = 0;
+ iput(ip);
+ }
out2:
free_UCSname(&dname);
out1:
- IWRITE_UNLOCK(dip);
jFYI(1, ("jfs_create: rc:%d\n", -rc));
return -rc;
}
jFYI(1, ("jfs_mkdir: dip:0x%p name:%s\n", dip, dentry->d_name.name));
- IWRITE_LOCK(dip);
-
/* link count overflow on parent directory ? */
if (dip->i_nlink == JFS_LINK_MAX) {
rc = EMLINK;
tid = txBegin(dip->i_sb, 0);
+ down(&JFS_IP(dip)->commit_sem);
+ down(&JFS_IP(ip)->commit_sem);
+
if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
jERROR(1, ("jfs_mkdir: dtSearch returned %d\n", rc));
- ip->i_nlink = 0;
- iput(ip);
- txEnd(tid);
- goto out2;
+ goto out3;
}
tblk = tid_to_tblock(tid);
ino = ip->i_ino;
if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
jERROR(1, ("jfs_mkdir: dtInsert returned %d\n", rc));
- /* discard new directory inode */
- ip->i_nlink = 0;
- iput(ip);
if (rc == EIO)
txAbort(tid, 1); /* Marks Filesystem dirty */
else
txAbort(tid, 0); /* Filesystem full */
- txEnd(tid);
- goto out2;
+ goto out3;
}
ip->i_nlink = 2; /* for '.' */
mark_inode_dirty(dip);
rc = txCommit(tid, 2, &iplist[0], 0);
+
+ out3:
txEnd(tid);
+ up(&JFS_IP(dip)->commit_sem);
+ up(&JFS_IP(ip)->commit_sem);
+ if (rc) {
+ ip->i_nlink = 0;
+ iput(ip);
+ }
out2:
free_UCSname(&dname);
out1:
- IWRITE_UNLOCK(dip);
-
jFYI(1, ("jfs_mkdir: rc:%d\n", -rc));
return -rc;
}
jFYI(1, ("jfs_rmdir: dip:0x%p name:%s\n", dip, dentry->d_name.name));
- IWRITE_LOCK_LIST(2, dip, ip);
-
/* directory must be empty to be removed */
if (!dtEmpty(ip)) {
- IWRITE_UNLOCK(ip);
- IWRITE_UNLOCK(dip);
rc = ENOTEMPTY;
goto out;
}
if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) {
- IWRITE_UNLOCK(ip);
- IWRITE_UNLOCK(dip);
goto out;
}
tid = txBegin(dip->i_sb, 0);
+ down(&JFS_IP(dip)->commit_sem);
+ down(&JFS_IP(ip)->commit_sem);
+
iplist[0] = dip;
iplist[1] = ip;
if (rc == EIO)
txAbort(tid, 1);
txEnd(tid);
-
- IWRITE_UNLOCK(ip);
- IWRITE_UNLOCK(dip);
+ up(&JFS_IP(dip)->commit_sem);
+ up(&JFS_IP(ip)->commit_sem);
goto out2;
}
txEnd(tid);
- IWRITE_UNLOCK(ip);
+ up(&JFS_IP(dip)->commit_sem);
+ up(&JFS_IP(ip)->commit_sem);
/*
* Truncating the directory index table is not guaranteed. It
clear_cflag(COMMIT_Stale, dip);
}
- IWRITE_UNLOCK(dip);
-
out2:
free_UCSname(&dname);
if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
goto out;
- IWRITE_LOCK_LIST(2, ip, dip);
+ IWRITE_LOCK(ip);
tid = txBegin(dip->i_sb, 0);
+ down(&JFS_IP(dip)->commit_sem);
+ down(&JFS_IP(ip)->commit_sem);
+
iplist[0] = dip;
iplist[1] = ip;
if (rc == EIO)
txAbort(tid, 1); /* Marks FS Dirty */
txEnd(tid);
+ up(&JFS_IP(dip)->commit_sem);
+ up(&JFS_IP(ip)->commit_sem);
IWRITE_UNLOCK(ip);
- IWRITE_UNLOCK(dip);
goto out1;
}
if ((new_size = commitZeroLink(tid, ip)) < 0) {
txAbort(tid, 1); /* Marks FS Dirty */
txEnd(tid);
+ up(&JFS_IP(dip)->commit_sem);
+ up(&JFS_IP(ip)->commit_sem);
IWRITE_UNLOCK(ip);
- IWRITE_UNLOCK(dip);
rc = -new_size; /* We return -rc */
goto out1;
}
txEnd(tid);
+ up(&JFS_IP(dip)->commit_sem);
+ up(&JFS_IP(ip)->commit_sem);
+
+
while (new_size && (rc == 0)) {
tid = txBegin(dip->i_sb, 0);
+ down(&JFS_IP(ip)->commit_sem);
new_size = xtTruncate_pmap(tid, ip, new_size);
if (new_size < 0) {
txAbort(tid, 1); /* Marks FS Dirty */
} else
rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC);
txEnd(tid);
+ up(&JFS_IP(ip)->commit_sem);
}
if (ip->i_nlink == 0)
clear_cflag(COMMIT_Stale, dip);
}
- IWRITE_UNLOCK(dip);
-
out1:
free_UCSname(&dname);
out:
("jfs_link: %s %s\n", old_dentry->d_name.name,
dentry->d_name.name));
- IWRITE_LOCK_LIST(2, dir, ip);
-
tid = txBegin(ip->i_sb, 0);
+ down(&JFS_IP(dir)->commit_sem);
+ down(&JFS_IP(ip)->commit_sem);
+
if (ip->i_nlink == JFS_LINK_MAX) {
rc = EMLINK;
goto out;
rc = txCommit(tid, 2, &iplist[0], 0);
out:
- IWRITE_UNLOCK(dir);
- IWRITE_UNLOCK(ip);
-
txEnd(tid);
+ up(&JFS_IP(dir)->commit_sem);
+ up(&JFS_IP(ip)->commit_sem);
+
jFYI(1, ("jfs_link: rc:%d\n", rc));
return -rc;
}
jFYI(1, ("jfs_symlink: dip:0x%p name:%s\n", dip, name));
- IWRITE_LOCK(dip);
-
ssize = strlen(name) + 1;
- tid = txBegin(dip->i_sb, 0);
-
/*
* search parent directory for entry/freespace
* (dtSearch() returns parent directory page pinned)
if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
goto out1;
- if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE)))
- goto out2;
-
-
-
/*
* allocate on-disk/in-memory inode for symbolic link:
* (iAlloc() returns new, locked inode)
*/
-
ip = ialloc(dip, S_IFLNK | 0777);
if (ip == NULL) {
- BT_PUTSEARCH(&btstack);
rc = ENOSPC;
goto out2;
}
+ tid = txBegin(dip->i_sb, 0);
+
+ down(&JFS_IP(dip)->commit_sem);
+ down(&JFS_IP(ip)->commit_sem);
+
+ if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE)))
+ goto out3;
+
tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_CREATE;
tblk->ip = ip;
if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
jERROR(1, ("jfs_symlink: dtInsert returned %d\n", rc));
/* discard ne inode */
- ip->i_nlink = 0;
- iput(ip);
- goto out2;
+ goto out3;
}
if (mp == NULL) {
dtDelete(tid, dip, &dname, &ino,
JFS_REMOVE);
- ip->i_nlink = 0;
- iput(ip);
rc = EIO;
- goto out2;
+ goto out3;
}
memcpy(mp->data, name, copy_size);
flush_metapage(mp);
ip->i_blocks = LBLK2PBLK(sb, xlen);
} else {
dtDelete(tid, dip, &dname, &ino, JFS_REMOVE);
- ip->i_nlink = 0;
- iput(ip);
rc = ENOSPC;
- goto out2;
+ goto out3;
}
}
} else
rc = txCommit(tid, 1, &iplist[0], 0);
- out2:
+ out3:
+ txEnd(tid);
+ up(&JFS_IP(dip)->commit_sem);
+ up(&JFS_IP(ip)->commit_sem);
+ if (rc) {
+ ip->i_nlink = 0;
+ iput(ip);
+ }
+ out2:
free_UCSname(&dname);
- out1:
- IWRITE_UNLOCK(dip);
-
- txEnd(tid);
+ out1:
jFYI(1, ("jfs_symlink: rc:%d\n", -rc));
return -rc;
}
old_ip = old_dentry->d_inode;
new_ip = new_dentry->d_inode;
- if (old_dir == new_dir) {
- if (new_ip)
- IWRITE_LOCK_LIST(3, old_dir, old_ip, new_ip);
- else
- IWRITE_LOCK_LIST(2, old_dir, old_ip);
- } else {
- if (new_ip)
- IWRITE_LOCK_LIST(4, old_dir, new_dir, old_ip,
- new_ip);
- else
- IWRITE_LOCK_LIST(3, old_dir, new_dir, old_ip);
- }
-
if ((rc = get_UCSname(&old_dname, old_dentry,
JFS_SBI(old_dir->i_sb)->nls_tab)))
goto out1;
rc = EMLINK;
goto out3;
}
- }
+ } else if (new_ip)
+ IWRITE_LOCK(new_ip);
/*
* The real work starts here
*/
tid = txBegin(new_dir->i_sb, 0);
+ down(&JFS_IP(new_dir)->commit_sem);
+ down(&JFS_IP(old_ip)->commit_sem);
+ if (old_dir != new_dir)
+ down(&JFS_IP(old_dir)->commit_sem);
+
if (new_ip) {
+ down(&JFS_IP(new_ip)->commit_sem);
/*
* Change existing directory entry to new inode number
*/
/*
* Don't unlock new_ip if COMMIT_HOLDLOCK is set
*/
- if (new_ip && test_cflag(COMMIT_Holdlock, new_ip))
+ if (new_ip && test_cflag(COMMIT_Holdlock, new_ip)) {
+ up(&JFS_IP(new_ip)->commit_sem);
new_ip = 0;
+ }
out4:
txEnd(tid);
+ up(&JFS_IP(new_dir)->commit_sem);
+ up(&JFS_IP(old_ip)->commit_sem);
+ if (old_dir != new_dir)
+ up(&JFS_IP(old_dir)->commit_sem);
+ if (new_ip)
+ up(&JFS_IP(new_ip)->commit_sem);
+
while (new_size && (rc == 0)) {
tid = txBegin(new_ip->i_sb, 0);
+ down(&JFS_IP(new_ip)->commit_sem);
new_size = xtTruncate_pmap(tid, new_ip, new_size);
if (new_size < 0) {
txAbort(tid, 1);
} else
rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
txEnd(tid);
+ up(&JFS_IP(new_ip)->commit_sem);
}
if (new_ip && (new_ip->i_nlink == 0))
set_cflag(COMMIT_Nolink, new_ip);
out2:
free_UCSname(&old_dname);
out1:
- IWRITE_UNLOCK(old_ip);
- if (old_dir != new_dir)
- IWRITE_UNLOCK(new_dir);
- if (new_ip)
+ if (new_ip && !S_ISDIR(new_ip->i_mode))
IWRITE_UNLOCK(new_ip);
-
/*
* Truncating the directory index table is not guaranteed. It
* may need to be done iteratively
clear_cflag(COMMIT_Stale, old_dir);
}
- IWRITE_UNLOCK(old_dir);
-
jFYI(1, ("jfs_rename: returning %d\n", rc));
return -rc;
}
if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab)))
goto out;
- IWRITE_LOCK(dir);
-
ip = ialloc(dir, mode);
if (ip == NULL) {
rc = ENOSPC;
tid = txBegin(dir->i_sb, 0);
- if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) {
- ip->i_nlink = 0;
- iput(ip);
- txEnd(tid);
- goto out1;
- }
+ down(&JFS_IP(dir)->commit_sem);
+ down(&JFS_IP(ip)->commit_sem);
+
+ if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE)))
+ goto out3;
tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_CREATE;
tblk->ip = ip;
ino = ip->i_ino;
- if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) {
- ip->i_nlink = 0;
- iput(ip);
- txEnd(tid);
- goto out1;
- }
+ if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack)))
+ goto out3;
init_special_inode(ip, ip->i_mode, rdev);
iplist[0] = dir;
iplist[1] = ip;
rc = txCommit(tid, 2, iplist, 0);
+
+ out3:
txEnd(tid);
+ up(&JFS_IP(ip)->commit_sem);
+ up(&JFS_IP(dir)->commit_sem);
+ if (rc) {
+ ip->i_nlink = 0;
+ iput(ip);
+ }
out1:
- IWRITE_UNLOCK(dir);
free_UCSname(&dname);
out:
if ((rc =
get_UCSname(&key, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
return ERR_PTR(-rc);
- IREAD_LOCK(dip);
rc = dtSearch(dip, &key, &inum, &btstack, JFS_LOOKUP);
- IREAD_UNLOCK(dip);
free_UCSname(&key);
if (rc == ENOENT) {
d_add(dentry, NULL);