Whamcloud - gitweb
LU-3321 clio: revert LU-2622 for removing global env list
[fs/lustre-release.git] / lustre / liblustre / rw.c
index 6c848de..2fefc31 100644 (file)
@@ -1,6 +1,4 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
  * GPL HEADER START
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2013, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 #include <fcntl.h>
 #include <sys/uio.h>
 
-#include <sysio.h>
-#ifdef HAVE_XTIO_H
-#include <xtio.h>
-#endif
-#include <fs.h>
-#include <mount.h>
-#include <inode.h>
-#ifdef HAVE_FILE_H
-#include <file.h>
-#endif
-
 #include "llite_lib.h"
 
 typedef ssize_t llu_file_piov_t(const struct iovec *iovec, int iovlen,
@@ -69,11 +58,10 @@ typedef ssize_t llu_file_piov_t(const struct iovec *iovec, int iovlen,
 
 size_t llap_cookie_size;
 
-static int llu_lock_to_stripe_offset(struct inode *inode, struct ldlm_lock *lock)
+static int llu_lock_to_stripe_offset(struct obd_export *exp,
+                                    struct lov_stripe_md *lsm,
+                                    struct ldlm_lock *lock)
 {
-        struct llu_inode_info *lli = llu_i2info(inode);
-        struct lov_stripe_md *lsm = lli->lli_smd;
-        struct obd_export *exp = llu_i2obdexp(inode);
         struct {
                 char name[16];
                 struct ldlm_lock *lock;
@@ -82,17 +70,17 @@ static int llu_lock_to_stripe_offset(struct inode *inode, struct ldlm_lock *lock
         int rc;
         ENTRY;
 
-        if (lsm->lsm_stripe_count == 1)
-                RETURN(0);
+       if (lsm == NULL || lsm->lsm_stripe_count == 1)
+               RETURN(0);
 
         /* get our offset in the lov */
-        rc = obd_get_info(exp, sizeof(key), &key, &vallen, &stripe, lsm);
+        rc = obd_get_info(NULL, exp, sizeof(key), &key, &vallen, &stripe, lsm);
         if (rc != 0) {
                 CERROR("obd_get_info: rc = %d\n", rc);
                 LBUG();
         }
         LASSERT(stripe < lsm->lsm_stripe_count);
-        RETURN(stripe);
+       RETURN(stripe);
 }
 
 int llu_extent_lock_cancel_cb(struct ldlm_lock *lock,
@@ -111,7 +99,7 @@ int llu_extent_lock_cancel_cb(struct ldlm_lock *lock,
         switch (flag) {
         case LDLM_CB_BLOCKING:
                 ldlm_lock2handle(lock, &lockh);
-                rc = ldlm_cli_cancel(&lockh);
+               rc = ldlm_cli_cancel(&lockh, 0);
                 if (rc != ELDLM_OK)
                         CERROR("ldlm_cli_cancel failed: %d\n", rc);
                 break;
@@ -132,11 +120,15 @@ int llu_extent_lock_cancel_cb(struct ldlm_lock *lock,
                 lli= llu_i2info(inode);
                 if (!lli)
                         goto iput;
-                if (!lli->lli_smd)
-                        goto iput;
-                lsm = lli->lli_smd;
+               if (!lli->lli_has_smd)
+                       goto iput;
 
-                stripe = llu_lock_to_stripe_offset(inode, lock);
+               lsm = ccc_inode_lsm_get(inode);
+               if (lsm == NULL)
+                       goto iput;
+
+                stripe = llu_lock_to_stripe_offset(llu_i2obdexp(inode),
+                                                  lsm, lock);
                 lock_res_and_lock(lock);
                 kms = ldlm_extent_shift_kms(lock,
                                             lsm->lsm_oinfo[stripe]->loi_kms);
@@ -145,6 +137,7 @@ int llu_extent_lock_cancel_cb(struct ldlm_lock *lock,
                         LDLM_DEBUG(lock, "updating kms from "LPU64" to "LPU64,
                                    lsm->lsm_oinfo[stripe]->loi_kms, kms);
                 loi_kms_set(lsm->lsm_oinfo[stripe], kms);
+               ccc_inode_lsm_put(inode, lsm);
 iput:
                 I_RELE(inode);
                 break;
@@ -158,10 +151,11 @@ iput:
 
 static int llu_glimpse_callback(struct ldlm_lock *lock, void *reqp)
 {
-        struct ptlrpc_request *req = reqp;
-        struct inode *inode = llu_inode_from_lock(lock);
-        struct llu_inode_info *lli;
-        struct ost_lvb *lvb;
+       struct ptlrpc_request *req = reqp;
+       struct inode *inode = llu_inode_from_lock(lock);
+       struct llu_inode_info *lli;
+       struct ost_lvb *lvb;
+       struct lov_stripe_md *lsm;
         int rc, stripe = 0;
         ENTRY;
 
@@ -170,26 +164,32 @@ static int llu_glimpse_callback(struct ldlm_lock *lock, void *reqp)
         lli = llu_i2info(inode);
         if (lli == NULL)
                 GOTO(iput, rc = -ELDLM_NO_LOCK_DATA);
-        if (lli->lli_smd == NULL)
-                GOTO(iput, rc = -ELDLM_NO_LOCK_DATA);
-
-        /* First, find out which stripe index this lock corresponds to. */
-        if (lli->lli_smd->lsm_stripe_count > 1)
-                stripe = llu_lock_to_stripe_offset(inode, lock);
 
         req_capsule_extend(&req->rq_pill, &RQF_LDLM_GL_CALLBACK);
-        req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
-                             sizeof(*lvb));
+       if (exp_connect_lvb_type(req->rq_export))
+               req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
+                                    sizeof(*lvb));
+       else
+               req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
+                                    sizeof(struct ost_lvb_v1));
         rc = req_capsule_server_pack(&req->rq_pill);
         if (rc) {
                 CERROR("failed pack reply: %d\n", rc);
                 GOTO(iput, rc);
         }
 
-        lvb = req_capsule_server_get(&req->rq_pill, &RMF_DLM_LVB);
-        lvb->lvb_size = lli->lli_smd->lsm_oinfo[stripe]->loi_kms;
+       lsm = ccc_inode_lsm_get(inode);
+       if (lsm == NULL)
+               GOTO(iput, rc = -ELDLM_NO_LOCK_DATA);
+
+        /* First, find out which stripe index this lock corresponds to. */
+       stripe = llu_lock_to_stripe_offset(llu_i2obdexp(inode), lsm, lock);
+
+       lvb = req_capsule_server_get(&req->rq_pill, &RMF_DLM_LVB);
+       lvb->lvb_size = lsm->lsm_oinfo[stripe]->loi_kms;
+       ccc_inode_lsm_put(inode, lsm);
 
-        LDLM_DEBUG(lock, "i_size: %llu -> stripe number %u -> kms "LPU64,
+        LDLM_DEBUG(lock, "i_size: "LPU64" -> stripe number %u -> kms "LPU64,
                    (__u64)llu_i2stat(inode)->st_size, stripe,lvb->lvb_size);
  iput:
         I_RELE(inode);
@@ -203,27 +203,43 @@ static int llu_glimpse_callback(struct ldlm_lock *lock, void *reqp)
         return rc;
 }
 
-int llu_merge_lvb(struct inode *inode)
+int llu_merge_lvb(const struct lu_env *env, struct inode *inode)
 {
-        struct llu_inode_info *lli = llu_i2info(inode);
-        struct llu_sb_info *sbi = llu_i2sbi(inode);
-        struct intnl_stat *st = llu_i2stat(inode);
-        struct ost_lvb lvb;
-        int rc;
-        ENTRY;
-
-        inode_init_lvb(inode, &lvb);
-        rc = obd_merge_lvb(sbi->ll_dt_exp, lli->lli_smd, &lvb, 0);
-        st->st_size = lvb.lvb_size;
-        st->st_blocks = lvb.lvb_blocks;
-        /* handle st_blocks overflow gracefully */
-        if (st->st_blocks < lvb.lvb_blocks)
-                st->st_blocks = ~0UL;
-        st->st_mtime = lvb.lvb_mtime;
-        st->st_atime = lvb.lvb_atime;
-        st->st_ctime = lvb.lvb_ctime;
-
-        RETURN(rc);
+       struct llu_inode_info *lli = llu_i2info(inode);
+       struct cl_object *obj = lli->lli_clob;
+       struct intnl_stat *st = llu_i2stat(inode);
+       struct cl_attr *attr = ccc_env_thread_attr(env);
+       struct ost_lvb lvb;
+       int rc;
+       ENTRY;
+
+       /* merge timestamps the most recently obtained from mds with
+          timestamps obtained from osts */
+       LTIME_S(inode->i_atime) = lli->lli_lvb.lvb_atime;
+       LTIME_S(inode->i_mtime) = lli->lli_lvb.lvb_mtime;
+       LTIME_S(inode->i_ctime) = lli->lli_lvb.lvb_ctime;
+
+       inode_init_lvb(inode, &lvb);
+
+       cl_object_attr_lock(obj);
+       rc = cl_object_attr_get(env, obj, attr);
+       cl_object_attr_unlock(obj);
+       if (rc == 0) {
+               if (lvb.lvb_atime < attr->cat_atime)
+                       lvb.lvb_atime = attr->cat_atime;
+               if (lvb.lvb_ctime < attr->cat_ctime)
+                       lvb.lvb_ctime = attr->cat_ctime;
+               if (lvb.lvb_mtime < attr->cat_mtime)
+                       lvb.lvb_mtime = attr->cat_mtime;
+
+               st->st_size = lvb.lvb_size;
+               st->st_blocks = lvb.lvb_blocks;
+               st->st_mtime = lvb.lvb_mtime;
+               st->st_atime = lvb.lvb_atime;
+               st->st_ctime = lvb.lvb_ctime;
+       }
+
+       RETURN(rc);
 }
 
 int llu_extent_lock(struct ll_file_data *fd, struct inode *inode,
@@ -247,7 +263,7 @@ int llu_extent_lock(struct ll_file_data *fd, struct inode *inode,
             (sbi->ll_flags & LL_SBI_NOLCK) || mode == LCK_NL)
                 RETURN(0);
 
-        CDEBUG(D_DLMTRACE, "Locking inode %llu, start "LPU64" end "LPU64"\n",
+        CDEBUG(D_DLMTRACE, "Locking inode "LPU64", start "LPU64" end "LPU64"\n",
                (__u64)st->st_ino, policy->l_extent.start,
                policy->l_extent.end);
 
@@ -333,8 +349,8 @@ ssize_t llu_file_prwv(const struct iovec *iovec, int iovlen,
         if (IS_ERR(env))
                 RETURN(PTR_ERR(env));
 
+        /* Do NOT call "ccc_env_thread_io()" again to prevent reinitializing */
         io = &ccc_env_info(env)->cti_io;
-
         if (cl_io_rw_init(env, io, session->lis_cmd == OBD_BRW_WRITE?CIT_WRITE:
                                                                       CIT_READ,
                           pos, len) == 0) {
@@ -344,6 +360,7 @@ ssize_t llu_file_prwv(const struct iovec *iovec, int iovlen,
                 /* XXX this is not right: cio->cui_iov can be modified. */
                 cio->cui_iov = (struct iovec *)iovec;
                 cio->cui_nrsegs = iovlen;
+                cio->cui_tot_nrsegs = iovlen;
                 sio->sio_session = session;
                 err = cl_io_loop(env, io);
         } else {
@@ -428,8 +445,6 @@ void llu_io_init(struct cl_io *io, struct inode *inode, int write)
 {
         struct llu_inode_info *lli = llu_i2info(inode);
 
-        memset(io, 0, sizeof *io);
-
         io->u.ci_rw.crw_nonblock = lli->lli_open_flags & O_NONBLOCK;
         if (write)
                 io->u.ci_wr.wr_append = lli->lli_open_flags & O_APPEND;
@@ -457,7 +472,7 @@ int llu_iop_read(struct inode *ino,
         if (IS_ERR(env))
                 RETURN(PTR_ERR(env));
 
-        io = &ccc_env_info(env)->cti_io;
+        io = ccc_env_thread_io(env);
         llu_io_init(io, ino, 0);
 
         ret = llu_file_rwx(ino, ioctx, 1);
@@ -481,7 +496,7 @@ int llu_iop_write(struct inode *ino,
         if (IS_ERR(env))
                 RETURN(PTR_ERR(env));
 
-        io = &ccc_env_info(env)->cti_io;
+        io = ccc_env_thread_io(env);
         llu_io_init(io, ino, 1);
 
         ret = llu_file_rwx(ino, ioctx, 0);