Whamcloud - gitweb
LU-10948 llite: Revalidate dentries in ll_intent_file_open
[fs/lustre-release.git] / lustre / llite / file.c
index 4e063f5..6f26724 100644 (file)
@@ -413,27 +413,14 @@ void ll_dom_finish_open(struct inode *inode, struct ptlrpc_request *req,
        struct page *vmpage;
        struct niobuf_remote *rnb;
        char *data;
-       struct lustre_handle lockh;
-       struct ldlm_lock *lock;
        unsigned long index, start;
        struct niobuf_local lnb;
-       bool dom_lock = false;
 
        ENTRY;
 
        if (obj == NULL)
                RETURN_EXIT;
 
-       if (it->it_lock_mode != 0) {
-               lockh.cookie = it->it_lock_handle;
-               lock = ldlm_handle2lock(&lockh);
-               if (lock != NULL)
-                       dom_lock = ldlm_has_dom(lock);
-               LDLM_LOCK_PUT(lock);
-       }
-       if (!dom_lock)
-               RETURN_EXIT;
-
        if (!req_capsule_has_field(&req->rq_pill, &RMF_NIOBUF_INLINE,
                                   RCL_SERVER))
                RETURN_EXIT;
@@ -509,12 +496,14 @@ static int ll_intent_file_open(struct dentry *de, void *lmm, int lmmsize,
 
        /* if server supports open-by-fid, or file name is invalid, don't pack
         * name in open request */
-       if (!(exp_connect_flags(sbi->ll_md_exp) & OBD_CONNECT_OPEN_BY_FID)) {
+       if (OBD_FAIL_CHECK(OBD_FAIL_LLITE_OPEN_BY_NAME) ||
+           !(exp_connect_flags(sbi->ll_md_exp) & OBD_CONNECT_OPEN_BY_FID)) {
 retry:
                len = de->d_name.len;
-               name = kmalloc(len, GFP_NOFS);
+               name = kmalloc(len + 1, GFP_NOFS);
                if (!name)
                        RETURN(-ENOMEM);
+
                /* race here */
                spin_lock(&de->d_lock);
                if (len != de->d_name.len) {
@@ -523,12 +512,12 @@ retry:
                        goto retry;
                }
                memcpy(name, de->d_name.name, len);
+               name[len] = '\0';
                spin_unlock(&de->d_lock);
 
                if (!lu_name_is_valid_2(name, len)) {
                        kfree(name);
-                       name = NULL;
-                       len = 0;
+                       RETURN(-ESTALE);
                }
        }
 
@@ -568,8 +557,27 @@ retry:
        rc = ll_prep_inode(&de->d_inode, req, NULL, itp);
 
        if (!rc && itp->it_lock_mode) {
-               ll_dom_finish_open(de->d_inode, req, itp);
+               struct lustre_handle handle = {.cookie = itp->it_lock_handle};
+               struct ldlm_lock *lock;
+               bool has_dom_bit = false;
+
+               /* If we got a lock back and it has a LOOKUP bit set,
+                * make sure the dentry is marked as valid so we can find it.
+                * We don't need to care about actual hashing since other bits
+                * of kernel will deal with that later.
+                */
+               lock = ldlm_handle2lock(&handle);
+               if (lock) {
+                       has_dom_bit = ldlm_has_dom(lock);
+                       if (lock->l_policy_data.l_inodebits.bits &
+                           MDS_INODELOCK_LOOKUP)
+                               d_lustre_revalidate(de);
+
+                       LDLM_LOCK_PUT(lock);
+               }
                ll_set_lock_data(sbi->ll_md_exp, de->d_inode, itp, NULL);
+               if (has_dom_bit)
+                       ll_dom_finish_open(de->d_inode, req, itp);
        }
 
 out:
@@ -1610,6 +1618,8 @@ static ssize_t ll_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
        ssize_t rc2;
        __u16 refcheck;
 
+       ll_ras_enter(iocb->ki_filp);
+
        result = ll_do_fast_read(iocb, to);
        if (result < 0 || iov_iter_count(to) == 0)
                GOTO(out, result);
@@ -1887,6 +1897,8 @@ static ssize_t ll_file_splice_read(struct file *in_file, loff_t *ppos,
        __u16               refcheck;
         ENTRY;
 
+       ll_ras_enter(in_file);
+
         env = cl_env_get(&refcheck);
         if (IS_ERR(env))
                 RETURN(PTR_ERR(env));
@@ -1969,7 +1981,8 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
 
        if (lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_V1) &&
            lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_V3) &&
-           lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_COMP_V1))
+           lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_COMP_V1) &&
+           lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_FOREIGN))
                GOTO(out, rc = -EPROTO);
 
         /*
@@ -2008,6 +2021,15 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
                           cpu_to_le32(LOV_MAGIC_COMP_V1)) {
                        lustre_swab_lov_comp_md_v1(
                                        (struct lov_comp_md_v1 *)lmm);
+               } else if (lmm->lmm_magic ==
+                          cpu_to_le32(LOV_MAGIC_FOREIGN)) {
+                       struct lov_foreign_md *lfm;
+
+                       lfm = (struct lov_foreign_md *)lmm;
+                       __swab32s(&lfm->lfm_magic);
+                       __swab32s(&lfm->lfm_length);
+                       __swab32s(&lfm->lfm_type);
+                       __swab32s(&lfm->lfm_flags);
                }
        }
 
@@ -3285,7 +3307,7 @@ static void ll_heat_get(struct inode *inode, struct lu_heat *heat)
        spin_unlock(&lli->lli_heat_lock);
 }
 
-static int ll_heat_set(struct inode *inode, __u64 flags)
+static int ll_heat_set(struct inode *inode, enum lu_heat_flag flags)
 {
        struct ll_inode_info *lli = ll_i2info(inode);
        int rc = 0;
@@ -4458,6 +4480,11 @@ static int ll_merge_md_attr(struct inode *inode)
        int rc;
 
        LASSERT(lli->lli_lsm_md != NULL);
+
+       /* foreign dir is not striped dir */
+       if (lli->lli_lsm_md->lsm_md_magic == LMV_MAGIC_FOREIGN)
+               RETURN(0);
+
        down_read(&lli->lli_lsm_sem);
        rc = md_merge_attr(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md,
                           &attr, ll_md_blocking_ast);