Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / llite / dir.c
index 4c463d1..b84b877 100644 (file)
 #include <linux/version.h>
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-# include <linux/locks.h>   // for wait_on_buffer
-#else
-# include <linux/buffer_head.h>   // for wait_on_buffer
-#endif
+#include <linux/buffer_head.h>   // for wait_on_buffer
 
 #define DEBUG_SUBSYSTEM S_LLITE
 
@@ -528,12 +524,52 @@ do {                                    \
         Q_COPY(out, in, qc_dqblk);      \
 } while (0)
 
-int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump)
+int ll_send_mgc_param(struct obd_export *mgc, char *string)
+{
+        struct mgs_send_param *msp;
+        int rc = 0;
+
+        OBD_ALLOC_PTR(msp);
+        if (!msp)
+                return -ENOMEM;
+
+        strncpy(msp->mgs_param, string, MGS_PARAM_MAXLEN);
+        rc = obd_set_info_async(mgc, strlen(KEY_SET_INFO), KEY_SET_INFO,
+                                sizeof(struct mgs_send_param), msp, NULL);
+        if (rc)
+                CERROR("Failed to set parameter: %d\n", rc);
+        OBD_FREE_PTR(msp);
+
+        return rc;
+}
+
+char *ll_get_fsname(struct inode *inode)
+{
+        struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
+        char *ptr, *fsname;
+        int len;
+
+        OBD_ALLOC(fsname, MGS_PARAM_MAXLEN);
+        len = strlen(lsi->lsi_lmd->lmd_profile);
+        ptr = strrchr(lsi->lsi_lmd->lmd_profile, '-');
+        if (ptr && (strcmp(ptr, "-client") == 0))
+                len -= 7;
+        strncpy(fsname, lsi->lsi_lmd->lmd_profile, len);
+        fsname[len] = '\0';
+
+        return fsname;
+}
+
+int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
+                     int set_default)
 {
         struct ll_sb_info *sbi = ll_i2sbi(inode);
         struct md_op_data *op_data;
         struct ptlrpc_request *req = NULL;
         int rc = 0;
+        struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
+        struct obd_device *mgc = lsi->lsi_mgc;
+        char *fsname = NULL, *param = NULL;
 
         /*
          * This is coming from userspace, so should be in
@@ -553,15 +589,46 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump)
 
         /* swabbing is done in lov_setstripe() on server side */
         rc = md_setattr(sbi->ll_md_exp, op_data, lump, sizeof(*lump),
-                        NULL, 0, &req);
+                        NULL, 0, &req, NULL);
         ll_finish_md_op_data(op_data);
         ptlrpc_req_finished(req);
         if (rc) {
                 if (rc != -EPERM && rc != -EACCES)
                         CERROR("mdc_setattr fails: rc = %d\n", rc);
         }
-        return rc;
 
+        if (set_default && mgc->u.cli.cl_mgc_mgsexp) {
+                OBD_ALLOC(param, MGS_PARAM_MAXLEN);
+
+                /* Get fsname and assume devname to be -MDT0000. */
+                fsname = ll_get_fsname(inode);
+                /* Set root stripesize */
+                sprintf(param, "%s-MDT0000.lov.stripesize=%u", fsname,
+                        lump->lmm_stripe_size);
+                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,
+                        lump->lmm_stripe_count);
+                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,
+                        lump->lmm_stripe_offset);
+                rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param);
+                if (rc)
+                        goto end;
+end:
+                if (fsname)
+                        OBD_FREE(fsname, MGS_PARAM_MAXLEN);
+                if (param)
+                        OBD_FREE(param, MGS_PARAM_MAXLEN);
+        }
+        return rc;
 }
 
 int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp, 
@@ -690,6 +757,7 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
         case LL_IOC_LOV_SETSTRIPE: {
                 struct lov_user_md lum, *lump = (struct lov_user_md *)arg;
                 int rc = 0;
+                int set_default = 0;
 
                 LASSERT(sizeof(lum) == sizeof(*lump));
                 LASSERT(sizeof(lum.lmm_objects[0]) ==
@@ -698,7 +766,10 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
                 if (rc)
                         RETURN(-EFAULT);
 
-                rc = ll_dir_setstripe(inode, &lum);
+                if (inode->i_sb->s_root == file->f_dentry)
+                        set_default = 1;
+
+                rc = ll_dir_setstripe(inode, &lum, set_default);
 
                 RETURN(rc);
         }