From f6e7cc6d3a640e02192096584f4c6625b99e4678 Mon Sep 17 00:00:00 2001 From: Alexander Zarochentsev Date: Fri, 24 Oct 2014 07:42:27 +0400 Subject: [PATCH] LU-5770 osd: find bufsize in declare_xattr_set mdd_link/mdd_unlink need to know LINKEA buffer size before transaction start for correct estimation of tx credits. In case if xattr size not known, make a call to osd_xattr_set() to find correct buffer size. Xyratex-bug-id: MRP-2093 Signed-off-by: Alexander Zarochentsev Change-Id: I890e8182bd2d191a0322d25f0684f2a220873546 Reviewed-on: http://review.whamcloud.com/12412 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: wangdi Reviewed-by: Faccini Bruno Reviewed-by: Oleg Drokin --- lustre/osd-ldiskfs/osd_handler.c | 26 +++++++++++++++++++++++--- lustre/osd-ldiskfs/osd_internal.h | 4 ++++ lustre/osd-ldiskfs/osd_io.c | 8 +++----- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index aebd82f..a2e8f51 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -3086,9 +3086,29 @@ static int osd_declare_xattr_set(const struct lu_env *env, } else { upgrade: credits = osd_dto_credits_noquota[DTO_XATTR_SET]; - if (buf && buf->lb_len > sb->s_blocksize) { - credits *= (buf->lb_len + sb->s_blocksize - 1) >> - sb->s_blocksize_bits; + + if (buf != NULL) { + ssize_t buflen; + + if (buf->lb_buf == NULL && dt_object_exists(dt)) { + /* learn xattr size from osd_xattr_get if + attribute has not been read yet */ + buflen = __osd_xattr_get( + osd_dt_obj(dt)->oo_inode, + &osd_oti_get(env)->oti_obj_dentry, + name, NULL, 0); + if (buflen < 0) + buflen = 0; + } else { + buflen = buf->lb_len; + } + + if (buflen > sb->s_blocksize) { + credits += osd_calc_bkmap_credits( + sb, NULL, 0, -1, + (buflen + sb->s_blocksize - 1) >> + sb->s_blocksize_bits); + } } /* * xattr set may involve inode quota change, reserve credits for diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h index 7ef1032..b182ad9 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -936,6 +936,10 @@ static inline void osd_ipd_put(const struct lu_env *env, bag->ic_descr->id_ops->id_ipd_free(ipd); } +int osd_calc_bkmap_credits(struct super_block *sb, struct inode *inode, + const loff_t size, const loff_t pos, + const int blocks); + int osd_ldiskfs_read(struct inode *inode, void *buf, int size, loff_t *offs); int osd_ldiskfs_write_record(struct inode *inode, void *buf, int bufsize, int write_NUL, loff_t *offs, handle_t *handle); diff --git a/lustre/osd-ldiskfs/osd_io.c b/lustre/osd-ldiskfs/osd_io.c index 83c72ff..2373646 100644 --- a/lustre/osd-ldiskfs/osd_io.c +++ b/lustre/osd-ldiskfs/osd_io.c @@ -1488,11 +1488,9 @@ static inline int osd_extents_enabled(struct super_block *sb, return 0; } -static inline int osd_calc_bkmap_credits(struct super_block *sb, - struct inode *inode, - const loff_t size, - const loff_t pos, - const int blocks) +int osd_calc_bkmap_credits(struct super_block *sb, struct inode *inode, + const loff_t size, const loff_t pos, + const int blocks) { int credits, bits, bs, i; -- 1.8.3.1