patch-2.1.45 linux/fs/minix/namei.c

Next file: linux/fs/minix/symlink.c
Previous file: linux/fs/minix/inode.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.44/linux/fs/minix/namei.c linux/fs/minix/namei.c
@@ -104,7 +104,7 @@
 	return NULL;
 }
 
-int minix_lookup(struct inode * dir,const char * name, int len,
+int minix_lookup(struct inode * dir, struct qstr *name,
 	struct inode ** result)
 {
 	int ino;
@@ -114,21 +114,14 @@
 	*result = NULL;
 	if (!dir)
 		return -ENOENT;
-	if (!S_ISDIR(dir->i_mode)) {
-		iput(dir);
+	if (!S_ISDIR(dir->i_mode))
 		return -ENOENT;
-	}
-	if (!(bh = minix_find_entry(dir,name,len,&de))) {
-		iput(dir);
+	if (!(bh = minix_find_entry(dir, name->name, name->len, &de)))
 		return -ENOENT;
-	}
 	ino = de->inode;
 	brelse(bh);
-	if (!(*result = iget(dir->i_sb,ino))) {
-		iput(dir);
+	if (!(*result = iget(dir->i_sb,ino)))
 		return -EACCES;
-	}
-	iput(dir);
 	return 0;
 }
 
@@ -180,7 +173,7 @@
 		if (block*bh->b_size + offset > dir->i_size) {
 			de->inode = 0;
 			dir->i_size = block*bh->b_size + offset;
-			dir->i_dirt = 1;
+			mark_inode_dirty(dir);
 		}
 		if (de->inode) {
 			if (namecompare(namelen, info->s_namelen, name, de->name)) {
@@ -189,7 +182,7 @@
 			}
 		} else {
 			dir->i_mtime = dir->i_ctime = CURRENT_TIME;
-			dir->i_dirt = 1;
+			mark_inode_dirty(dir);
 			for (i = 0; i < info->s_namelen ; i++)
 				de->name[i] = (i < namelen) ? name[i] : 0;
 			dir->i_version = ++event;
@@ -208,42 +201,37 @@
 	return 0;
 }
 
-int minix_create(struct inode * dir,const char * name, int len, int mode,
-	struct inode ** result)
+int minix_create(struct inode * dir, struct dentry *dentry, int mode)
 {
 	int error;
 	struct inode * inode;
 	struct buffer_head * bh;
 	struct minix_dir_entry * de;
 
-	*result = NULL;
 	if (!dir)
 		return -ENOENT;
 	inode = minix_new_inode(dir);
-	if (!inode) {
-		iput(dir);
+	if (!inode)
 		return -ENOSPC;
-	}
 	inode->i_op = &minix_file_inode_operations;
 	inode->i_mode = mode;
-	inode->i_dirt = 1;
-	error = minix_add_entry(dir,name,len, &bh ,&de);
+	mark_inode_dirty(inode);
+	error = minix_add_entry(dir, dentry->d_name.name,
+				dentry->d_name.len, &bh ,&de);
 	if (error) {
 		inode->i_nlink--;
-		inode->i_dirt = 1;
+		mark_inode_dirty(inode);
 		iput(inode);
-		iput(dir);
 		return error;
 	}
 	de->inode = inode->i_ino;
 	mark_buffer_dirty(bh, 1);
 	brelse(bh);
-	iput(dir);
-	*result = inode;
+	d_instantiate(dentry, inode);
 	return 0;
 }
 
-int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rdev)
+int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev)
 {
 	int error;
 	struct inode * inode;
@@ -252,17 +240,15 @@
 
 	if (!dir)
 		return -ENOENT;
-	bh = minix_find_entry(dir,name,len,&de);
+	bh = minix_find_entry(dir, dentry->d_name.name,
+			      dentry->d_name.len, &de);
 	if (bh) {
 		brelse(bh);
-		iput(dir);
 		return -EEXIST;
 	}
 	inode = minix_new_inode(dir);
-	if (!inode) {
-		iput(dir);
+	if (!inode)
 		return -ENOSPC;
-	}
 	inode->i_uid = current->fsuid;
 	inode->i_mode = mode;
 	inode->i_op = NULL;
@@ -283,24 +269,22 @@
 		init_fifo(inode);
 	if (S_ISBLK(mode) || S_ISCHR(mode))
 		inode->i_rdev = to_kdev_t(rdev);
-	inode->i_dirt = 1;
-	error = minix_add_entry(dir, name, len, &bh, &de);
+	mark_inode_dirty(inode);
+	error = minix_add_entry(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de);
 	if (error) {
 		inode->i_nlink--;
-		inode->i_dirt = 1;
+		mark_inode_dirty(inode);
 		iput(inode);
-		iput(dir);
 		return error;
 	}
 	de->inode = inode->i_ino;
 	mark_buffer_dirty(bh, 1);
 	brelse(bh);
-	iput(dir);
-	iput(inode);
+	d_instantiate(dentry, inode);
 	return 0;
 }
 
-int minix_mkdir(struct inode * dir, const char * name, int len, int mode)
+int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
 {
 	int error;
 	struct inode * inode;
@@ -308,33 +292,26 @@
 	struct minix_dir_entry * de;
 	struct minix_sb_info * info;
 
-	if (!dir || !dir->i_sb) {
-		iput(dir);
+	if (!dir || !dir->i_sb)
 		return -EINVAL;
-	}
 	info = &dir->i_sb->u.minix_sb;
-	bh = minix_find_entry(dir,name,len,&de);
+	bh = minix_find_entry(dir, dentry->d_name.name,
+			      dentry->d_name.len, &de);
 	if (bh) {
 		brelse(bh);
-		iput(dir);
 		return -EEXIST;
 	}
-	if (dir->i_nlink >= MINIX_LINK_MAX) {
-		iput(dir);
+	if (dir->i_nlink >= MINIX_LINK_MAX)
 		return -EMLINK;
-	}
 	inode = minix_new_inode(dir);
-	if (!inode) {
-		iput(dir);
+	if (!inode)
 		return -ENOSPC;
-	}
 	inode->i_op = &minix_dir_inode_operations;
 	inode->i_size = 2 * info->s_dirsize;
 	dir_block = minix_bread(inode,0,1);
 	if (!dir_block) {
-		iput(dir);
 		inode->i_nlink--;
-		inode->i_dirt = 1;
+		mark_inode_dirty(inode);
 		iput(inode);
 		return -ENOSPC;
 	}
@@ -350,10 +327,10 @@
 	inode->i_mode = S_IFDIR | (mode & 0777 & ~current->fs->umask);
 	if (dir->i_mode & S_ISGID)
 		inode->i_mode |= S_ISGID;
-	inode->i_dirt = 1;
-	error = minix_add_entry(dir, name, len, &bh, &de);
+	mark_inode_dirty(inode);
+	error = minix_add_entry(dir, dentry->d_name.name,
+				dentry->d_name.len, &bh, &de);
 	if (error) {
-		iput(dir);
 		inode->i_nlink=0;
 		iput(inode);
 		return error;
@@ -361,10 +338,9 @@
 	de->inode = inode->i_ino;
 	mark_buffer_dirty(bh, 1);
 	dir->i_nlink++;
-	dir->i_dirt = 1;
-	iput(dir);
-	iput(inode);
+	mark_inode_dirty(dir);
 	brelse(bh);
+	d_instantiate(dentry, inode);
 	return 0;
 }
 
@@ -427,7 +403,7 @@
 	return 1;
 }
 
-int minix_rmdir(struct inode * dir, const char * name, int len)
+int minix_rmdir(struct inode * dir, struct dentry *dentry)
 {
 	int retval;
 	struct inode * inode;
@@ -435,13 +411,14 @@
 	struct minix_dir_entry * de;
 
 	inode = NULL;
-	bh = minix_find_entry(dir,name,len,&de);
+	bh = minix_find_entry(dir, dentry->d_name.name,
+			      dentry->d_name.len, &de);
 	retval = -ENOENT;
 	if (!bh)
 		goto end_rmdir;
 	retval = -EPERM;
-	if (!(inode = iget(dir->i_sb, de->inode)))
-		goto end_rmdir;
+	inode = dentry->d_inode;
+
         if ((dir->i_mode & S_ISVTX) && !fsuser() &&
             current->fsuid != inode->i_uid &&
             current->fsuid != dir->i_uid)
@@ -462,7 +439,7 @@
 		retval = -ENOENT;
 		goto end_rmdir;
 	}
-	if (atomic_read(&inode->i_count) > 1) {
+	if (inode->i_count > 1) {
 		retval = -EBUSY;
 		goto end_rmdir;
 	}
@@ -472,19 +449,18 @@
 	dir->i_version = ++event;
 	mark_buffer_dirty(bh, 1);
 	inode->i_nlink=0;
-	inode->i_dirt=1;
+	mark_inode_dirty(inode);
 	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 	dir->i_nlink--;
-	dir->i_dirt=1;
+	mark_inode_dirty(dir);
+	d_delete(dentry);
 	retval = 0;
 end_rmdir:
-	iput(dir);
-	iput(inode);
 	brelse(bh);
 	return retval;
 }
 
-int minix_unlink(struct inode * dir, const char * name, int len)
+int minix_unlink(struct inode * dir, struct dentry *dentry)
 {
 	int retval;
 	struct inode * inode;
@@ -494,16 +470,16 @@
 repeat:
 	retval = -ENOENT;
 	inode = NULL;
-	bh = minix_find_entry(dir,name,len,&de);
+	bh = minix_find_entry(dir, dentry->d_name.name,
+			      dentry->d_name.len, &de);
 	if (!bh)
 		goto end_unlink;
-	if (!(inode = iget(dir->i_sb, de->inode)))
-		goto end_unlink;
+	inode = dentry->d_inode;
+
 	retval = -EPERM;
 	if (S_ISDIR(inode->i_mode))
 		goto end_unlink;
 	if (de->inode != inode->i_ino) {
-		iput(inode);
 		brelse(bh);
 		current->counter = 0;
 		schedule();
@@ -527,19 +503,19 @@
 	dir->i_version = ++event;
 	mark_buffer_dirty(bh, 1);
 	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-	dir->i_dirt = 1;
+	mark_inode_dirty(dir);
 	inode->i_nlink--;
 	inode->i_ctime = dir->i_ctime;
-	inode->i_dirt = 1;
+	mark_inode_dirty(inode);
+	d_delete(dentry);	/* This also frees the inode */
 	retval = 0;
 end_unlink:
 	brelse(bh);
-	iput(inode);
-	iput(dir);
 	return retval;
 }
 
-int minix_symlink(struct inode * dir, const char * name, int len, const char * symname)
+int minix_symlink(struct inode * dir, struct dentry *dentry,
+		  const char * symname)
 {
 	struct minix_dir_entry * de;
 	struct inode * inode = NULL;
@@ -547,17 +523,15 @@
 	int i;
 	char c;
 
-	if (!(inode = minix_new_inode(dir))) {
-		iput(dir);
+	if (!(inode = minix_new_inode(dir)))
 		return -ENOSPC;
-	}
+
 	inode->i_mode = S_IFLNK | 0777;
 	inode->i_op = &minix_symlink_inode_operations;
 	name_block = minix_bread(inode,0,1);
 	if (!name_block) {
-		iput(dir);
 		inode->i_nlink--;
-		inode->i_dirt = 1;
+	        mark_inode_dirty(inode);
 		iput(inode);
 		return -ENOSPC;
 	}
@@ -568,69 +542,63 @@
 	mark_buffer_dirty(name_block, 1);
 	brelse(name_block);
 	inode->i_size = i;
-	inode->i_dirt = 1;
-	bh = minix_find_entry(dir,name,len,&de);
+	mark_inode_dirty(inode);
+	bh = minix_find_entry(dir, dentry->d_name.name,
+			      dentry->d_name.len, &de);
 	if (bh) {
 		inode->i_nlink--;
-		inode->i_dirt = 1;
+		mark_inode_dirty(inode);
 		iput(inode);
 		brelse(bh);
-		iput(dir);
 		return -EEXIST;
 	}
-	i = minix_add_entry(dir, name, len, &bh, &de);
+	i = minix_add_entry(dir, dentry->d_name.name,
+			    dentry->d_name.len, &bh, &de);
 	if (i) {
 		inode->i_nlink--;
-		inode->i_dirt = 1;
+		mark_inode_dirty(inode);
 		iput(inode);
-		iput(dir);
 		return i;
 	}
 	de->inode = inode->i_ino;
 	mark_buffer_dirty(bh, 1);
 	brelse(bh);
-	iput(dir);
-	iput(inode);
+	d_instantiate(dentry, inode);
 	return 0;
 }
 
-int minix_link(struct inode * oldinode, struct inode * dir, const char * name, int len)
+int minix_link(struct inode * inode, struct inode * dir,
+	       struct dentry *dentry)
 {
 	int error;
 	struct minix_dir_entry * de;
 	struct buffer_head * bh;
 
-	if (S_ISDIR(oldinode->i_mode)) {
-		iput(oldinode);
-		iput(dir);
+	if (S_ISDIR(inode->i_mode))
 		return -EPERM;
-	}
-	if (oldinode->i_nlink >= MINIX_LINK_MAX) {
-		iput(oldinode);
-		iput(dir);
+
+	if (inode->i_nlink >= MINIX_LINK_MAX)
 		return -EMLINK;
-	}
-	bh = minix_find_entry(dir,name,len,&de);
+
+	bh = minix_find_entry(dir, dentry->d_name.name,
+			      dentry->d_name.len, &de);
 	if (bh) {
 		brelse(bh);
-		iput(dir);
-		iput(oldinode);
 		return -EEXIST;
 	}
-	error = minix_add_entry(dir, name, len, &bh, &de);
+	error = minix_add_entry(dir, dentry->d_name.name,
+				dentry->d_name.len, &bh, &de);
 	if (error) {
-		iput(dir);
-		iput(oldinode);
+		brelse(bh);
 		return error;
 	}
-	de->inode = oldinode->i_ino;
+	de->inode = inode->i_ino;
 	mark_buffer_dirty(bh, 1);
 	brelse(bh);
-	iput(dir);
-	oldinode->i_nlink++;
-	oldinode->i_ctime = CURRENT_TIME;
-	oldinode->i_dirt = 1;
-	iput(oldinode);
+	inode->i_nlink++;
+	inode->i_ctime = CURRENT_TIME;
+	mark_inode_dirty(inode);
+	d_instantiate(dentry, inode);
 	return 0;
 }
 
@@ -639,7 +607,7 @@
 	int ino;
 	int result;
 
-	atomic_inc(&new_inode->i_count);
+	new_inode->i_count++;
 	result = 0;
 	for (;;) {
 		if (new_inode == old_inode) {
@@ -649,7 +617,9 @@
 		if (new_inode->i_dev != old_inode->i_dev)
 			break;
 		ino = new_inode->i_ino;
-		if (minix_lookup(new_inode,"..",2,&new_inode))
+		if (minix_lookup(new_inode,
+				 &(struct qstr) { "..", 2, 0 },
+				 &new_inode))
 			break;
 		if (new_inode->i_ino == ino)
 			break;
@@ -671,8 +641,8 @@
  * Anybody can rename anything with this: the permission checks are left to the
  * higher-level routines.
  */
-static int do_minix_rename(struct inode * old_dir, const char * old_name, int old_len,
-			   struct inode * new_dir, const char * new_name, int new_len)
+static int do_minix_rename(struct inode * old_dir, struct dentry *old_dentry,
+			   struct inode * new_dir, struct dentry *new_dentry)
 {
 	struct inode * old_inode, * new_inode;
 	struct buffer_head * old_bh, * new_bh, * dir_bh;
@@ -686,28 +656,26 @@
 	brelse(old_bh);
 	brelse(new_bh);
 	brelse(dir_bh);
-	iput(old_inode);
-	iput(new_inode);
 	current->counter = 0;
 	schedule();
 start_up:
 	old_inode = new_inode = NULL;
 	old_bh = new_bh = dir_bh = NULL;
-	old_bh = minix_find_entry(old_dir,old_name,old_len,&old_de);
+	old_bh = minix_find_entry(old_dir, old_dentry->d_name.name,
+				  old_dentry->d_name.len, &old_de);
 	retval = -ENOENT;
 	if (!old_bh)
 		goto end_rename;
-	old_inode = __iget(old_dir->i_sb, old_de->inode);
-	if (!old_inode)
-		goto end_rename;
+	old_inode = old_dentry->d_inode;
 	retval = -EPERM;
 	if ((old_dir->i_mode & S_ISVTX) && 
 	    current->fsuid != old_inode->i_uid &&
 	    current->fsuid != old_dir->i_uid && !fsuser())
 		goto end_rename;
-	new_bh = minix_find_entry(new_dir,new_name,new_len,&new_de);
+	new_inode = new_dentry->d_inode;
+	new_bh = minix_find_entry(new_dir, new_dentry->d_name.name,
+				  new_dentry->d_name.len, &new_de);
 	if (new_bh) {
-		new_inode = __iget(new_dir->i_sb, new_de->inode);
 		if (!new_inode) {
 			brelse(new_bh);
 			new_bh = NULL;
@@ -728,7 +696,7 @@
 		if (!empty_dir(new_inode))
 			goto end_rename;
 		retval = -EBUSY;
-		if (atomic_read(&new_inode->i_count) > 1)
+		if (new_inode->i_count > 1)
 			goto end_rename;
 	}
 	retval = -EPERM;
@@ -754,7 +722,10 @@
 			goto end_rename;
 	}
 	if (!new_bh) {
-		retval = minix_add_entry(new_dir,new_name,new_len,&new_bh,&new_de);
+		retval = minix_add_entry(new_dir,
+					 new_dentry->d_name.name,
+					 new_dentry->d_name.len,
+					 &new_bh, &new_de);
 		if (retval)
 			goto end_rename;
 	}
@@ -769,15 +740,15 @@
 	old_de->inode = 0;
 	new_de->inode = old_inode->i_ino;
 	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
-	old_dir->i_dirt = 1;
+	mark_inode_dirty(old_dir);
 	old_dir->i_version = ++event;
 	new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;
-	new_dir->i_dirt = 1;
+	mark_inode_dirty(new_dir);
 	new_dir->i_version = ++event;
 	if (new_inode) {
 		new_inode->i_nlink--;
 		new_inode->i_ctime = CURRENT_TIME;
-		new_inode->i_dirt = 1;
+		mark_inode_dirty(new_inode);
 	}
 	mark_buffer_dirty(old_bh, 1);
 	mark_buffer_dirty(new_bh, 1);
@@ -785,24 +756,23 @@
 		PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
 		mark_buffer_dirty(dir_bh, 1);
 		old_dir->i_nlink--;
-		old_dir->i_dirt = 1;
+		mark_inode_dirty(old_dir);
 		if (new_inode) {
 			new_inode->i_nlink--;
-			new_inode->i_dirt = 1;
+			mark_inode_dirty(new_inode);
 		} else {
 			new_dir->i_nlink++;
-			new_dir->i_dirt = 1;
+			mark_inode_dirty(new_dir);
 		}
 	}
+	/* Update the dcache */
+	d_move(old_dentry, new_dentry->d_parent, &new_dentry->d_name);
+	d_delete(new_dentry);
 	retval = 0;
 end_rename:
 	brelse(dir_bh);
 	brelse(old_bh);
 	brelse(new_bh);
-	iput(old_inode);
-	iput(new_inode);
-	iput(old_dir);
-	iput(new_dir);
 	return retval;
 }
 
@@ -815,8 +785,8 @@
  * the same device that races occur: many renames can happen at once, as long
  * as they are on different partitions.
  */
-int minix_rename(struct inode * old_dir, const char * old_name, int old_len,
-		 struct inode * new_dir, const char * new_name, int new_len)
+int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
+		 struct inode * new_dir, struct dentry *new_dentry)
 {
 	static struct wait_queue * wait = NULL;
 	static int lock = 0;
@@ -825,8 +795,8 @@
 	while (lock)
 		sleep_on(&wait);
 	lock = 1;
-	result = do_minix_rename(old_dir, old_name, old_len,
-				 new_dir, new_name, new_len);
+	result = do_minix_rename(old_dir, old_dentry,
+				 new_dir, new_dentry);
 	lock = 0;
 	wake_up(&wait);
 	return result;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov