aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorYingping Lu <yingping@sgi.com>2006-01-31 20:14:34 -0500
committerNathan Scott <nathans@sgi.com>2006-01-31 20:14:34 -0500
commit3a69c7dc6f3d58aeb9ce5051fc7060d55e05c003 (patch)
treed9083f4e790cdcc0ce94cb583e7e751927df92f8 /fs
parent3ee68c4af3fd7228c1be63254b9f884614f9ebb2 (diff)
[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>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c50
1 files changed, 32 insertions, 18 deletions
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 76c6df34d0db..eda7919b70a1 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -262,6 +262,31 @@ has_fs_struct(struct task_struct *task)
262 return (task->fs != init_task.fs); 262 return (task->fs != init_task.fs);
263} 263}
264 264
265STATIC inline void
266cleanup_inode(
267 vnode_t *dvp,
268 vnode_t *vp,
269 struct dentry *dentry,
270 int mode)
271{
272 struct dentry teardown = {};
273 int err2;
274
275 /* Oh, the horror.
276 * If we can't add the ACL or we fail in
277 * linvfs_init_security we must back out.
278 * ENOSPC can hit here, among other things.
279 */
280 teardown.d_inode = LINVFS_GET_IP(vp);
281 teardown.d_name = dentry->d_name;
282
283 if (S_ISDIR(mode))
284 VOP_RMDIR(dvp, &teardown, NULL, err2);
285 else
286 VOP_REMOVE(dvp, &teardown, NULL, err2);
287 VN_RELE(vp);
288}
289
265STATIC int 290STATIC int
266linvfs_mknod( 291linvfs_mknod(
267 struct inode *dir, 292 struct inode *dir,
@@ -316,30 +341,19 @@ linvfs_mknod(
316 } 341 }
317 342
318 if (!error) 343 if (!error)
344 {
319 error = linvfs_init_security(vp, dir); 345 error = linvfs_init_security(vp, dir);
346 if (error)
347 cleanup_inode(dvp, vp, dentry, mode);
348 }
320 349
321 if (default_acl) { 350 if (default_acl) {
322 if (!error) { 351 if (!error) {
323 error = _ACL_INHERIT(vp, &va, default_acl); 352 error = _ACL_INHERIT(vp, &va, default_acl);
324 if (!error) { 353 if (!error)
325 VMODIFY(vp); 354 VMODIFY(vp);
326 } else { 355 else
327 struct dentry teardown = {}; 356 cleanup_inode(dvp, vp, dentry, mode);
328 int err2;
329
330 /* Oh, the horror.
331 * If we can't add the ACL we must back out.
332 * ENOSPC can hit here, among other things.
333 */
334 teardown.d_inode = ip = LINVFS_GET_IP(vp);
335 teardown.d_name = dentry->d_name;
336
337 if (S_ISDIR(mode))
338 VOP_RMDIR(dvp, &teardown, NULL, err2);
339 else
340 VOP_REMOVE(dvp, &teardown, NULL, err2);
341 VN_RELE(vp);
342 }
343 } 357 }
344 _ACL_FREE(default_acl); 358 _ACL_FREE(default_acl);
345 } 359 }