Whamcloud - gitweb
b=22187 properly handle null value for setattr -n lustre.lov
authoryangsheng <Sheng.Yang@Sun.COM>
Tue, 16 Mar 2010 13:58:48 +0000 (21:58 +0800)
committerJohann Lombardi <johann@sun.com>
Tue, 16 Mar 2010 14:13:14 +0000 (15:13 +0100)
i=adilger
i=johann

Running "setfattr -n trusted.lov ." causes a NULL dereference
in ll_setxattr() due to no checking if "value" is NULL.
This command now resets to the default striping when
executed against a directory.

lustre/llite/dir.c
lustre/llite/xattr.c
lustre/mdc/mdc_lib.c

index ce66441..613848b 100644 (file)
@@ -982,23 +982,27 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
         struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
         struct obd_device *mgc = lsi->lsi_mgc;
         char *fsname = NULL, *param = NULL;
-        int lum_size = sizeof(struct lov_user_md_v1);
-
         struct iattr attr = { 0 };
-        int rc = 0;
+        int lum_size = 0, rc = 0;
 
-        if (lump->lmm_magic == LOV_USER_MAGIC_V3)
-                lum_size = sizeof(struct lov_user_md_v3);
-        /*
-         * 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.
-         */
-        if ((lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V1)) &&
-            (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V3))) {
-                rc = lustre_swab_lov_user_md(lump);
-                if (rc) 
-                        return rc;
+        if (lump != NULL) {
+                if (lump->lmm_magic == LOV_USER_MAGIC_V3)
+                        lum_size = sizeof(struct lov_user_md_v3);
+                else
+                        lum_size = sizeof(struct lov_user_md_v1);
+                /*
+                 * 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.
+                 */
+                if ((lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V1)) &&
+                    (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V3))) {
+                        rc = lustre_swab_lov_user_md(lump);
+                        if (rc) 
+                                return rc;
+                }
+        } else { /* NULL value means remove LOV EA */
+                lum_size = sizeof(struct lov_user_md_v1);
         }
 
         ll_prepare_mdc_op_data(&data, inode, NULL, NULL, 0, 0, NULL);
@@ -1024,21 +1028,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,
-                        le32_to_cpu(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=%u", fsname,
-                        le16_to_cpu(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=%u", fsname,
-                        le16_to_cpu(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;
index 8fbc7bf..586e120 100644 (file)
@@ -183,18 +183,16 @@ 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;
 
                         f.f_dentry = dentry;
-                        rc = ll_lov_setstripe_ea_info(inode, &f, flags,
-                                                      lump, sizeof(*lump));
+                        ll_lov_setstripe_ea_info(inode, &f, flags, lump, size);
                         /* b10667: rc always be 0 here for now */
-                        rc = 0;
                 } else if (S_ISDIR(inode->i_mode)) {
                         rc = ll_dir_setstripe(inode, lump, 0);
                 }
index 443227c..68d1206 100644 (file)
@@ -439,6 +439,7 @@ void mdc_setattr_pack_18(struct ptlrpc_request *req, int offset,
                          struct mdc_op_data *data, struct iattr *iattr, void *ea,
                          int ealen, void *ea2, int ea2len)
 {
+        struct lov_user_md     *lum = NULL;
         struct mds_rec_setattr *rec = lustre_msg_buf(req->rq_reqmsg, offset,
                                                      sizeof(*rec));
         ENTRY;
@@ -472,7 +473,15 @@ void mdc_setattr_pack_18(struct ptlrpc_request *req, int offset,
                 return;
         }
 
-        memcpy(lustre_msg_buf(req->rq_reqmsg, offset + 1, ealen), ea, ealen);
+        lum = lustre_msg_buf(req->rq_reqmsg, offset + 1, ealen);
+        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) {
                 EXIT;
@@ -519,7 +528,9 @@ static void mdc_setattr_pack_20(struct ptlrpc_request *req, int offset,
                 EXIT;
                 return;
         }
-        memcpy(lustre_msg_buf(req->rq_reqmsg, offset + 3, ealen), ea, ealen);
+        if (ea)
+                memcpy(lustre_msg_buf(req->rq_reqmsg, offset + 3, ealen),
+                       ea, ealen);
 
         if (ea2len == 0) {
                 EXIT;