diff options
Diffstat (limited to 'fs/ocfs2/namei.c')
-rw-r--r-- | fs/ocfs2/namei.c | 107 |
1 files changed, 95 insertions, 12 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index e8ff0bae179d..40da46b907fb 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -229,6 +229,12 @@ static int ocfs2_mknod(struct inode *dir, | |||
229 | struct inode *inode = NULL; | 229 | struct inode *inode = NULL; |
230 | struct ocfs2_alloc_context *inode_ac = NULL; | 230 | struct ocfs2_alloc_context *inode_ac = NULL; |
231 | struct ocfs2_alloc_context *data_ac = NULL; | 231 | struct ocfs2_alloc_context *data_ac = NULL; |
232 | struct ocfs2_alloc_context *xattr_ac = NULL; | ||
233 | int want_clusters = 0; | ||
234 | int xattr_credits = 0; | ||
235 | struct ocfs2_security_xattr_info si = { | ||
236 | .enable = 1, | ||
237 | }; | ||
232 | 238 | ||
233 | mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode, | 239 | mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode, |
234 | (unsigned long)dev, dentry->d_name.len, | 240 | (unsigned long)dev, dentry->d_name.len, |
@@ -285,17 +291,39 @@ static int ocfs2_mknod(struct inode *dir, | |||
285 | goto leave; | 291 | goto leave; |
286 | } | 292 | } |
287 | 293 | ||
288 | /* Reserve a cluster if creating an extent based directory. */ | 294 | /* get security xattr */ |
289 | if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) { | 295 | status = ocfs2_init_security_get(inode, dir, &si); |
290 | status = ocfs2_reserve_clusters(osb, 1, &data_ac); | 296 | if (status) { |
297 | if (status == -EOPNOTSUPP) | ||
298 | si.enable = 0; | ||
299 | else { | ||
300 | mlog_errno(status); | ||
301 | goto leave; | ||
302 | } | ||
303 | } | ||
304 | |||
305 | /* calculate meta data/clusters for setting security xattr */ | ||
306 | if (si.enable) { | ||
307 | status = ocfs2_calc_security_init(dir, &si, &want_clusters, | ||
308 | &xattr_credits, &xattr_ac); | ||
291 | if (status < 0) { | 309 | if (status < 0) { |
292 | if (status != -ENOSPC) | 310 | mlog_errno(status); |
293 | mlog_errno(status); | ||
294 | goto leave; | 311 | goto leave; |
295 | } | 312 | } |
296 | } | 313 | } |
297 | 314 | ||
298 | handle = ocfs2_start_trans(osb, OCFS2_MKNOD_CREDITS); | 315 | /* Reserve a cluster if creating an extent based directory. */ |
316 | if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) | ||
317 | want_clusters += 1; | ||
318 | |||
319 | status = ocfs2_reserve_clusters(osb, want_clusters, &data_ac); | ||
320 | if (status < 0) { | ||
321 | if (status != -ENOSPC) | ||
322 | mlog_errno(status); | ||
323 | goto leave; | ||
324 | } | ||
325 | |||
326 | handle = ocfs2_start_trans(osb, OCFS2_MKNOD_CREDITS + xattr_credits); | ||
299 | if (IS_ERR(handle)) { | 327 | if (IS_ERR(handle)) { |
300 | status = PTR_ERR(handle); | 328 | status = PTR_ERR(handle); |
301 | handle = NULL; | 329 | handle = NULL; |
@@ -335,6 +363,15 @@ static int ocfs2_mknod(struct inode *dir, | |||
335 | inc_nlink(dir); | 363 | inc_nlink(dir); |
336 | } | 364 | } |
337 | 365 | ||
366 | if (si.enable) { | ||
367 | status = ocfs2_init_security_set(handle, inode, new_fe_bh, &si, | ||
368 | xattr_ac, data_ac); | ||
369 | if (status < 0) { | ||
370 | mlog_errno(status); | ||
371 | goto leave; | ||
372 | } | ||
373 | } | ||
374 | |||
338 | status = ocfs2_add_entry(handle, dentry, inode, | 375 | status = ocfs2_add_entry(handle, dentry, inode, |
339 | OCFS2_I(inode)->ip_blkno, parent_fe_bh, | 376 | OCFS2_I(inode)->ip_blkno, parent_fe_bh, |
340 | de_bh); | 377 | de_bh); |
@@ -366,6 +403,8 @@ leave: | |||
366 | brelse(new_fe_bh); | 403 | brelse(new_fe_bh); |
367 | brelse(de_bh); | 404 | brelse(de_bh); |
368 | brelse(parent_fe_bh); | 405 | brelse(parent_fe_bh); |
406 | kfree(si.name); | ||
407 | kfree(si.value); | ||
369 | 408 | ||
370 | if ((status < 0) && inode) { | 409 | if ((status < 0) && inode) { |
371 | clear_nlink(inode); | 410 | clear_nlink(inode); |
@@ -378,6 +417,9 @@ leave: | |||
378 | if (data_ac) | 417 | if (data_ac) |
379 | ocfs2_free_alloc_context(data_ac); | 418 | ocfs2_free_alloc_context(data_ac); |
380 | 419 | ||
420 | if (xattr_ac) | ||
421 | ocfs2_free_alloc_context(xattr_ac); | ||
422 | |||
381 | mlog_exit(status); | 423 | mlog_exit(status); |
382 | 424 | ||
383 | return status; | 425 | return status; |
@@ -1508,6 +1550,12 @@ static int ocfs2_symlink(struct inode *dir, | |||
1508 | handle_t *handle = NULL; | 1550 | handle_t *handle = NULL; |
1509 | struct ocfs2_alloc_context *inode_ac = NULL; | 1551 | struct ocfs2_alloc_context *inode_ac = NULL; |
1510 | struct ocfs2_alloc_context *data_ac = NULL; | 1552 | struct ocfs2_alloc_context *data_ac = NULL; |
1553 | struct ocfs2_alloc_context *xattr_ac = NULL; | ||
1554 | int want_clusters = 0; | ||
1555 | int xattr_credits = 0; | ||
1556 | struct ocfs2_security_xattr_info si = { | ||
1557 | .enable = 1, | ||
1558 | }; | ||
1511 | 1559 | ||
1512 | mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir, | 1560 | mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir, |
1513 | dentry, symname, dentry->d_name.len, dentry->d_name.name); | 1561 | dentry, symname, dentry->d_name.len, dentry->d_name.name); |
@@ -1561,17 +1609,39 @@ static int ocfs2_symlink(struct inode *dir, | |||
1561 | goto bail; | 1609 | goto bail; |
1562 | } | 1610 | } |
1563 | 1611 | ||
1564 | /* don't reserve bitmap space for fast symlinks. */ | 1612 | /* get security xattr */ |
1565 | if (l > ocfs2_fast_symlink_chars(sb)) { | 1613 | status = ocfs2_init_security_get(inode, dir, &si); |
1566 | status = ocfs2_reserve_clusters(osb, 1, &data_ac); | 1614 | if (status) { |
1615 | if (status == -EOPNOTSUPP) | ||
1616 | si.enable = 0; | ||
1617 | else { | ||
1618 | mlog_errno(status); | ||
1619 | goto bail; | ||
1620 | } | ||
1621 | } | ||
1622 | |||
1623 | /* calculate meta data/clusters for setting security xattr */ | ||
1624 | if (si.enable) { | ||
1625 | status = ocfs2_calc_security_init(dir, &si, &want_clusters, | ||
1626 | &xattr_credits, &xattr_ac); | ||
1567 | if (status < 0) { | 1627 | if (status < 0) { |
1568 | if (status != -ENOSPC) | 1628 | mlog_errno(status); |
1569 | mlog_errno(status); | ||
1570 | goto bail; | 1629 | goto bail; |
1571 | } | 1630 | } |
1572 | } | 1631 | } |
1573 | 1632 | ||
1574 | handle = ocfs2_start_trans(osb, credits); | 1633 | /* don't reserve bitmap space for fast symlinks. */ |
1634 | if (l > ocfs2_fast_symlink_chars(sb)) | ||
1635 | want_clusters += 1; | ||
1636 | |||
1637 | status = ocfs2_reserve_clusters(osb, want_clusters, &data_ac); | ||
1638 | if (status < 0) { | ||
1639 | if (status != -ENOSPC) | ||
1640 | mlog_errno(status); | ||
1641 | goto bail; | ||
1642 | } | ||
1643 | |||
1644 | handle = ocfs2_start_trans(osb, credits + xattr_credits); | ||
1575 | if (IS_ERR(handle)) { | 1645 | if (IS_ERR(handle)) { |
1576 | status = PTR_ERR(handle); | 1646 | status = PTR_ERR(handle); |
1577 | handle = NULL; | 1647 | handle = NULL; |
@@ -1632,6 +1702,15 @@ static int ocfs2_symlink(struct inode *dir, | |||
1632 | } | 1702 | } |
1633 | } | 1703 | } |
1634 | 1704 | ||
1705 | if (si.enable) { | ||
1706 | status = ocfs2_init_security_set(handle, inode, new_fe_bh, &si, | ||
1707 | xattr_ac, data_ac); | ||
1708 | if (status < 0) { | ||
1709 | mlog_errno(status); | ||
1710 | goto bail; | ||
1711 | } | ||
1712 | } | ||
1713 | |||
1635 | status = ocfs2_add_entry(handle, dentry, inode, | 1714 | status = ocfs2_add_entry(handle, dentry, inode, |
1636 | le64_to_cpu(fe->i_blkno), parent_fe_bh, | 1715 | le64_to_cpu(fe->i_blkno), parent_fe_bh, |
1637 | de_bh); | 1716 | de_bh); |
@@ -1658,10 +1737,14 @@ bail: | |||
1658 | brelse(new_fe_bh); | 1737 | brelse(new_fe_bh); |
1659 | brelse(parent_fe_bh); | 1738 | brelse(parent_fe_bh); |
1660 | brelse(de_bh); | 1739 | brelse(de_bh); |
1740 | kfree(si.name); | ||
1741 | kfree(si.value); | ||
1661 | if (inode_ac) | 1742 | if (inode_ac) |
1662 | ocfs2_free_alloc_context(inode_ac); | 1743 | ocfs2_free_alloc_context(inode_ac); |
1663 | if (data_ac) | 1744 | if (data_ac) |
1664 | ocfs2_free_alloc_context(data_ac); | 1745 | ocfs2_free_alloc_context(data_ac); |
1746 | if (xattr_ac) | ||
1747 | ocfs2_free_alloc_context(xattr_ac); | ||
1665 | if ((status < 0) && inode) { | 1748 | if ((status < 0) && inode) { |
1666 | clear_nlink(inode); | 1749 | clear_nlink(inode); |
1667 | iput(inode); | 1750 | iput(inode); |