From: yangsheng Date: Tue, 30 Mar 2010 19:00:24 +0000 (-0700) Subject: b=22187 Handle the NULL pointer as legal value. X-Git-Tag: 1.10.0.39~16 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=219e03a261e510e1551ab0695633cc4d2f5196fb b=22187 Handle the NULL pointer as legal value. i=adilger i=johann --- diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 4871640..266ae99 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -559,31 +559,36 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, char *fsname = NULL, *param = NULL; int lum_size; - /* - * This is coming from userspace, so should be in - * local endian. But the MDS would like it in little - * endian, so we swab it before we send it. - */ - switch (lump->lmm_magic) { - case LOV_USER_MAGIC_V1: { - if (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V1)) - lustre_swab_lov_user_md_v1(lump); + if (lump != NULL) { + /* + * This is coming from userspace, so should be in + * local endian. But the MDS would like it in little + * endian, so we swab it before we send it. + */ + switch (lump->lmm_magic) { + case LOV_USER_MAGIC_V1: { + if (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V1)) + lustre_swab_lov_user_md_v1(lump); + lum_size = sizeof(struct lov_user_md_v1); + break; + } + case LOV_USER_MAGIC_V3: { + if (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V3)) + lustre_swab_lov_user_md_v3( + (struct lov_user_md_v3 *)lump); + lum_size = sizeof(struct lov_user_md_v3); + break; + } + default: { + CDEBUG(D_IOCTL, "bad userland LOV MAGIC:" + " %#08x != %#08x nor %#08x\n", + lump->lmm_magic, LOV_USER_MAGIC_V1, + LOV_USER_MAGIC_V3); + RETURN(-EINVAL); + } + } + } else { lum_size = sizeof(struct lov_user_md_v1); - break; - } - case LOV_USER_MAGIC_V3: { - if (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V3)) - lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lump); - lum_size = sizeof(struct lov_user_md_v3); - break; - } - default: { - CDEBUG(D_IOCTL, "bad userland LOV MAGIC:" - " %#08x != %#08x nor %#08x\n", - lump->lmm_magic, LOV_USER_MAGIC_V1, - LOV_USER_MAGIC_V3); - RETURN(-EINVAL); - } } op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0, @@ -611,21 +616,22 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, fsname = ll_get_fsname(inode); /* Set root stripesize */ sprintf(param, "%s-MDT0000.lov.stripesize=%u", fsname, - lump->lmm_stripe_size); + lump ? le32_to_cpu(lump->lmm_stripe_size) : 0); rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param); if (rc) goto end; /* Set root stripecount */ sprintf(param, "%s-MDT0000.lov.stripecount=%hd", fsname, - lump->lmm_stripe_count); + lump ? le16_to_cpu(lump->lmm_stripe_count) : 0); rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param); if (rc) goto end; /* Set root stripeoffset */ sprintf(param, "%s-MDT0000.lov.stripeoffset=%hd", fsname, - lump->lmm_stripe_offset); + lump ? le16_to_cpu(lump->lmm_stripe_offset) : + (typeof(lump->lmm_stripe_offset))(-1)); rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param); if (rc) goto end; diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index 29d3a67..eecff63 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -222,10 +222,10 @@ int ll_setxattr(struct dentry *dentry, const char *name, /* Attributes that are saved via getxattr will always have * the stripe_offset as 0. Instead, the MDS should be * allowed to pick the starting OST index. b=17846 */ - if (lump->lmm_stripe_offset == 0) + if (lump != NULL && lump->lmm_stripe_offset == 0) lump->lmm_stripe_offset = -1; - if (S_ISREG(inode->i_mode)) { + if (lump != NULL && S_ISREG(inode->i_mode)) { struct file f; int flags = FMODE_WRITE; diff --git a/lustre/mdc/mdc_lib.c b/lustre/mdc/mdc_lib.c index db43656..96f05d1 100644 --- a/lustre/mdc/mdc_lib.c +++ b/lustre/mdc/mdc_lib.c @@ -320,6 +320,7 @@ void mdc_setattr_pack(struct ptlrpc_request *req, struct md_op_data *op_data, { struct mdt_rec_setattr *rec; struct mdt_ioepoch *epoch; + struct lov_user_md *lum = NULL; CLASSERT(sizeof(struct mdt_rec_reint) ==sizeof(struct mdt_rec_setattr)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); @@ -335,7 +336,15 @@ void mdc_setattr_pack(struct ptlrpc_request *req, struct md_op_data *op_data, if (ealen == 0) return; - memcpy(req_capsule_client_get(&req->rq_pill, &RMF_EADATA), ea, ealen); + lum = req_capsule_client_get(&req->rq_pill, &RMF_EADATA); + if (ea == NULL) { /* Remove LOV EA */ + lum->lmm_magic = LOV_USER_MAGIC_V1; + lum->lmm_stripe_size = 0; + lum->lmm_stripe_count = 0; + lum->lmm_stripe_offset = (typeof(lum->lmm_stripe_offset))(-1); + } else { + memcpy(lum, ea, ealen); + } if (ea2len == 0) return; diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index aebf88d..0752702 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -4379,6 +4379,28 @@ test_102j() { } run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ===" +test_102k() { + touch $DIR/$tfile + # b22187 just check that does not crash for regular file. + setfattr -n trusted.lov $DIR/$tfile + # b22187 'setfattr -n trusted.lov' should work as remove LOV EA for directories + local test_kdir=$DIR/d102k + mkdir $test_kdir + local default_size=`$GETSTRIPE -s $test_kdir` + local default_count=`$GETSTRIPE -c $test_kdir` + local default_offset=`$GETSTRIPE -o $test_kdir` + $SETSTRIPE -s 65536 -i 1 -c 2 $test_kdir || error 'dir setstripe failed' + setfattr -n trusted.lov $test_kdir + local stripe_size=`$GETSTRIPE -s $test_kdir` + local stripe_count=`$GETSTRIPE -c $test_kdir` + local stripe_offset=`$GETSTRIPE -o $test_kdir` + [ $stripe_size -eq $default_size ] || error "stripe size $stripe_size != $default_size" + [ $stripe_count -eq $default_count ] || error "stripe count $stripe_count != $default_count" + [ $stripe_offset -eq $default_offset ] || error "stripe offset $stripe_offset != $default_offset" + rm -rf $DIR/$tfile $test_kdir +} +run_test 102k "setfattr without parameter of value shouldn't cause a crash" + cleanup_test102 run_acl_subtest()