Whamcloud - gitweb
1)add clonefs read in lustre
authorwangdi <wangdi>
Wed, 21 Jul 2004 18:28:32 +0000 (18:28 +0000)
committerwangdi <wangdi>
Wed, 21 Jul 2004 18:28:32 +0000 (18:28 +0000)
2)add clientfsoption in lmc and lconf
3)some fix in cobd for cache miss handler

19 files changed:
lustre/cobd/cache_obd.c
lustre/include/linux/lustre_cfg.h
lustre/include/linux/lustre_idl.h
lustre/include/linux/lustre_snap.h
lustre/include/linux/obd.h
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/mdc/mdc_locks.c
lustre/mds/handler.c
lustre/mds/mds_internal.h
lustre/mds/mds_reint.c
lustre/ptlrpc/pack_generic.c
lustre/ptlrpc/ptlrpc_module.c
lustre/smfs/dir.c
lustre/smfs/smfs_cow.c
lustre/smfs/smfs_internal.h
lustre/utils/lconf
lustre/utils/llmount.c
lustre/utils/lmc

index fdebff1..a326430 100644 (file)
@@ -66,7 +66,8 @@ static int cobd_setup(struct obd_device *obd, obd_count len, void *buf)
 {
         struct lustre_cfg *lcfg = (struct lustre_cfg *)buf;
         struct cache_obd  *cobd = &obd->u.cobd;
-        struct lustre_handle real_conn = {0,}, cache_conn = {0,};
+//        struct lustre_handle real_conn = {0,}, cache_conn = {0,};
+        struct lustre_handle  cache_conn = {0,};
         struct obd_device *real;
         struct obd_device *cache;
         int rc;
@@ -109,13 +110,14 @@ static int cobd_setup(struct obd_device *obd, obd_count len, void *buf)
         memcpy(cobd->cobd_cache_name, lcfg->lcfg_inlbuf2, 
                strlen(lcfg->lcfg_inlbuf2));
 
+#if 0        
         /* don't bother checking attached/setup;
          * obd_connect() should, and it can change underneath us */
         rc = connect_to_obd(cobd->cobd_real_name, &real_conn);
         if (rc != 0)
                 GOTO(exit, rc);
         cobd->cobd_real_exp = class_conn2export(&real_conn);
-        
+#endif        
         rc = connect_to_obd(cobd->cobd_cache_name, &cache_conn);
         if (rc != 0) {
                 obd_disconnect(cobd->cobd_cache_exp, 0);
@@ -123,6 +125,7 @@ static int cobd_setup(struct obd_device *obd, obd_count len, void *buf)
         }
         cobd->cobd_cache_exp = class_conn2export(&cache_conn);
         
+        cobd->cache_on = 1;
         if (!strcmp(real->obd_type->typ_name, LUSTRE_MDC_NAME)) {
                 /* set mds_num for lustre */
                 int mds_num;
@@ -143,7 +146,6 @@ exit:
                         OBD_FREE(cobd->cobd_real_name, 
                                  strlen(cobd->cobd_real_name) + 1);
         }
-        cobd->cache_on = 1;
         RETURN(rc);
 }
 
@@ -155,9 +157,12 @@ static int cobd_cleanup(struct obd_device *obd, int flags)
         if (!list_empty(&obd->obd_exports))
                 return (-EBUSY);
         
-        OBD_FREE(cobd->cobd_cache_name, strlen(cobd->cobd_cache_name) + 1);
-        OBD_FREE(cobd->cobd_real_name, strlen(cobd->cobd_real_name) + 1);
-        
+        if (cobd->cobd_cache_name)
+                OBD_FREE(cobd->cobd_cache_name, 
+                         strlen(cobd->cobd_cache_name) + 1);
+        if (cobd->cobd_real_name)
+                OBD_FREE(cobd->cobd_real_name, 
+                         strlen(cobd->cobd_real_name) + 1);
         if (cobd->cache_on) { 
                 rc = obd_disconnect(cobd->cobd_cache_exp, flags);
                 if (rc != 0)
@@ -680,8 +685,7 @@ static int cobd_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
 {
         struct obd_device *obd = class_exp2obd(exp);
         struct cache_obd  *cobd = &obd->u.cobd;
-        struct obd_device *real_dev = class_exp2obd(cobd->cobd_real_exp);
-        struct obd_device *cache_dev = class_exp2obd(cobd->cobd_cache_exp); 
+        struct obd_device *real_dev = NULL;
         struct obd_export *cobd_exp;
         int rc = 0;
  
@@ -690,29 +694,40 @@ static int cobd_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                 if (!cobd->cache_on) {
                         struct lustre_handle cache_conn = {0,};
                         
+                        rc = obd_disconnect(cobd->cobd_real_exp, 0);
+                        if (rc != 0)
+                                CERROR("error %d disconnecting real\n", rc);
                         rc = connect_to_obd(cobd->cobd_cache_name, &cache_conn);
                         if (rc != 0)
                                 RETURN(rc); 
                         cobd->cobd_cache_exp = class_conn2export(&cache_conn);
+                        
                         cobd->cache_on = 1;
                 }
                 break;
         case OBD_IOC_COBD_COFF: 
                 if (cobd->cache_on) {
-                        /*Here disconnect for cancel unused ldlm resources,
-                         *then do flush, otherwise, there will be some problems
-                         *in flush cache
-                         *is is right? FIXME later*/
+                        struct lustre_handle real_conn = {0,};
+                        struct obd_device *cache_dev = NULL;
+                        int m_easize, m_cooksize;
+
+                        cache_dev = class_exp2obd(cobd->cobd_cache_exp); 
+                        m_easize = cache_dev->u.cli.cl_max_mds_easize; 
+                        m_cooksize = cache_dev->u.cli.cl_max_mds_cookiesize; 
                         rc = obd_disconnect(cobd->cobd_cache_exp, 0);
                         if (rc != 0)
                                 CERROR("error %d disconnecting real\n", rc);
 
-                        cobd->cache_on = 0;
                         /*FIXME, should read from real_dev*/
-                       real_dev->u.cli.cl_max_mds_easize =
-                                              cache_dev->u.cli.cl_max_mds_easize;
-                       real_dev->u.cli.cl_max_mds_cookiesize =
-                                              cache_dev->u.cli.cl_max_mds_cookiesize;
+                        
+                        rc = connect_to_obd(cobd->cobd_real_name, &real_conn);
+                        if (rc != 0)
+                                RETURN(rc); 
+                        cobd->cobd_real_exp = class_conn2export(&real_conn);
+                        real_dev = class_exp2obd(cobd->cobd_real_exp);
+                        real_dev->u.cli.cl_max_mds_easize = m_easize;
+                        real_dev->u.cli.cl_max_mds_cookiesize = m_cooksize;
+                        cobd->cache_on = 0;
                 }
                 break;
         case OBD_IOC_COBD_CFLUSH:
index fcc9a56..eb17e8d 100644 (file)
@@ -277,6 +277,7 @@ struct lustre_mount_data {
         uint32_t lmd_nal;
         uint32_t lmd_server_ipaddr;
         uint32_t lmd_port;
+        uint32_t lmd_clone_index;
         char     lmd_mds[64];
         char     lmd_profile[64];
 };
index 5888826..14cdee1 100644 (file)
@@ -870,6 +870,11 @@ struct ptlbd_rsp {
 
 extern void lustre_swab_ptlbd_rsp (struct ptlbd_rsp *r);
 
+struct clonefs_info {
+        int clone_index;
+        int clone_flags;
+};
+extern void lustre_swab_clonefs_info(struct clonefs_info *clone);
 /*
  * Opcodes for management/monitoring node.
  */
index cd8e9c6..77fd369 100644 (file)
@@ -146,6 +146,9 @@ struct snap_ea{
 #define SNAPTABLE_INFO          "snaptable"
 #define SNAP_GENERATION         "snap_generation"
 
+
+#define SNAP_LOOKUP     (REINT_MAX + 1)
+
 struct snap {
         time_t          sn_time;
         unsigned int    sn_index;
@@ -170,6 +173,13 @@ struct snap_info {
         struct snap_table        *sntbl;
         struct dentry            *sn_cowed_dentry;
 };
+#define SM_CLONE_FS        0x01
+#define SET_CLONE_INDEX(clone_info, index)            \
+                       (((struct clonefs_info *)clone_info)->clone_index = index)
+#define SET_CLONE_FLAGS(clone_info, flags)            \
+                       (((struct clonefs_info *)clone_info)->clone_flags = flags)
+
+
 extern int smfs_add_snap_item(struct super_block *sb, char *name);
 extern int smfs_start_cow(struct super_block *sb);
 extern int smfs_stop_cow(struct super_block *sb);
@@ -182,4 +192,5 @@ int smfs_cow(struct inode *dir, struct dentry *dentry,
              void *data1, void *data2, int op);
 int smfs_cow_write(struct inode *inode, struct dentry *dentry, void *data1,
                    void *data2);
+struct inode* smfs_cow_get_ind(struct inode *inode, int index);
 #endif /*_LUSTRE_SNAP_H*/
index 3f1bd99..e749973 100644 (file)
@@ -280,7 +280,8 @@ struct client_obd {
 
         struct mdc_rpc_lock     *cl_rpc_lock;
         struct mdc_rpc_lock     *cl_setattr_lock;
-        struct osc_creator      cl_oscc;
+        struct osc_creator       cl_oscc;
+        void                    *cl_clone_info;
 };
 
 /* Like a client, with some hangers-on.  Keep mc_client_obd first so that we
index 2cca168..03a4135 100644 (file)
@@ -198,7 +198,8 @@ extern struct super_operations lustre_super_operations;
 
 char *ll_read_opt(const char *opt, char *data);
 int ll_set_opt(const char *opt, char *data, int fl);
-void ll_options(char *options, char **ost, char **mds, int *flags);
+void ll_options(char *options, char **ost, char **mds, int *flags, 
+                char **clone_ops);
 void ll_lli_init(struct ll_inode_info *lli);
 int ll_fill_super(struct super_block *sb, void *data, int silent);
 int lustre_fill_super(struct super_block *sb, void *data, int silent);
index 5aae834..170d3fd 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/lustre_ha.h>
 #include <linux/lustre_dlm.h>
 #include <linux/lprocfs_status.h>
+#include <linux/lustre_snap.h>
 #include "llite_internal.h"
 
 kmem_cache_t *ll_file_data_slab;
@@ -111,6 +112,70 @@ int lustre_init_ea_size(struct ll_sb_info *sbi)
         }
         RETURN(rc);
 }
+#if CONFIG_SNAPFS
+int lustre_set_clone_info(struct super_block *sb, int clone_index)
+{
+        struct ll_sb_info *sbi = ll_s2sbi(sb);
+        
+        ENTRY;
+
+        CDEBUG(D_INFO, "set clone index %d\n", clone_index);
+        if (!clone_index)
+                RETURN(0); 
+        
+        if (sbi->ll_mdc_exp) {
+                struct obd_import *climp = class_exp2cliimp(sbi->ll_mdc_exp);
+                struct client_obd *cl_obd = &climp->imp_obd->u.cli;
+
+                OBD_ALLOC(cl_obd->cl_clone_info, sizeof(struct clonefs_info));
+                if (!cl_obd->cl_clone_info) 
+                        RETURN(-ENOMEM);
+                SET_CLONE_INDEX(cl_obd->cl_clone_info, clone_index);
+                SET_CLONE_FLAGS(cl_obd->cl_clone_info, SM_CLONE_FS);
+        }
+        
+        if (sbi->ll_osc_exp) {
+                struct obd_import *climp = class_exp2cliimp(sbi->ll_osc_exp);
+                struct client_obd *cl_obd = &climp->imp_obd->u.cli;
+
+                OBD_ALLOC(cl_obd->cl_clone_info, sizeof(struct clonefs_info));
+                if (!cl_obd->cl_clone_info) 
+                        RETURN(-ENOMEM);
+                SET_CLONE_INDEX(cl_obd->cl_clone_info, clone_index);
+                SET_CLONE_FLAGS(cl_obd->cl_clone_info, SM_CLONE_FS);
+        }
+        RETURN(0); 
+}
+
+int lustre_cleanup_clone_info(struct super_block *sb)
+{
+        struct ll_sb_info *sbi = ll_s2sbi(sb);
+       
+        ENTRY; 
+
+        if (sbi->ll_mdc_exp) {
+                struct obd_import *climp = class_exp2cliimp(sbi->ll_mdc_exp);
+                struct client_obd *cl_obd = &climp->imp_obd->u.cli;
+
+                if (!cl_obd->cl_clone_info) 
+                        RETURN(0); 
+                CDEBUG(D_INFO, "clean clone info %p\n", cl_obd->cl_clone_info);
+                OBD_FREE(cl_obd->cl_clone_info, sizeof(struct clonefs_info));
+        }
+        
+        if (sbi->ll_osc_exp) {
+                struct obd_import *climp = class_exp2cliimp(sbi->ll_osc_exp);
+                struct client_obd *cl_obd = &climp->imp_obd->u.cli;
+
+                if (!cl_obd->cl_clone_info) 
+                        RETURN(0); 
+                CDEBUG(D_INFO, "clean clone info %p\n", cl_obd->cl_clone_info);
+                OBD_FREE(cl_obd->cl_clone_info, sizeof(struct clonefs_info));
+        }
+        RETURN(0); 
+}
+#endif
+
 
 int lustre_common_fill_super(struct super_block *sb, char *mdc, char *osc)
 {
@@ -330,7 +395,8 @@ int ll_set_opt(const char *opt, char *data, int fl)
                 RETURN(fl);
 }
 
-void ll_options(char *options, char **ost, char **mdc, int *flags)
+void ll_options(char *options, char **ost, char **mdc, int *flags, 
+                char **clone_opts)
 {
         char *this_char;
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
@@ -355,12 +421,16 @@ void ll_options(char *options, char **ost, char **mdc, int *flags)
                         continue;
                 if (!*mdc && (*mdc = ll_read_opt("mdc", this_char)))
                         continue;
+                if (!*clone_opts && (*clone_opts = ll_read_opt("clone", 
+                                                                this_char))) 
+                        continue; 
                 if (!(*flags & LL_SBI_NOLCK) &&
                     ((*flags) = (*flags) |
                                 ll_set_opt("nolock", this_char,
                                            LL_SBI_NOLCK)))
                         continue;
         }
+        
         EXIT;
 }
 
@@ -378,6 +448,7 @@ int ll_fill_super(struct super_block *sb, void *data, int silent)
         struct ll_sb_info *sbi;
         char *osc = NULL;
         char *mdc = NULL;
+        char *clone_opts = NULL;
         int err;
         ENTRY;
 
@@ -388,7 +459,7 @@ int ll_fill_super(struct super_block *sb, void *data, int silent)
                 RETURN(-ENOMEM);
 
         sbi->ll_flags |= LL_SBI_READAHEAD;
-        ll_options(data, &osc, &mdc, &sbi->ll_flags);
+        ll_options(data, &osc, &mdc, &sbi->ll_flags, &clone_opts);
 
         if (!osc) {
                 CERROR("no osc\n");
@@ -401,6 +472,16 @@ int ll_fill_super(struct super_block *sb, void *data, int silent)
         }
 
         err = lustre_common_fill_super(sb, mdc, osc);
+#if CONFIG_SNAPFS        
+        if (clone_opts) {
+                int clone_index = 0;
+                char *endp;
+
+                /*set clone info to the super block*/
+                clone_index = simple_strtoul(clone_opts, &endp, 0);
+                err = lustre_set_clone_info(sb, clone_index);                
+        }
+#endif         
 out:
         if (err)
                 lustre_free_sbi(sb);
@@ -409,6 +490,8 @@ out:
                 OBD_FREE(mdc, strlen(mdc) + 1);
         if (osc)
                 OBD_FREE(osc, strlen(osc) + 1);
+        if (clone_opts)
+                OBD_FREE(clone_opts, strlen(clone_opts) + 1);
 
         RETURN(err);
 } /* ll_read_super */
@@ -631,6 +714,15 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent)
         if (err)
                 GOTO(out_free, err);
 
+#if CONFIG_SNAPFS
+        if (lmd->lmd_clone_index) {
+                err = lustre_set_clone_info(sb, lmd->lmd_clone_index);                
+        }
+        
+        if (err)
+                GOTO(out_free, err);
+#endif
+        
 out_dev:
         if (mdc)
                 OBD_FREE(mdc, strlen(mdc) + 1);
@@ -663,6 +755,9 @@ out_free:
                 }
                 OBD_FREE(sbi->ll_lmd, sizeof(*sbi->ll_lmd));
         }
+#if CONFIG_SNAPFS
+        lustre_cleanup_clone_info(sb);
+#endif
         lustre_free_sbi(sb);
 
         goto out_dev;
@@ -710,8 +805,11 @@ void lustre_put_super(struct super_block *sb)
                 force_umount = obd->obd_no_recov;
         obd = NULL;
 
-        lustre_common_put_super(sb);
+#if CONFIG_SNAPFS
+        lustre_cleanup_clone_info(sb);
+#endif
 
+        lustre_common_put_super(sb);
         if (sbi->ll_lmd != NULL) {
                 char * cln_prof;
                 int len = strlen(sbi->ll_lmd->lmd_profile) + sizeof("-clean")+1;
index f36f7f4..c3bafd1 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/obd_class.h>
 #include <linux/lustre_mds.h>
 #include <linux/lustre_dlm.h>
+#include <linux/lustre_snap.h>
 #include <linux/lprocfs_status.h>
 #include "mdc_internal.h"
 
@@ -173,7 +174,20 @@ int mdc_change_cbdata(struct obd_export *exp, struct ll_fid *fid,
         return 0;
 }
 
-
+#if CONFIG_SNAPFS
+int mdc_set_clone_info(struct obd_import *climp, struct lustre_msg *msg, 
+                       int offset)
+{
+        struct client_obd *cli_obd = &climp->imp_obd->u.cli;
+        struct clonefs_info *cl_info;
+        ENTRY;
+         
+        cl_info = (struct clonefs_info *)lustre_msg_buf(msg, offset, 
+                                                         sizeof (*cl_info));
+        memcpy(cl_info, cli_obd->cl_clone_info, sizeof(*cl_info));
+        RETURN(0);        
+} 
+#endif
 
 /* We always reserve enough space in the reply packet for a stripe MD, because
  * we don't know in advance the file type. */
@@ -244,9 +258,15 @@ int mdc_enqueue(struct obd_export *exp,
 
                 if (it->it_op & IT_GETATTR)
                         policy.l_inodebits.bits = MDS_INODELOCK_UPDATE;
-
+#if CONFIG_SNAPFS                
+                size[4] = sizeof(struct clonefs_info); 
+                req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 5,
+                                      size, NULL);
+#else
                 req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 4,
                                       size, NULL);
+
+#endif
                 if (!req)
                         RETURN(-ENOMEM);
 
@@ -256,16 +276,28 @@ int mdc_enqueue(struct obd_export *exp,
 
                 /* pack the intended request */
                 mdc_getattr_pack(req->rq_reqmsg, valid, 2, it->it_flags, data);
+#if CONFIG_SNAPFS               
+                mdc_set_clone_info(class_exp2cliimp(exp), req->rq_reqmsg, 4); 
+#endif                 
                 /* get ready for the reply */
                 reply_buffers = 3;
                 req->rq_replen = lustre_msg_size(3, repsize);
         } else if (it->it_op == IT_READDIR) {
                 policy.l_inodebits.bits = MDS_INODELOCK_UPDATE;
+#if CONFIG_SNAPFS                
+                size[1] = sizeof(struct clonefs_info); 
+                req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 2,
+                                      size, NULL);
+#else
                 req = ptlrpc_prep_req(class_exp2cliimp(exp), LDLM_ENQUEUE, 1,
                                       size, NULL);
+                
+#endif                
                 if (!req)
                         RETURN(-ENOMEM);
-
+#if CONFIG_SNAPFS               
+                mdc_set_clone_info(class_exp2cliimp(exp), req->rq_reqmsg, 1); 
+#endif                 
                 /* get ready for the reply */
                 reply_buffers = 1;
                 req->rq_replen = lustre_msg_size(1, repsize);
index 4591616..8e80be4 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/obd_lov.h>
 #include <linux/lustre_mds.h>
 #include <linux/lustre_fsfilt.h>
+#include <linux/lustre_snap.h>
 #include <linux/lprocfs_status.h>
 #include <linux/lustre_commit_confd.h>
 
@@ -850,6 +851,7 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req,
         struct lustre_handle parent_lockh[2];
         int namesize, update_mode;
         int rc = 0, cleanup_phase = 0, resent_req = 0;
+        struct clonefs_info *clone_info = NULL;
         char *name;
         ENTRY;
 
@@ -870,6 +872,14 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req,
                 CERROR("Can't unpack name\n");
                 GOTO(cleanup, rc = -EFAULT);
         }
+#if CONFIG_SNAPFS
+        clone_info = lustre_swab_reqbuf(req, offset + 2, sizeof(*clone_info), 
+                                        lustre_swab_clonefs_info);
+        if (clone_info) {
+                CDEBUG(D_INFO,"getattr name %s clone_info index %d \n", name,
+                       clone_info->clone_index);
+        }
+#endif
         namesize = req->rq_reqmsg->buflens[offset + 1];
 
         LASSERT (offset == 0 || offset == 2);
@@ -954,7 +964,7 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req,
                                                  LCK_PR, MDS_INODELOCK_LOOKUP,
                                                  &update_mode, name, namesize,
                                                  child_lockh, &dchild, LCK_PR,
-                                                 child_part);
+                                                 child_part, clone_info);
                 if (rc)
                         GOTO(cleanup, rc);
         } else {
index 27e7f53..0f3a091 100644 (file)
@@ -50,7 +50,7 @@ int mds_get_parent_child_locked(struct obd_device *obd, struct mds_obd *mds,
                                 char *name, int namelen,
                                 struct lustre_handle *child_lockh,
                                 struct dentry **dchildp, int child_mode,
-                                __u64 child_lockpart);
+                                __u64 child_lockpart, void* clone_info);
 int mds_lock_new_child(struct obd_device *obd, struct inode *inode,
                        struct lustre_handle *child_lockh);
 
index 80fe242..3689a10 100644 (file)
@@ -1227,7 +1227,7 @@ int mds_get_parent_child_locked(struct obd_device *obd, struct mds_obd *mds,
                                 char *name, int namelen,
                                 struct lustre_handle *child_lockh,
                                 struct dentry **dchildp, int child_mode,
-                                __u64 child_lockpart)
+                                __u64 child_lockpart, void *clone_info)
 {
         struct ldlm_res_id child_res_id = { .name = {0} };
         struct ldlm_res_id parent_res_id = { .name = {0} };
@@ -1281,6 +1281,13 @@ int mds_get_parent_child_locked(struct obd_device *obd, struct mds_obd *mds,
 #endif
 
         cleanup_phase = 1; /* parent dentry */
+#ifdef CONFIG_SNAPFS
+        if (clone_info) {
+                /*FIXME is there any other FUNC will use d_fsdata, 
+                 *excepet creating inode according inum*/
+                (*dparentp)->d_fsdata = clone_info;         
+        }
+#endif
 
         /* Step 2: Lookup child (without DLM lock, to get resource name) */
         *dchildp = ll_lookup_one_len(name, *dparentp, namelen - 1);
@@ -1659,7 +1666,7 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset,
                                                  rec->ur_namelen, &child_lockh,
                                                  &dchild, LCK_EX,
                                                  MDS_INODELOCK_LOOKUP |
-                                                        MDS_INODELOCK_UPDATE);
+                                                   MDS_INODELOCK_UPDATE, NULL);
         }
         if (rc)
                 GOTO(cleanup, rc);
@@ -2514,7 +2521,7 @@ static int mds_reint_rename_create_name(struct mds_update_record *rec,
                                          &de_srcdir,LCK_PW,MDS_INODELOCK_UPDATE,
                                          &update_mode, rec->ur_tgt, rec->ur_tgtlen,
                                          &child_lockh, &de_new, LCK_EX,
-                                         MDS_INODELOCK_LOOKUP);
+                                         MDS_INODELOCK_LOOKUP, NULL);
         if (rc)
                 GOTO(cleanup, rc);
 
@@ -2609,7 +2616,7 @@ static int mds_reint_rename_to_remote(struct mds_update_record *rec, int offset,
                                          &de_srcdir,LCK_PW,MDS_INODELOCK_UPDATE,
                                          &update_mode, rec->ur_name, 
                                          rec->ur_namelen, &child_lockh, &de_old,
-                                         LCK_EX, MDS_INODELOCK_LOOKUP);
+                                         LCK_EX, MDS_INODELOCK_LOOKUP, NULL);
         LASSERT(rc == 0);
         LASSERT(de_srcdir);
         LASSERT(de_srcdir->d_inode);
index 56fb946..1f6fc59 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/obd_support.h>
 #include <linux/obd_class.h>
 #include <linux/lustre_net.h>
+#include <linux/lustre_snap.h>
 #include <linux/fcntl.h>
 
 
@@ -640,7 +641,11 @@ void lustre_swab_mds_body (struct mds_body *b)
         __swab32s (&b->suppgid);
         __swab32s (&b->eadatasize);
 }
-
+void lustre_swab_clonefs_info (struct clonefs_info *clone)
+{
+       __swab32s(&clone->clone_index);
+       __swab32s(&clone->clone_flags); 
+}
 void lustre_swab_mds_rec_setattr (struct mds_rec_setattr *sa)
 {
         __swab32s (&sa->sa_opcode);
index 1097379..d00dde8 100644 (file)
@@ -182,6 +182,7 @@ EXPORT_SYMBOL(lustre_swab_ldlm_reply);
 EXPORT_SYMBOL(lustre_swab_ptlbd_op);
 EXPORT_SYMBOL(lustre_swab_ptlbd_niob);
 EXPORT_SYMBOL(lustre_swab_ptlbd_rsp);
+EXPORT_SYMBOL(lustre_swab_clonefs_info);
 EXPORT_SYMBOL(mdc_create_pack);
 EXPORT_SYMBOL(mdc_setattr_pack);
 EXPORT_SYMBOL(mdc_unlink_pack);
index 7fc58f3..1420009 100644 (file)
@@ -150,6 +150,8 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry,
         if (!cache_dir && cache_dir->i_op->lookup)
                 GOTO(exit, rc = ERR_PTR(-ENOENT));
 
+        SMFS_PRE_COW(dir, dentry, NULL, NULL, SNAP_LOOKUP, "lookup", rc, exit);
+
         /* perform lookup in backing fs. */
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
         rc = cache_dir->i_op->lookup(cache_dir, cache_dentry);
index 3c68a24..d179915 100644 (file)
@@ -646,6 +646,60 @@ exit:
 }
 EXPORT_SYMBOL(smfs_cow_write);
 
+int smfs_cow_lookup(struct inode *inode, struct dentry *dentry, void *data1,
+                    void *data2)
+{
+        struct snap_info *snap_info = S2SNAPI(inode->i_sb);
+        struct fsfilt_operations *snapops = snap_info->snap_fsfilt;
+        struct dentry *dparent = dentry->d_parent;
+        struct clonefs_info *clone_info=(struct clonefs_info*)dparent->d_fsdata;
+        int rc = 0;
+        if (clone_info && clone_info->clone_flags && SM_CLONE_FS) {
+                struct inode *ind_inode = NULL;
+                struct inode *cache_ind = NULL;
+                struct dentry *cache_dentry = NULL;
+                struct dentry *cache_parent = NULL;
+                struct inode *cache_inode;
+                struct dentry *tmp;
+                rc = 1;
+                ind_inode = snapops->fs_get_indirect(inode, NULL, clone_info->clone_index);
+                if (!ind_inode) 
+                        RETURN(-ENOENT);
+                
+                if (!(cache_ind = I2CI(ind_inode)))
+                        GOTO(exit, rc = -ENOENT);
+
+                cache_parent=pre_smfs_dentry(NULL, cache_ind, dentry->d_parent);
+                cache_dentry=pre_smfs_dentry(cache_parent, NULL, dentry);
+
+                tmp = cache_ind->i_op->lookup(cache_ind, cache_dentry);
+        
+                if (IS_ERR(tmp))
+                        GOTO(exit, rc = -ENOENT);
+
+                if ((cache_inode = tmp ? tmp->d_inode : cache_dentry->d_inode)) {
+                        if (IS_ERR(cache_inode)) {
+                                dentry->d_inode = cache_inode;
+                                GOTO(exit, rc = -ENOENT);
+                        }
+                        inode = iget4(inode->i_sb, cache_inode->i_ino, NULL,
+                                      &I2SMI(inode)->smi_flags);
+                } else {
+                        d_add(dentry, NULL);
+                        GOTO(exit, rc = -ENOENT);
+                }
+                d_add(dentry, inode);
+exit:
+                iput(ind_inode);
+                post_smfs_dentry(cache_dentry);
+                post_smfs_dentry(cache_parent);
+                RETURN(rc);
+        } 
+        RETURN(rc);         
+}
+
 struct inode *smfs_cow_get_ind(struct inode *inode, int index)
 {
         struct snap_info *snap_info = S2SNAPI(inode->i_sb);
@@ -673,16 +727,19 @@ struct inode *smfs_cow_get_ind(struct inode *inode, int index)
         RETURN(NULL);
 }
 EXPORT_SYMBOL(smfs_cow_get_ind);
+
 typedef int (*cow_funcs)(struct inode *dir, struct dentry *dentry, 
                          void *new_dir, void *new_dentry);
 
-static cow_funcs smfs_cow_funcs[REINT_MAX + 1] = {
+
+static cow_funcs smfs_cow_funcs[REINT_MAX + 2] = {
         [REINT_SETATTR] smfs_cow_setattr,
         [REINT_CREATE]  smfs_cow_create,
         [REINT_LINK]    smfs_cow_link,
         [REINT_UNLINK]  smfs_cow_unlink,
         [REINT_RENAME]  smfs_cow_rename,
         [REINT_WRITE]   smfs_cow_write,
+        [SNAP_LOOKUP]   smfs_cow_lookup,
 };
 
 int smfs_cow(struct inode *dir, struct dentry *dentry, void *new_dir, 
index cb5862a..c3ef77e 100644 (file)
@@ -321,7 +321,9 @@ do {                                                                           \
                 CDEBUG(D_INODE, "Do %s snap post for dir %lu \n",              \
                               name, dir->i_ino);                               \
                 rc = smfs_cow(dir, dentry, new_dir, new_dentry, op);           \
-                if (rc)                                                        \
+                if (op == SNAP_LOOKUP && rc == 1)                              \
+                        GOTO(label, rc = 0);                                   \
+                else if (rc)                                                   \
                         GOTO(label, rc);                                       \
         }                                                                      \
 } while(0)
index 858450b..99ffab2 100755 (executable)
@@ -2432,6 +2432,7 @@ class Mountpoint(Module):
     def __init__(self,db):
         Module.__init__(self, 'MTPT', db)
         self.path = self.db.get_val('path')
+       self.clientoptions = self.db.get_val('clientoptions', '')
         self.fs_uuid = self.db.get_first_ref('filesystem')
         fs = self.db.lookup(self.fs_uuid)
         self.mds_uuid = fs.get_first_ref('lmv')
@@ -2477,8 +2478,23 @@ class Mountpoint(Module):
         if config.record or config.lctl_dump:
             lctl.mount_option(local_node_name, self.vosc.get_name(), vmdc_name)
             return
-        cmd = "mount -t lustre_lite -o osc=%s,mdc=%s %s %s" % \
-              (self.vosc.get_name(), vmdc_name, config.config, self.path)
+
+        if config.clientoptions:
+            if self.clientoptions:
+                self.clientoptions = self.clientoptions + ',' + \
+                                    config.clientoptions
+            else:
+                self.clientoptions = config.clientoptions
+        if self.clientoptions:
+            self.clientoptions = ',' + self.clientoptions
+            # Linux kernel will deal with async and not pass it to ll_fill_super,
+            # so replace it with Lustre async
+            self.clientoptions = string.replace(self.clientoptions, "async", 
+                                               "lasync")
+
+        cmd = "mount -t lustre_lite -o osc=%s,mdc=%s%s %s %s" % \
+              (self.vosc.get_name(), vmdc_name, self.clientoptions, 
+              config.config, self.path)
         run("mkdir", self.path)
         ret, val = run(cmd)
         if ret:
@@ -3271,6 +3287,7 @@ lconf_options = [
     ('reformat', "Reformat all devices (without question)"),
     ('mkfsoptions', "Additional options for the mk*fs command line", PARAM),
     ('mountfsoptions', "Additional options for mount fs command line", PARAM),
+    ('clientoptions', "Additional options for Lustre", PARAM),
     ('dump',  "Dump the kernel debug log to file before portals is unloaded",
                PARAM),
     ('write_conf', "Save all the client config information on mds."),
index 8e75f5c..198e30e 100644 (file)
@@ -246,6 +246,9 @@ int parse_options(char * options, struct lustre_mount_data *lmd)
                         } else if (!strcmp(opt, "port")) {
                                 lmd->lmd_port = val;
                         }
+                        else if (!strcmp(opt, "clone")) {
+                                lmd->lmd_clone_index = val;
+                        } 
                 } else {
                         val = 1;
                         if (!strncmp(opt, "no", 2)) {
index 476477c..849afb4 100755 (executable)
@@ -137,6 +137,7 @@ Object creation command summary:
   --mds mds_name
   --lmv lmv_name
   --ost ost_name OR --lov lov_name
+  --clientoptions options
 
 --add route
   --node nodename
@@ -236,6 +237,7 @@ lmc_options = [
     ('echo_client', "", PARAM),
     ('path', "Specify the mountpoint for Lustre.", PARAM),
     ('filesystem', "Lustre filesystem name", PARAM,""),
+    ('clientoptions', "Specify the options for Lustre, such as async.", PARAM, ""),
 
     # lov
     ('lov', "Specify LOV name.", PARAM,""),
@@ -558,10 +560,12 @@ class GenConfig:
         mgmt.appendChild(self.ref("active", mgmt_uuid))
         return mgmt
 
-    def mountpoint(self, name, uuid, fs_uuid, path):
+    def mountpoint(self, name, uuid, fs_uuid, path, clientoptions):
         mtpt = self.newService("mountpoint", name, uuid)
         mtpt.appendChild(self.ref("filesystem", fs_uuid))
         self.addElement(mtpt, "path", path)
+        if clientoptions:
+            self.addElement(mtpt, "clientoptions", clientoptions)
         return mtpt
 
     def filesystem(self, name, uuid, mds_uuid, obd_uuid, mgmt_uuid):
@@ -1366,6 +1370,7 @@ def add_mtpt(gen, lustre, options):
     node_name = get_option(options, 'node')
 
     path = get_option(options, 'path')
+    clientoptions = get_option(options, "clientoptions")
     fs_name = get_option(options, 'filesystem')
 
     lov_name = get_option(options, 'lov')
@@ -1402,7 +1407,7 @@ def add_mtpt(gen, lustre, options):
         error("MOUNTPOINT: ", name, " already exists.")
 
     uuid = new_uuid(name)
-    mtpt = gen.mountpoint(name, uuid, fs_uuid, path)
+    mtpt = gen.mountpoint(name, uuid, fs_uuid, path, clientoptions)
     node = findByName(lustre, node_name, "node")
     if not node:
         error('node:',  node_name, "not found.")