[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>
This commit is contained in:
Yingping Lu 2006-02-01 12:14:34 +11:00 committed by Nathan Scott
parent 3ee68c4af3
commit 3a69c7dc6f

View File

@ -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 { else
struct dentry teardown = {}; cleanup_inode(dvp, vp, dentry, mode);
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);
}
} }
_ACL_FREE(default_acl); _ACL_FREE(default_acl);
} }