Whamcloud - gitweb
LU-1445 fid: Add DATA fid type in fid_request.
[fs/lustre-release.git] / lustre / llite / llite_lib.c
index 2d8665b..fe87c92 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Whamcloud, Inc.
+ * Copyright (c) 2011, 2012, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -68,7 +68,7 @@ extern struct address_space_operations_ext ll_aops;
 #endif
 
 #ifndef log2
-#define log2(n) cfs_ffz(~(n))
+#define log2(n) ffz(~(n))
 #endif
 
 static struct ll_sb_info *ll_init_sbi(void)
@@ -85,10 +85,10 @@ static struct ll_sb_info *ll_init_sbi(void)
         if (!sbi)
                 RETURN(NULL);
 
-        cfs_spin_lock_init(&sbi->ll_lock);
-        cfs_mutex_init(&sbi->ll_lco.lco_lock);
-        cfs_spin_lock_init(&sbi->ll_pp_extent_lock);
-        cfs_spin_lock_init(&sbi->ll_process_lock);
+       spin_lock_init(&sbi->ll_lock);
+       mutex_init(&sbi->ll_lco.lco_lock);
+       spin_lock_init(&sbi->ll_pp_extent_lock);
+       spin_lock_init(&sbi->ll_process_lock);
         sbi->ll_rw_stats_on = 0;
 
         si_meminfo(&si);
@@ -107,7 +107,7 @@ static struct ll_sb_info *ll_init_sbi(void)
        cfs_atomic_set(&sbi->ll_cache.ccc_users, 0);
        sbi->ll_cache.ccc_lru_max = lru_page_max;
        cfs_atomic_set(&sbi->ll_cache.ccc_lru_left, lru_page_max);
-       cfs_spin_lock_init(&sbi->ll_cache.ccc_lru_lock);
+       spin_lock_init(&sbi->ll_cache.ccc_lru_lock);
        CFS_INIT_LIST_HEAD(&sbi->ll_cache.ccc_lru);
 
         sbi->ll_ra_info.ra_max_pages_per_file = min(pages / 32,
@@ -122,9 +122,9 @@ static struct ll_sb_info *ll_init_sbi(void)
         class_uuid_unparse(uuid, &sbi->ll_sb_uuid);
         CDEBUG(D_CONFIG, "generated uuid: %s\n", sbi->ll_sb_uuid.uuid);
 
-        cfs_spin_lock(&ll_sb_lock);
-        cfs_list_add_tail(&sbi->ll_list, &ll_super_blocks);
-        cfs_spin_unlock(&ll_sb_lock);
+       spin_lock(&ll_sb_lock);
+       cfs_list_add_tail(&sbi->ll_list, &ll_super_blocks);
+       spin_unlock(&ll_sb_lock);
 
         sbi->ll_flags |= LL_SBI_VERBOSE;
 #ifdef ENABLE_CHECKSUM
@@ -136,10 +136,10 @@ static struct ll_sb_info *ll_init_sbi(void)
 #endif
 
         for (i = 0; i <= LL_PROCESS_HIST_MAX; i++) {
-                cfs_spin_lock_init(&sbi->ll_rw_extents_info.pp_extents[i]. \
-                                   pp_r_hist.oh_lock);
-                cfs_spin_lock_init(&sbi->ll_rw_extents_info.pp_extents[i]. \
-                                   pp_w_hist.oh_lock);
+               spin_lock_init(&sbi->ll_rw_extents_info.pp_extents[i].
+                              pp_r_hist.oh_lock);
+               spin_lock_init(&sbi->ll_rw_extents_info.pp_extents[i].
+                              pp_w_hist.oh_lock);
         }
 
         /* metadata statahead is enabled by default */
@@ -154,16 +154,16 @@ static struct ll_sb_info *ll_init_sbi(void)
 
 void ll_free_sbi(struct super_block *sb)
 {
-        struct ll_sb_info *sbi = ll_s2sbi(sb);
-        ENTRY;
+       struct ll_sb_info *sbi = ll_s2sbi(sb);
+       ENTRY;
 
-        if (sbi != NULL) {
-                cfs_spin_lock(&ll_sb_lock);
-                cfs_list_del(&sbi->ll_list);
-                cfs_spin_unlock(&ll_sb_lock);
-                OBD_FREE(sbi, sizeof(*sbi));
-        }
-        EXIT;
+       if (sbi != NULL) {
+               spin_lock(&ll_sb_lock);
+               cfs_list_del(&sbi->ll_list);
+               spin_unlock(&ll_sb_lock);
+               OBD_FREE(sbi, sizeof(*sbi));
+       }
+       EXIT;
 }
 
 static struct dentry_operations ll_d_root_ops = {
@@ -221,7 +221,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                                   OBD_CONNECT_RMT_CLIENT | OBD_CONNECT_VBR    |
                                   OBD_CONNECT_FULL20   | OBD_CONNECT_64BITHASH|
                                  OBD_CONNECT_EINPROGRESS |
-                                 OBD_CONNECT_JOBSTATS;
+                                 OBD_CONNECT_JOBSTATS | OBD_CONNECT_LVB_TYPE |
+                                 OBD_CONNECT_LAYOUTLOCK;
 
         if (sbi->ll_flags & LL_SBI_SOM_PREVIEW)
                 data->ocd_connect_flags |= OBD_CONNECT_SOM;
@@ -281,49 +282,43 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                 GOTO(out, err);
         }
 
-        err = obd_fid_init(sbi->ll_md_exp);
-        if (err) {
-                CERROR("Can't init metadata layer FID infrastructure, "
-                       "rc %d\n", err);
-                GOTO(out_md, err);
-        }
+       err = obd_statfs(NULL, sbi->ll_md_exp, osfs,
+                        cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), 0);
+       if (err)
+               GOTO(out_md, err);
+
+       /* This needs to be after statfs to ensure connect has finished.
+        * Note that "data" does NOT contain the valid connect reply.
+        * If connecting to a 1.8 server there will be no LMV device, so
+        * we can access the MDC export directly and exp_connect_flags will
+        * be non-zero, but if accessing an upgraded 2.1 server it will
+        * have the correct flags filled in.
+        * XXX: fill in the LMV exp_connect_flags from MDC(s). */
+       valid = sbi->ll_md_exp->exp_connect_flags & CLIENT_CONNECT_MDT_REQD;
+       if (sbi->ll_md_exp->exp_connect_flags != 0 &&
+           valid != CLIENT_CONNECT_MDT_REQD) {
+               char *buf;
+
+               OBD_ALLOC_WAIT(buf, CFS_PAGE_SIZE);
+               obd_connect_flags2str(buf, CFS_PAGE_SIZE,
+                                     valid ^ CLIENT_CONNECT_MDT_REQD, ",");
+               LCONSOLE_ERROR_MSG(0x170, "Server %s does not support "
+                                  "feature(s) needed for correct operation "
+                                  "of this client (%s). Please upgrade "
+                                  "server or downgrade client.\n",
+                                  sbi->ll_md_exp->exp_obd->obd_name, buf);
+               OBD_FREE(buf, CFS_PAGE_SIZE);
+               GOTO(out_md, err = -EPROTO);
+       }
 
-        err = obd_statfs(NULL, sbi->ll_md_exp, osfs,
-                         cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), 0);
-        if (err)
-                GOTO(out_md_fid, err);
-
-        /* This needs to be after statfs to ensure connect has finished.
-         * Note that "data" does NOT contain the valid connect reply.
-         * If connecting to a 1.8 server there will be no LMV device, so
-         * we can access the MDC export directly and exp_connect_flags will
-         * be non-zero, but if accessing an upgraded 2.1 server it will
-         * have the correct flags filled in.
-         * XXX: fill in the LMV exp_connect_flags from MDC(s). */
-        valid = sbi->ll_md_exp->exp_connect_flags & CLIENT_CONNECT_MDT_REQD;
-        if (sbi->ll_md_exp->exp_connect_flags != 0 &&
-            valid != CLIENT_CONNECT_MDT_REQD) {
-                char *buf;
-
-                OBD_ALLOC_WAIT(buf, CFS_PAGE_SIZE);
-                obd_connect_flags2str(buf, CFS_PAGE_SIZE,
-                                      valid ^ CLIENT_CONNECT_MDT_REQD, ",");
-                LCONSOLE_ERROR_MSG(0x170, "Server %s does not support "
-                                   "feature(s) needed for correct operation "
-                                   "of this client (%s). Please upgrade "
-                                   "server or downgrade client.\n",
-                                   sbi->ll_md_exp->exp_obd->obd_name, buf);
-                OBD_FREE(buf, CFS_PAGE_SIZE);
-                GOTO(out_md, err = -EPROTO);
-        }
-
-        size = sizeof(*data);
-        err = obd_get_info(NULL, sbi->ll_md_exp, sizeof(KEY_CONN_DATA),
-                           KEY_CONN_DATA,  &size, data, NULL);
-        if (err) {
-                CERROR("Get connect data failed: %d \n", err);
-                GOTO(out_md, err);
-        }
+       size = sizeof(*data);
+       err = obd_get_info(NULL, sbi->ll_md_exp, sizeof(KEY_CONN_DATA),
+                          KEY_CONN_DATA,  &size, data, NULL);
+       if (err) {
+               CERROR("%s: Get connect data failed: rc = %d\n",
+                      sbi->ll_md_exp->exp_obd->obd_name, err);
+               GOTO(out_md, err);
+       }
 
         LASSERT(osfs->os_bsize);
         sb->s_blocksize = osfs->os_bsize;
@@ -389,11 +384,11 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                sbi->ll_flags |= LL_SBI_LAYOUT_LOCK;
        }
 
-        obd = class_name2obd(dt);
-        if (!obd) {
-                CERROR("DT %s: not setup or attached\n", dt);
-                GOTO(out_md_fid, err = -ENODEV);
-        }
+       obd = class_name2obd(dt);
+       if (!obd) {
+               CERROR("DT %s: not setup or attached\n", dt);
+               GOTO(out_md, err = -ENODEV);
+       }
 
         data->ocd_connect_flags = OBD_CONNECT_GRANT     | OBD_CONNECT_VERSION  |
                                   OBD_CONNECT_REQPORTAL | OBD_CONNECT_BRW_SIZE |
@@ -404,7 +399,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                                   OBD_CONNECT_FULL20 | OBD_CONNECT_64BITHASH |
                                   OBD_CONNECT_MAXBYTES |
                                  OBD_CONNECT_EINPROGRESS |
-                                 OBD_CONNECT_JOBSTATS;
+                                 OBD_CONNECT_JOBSTATS | OBD_CONNECT_LVB_TYPE |
+                                 OBD_CONNECT_LAYOUTLOCK;
 
         if (sbi->ll_flags & LL_SBI_SOM_PREVIEW)
                 data->ocd_connect_flags |= OBD_CONNECT_SOM;
@@ -437,80 +433,79 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
 
         data->ocd_brw_size = PTLRPC_MAX_BRW_SIZE;
 
-        err = obd_connect(NULL, &sbi->ll_dt_exp, obd, &sbi->ll_sb_uuid, data, NULL);
-        if (err == -EBUSY) {
-                LCONSOLE_ERROR_MSG(0x150, "An OST (dt %s) is performing "
-                                   "recovery, of which this client is not a "
-                                   "part.  Please wait for recovery to "
-                                   "complete, abort, or time out.\n", dt);
-                GOTO(out_md_fid, err);
-        } else if (err) {
-                CERROR("Cannot connect to %s: rc = %d\n", dt, err);
-                GOTO(out_md_fid, err);
-        }
-
-        err = obd_fid_init(sbi->ll_dt_exp);
-        if (err) {
-                CERROR("Can't init data layer FID infrastructure, "
-                       "rc %d\n", err);
-                GOTO(out_dt, err);
-        }
-
-        cfs_mutex_lock(&sbi->ll_lco.lco_lock);
-        sbi->ll_lco.lco_flags = data->ocd_connect_flags;
-        sbi->ll_lco.lco_md_exp = sbi->ll_md_exp;
-        sbi->ll_lco.lco_dt_exp = sbi->ll_dt_exp;
-        cfs_mutex_unlock(&sbi->ll_lco.lco_lock);
+       err = obd_connect(NULL, &sbi->ll_dt_exp, obd, &sbi->ll_sb_uuid, data,
+                         NULL);
+       if (err == -EBUSY) {
+               LCONSOLE_ERROR_MSG(0x150, "An OST (dt %s) is performing "
+                                  "recovery, of which this client is not a "
+                                  "part.  Please wait for recovery to "
+                                  "complete, abort, or time out.\n", dt);
+               GOTO(out_md, err);
+       } else if (err) {
+               CERROR("%s: Cannot connect to %s: rc = %d\n",
+                      sbi->ll_dt_exp->exp_obd->obd_name, dt, err);
+               GOTO(out_md, err);
+       }
 
-        fid_zero(&sbi->ll_root_fid);
-        err = md_getstatus(sbi->ll_md_exp, &sbi->ll_root_fid, &oc);
-        if (err) {
-                CERROR("cannot mds_connect: rc = %d\n", err);
-                GOTO(out_lock_cn_cb, err);
-        }
-        if (!fid_is_sane(&sbi->ll_root_fid)) {
-                CERROR("Invalid root fid during mount\n");
-                GOTO(out_lock_cn_cb, err = -EINVAL);
-        }
-        CDEBUG(D_SUPER, "rootfid "DFID"\n", PFID(&sbi->ll_root_fid));
+       mutex_lock(&sbi->ll_lco.lco_lock);
+       sbi->ll_lco.lco_flags = data->ocd_connect_flags;
+       sbi->ll_lco.lco_md_exp = sbi->ll_md_exp;
+       sbi->ll_lco.lco_dt_exp = sbi->ll_dt_exp;
+       mutex_unlock(&sbi->ll_lco.lco_lock);
+
+       fid_zero(&sbi->ll_root_fid);
+       err = md_getstatus(sbi->ll_md_exp, &sbi->ll_root_fid, &oc);
+       if (err) {
+               CERROR("cannot mds_connect: rc = %d\n", err);
+               GOTO(out_dt, err);
+       }
+       if (!fid_is_sane(&sbi->ll_root_fid)) {
+               CERROR("%s: Invalid root fid "DFID" during mount\n",
+                      sbi->ll_md_exp->exp_obd->obd_name,
+                      PFID(&sbi->ll_root_fid));
+               GOTO(out_dt, err = -EINVAL);
+       }
+       CDEBUG(D_SUPER, "rootfid "DFID"\n", PFID(&sbi->ll_root_fid));
 
-        sb->s_op = &lustre_super_operations;
+       sb->s_op = &lustre_super_operations;
 #if THREAD_SIZE >= 8192 /*b=17630*/
         sb->s_export_op = &lustre_export_operations;
 #endif
 
-        /* make root inode
-         * XXX: move this to after cbd setup? */
-        valid = OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS | OBD_MD_FLMDSCAPA;
-        if (sbi->ll_flags & LL_SBI_RMT_CLIENT)
-                valid |= OBD_MD_FLRMTPERM;
-        else if (sbi->ll_flags & LL_SBI_ACL)
-                valid |= OBD_MD_FLACL;
-
-        OBD_ALLOC_PTR(op_data);
-        if (op_data == NULL)
-                GOTO(out_lock_cn_cb, err = -ENOMEM);
-
-        op_data->op_fid1 = sbi->ll_root_fid;
-        op_data->op_mode = 0;
-        op_data->op_capa1 = oc;
-        op_data->op_valid = valid;
+       /* make root inode
+        * XXX: move this to after cbd setup? */
+       valid = OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS | OBD_MD_FLMDSCAPA;
+       if (sbi->ll_flags & LL_SBI_RMT_CLIENT)
+               valid |= OBD_MD_FLRMTPERM;
+       else if (sbi->ll_flags & LL_SBI_ACL)
+               valid |= OBD_MD_FLACL;
+
+       OBD_ALLOC_PTR(op_data);
+       if (op_data == NULL)
+               GOTO(out_dt, err = -ENOMEM);
+
+       op_data->op_fid1 = sbi->ll_root_fid;
+       op_data->op_mode = 0;
+       op_data->op_capa1 = oc;
+       op_data->op_valid = valid;
+
+       err = md_getattr(sbi->ll_md_exp, op_data, &request);
+       if (oc)
+               capa_put(oc);
+       OBD_FREE_PTR(op_data);
+       if (err) {
+               CERROR("%s: md_getattr failed for root: rc = %d\n",
+                      sbi->ll_md_exp->exp_obd->obd_name, err);
+               GOTO(out_dt, err);
+       }
 
-        err = md_getattr(sbi->ll_md_exp, op_data, &request);
-        if (oc)
-                capa_put(oc);
-        OBD_FREE_PTR(op_data);
-        if (err) {
-                CERROR("md_getattr failed for root: rc = %d\n", err);
-                GOTO(out_lock_cn_cb, err);
-        }
-        err = md_get_lustre_md(sbi->ll_md_exp, request, sbi->ll_dt_exp,
-                               sbi->ll_md_exp, &lmd);
-        if (err) {
-                CERROR("failed to understand root inode md: rc = %d\n", err);
-                ptlrpc_req_finished (request);
-                GOTO(out_lock_cn_cb, err);
-        }
+       err = md_get_lustre_md(sbi->ll_md_exp, request, sbi->ll_dt_exp,
+                              sbi->ll_md_exp, &lmd);
+       if (err) {
+               CERROR("failed to understand root inode md: rc = %d\n", err);
+               ptlrpc_req_finished(request);
+               GOTO(out_dt, err);
+       }
 
         LASSERT(fid_is_sane(&sbi->ll_root_fid));
         root = ll_iget(sb, cl_fid_build_ino(&sbi->ll_root_fid, 0), &lmd);
@@ -555,7 +550,13 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                                 KEY_CACHE_SET, sizeof(sbi->ll_cache),
                                 &sbi->ll_cache, NULL);
 
-       sb->s_root = d_alloc_root(root);
+       sb->s_root = d_make_root(root);
+       if (sb->s_root == NULL) {
+               CERROR("%s: can't make root dentry\n",
+                       ll_get_fsname(sb, NULL, 0));
+               GOTO(out_root, err = -ENOMEM);
+       }
+
 #ifdef HAVE_DCACHE_LOCK
        sb->s_root->d_op = &ll_d_root_ops;
 #else
@@ -584,13 +585,11 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
 out_root:
         if (root)
                 iput(root);
-out_lock_cn_cb:
-        obd_fid_fini(sbi->ll_dt_exp);
 out_dt:
         obd_disconnect(sbi->ll_dt_exp);
         sbi->ll_dt_exp = NULL;
-out_md_fid:
-        obd_fid_fini(sbi->ll_md_exp);
+       /* Make sure all OScs are gone, since cl_cache is accessing sbi. */
+       obd_zombie_barrier();
 out_md:
         obd_disconnect(sbi->ll_md_exp);
         sbi->ll_md_exp = NULL;
@@ -619,17 +618,17 @@ int ll_get_max_mdsize(struct ll_sb_info *sbi, int *lmmsize)
 
 void ll_dump_inode(struct inode *inode)
 {
-        struct list_head *tmp;
-        int dentry_count = 0;
+       struct ll_d_hlist_node *tmp;
+       int dentry_count = 0;
 
-        LASSERT(inode != NULL);
+       LASSERT(inode != NULL);
 
-        list_for_each(tmp, &inode->i_dentry)
-                dentry_count++;
+       ll_d_hlist_for_each(tmp, &inode->i_dentry)
+               dentry_count++;
 
-        CERROR("inode %p dump: dev=%s ino=%lu mode=%o count=%u, %d dentries\n",
-               inode, ll_i2mdexp(inode)->exp_obd->obd_name, inode->i_ino,
-               inode->i_mode, atomic_read(&inode->i_count), dentry_count);
+       CERROR("inode %p dump: dev=%s ino=%lu mode=%o count=%u, %d dentries\n",
+              inode, ll_i2mdexp(inode)->exp_obd->obd_name, inode->i_ino,
+              inode->i_mode, atomic_read(&inode->i_count), dentry_count);
 }
 
 void lustre_dump_dentry(struct dentry *dentry, int recur)
@@ -678,13 +677,14 @@ void client_common_put_super(struct super_block *sb)
 
         cfs_list_del(&sbi->ll_conn_chain);
 
-        obd_fid_fini(sbi->ll_dt_exp);
         obd_disconnect(sbi->ll_dt_exp);
         sbi->ll_dt_exp = NULL;
+       /* wait till all OSCs are gone, since cl_cache is accessing sbi.
+        * see LU-2543. */
+       obd_zombie_barrier();
 
         lprocfs_unregister_mountpoint(sbi);
 
-        obd_fid_fini(sbi->ll_md_exp);
         obd_disconnect(sbi->ll_md_exp);
         sbi->ll_md_exp = NULL;
 
@@ -887,14 +887,14 @@ next:
 
 void ll_lli_init(struct ll_inode_info *lli)
 {
-        lli->lli_inode_magic = LLI_INODE_MAGIC;
-        lli->lli_flags = 0;
-        lli->lli_ioepoch = 0;
-        lli->lli_maxbytes = MAX_LFS_FILESIZE;
-        cfs_spin_lock_init(&lli->lli_lock);
-        lli->lli_posix_acl = NULL;
-        lli->lli_remote_perms = NULL;
-        cfs_mutex_init(&lli->lli_rmtperm_mutex);
+       lli->lli_inode_magic = LLI_INODE_MAGIC;
+       lli->lli_flags = 0;
+       lli->lli_ioepoch = 0;
+       lli->lli_maxbytes = MAX_LFS_FILESIZE;
+       spin_lock_init(&lli->lli_lock);
+       lli->lli_posix_acl = NULL;
+       lli->lli_remote_perms = NULL;
+       mutex_init(&lli->lli_rmtperm_mutex);
         /* Do not set lli_fid, it has been initialized already. */
         fid_zero(&lli->lli_pfid);
         CFS_INIT_LIST_HEAD(&lli->lli_close_list);
@@ -909,32 +909,33 @@ void ll_lli_init(struct ll_inode_info *lli)
         lli->lli_open_fd_read_count = 0;
         lli->lli_open_fd_write_count = 0;
         lli->lli_open_fd_exec_count = 0;
-        cfs_mutex_init(&lli->lli_och_mutex);
-        cfs_spin_lock_init(&lli->lli_agl_lock);
+       mutex_init(&lli->lli_och_mutex);
+       spin_lock_init(&lli->lli_agl_lock);
        lli->lli_has_smd = false;
-        lli->lli_clob = NULL;
-
-        LASSERT(lli->lli_vfs_inode.i_mode != 0);
-        if (S_ISDIR(lli->lli_vfs_inode.i_mode)) {
-                cfs_mutex_init(&lli->lli_readdir_mutex);
-                lli->lli_opendir_key = NULL;
-                lli->lli_sai = NULL;
-                lli->lli_def_acl = NULL;
-                cfs_spin_lock_init(&lli->lli_sa_lock);
-                lli->lli_opendir_pid = 0;
-        } else {
-                cfs_sema_init(&lli->lli_size_sem, 1);
-                lli->lli_size_sem_owner = NULL;
-                lli->lli_symlink_name = NULL;
-                cfs_init_rwsem(&lli->lli_trunc_sem);
-                cfs_mutex_init(&lli->lli_write_mutex);
-               cfs_init_rwsem(&lli->lli_glimpse_sem);
+       lli->lli_layout_gen = LL_LAYOUT_GEN_ZERO;
+       lli->lli_clob = NULL;
+
+       LASSERT(lli->lli_vfs_inode.i_mode != 0);
+       if (S_ISDIR(lli->lli_vfs_inode.i_mode)) {
+               mutex_init(&lli->lli_readdir_mutex);
+               lli->lli_opendir_key = NULL;
+               lli->lli_sai = NULL;
+               lli->lli_def_acl = NULL;
+               spin_lock_init(&lli->lli_sa_lock);
+               lli->lli_opendir_pid = 0;
+       } else {
+               sema_init(&lli->lli_size_sem, 1);
+               lli->lli_size_sem_owner = NULL;
+               lli->lli_symlink_name = NULL;
+               init_rwsem(&lli->lli_trunc_sem);
+               mutex_init(&lli->lli_write_mutex);
+               init_rwsem(&lli->lli_glimpse_sem);
                lli->lli_glimpse_time = 0;
                CFS_INIT_LIST_HEAD(&lli->lli_agl_list);
                lli->lli_agl_index = 0;
                lli->lli_async_rc = 0;
        }
-       cfs_mutex_init(&lli->lli_layout_mutex);
+       mutex_init(&lli->lli_layout_mutex);
 }
 
 static inline int ll_bdi_register(struct backing_dev_info *bdi)
@@ -1404,9 +1405,9 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr)
         int rc = 0, rc1 = 0;
         ENTRY;
 
-       CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu (%p) to %llu, valid %x\n",
-               inode->i_ino,
-               inode,i_size_read(inode),
+       CDEBUG(D_VFSTRACE, "%s: setattr inode %p/fid:"DFID" from %llu to %llu, "
+               "valid %x\n", ll_get_fsname(inode->i_sb, NULL, 0), inode,
+               PFID(&lli->lli_fid), i_size_read(inode), attr->ia_size,
                attr->ia_valid);
 
         if (ia_valid & ATTR_SIZE) {
@@ -1454,6 +1455,13 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr)
                        LTIME_S(attr->ia_mtime), LTIME_S(attr->ia_ctime),
                        cfs_time_current_sec());
 
+       /* If we are changing file size, file content is modified, flag it. */
+       if (attr->ia_valid & ATTR_SIZE) {
+               spin_lock(&lli->lli_lock);
+               lli->lli_flags |= LLIF_DATA_MODIFIED;
+               spin_unlock(&lli->lli_lock);
+       }
+
         /* We always do an MDS RPC, even if we're only changing the size;
          * only the MDS knows whether truncate() should fail with -ETXTBUSY */
 
@@ -1465,7 +1473,7 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr)
                if (ia_valid & ATTR_SIZE)
                        inode_dio_write_done(inode);
                mutex_unlock(&inode->i_mutex);
-               cfs_down_write(&lli->lli_trunc_sem);
+               down_write(&lli->lli_trunc_sem);
                mutex_lock(&inode->i_mutex);
                if (ia_valid & ATTR_SIZE)
                        inode_dio_wait(inode);
@@ -1493,6 +1501,13 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr)
         if (rc)
                 GOTO(out, rc);
 
+       /* RPC to MDT is sent, cancel data modification flag */
+       if (rc == 0 && (op_data->op_bias & MDS_DATA_MODIFIED)) {
+               spin_lock(&lli->lli_lock);
+               lli->lli_flags &= ~LLIF_DATA_MODIFIED;
+               spin_unlock(&lli->lli_lock);
+       }
+
         ll_ioepoch_open(lli, op_data->op_ioepoch);
        if (!S_ISREG(inode->i_mode))
                 GOTO(out, rc = 0);
@@ -1520,7 +1535,7 @@ out:
                 ll_finish_md_op_data(op_data);
         }
         if (!S_ISDIR(inode->i_mode))
-                cfs_up_write(&lli->lli_trunc_sem);
+               up_write(&lli->lli_trunc_sem);
 
         ll_stats_ops_tally(ll_i2sbi(inode), (ia_valid & ATTR_SIZE) ?
                            LPROC_LL_TRUNC : LPROC_LL_SETATTR, 1);
@@ -1652,7 +1667,7 @@ void ll_inode_size_lock(struct inode *inode)
 
         lli = ll_i2info(inode);
         LASSERT(lli->lli_size_sem_owner != current);
-        cfs_down(&lli->lli_size_sem);
+       down(&lli->lli_size_sem);
         LASSERT(lli->lli_size_sem_owner == NULL);
         lli->lli_size_sem_owner = current;
 }
@@ -1664,7 +1679,7 @@ void ll_inode_size_unlock(struct inode *inode)
         lli = ll_i2info(inode);
         LASSERT(lli->lli_size_sem_owner == current);
         lli->lli_size_sem_owner = NULL;
-        cfs_up(&lli->lli_size_sem);
+       up(&lli->lli_size_sem);
 }
 
 void ll_update_inode(struct inode *inode, struct lustre_md *md)
@@ -1676,21 +1691,9 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
 
        LASSERT ((lsm != NULL) == ((body->valid & OBD_MD_FLEASIZE) != 0));
        if (lsm != NULL) {
-               LASSERT(S_ISREG(inode->i_mode));
-               CDEBUG(D_INODE, "adding lsm %p to inode %lu/%u(%p)\n",
-                               lsm, inode->i_ino, inode->i_generation, inode);
-               /* cl_file_inode_init must go before lli_has_smd or a race
-                * is possible where client thinks the file has stripes,
-                * but lov raid0 is not setup yet and parallel e.g.
-                * glimpse would try to use uninitialized lov */
-               if (cl_file_inode_init(inode, md) == 0)
-                       lli->lli_has_smd = true;
-
                lli->lli_maxbytes = lsm->lsm_maxbytes;
                if (lli->lli_maxbytes > MAX_LFS_FILESIZE)
                        lli->lli_maxbytes = MAX_LFS_FILESIZE;
-               if (md->lsm != NULL)
-                       obd_free_memmd(ll_i2dtexp(inode), &md->lsm);
        }
 
         if (sbi->ll_flags & LL_SBI_RMT_CLIENT) {
@@ -1698,13 +1701,13 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
                         ll_update_remote_perm(inode, md->remote_perm);
         }
 #ifdef CONFIG_FS_POSIX_ACL
-        else if (body->valid & OBD_MD_FLACL) {
-                cfs_spin_lock(&lli->lli_lock);
-                if (lli->lli_posix_acl)
-                        posix_acl_release(lli->lli_posix_acl);
-                lli->lli_posix_acl = md->posix_acl;
-                cfs_spin_unlock(&lli->lli_lock);
-        }
+       else if (body->valid & OBD_MD_FLACL) {
+               spin_lock(&lli->lli_lock);
+               if (lli->lli_posix_acl)
+                       posix_acl_release(lli->lli_posix_acl);
+               lli->lli_posix_acl = md->posix_acl;
+               spin_unlock(&lli->lli_lock);
+       }
 #endif
         inode->i_ino = cl_fid_build_ino(&body->fid1, 0);
         inode->i_generation = cl_fid_build_gen(&body->fid1);
@@ -1867,14 +1870,8 @@ void ll_read_inode2(struct inode *inode, void *opaque)
 void ll_delete_inode(struct inode *inode)
 {
        struct cl_inode_info *lli = cl_i2info(inode);
-       struct ll_sb_info    *sbi = ll_i2sbi(inode);
-       int rc;
        ENTRY;
 
-       rc = obd_fid_delete(sbi->ll_md_exp, ll_inode2fid(inode));
-       if (rc)
-               CERROR("fid_delete() failed, rc %d\n", rc);
-
        if (S_ISREG(inode->i_mode) && lli->lli_clob != NULL)
                /* discard all dirty pages before truncating them, required by
                 * osc_extent implementation at LU-1030. */
@@ -1895,11 +1892,9 @@ void ll_delete_inode(struct inode *inode)
         /* Workaround end */
 
 #ifdef HAVE_SBOPS_EVICT_INODE
-        ll_clear_inode(inode);
-        end_writeback(inode);
-#else
-        clear_inode(inode);
+       ll_clear_inode(inode);
 #endif
+       clear_inode(inode);
 
         EXIT;
 }
@@ -2117,13 +2112,11 @@ int ll_remount_fs(struct super_block *sb, int *flags, char *data)
         return 0;
 }
 
-int ll_prep_inode(struct inode **inode,
-                  struct ptlrpc_request *req,
-                  struct super_block *sb)
+int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req,
+                 struct super_block *sb, struct lookup_intent *it)
 {
        struct ll_sb_info *sbi = NULL;
        struct lustre_md md;
-       __u64 ibits;
         int rc;
         ENTRY;
 
@@ -2147,8 +2140,6 @@ int ll_prep_inode(struct inode **inode,
 
                 *inode = ll_iget(sb, cl_fid_build_ino(&md.body->fid1, 0), &md);
                 if (*inode == NULL || IS_ERR(*inode)) {
-                        if (md.lsm)
-                                obd_free_memmd(sbi->ll_dt_exp, &md.lsm);
 #ifdef CONFIG_FS_POSIX_ACL
                         if (md.posix_acl) {
                                 posix_acl_release(md.posix_acl);
@@ -2162,16 +2153,37 @@ int ll_prep_inode(struct inode **inode,
                 }
         }
 
-       /* sanity check for LAYOUT lock. */
-       ibits = MDS_INODELOCK_LAYOUT;
-       if (S_ISREG(md.body->mode) && sbi->ll_flags & LL_SBI_LAYOUT_LOCK &&
-           md.lsm != NULL && !ll_have_md_lock(*inode, &ibits, LCK_MINMODE)) {
-               CERROR("%s: inode "DFID" (%p) layout lock not granted.\n",
-                       ll_get_fsname(sb, NULL, 0),
-                       PFID(ll_inode2fid(*inode)), *inode);
+       /* Handling piggyback layout lock.
+        * Layout lock can be piggybacked by getattr and open request.
+        * The lsm can be applied to inode only if it comes with a layout lock
+        * otherwise correct layout may be overwritten, for example:
+        * 1. proc1: mdt returns a lsm but not granting layout
+        * 2. layout was changed by another client
+        * 3. proc2: refresh layout and layout lock granted
+        * 4. proc1: to apply a stale layout */
+       if (it != NULL && it->d.lustre.it_lock_mode != 0) {
+               struct lustre_handle lockh;
+               struct ldlm_lock *lock;
+
+               lockh.cookie = it->d.lustre.it_lock_handle;
+               lock = ldlm_handle2lock(&lockh);
+               LASSERT(lock != NULL);
+               if (ldlm_has_layout(lock)) {
+                       struct cl_object_conf conf;
+
+                       memset(&conf, 0, sizeof(conf));
+                       conf.coc_opc = OBJECT_CONF_SET;
+                       conf.coc_inode = *inode;
+                       conf.coc_lock = lock;
+                       conf.u.coc_md = &md;
+                       (void)ll_layout_conf(*inode, &conf);
+               }
+               LDLM_LOCK_PUT(lock);
        }
 
 out:
+       if (md.lsm != NULL)
+               obd_free_memmd(sbi->ll_dt_exp, &md.lsm);
        md_free_lustre_md(sbi->ll_md_exp, &md);
        RETURN(rc);
 }
@@ -2299,14 +2311,18 @@ struct md_op_data * ll_prep_md_op_data(struct md_op_data *op_data,
            !ll_i2info(i2)->lli_has_smd) {
                struct ll_inode_info *lli = ll_i2info(i2);
 
-               cfs_spin_lock(&lli->lli_lock);
+               spin_lock(&lli->lli_lock);
                if (likely(!lli->lli_has_smd && !fid_is_zero(&lli->lli_pfid)))
-                        op_data->op_fid1 = lli->lli_pfid;
-                cfs_spin_unlock(&lli->lli_lock);
-                /** We ignore parent's capability temporary. */
-        }
+                       op_data->op_fid1 = lli->lli_pfid;
+               spin_unlock(&lli->lli_lock);
+               /** We ignore parent's capability temporary. */
+       }
+
+       /* When called by ll_setattr_raw, file is i1. */
+       if (LLIF_DATA_MODIFIED & ll_i2info(i1)->lli_flags)
+               op_data->op_bias |= MDS_DATA_MODIFIED;
 
-        return op_data;
+       return op_data;
 }
 
 void ll_finish_md_op_data(struct md_op_data *op_data)
@@ -2316,12 +2332,21 @@ void ll_finish_md_op_data(struct md_op_data *op_data)
         OBD_FREE_PTR(op_data);
 }
 
+#ifdef HAVE_SUPEROPS_USE_DENTRY
+int ll_show_options(struct seq_file *seq, struct dentry *dentry)
+#else
 int ll_show_options(struct seq_file *seq, struct vfsmount *vfs)
+#endif
 {
         struct ll_sb_info *sbi;
 
-        LASSERT((seq != NULL) && (vfs != NULL));
-        sbi = ll_s2sbi(vfs->mnt_sb);
+#ifdef HAVE_SUPEROPS_USE_DENTRY
+       LASSERT((seq != NULL) && (dentry != NULL));
+       sbi = ll_s2sbi(dentry->d_sb);
+#else
+       LASSERT((seq != NULL) && (vfs != NULL));
+       sbi = ll_s2sbi(vfs->mnt_sb);
+#endif
 
         if (sbi->ll_flags & LL_SBI_NOLCK)
                 seq_puts(seq, ",nolock");
@@ -2428,7 +2453,8 @@ void ll_dirty_page_discard_warn(cfs_page_t *page, int ioret)
        struct dentry *dentry = NULL;
        struct ccc_object *obj = cl_inode2ccc(page->mapping->host);
 
-       buf = (char *)__get_free_page(GFP_KERNEL);
+       /* this can be called inside spin lock so use GFP_ATOMIC. */
+       buf = (char *)__get_free_page(GFP_ATOMIC);
        if (buf != NULL) {
                dentry = d_find_alias(page->mapping->host);
                if (dentry != NULL)