diff options
author | Yingping Lu <yingping@sgi.com> | 2006-01-31 20:14:34 -0500 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2006-01-31 20:14:34 -0500 |
commit | 3a69c7dc6f3d58aeb9ce5051fc7060d55e05c003 (patch) | |
tree | d9083f4e790cdcc0ce94cb583e7e751927df92f8 /fs | |
parent | 3ee68c4af3fd7228c1be63254b9f884614f9ebb2 (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.c | 50 |
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 | ||
265 | STATIC inline void | ||
266 | cleanup_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 | |||
265 | STATIC int | 290 | STATIC int |
266 | linvfs_mknod( | 291 | linvfs_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 | } |