diff options
Diffstat (limited to 'fs/ocfs2/dlmglue.c')
| -rw-r--r-- | fs/ocfs2/dlmglue.c | 168 |
1 files changed, 154 insertions, 14 deletions
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 6e6cc0a2e5f7..f731ab491795 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/debugfs.h> | 32 | #include <linux/debugfs.h> |
| 33 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
| 34 | #include <linux/time.h> | 34 | #include <linux/time.h> |
| 35 | #include <linux/quotaops.h> | ||
| 35 | 36 | ||
| 36 | #define MLOG_MASK_PREFIX ML_DLM_GLUE | 37 | #define MLOG_MASK_PREFIX ML_DLM_GLUE |
| 37 | #include <cluster/masklog.h> | 38 | #include <cluster/masklog.h> |
| @@ -51,6 +52,7 @@ | |||
| 51 | #include "slot_map.h" | 52 | #include "slot_map.h" |
| 52 | #include "super.h" | 53 | #include "super.h" |
| 53 | #include "uptodate.h" | 54 | #include "uptodate.h" |
| 55 | #include "quota.h" | ||
| 54 | 56 | ||
| 55 | #include "buffer_head_io.h" | 57 | #include "buffer_head_io.h" |
| 56 | 58 | ||
| @@ -68,6 +70,7 @@ struct ocfs2_mask_waiter { | |||
| 68 | static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres); | 70 | static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres); |
| 69 | static struct ocfs2_super *ocfs2_get_inode_osb(struct ocfs2_lock_res *lockres); | 71 | static struct ocfs2_super *ocfs2_get_inode_osb(struct ocfs2_lock_res *lockres); |
| 70 | static struct ocfs2_super *ocfs2_get_file_osb(struct ocfs2_lock_res *lockres); | 72 | static struct ocfs2_super *ocfs2_get_file_osb(struct ocfs2_lock_res *lockres); |
| 73 | static struct ocfs2_super *ocfs2_get_qinfo_osb(struct ocfs2_lock_res *lockres); | ||
| 71 | 74 | ||
| 72 | /* | 75 | /* |
| 73 | * Return value from ->downconvert_worker functions. | 76 | * Return value from ->downconvert_worker functions. |
| @@ -102,6 +105,7 @@ static int ocfs2_dentry_convert_worker(struct ocfs2_lock_res *lockres, | |||
| 102 | static void ocfs2_dentry_post_unlock(struct ocfs2_super *osb, | 105 | static void ocfs2_dentry_post_unlock(struct ocfs2_super *osb, |
| 103 | struct ocfs2_lock_res *lockres); | 106 | struct ocfs2_lock_res *lockres); |
| 104 | 107 | ||
| 108 | static void ocfs2_set_qinfo_lvb(struct ocfs2_lock_res *lockres); | ||
| 105 | 109 | ||
| 106 | #define mlog_meta_lvb(__level, __lockres) ocfs2_dump_meta_lvb_info(__level, __PRETTY_FUNCTION__, __LINE__, __lockres) | 110 | #define mlog_meta_lvb(__level, __lockres) ocfs2_dump_meta_lvb_info(__level, __PRETTY_FUNCTION__, __LINE__, __lockres) |
| 107 | 111 | ||
| @@ -111,8 +115,7 @@ static void ocfs2_dump_meta_lvb_info(u64 level, | |||
| 111 | unsigned int line, | 115 | unsigned int line, |
| 112 | struct ocfs2_lock_res *lockres) | 116 | struct ocfs2_lock_res *lockres) |
| 113 | { | 117 | { |
| 114 | struct ocfs2_meta_lvb *lvb = | 118 | struct ocfs2_meta_lvb *lvb = ocfs2_dlm_lvb(&lockres->l_lksb); |
| 115 | (struct ocfs2_meta_lvb *)ocfs2_dlm_lvb(&lockres->l_lksb); | ||
| 116 | 119 | ||
| 117 | mlog(level, "LVB information for %s (called from %s:%u):\n", | 120 | mlog(level, "LVB information for %s (called from %s:%u):\n", |
| 118 | lockres->l_name, function, line); | 121 | lockres->l_name, function, line); |
| @@ -258,6 +261,12 @@ static struct ocfs2_lock_res_ops ocfs2_flock_lops = { | |||
| 258 | .flags = 0, | 261 | .flags = 0, |
| 259 | }; | 262 | }; |
| 260 | 263 | ||
| 264 | static struct ocfs2_lock_res_ops ocfs2_qinfo_lops = { | ||
| 265 | .set_lvb = ocfs2_set_qinfo_lvb, | ||
| 266 | .get_osb = ocfs2_get_qinfo_osb, | ||
| 267 | .flags = LOCK_TYPE_REQUIRES_REFRESH | LOCK_TYPE_USES_LVB, | ||
| 268 | }; | ||
| 269 | |||
| 261 | static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres) | 270 | static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres) |
| 262 | { | 271 | { |
| 263 | return lockres->l_type == OCFS2_LOCK_TYPE_META || | 272 | return lockres->l_type == OCFS2_LOCK_TYPE_META || |
| @@ -279,6 +288,13 @@ static inline struct ocfs2_dentry_lock *ocfs2_lock_res_dl(struct ocfs2_lock_res | |||
| 279 | return (struct ocfs2_dentry_lock *)lockres->l_priv; | 288 | return (struct ocfs2_dentry_lock *)lockres->l_priv; |
| 280 | } | 289 | } |
| 281 | 290 | ||
| 291 | static inline struct ocfs2_mem_dqinfo *ocfs2_lock_res_qinfo(struct ocfs2_lock_res *lockres) | ||
| 292 | { | ||
| 293 | BUG_ON(lockres->l_type != OCFS2_LOCK_TYPE_QINFO); | ||
| 294 | |||
| 295 | return (struct ocfs2_mem_dqinfo *)lockres->l_priv; | ||
| 296 | } | ||
| 297 | |||
| 282 | static inline struct ocfs2_super *ocfs2_get_lockres_osb(struct ocfs2_lock_res *lockres) | 298 | static inline struct ocfs2_super *ocfs2_get_lockres_osb(struct ocfs2_lock_res *lockres) |
| 283 | { | 299 | { |
| 284 | if (lockres->l_ops->get_osb) | 300 | if (lockres->l_ops->get_osb) |
| @@ -507,6 +523,13 @@ static struct ocfs2_super *ocfs2_get_inode_osb(struct ocfs2_lock_res *lockres) | |||
| 507 | return OCFS2_SB(inode->i_sb); | 523 | return OCFS2_SB(inode->i_sb); |
| 508 | } | 524 | } |
| 509 | 525 | ||
| 526 | static struct ocfs2_super *ocfs2_get_qinfo_osb(struct ocfs2_lock_res *lockres) | ||
| 527 | { | ||
| 528 | struct ocfs2_mem_dqinfo *info = lockres->l_priv; | ||
| 529 | |||
| 530 | return OCFS2_SB(info->dqi_gi.dqi_sb); | ||
| 531 | } | ||
| 532 | |||
| 510 | static struct ocfs2_super *ocfs2_get_file_osb(struct ocfs2_lock_res *lockres) | 533 | static struct ocfs2_super *ocfs2_get_file_osb(struct ocfs2_lock_res *lockres) |
| 511 | { | 534 | { |
| 512 | struct ocfs2_file_private *fp = lockres->l_priv; | 535 | struct ocfs2_file_private *fp = lockres->l_priv; |
| @@ -609,6 +632,17 @@ void ocfs2_file_lock_res_init(struct ocfs2_lock_res *lockres, | |||
| 609 | lockres->l_flags |= OCFS2_LOCK_NOCACHE; | 632 | lockres->l_flags |= OCFS2_LOCK_NOCACHE; |
| 610 | } | 633 | } |
| 611 | 634 | ||
| 635 | void ocfs2_qinfo_lock_res_init(struct ocfs2_lock_res *lockres, | ||
| 636 | struct ocfs2_mem_dqinfo *info) | ||
| 637 | { | ||
| 638 | ocfs2_lock_res_init_once(lockres); | ||
| 639 | ocfs2_build_lock_name(OCFS2_LOCK_TYPE_QINFO, info->dqi_gi.dqi_type, | ||
| 640 | 0, lockres->l_name); | ||
| 641 | ocfs2_lock_res_init_common(OCFS2_SB(info->dqi_gi.dqi_sb), lockres, | ||
| 642 | OCFS2_LOCK_TYPE_QINFO, &ocfs2_qinfo_lops, | ||
| 643 | info); | ||
| 644 | } | ||
| 645 | |||
| 612 | void ocfs2_lock_res_free(struct ocfs2_lock_res *res) | 646 | void ocfs2_lock_res_free(struct ocfs2_lock_res *res) |
| 613 | { | 647 | { |
| 614 | mlog_entry_void(); | 648 | mlog_entry_void(); |
| @@ -1829,7 +1863,7 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode) | |||
| 1829 | 1863 | ||
| 1830 | mlog_entry_void(); | 1864 | mlog_entry_void(); |
| 1831 | 1865 | ||
| 1832 | lvb = (struct ocfs2_meta_lvb *)ocfs2_dlm_lvb(&lockres->l_lksb); | 1866 | lvb = ocfs2_dlm_lvb(&lockres->l_lksb); |
| 1833 | 1867 | ||
| 1834 | /* | 1868 | /* |
| 1835 | * Invalidate the LVB of a deleted inode - this way other | 1869 | * Invalidate the LVB of a deleted inode - this way other |
| @@ -1881,7 +1915,7 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode) | |||
| 1881 | 1915 | ||
| 1882 | mlog_meta_lvb(0, lockres); | 1916 | mlog_meta_lvb(0, lockres); |
| 1883 | 1917 | ||
| 1884 | lvb = (struct ocfs2_meta_lvb *)ocfs2_dlm_lvb(&lockres->l_lksb); | 1918 | lvb = ocfs2_dlm_lvb(&lockres->l_lksb); |
| 1885 | 1919 | ||
| 1886 | /* We're safe here without the lockres lock... */ | 1920 | /* We're safe here without the lockres lock... */ |
| 1887 | spin_lock(&oi->ip_lock); | 1921 | spin_lock(&oi->ip_lock); |
| @@ -1916,8 +1950,7 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode) | |||
| 1916 | static inline int ocfs2_meta_lvb_is_trustable(struct inode *inode, | 1950 | static inline int ocfs2_meta_lvb_is_trustable(struct inode *inode, |
| 1917 | struct ocfs2_lock_res *lockres) | 1951 | struct ocfs2_lock_res *lockres) |
| 1918 | { | 1952 | { |
| 1919 | struct ocfs2_meta_lvb *lvb = | 1953 | struct ocfs2_meta_lvb *lvb = ocfs2_dlm_lvb(&lockres->l_lksb); |
| 1920 | (struct ocfs2_meta_lvb *)ocfs2_dlm_lvb(&lockres->l_lksb); | ||
| 1921 | 1954 | ||
| 1922 | if (lvb->lvb_version == OCFS2_LVB_VERSION | 1955 | if (lvb->lvb_version == OCFS2_LVB_VERSION |
| 1923 | && be32_to_cpu(lvb->lvb_igeneration) == inode->i_generation) | 1956 | && be32_to_cpu(lvb->lvb_igeneration) == inode->i_generation) |
| @@ -2024,7 +2057,7 @@ static int ocfs2_inode_lock_update(struct inode *inode, | |||
| 2024 | } else { | 2057 | } else { |
| 2025 | /* Boo, we have to go to disk. */ | 2058 | /* Boo, we have to go to disk. */ |
| 2026 | /* read bh, cast, ocfs2_refresh_inode */ | 2059 | /* read bh, cast, ocfs2_refresh_inode */ |
| 2027 | status = ocfs2_read_block(inode, oi->ip_blkno, bh); | 2060 | status = ocfs2_read_inode_block(inode, bh); |
| 2028 | if (status < 0) { | 2061 | if (status < 0) { |
| 2029 | mlog_errno(status); | 2062 | mlog_errno(status); |
| 2030 | goto bail_refresh; | 2063 | goto bail_refresh; |
| @@ -2032,18 +2065,14 @@ static int ocfs2_inode_lock_update(struct inode *inode, | |||
| 2032 | fe = (struct ocfs2_dinode *) (*bh)->b_data; | 2065 | fe = (struct ocfs2_dinode *) (*bh)->b_data; |
| 2033 | 2066 | ||
| 2034 | /* This is a good chance to make sure we're not | 2067 | /* This is a good chance to make sure we're not |
| 2035 | * locking an invalid object. | 2068 | * locking an invalid object. ocfs2_read_inode_block() |
| 2069 | * already checked that the inode block is sane. | ||
| 2036 | * | 2070 | * |
| 2037 | * We bug on a stale inode here because we checked | 2071 | * We bug on a stale inode here because we checked |
| 2038 | * above whether it was wiped from disk. The wiping | 2072 | * above whether it was wiped from disk. The wiping |
| 2039 | * node provides a guarantee that we receive that | 2073 | * node provides a guarantee that we receive that |
| 2040 | * message and can mark the inode before dropping any | 2074 | * message and can mark the inode before dropping any |
| 2041 | * locks associated with it. */ | 2075 | * locks associated with it. */ |
| 2042 | if (!OCFS2_IS_VALID_DINODE(fe)) { | ||
| 2043 | OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, fe); | ||
| 2044 | status = -EIO; | ||
| 2045 | goto bail_refresh; | ||
| 2046 | } | ||
| 2047 | mlog_bug_on_msg(inode->i_generation != | 2076 | mlog_bug_on_msg(inode->i_generation != |
| 2048 | le32_to_cpu(fe->i_generation), | 2077 | le32_to_cpu(fe->i_generation), |
| 2049 | "Invalid dinode %llu disk generation: %u " | 2078 | "Invalid dinode %llu disk generation: %u " |
| @@ -2085,7 +2114,7 @@ static int ocfs2_assign_bh(struct inode *inode, | |||
| 2085 | return 0; | 2114 | return 0; |
| 2086 | } | 2115 | } |
| 2087 | 2116 | ||
| 2088 | status = ocfs2_read_block(inode, OCFS2_I(inode)->ip_blkno, ret_bh); | 2117 | status = ocfs2_read_inode_block(inode, ret_bh); |
| 2089 | if (status < 0) | 2118 | if (status < 0) |
| 2090 | mlog_errno(status); | 2119 | mlog_errno(status); |
| 2091 | 2120 | ||
| @@ -3449,6 +3478,117 @@ static int ocfs2_dentry_convert_worker(struct ocfs2_lock_res *lockres, | |||
| 3449 | return UNBLOCK_CONTINUE_POST; | 3478 | return UNBLOCK_CONTINUE_POST; |
| 3450 | } | 3479 | } |
| 3451 | 3480 | ||
| 3481 | static void ocfs2_set_qinfo_lvb(struct ocfs2_lock_res *lockres) | ||
| 3482 | { | ||
| 3483 | struct ocfs2_qinfo_lvb *lvb; | ||
| 3484 | struct ocfs2_mem_dqinfo *oinfo = ocfs2_lock_res_qinfo(lockres); | ||
| 3485 | struct mem_dqinfo *info = sb_dqinfo(oinfo->dqi_gi.dqi_sb, | ||
| 3486 | oinfo->dqi_gi.dqi_type); | ||
| 3487 | |||
| 3488 | mlog_entry_void(); | ||
| 3489 | |||
| 3490 | lvb = ocfs2_dlm_lvb(&lockres->l_lksb); | ||
| 3491 | lvb->lvb_version = OCFS2_QINFO_LVB_VERSION; | ||
| 3492 | lvb->lvb_bgrace = cpu_to_be32(info->dqi_bgrace); | ||
| 3493 | lvb->lvb_igrace = cpu_to_be32(info->dqi_igrace); | ||
| 3494 | lvb->lvb_syncms = cpu_to_be32(oinfo->dqi_syncms); | ||
| 3495 | lvb->lvb_blocks = cpu_to_be32(oinfo->dqi_gi.dqi_blocks); | ||
| 3496 | lvb->lvb_free_blk = cpu_to_be32(oinfo->dqi_gi.dqi_free_blk); | ||
| 3497 | lvb->lvb_free_entry = cpu_to_be32(oinfo->dqi_gi.dqi_free_entry); | ||
| 3498 | |||
| 3499 | mlog_exit_void(); | ||
| 3500 | } | ||
| 3501 | |||
| 3502 | void ocfs2_qinfo_unlock(struct ocfs2_mem_dqinfo *oinfo, int ex) | ||
| 3503 | { | ||
| 3504 | struct ocfs2_lock_res *lockres = &oinfo->dqi_gqlock; | ||
| 3505 | struct ocfs2_super *osb = OCFS2_SB(oinfo->dqi_gi.dqi_sb); | ||
| 3506 | int level = ex ? DLM_LOCK_EX : DLM_LOCK_PR; | ||
| 3507 | |||
| 3508 | mlog_entry_void(); | ||
| 3509 | if (!ocfs2_is_hard_readonly(osb) && !ocfs2_mount_local(osb)) | ||
| 3510 | ocfs2_cluster_unlock(osb, lockres, level); | ||
| 3511 | mlog_exit_void(); | ||
| 3512 | } | ||
| 3513 | |||
| 3514 | static int ocfs2_refresh_qinfo(struct ocfs2_mem_dqinfo *oinfo) | ||
| 3515 | { | ||
| 3516 | struct mem_dqinfo *info = sb_dqinfo(oinfo->dqi_gi.dqi_sb, | ||
| 3517 | oinfo->dqi_gi.dqi_type); | ||
| 3518 | struct ocfs2_lock_res *lockres = &oinfo->dqi_gqlock; | ||
| 3519 | struct ocfs2_qinfo_lvb *lvb = ocfs2_dlm_lvb(&lockres->l_lksb); | ||
| 3520 | struct buffer_head *bh = NULL; | ||
| 3521 | struct ocfs2_global_disk_dqinfo *gdinfo; | ||
| 3522 | int status = 0; | ||
| 3523 | |||
| 3524 | if (lvb->lvb_version == OCFS2_QINFO_LVB_VERSION) { | ||
| 3525 | info->dqi_bgrace = be32_to_cpu(lvb->lvb_bgrace); | ||
| 3526 | info->dqi_igrace = be32_to_cpu(lvb->lvb_igrace); | ||
| 3527 | oinfo->dqi_syncms = be32_to_cpu(lvb->lvb_syncms); | ||
| 3528 | oinfo->dqi_gi.dqi_blocks = be32_to_cpu(lvb->lvb_blocks); | ||
| 3529 | oinfo->dqi_gi.dqi_free_blk = be32_to_cpu(lvb->lvb_free_blk); | ||
| 3530 | oinfo->dqi_gi.dqi_free_entry = | ||
| 3531 | be32_to_cpu(lvb->lvb_free_entry); | ||
| 3532 | } else { | ||
| 3533 | status = ocfs2_read_quota_block(oinfo->dqi_gqinode, 0, &bh); | ||
| 3534 | if (status) { | ||
| 3535 | mlog_errno(status); | ||
| 3536 | goto bail; | ||
| 3537 | } | ||
| 3538 | gdinfo = (struct ocfs2_global_disk_dqinfo *) | ||
| 3539 | (bh->b_data + OCFS2_GLOBAL_INFO_OFF); | ||
| 3540 | info->dqi_bgrace = le32_to_cpu(gdinfo->dqi_bgrace); | ||
| 3541 | info->dqi_igrace = le32_to_cpu(gdinfo->dqi_igrace); | ||
| 3542 | oinfo->dqi_syncms = le32_to_cpu(gdinfo->dqi_syncms); | ||
| 3543 | oinfo->dqi_gi.dqi_blocks = le32_to_cpu(gdinfo->dqi_blocks); | ||
| 3544 | oinfo->dqi_gi.dqi_free_blk = le32_to_cpu(gdinfo->dqi_free_blk); | ||
| 3545 | oinfo->dqi_gi.dqi_free_entry = | ||
| 3546 | le32_to_cpu(gdinfo->dqi_free_entry); | ||
| 3547 | brelse(bh); | ||
| 3548 | ocfs2_track_lock_refresh(lockres); | ||
| 3549 | } | ||
| 3550 | |||
| 3551 | bail: | ||
| 3552 | return status; | ||
| 3553 | } | ||
| 3554 | |||
| 3555 | /* Lock quota info, this function expects at least shared lock on the quota file | ||
| 3556 | * so that we can safely refresh quota info from disk. */ | ||
| 3557 | int ocfs2_qinfo_lock(struct ocfs2_mem_dqinfo *oinfo, int ex) | ||
| 3558 | { | ||
| 3559 | struct ocfs2_lock_res *lockres = &oinfo->dqi_gqlock; | ||
| 3560 | struct ocfs2_super *osb = OCFS2_SB(oinfo->dqi_gi.dqi_sb); | ||
| 3561 | int level = ex ? DLM_LOCK_EX : DLM_LOCK_PR; | ||
| 3562 | int status = 0; | ||
| 3563 | |||
| 3564 | mlog_entry_void(); | ||
| 3565 | |||
| 3566 | /* On RO devices, locking really isn't needed... */ | ||
| 3567 | if (ocfs2_is_hard_readonly(osb)) { | ||
| 3568 | if (ex) | ||
| 3569 | status = -EROFS; | ||
| 3570 | goto bail; | ||
| 3571 | } | ||
| 3572 | if (ocfs2_mount_local(osb)) | ||
| 3573 | goto bail; | ||
| 3574 | |||
| 3575 | status = ocfs2_cluster_lock(osb, lockres, level, 0, 0); | ||
| 3576 | if (status < 0) { | ||
| 3577 | mlog_errno(status); | ||
| 3578 | goto bail; | ||
| 3579 | } | ||
| 3580 | if (!ocfs2_should_refresh_lock_res(lockres)) | ||
| 3581 | goto bail; | ||
| 3582 | /* OK, we have the lock but we need to refresh the quota info */ | ||
| 3583 | status = ocfs2_refresh_qinfo(oinfo); | ||
| 3584 | if (status) | ||
| 3585 | ocfs2_qinfo_unlock(oinfo, ex); | ||
| 3586 | ocfs2_complete_lock_res_refresh(lockres, status); | ||
| 3587 | bail: | ||
| 3588 | mlog_exit(status); | ||
| 3589 | return status; | ||
| 3590 | } | ||
| 3591 | |||
| 3452 | /* | 3592 | /* |
| 3453 | * This is the filesystem locking protocol. It provides the lock handling | 3593 | * This is the filesystem locking protocol. It provides the lock handling |
| 3454 | * hooks for the underlying DLM. It has a maximum version number. | 3594 | * hooks for the underlying DLM. It has a maximum version number. |
