浏览代码

[XFS] Interim solution for attribute insertion failure during file
creation due to ENOSPC. The current solution removes the inode when the
attribute insertion fails. Long term solution would be to make the inode
creation and attribute insertion atomic.

SGI-PV: 947610
SGI-Modid: xfs-linux-melb:xfs-kern:205193a

Signed-off-by: Yingping Lu <yingping@sgi.com>
Signed-off-by: Nathan Scott <nathans@sgi.com>

Yingping Lu 19 年之前
父节点
当前提交
3a69c7dc6f
共有 1 个文件被更改,包括 32 次插入18 次删除
  1. 32 18
      fs/xfs/linux-2.6/xfs_iops.c

+ 32 - 18
fs/xfs/linux-2.6/xfs_iops.c

@@ -262,6 +262,31 @@ has_fs_struct(struct task_struct *task)
 	return (task->fs != init_task.fs);
 	return (task->fs != init_task.fs);
 }
 }
 
 
+STATIC inline void
+cleanup_inode(
+	vnode_t		*dvp,
+	vnode_t		*vp,
+	struct dentry	*dentry,	
+	int		mode)
+{
+	struct dentry   teardown = {};
+	int             err2;
+
+	/* Oh, the horror.
+	 * If we can't add the ACL or we fail in 
+	 * linvfs_init_security we must back out.
+	 * ENOSPC can hit here, among other things.
+	 */
+	teardown.d_inode = LINVFS_GET_IP(vp);
+	teardown.d_name = dentry->d_name;
+
+	if (S_ISDIR(mode))
+	  	VOP_RMDIR(dvp, &teardown, NULL, err2);
+	else
+		VOP_REMOVE(dvp, &teardown, NULL, err2);
+	VN_RELE(vp);
+}
+
 STATIC int
 STATIC int
 linvfs_mknod(
 linvfs_mknod(
 	struct inode	*dir,
 	struct inode	*dir,
@@ -316,30 +341,19 @@ linvfs_mknod(
 	}
 	}
 
 
 	if (!error)
 	if (!error)
+	{
 		error = linvfs_init_security(vp, dir);
 		error = linvfs_init_security(vp, dir);
+		if (error)
+			cleanup_inode(dvp, vp, dentry, mode);
+	}
 
 
 	if (default_acl) {
 	if (default_acl) {
 		if (!error) {
 		if (!error) {
 			error = _ACL_INHERIT(vp, &va, default_acl);
 			error = _ACL_INHERIT(vp, &va, default_acl);
-			if (!error) {
+			if (!error) 
 				VMODIFY(vp);
 				VMODIFY(vp);
-			} else {
-				struct dentry	teardown = {};
-				int		err2;
-
-				/* Oh, the horror.
-				 * If we can't add the ACL we must back out.
-				 * ENOSPC can hit here, among other things.
-				 */
-				teardown.d_inode = ip = LINVFS_GET_IP(vp);
-				teardown.d_name = dentry->d_name;
-
-				if (S_ISDIR(mode))
-					VOP_RMDIR(dvp, &teardown, NULL, err2);
-				else
-					VOP_REMOVE(dvp, &teardown, NULL, err2);
-				VN_RELE(vp);
-			}
+			else
+				cleanup_inode(dvp, vp, dentry, mode);
 		}
 		}
 		_ACL_FREE(default_acl);
 		_ACL_FREE(default_acl);
 	}
 	}