Whamcloud - gitweb
Merge "LU-9771 flr: Merge branch 'flr'"
[fs/lustre-release.git] / lustre / llite / file.c
index a3d5b20..2dbabed 100644 (file)
@@ -1099,7 +1099,10 @@ int ll_merge_attr(const struct lu_env *env, struct inode *inode)
        ctime = LTIME_S(inode->i_ctime);
 
        cl_object_attr_lock(obj);
-       rc = cl_object_attr_get(env, obj, attr);
+       if (OBD_FAIL_CHECK(OBD_FAIL_MDC_MERGE))
+               rc = -EINVAL;
+       else
+               rc = cl_object_attr_get(env, obj, attr);
        cl_object_attr_unlock(obj);
 
        if (rc != 0)
@@ -2303,9 +2306,15 @@ int ll_hsm_release(struct inode *inode)
        if (IS_ERR(env))
                GOTO(out, rc = PTR_ERR(env));
 
-       ll_merge_attr(env, inode);
+       rc = ll_merge_attr(env, inode);
        cl_env_put(env, &refcheck);
 
+       /* If error happen, we have the wrong size for a file.
+        * Don't release it.
+        */
+       if (rc != 0)
+               GOTO(out, rc);
+
        /* Release the file.
         * NB: lease lock handle is released in mdc_hsm_release_pack() because
         * we still need it to pack l_remote_handle to MDT. */
@@ -4068,95 +4077,55 @@ static int ll_inode_revalidate_fini(struct inode *inode, int rc)
        return rc;
 }
 
-static int __ll_inode_revalidate(struct dentry *dentry, __u64 ibits)
+static int ll_inode_revalidate(struct dentry *dentry, enum ldlm_intent_flags op)
 {
-        struct inode *inode = dentry->d_inode;
-        struct ptlrpc_request *req = NULL;
-        struct obd_export *exp;
-        int rc = 0;
-        ENTRY;
-
-        LASSERT(inode != NULL);
+       struct inode *inode = dentry->d_inode;
+       struct obd_export *exp = ll_i2mdexp(inode);
+       struct lookup_intent oit = {
+               .it_op = op,
+       };
+       struct ptlrpc_request *req = NULL;
+       struct md_op_data *op_data;
+       int rc = 0;
+       ENTRY;
 
        CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p),name=%s\n",
               PFID(ll_inode2fid(inode)), inode, dentry->d_name.name);
 
-        exp = ll_i2mdexp(inode);
-
-        /* XXX: Enable OBD_CONNECT_ATTRFID to reduce unnecessary getattr RPC.
-         *      But under CMD case, it caused some lock issues, should be fixed
-         *      with new CMD ibits lock. See bug 12718 */
-       if (exp_connect_flags(exp) & OBD_CONNECT_ATTRFID) {
-                struct lookup_intent oit = { .it_op = IT_GETATTR };
-                struct md_op_data *op_data;
-
-                if (ibits == MDS_INODELOCK_LOOKUP)
-                        oit.it_op = IT_LOOKUP;
-
-                /* Call getattr by fid, so do not provide name at all. */
-                op_data = ll_prep_md_op_data(NULL, dentry->d_inode,
-                                             dentry->d_inode, NULL, 0, 0,
-                                             LUSTRE_OPC_ANY, NULL);
-                if (IS_ERR(op_data))
-                        RETURN(PTR_ERR(op_data));
-
-               rc = md_intent_lock(exp, op_data, &oit, &req,
-                                   &ll_md_blocking_ast, 0);
-                ll_finish_md_op_data(op_data);
-                if (rc < 0) {
-                        rc = ll_inode_revalidate_fini(inode, rc);
-                        GOTO (out, rc);
-                }
-
-                rc = ll_revalidate_it_finish(req, &oit, dentry);
-                if (rc != 0) {
-                        ll_intent_release(&oit);
-                        GOTO(out, rc);
-                }
-
-                /* Unlinked? Unhash dentry, so it is not picked up later by
-                   do_lookup() -> ll_revalidate_it(). We cannot use d_drop
-                   here to preserve get_cwd functionality on 2.6.
-                   Bug 10503 */
-               if (!dentry->d_inode->i_nlink) {
-                       ll_lock_dcache(inode);
-                       d_lustre_invalidate(dentry, 0);
-                       ll_unlock_dcache(inode);
-               }
-
-                ll_lookup_finish_locks(&oit, dentry);
-        } else if (!ll_have_md_lock(dentry->d_inode, &ibits, LCK_MINMODE)) {
-               struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode);
-               u64 valid = OBD_MD_FLGETATTR;
-               struct md_op_data *op_data;
-               int ealen = 0;
+       /* Call getattr by fid, so do not provide name at all. */
+       op_data = ll_prep_md_op_data(NULL, inode, inode, NULL, 0, 0,
+                                    LUSTRE_OPC_ANY, NULL);
+       if (IS_ERR(op_data))
+               RETURN(PTR_ERR(op_data));
 
-               if (S_ISREG(inode->i_mode)) {
-                       rc = ll_get_default_mdsize(sbi, &ealen);
-                       if (rc)
-                               RETURN(rc);
-                       valid |= OBD_MD_FLEASIZE | OBD_MD_FLMODEASIZE;
-               }
+       rc = md_intent_lock(exp, op_data, &oit, &req, &ll_md_blocking_ast, 0);
+       ll_finish_md_op_data(op_data);
+       if (rc < 0) {
+               rc = ll_inode_revalidate_fini(inode, rc);
+               GOTO(out, rc);
+       }
 
-                op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL,
-                                             0, ealen, LUSTRE_OPC_ANY,
-                                             NULL);
-                if (IS_ERR(op_data))
-                        RETURN(PTR_ERR(op_data));
+       rc = ll_revalidate_it_finish(req, &oit, dentry);
+       if (rc != 0) {
+               ll_intent_release(&oit);
+               GOTO(out, rc);
+       }
 
-                op_data->op_valid = valid;
-                rc = md_getattr(sbi->ll_md_exp, op_data, &req);
-                ll_finish_md_op_data(op_data);
-                if (rc) {
-                        rc = ll_inode_revalidate_fini(inode, rc);
-                        RETURN(rc);
-                }
+       /* Unlinked? Unhash dentry, so it is not picked up later by
+        * do_lookup() -> ll_revalidate_it(). We cannot use d_drop
+        * here to preserve get_cwd functionality on 2.6.
+        * Bug 10503 */
+       if (!dentry->d_inode->i_nlink) {
+               ll_lock_dcache(inode);
+               d_lustre_invalidate(dentry, 0);
+               ll_unlock_dcache(inode);
+       }
 
-                rc = ll_prep_inode(&inode, req, NULL, NULL);
-        }
+       ll_lookup_finish_locks(&oit, dentry);
 out:
-        ptlrpc_req_finished(req);
-        return rc;
+       ptlrpc_req_finished(req);
+
+       return rc;
 }
 
 static int ll_merge_md_attr(struct inode *inode)
@@ -4181,43 +4150,6 @@ static int ll_merge_md_attr(struct inode *inode)
        RETURN(0);
 }
 
-static int
-ll_inode_revalidate(struct dentry *dentry, __u64 ibits)
-{
-       struct inode    *inode = dentry->d_inode;
-       int              rc;
-       ENTRY;
-
-       rc = __ll_inode_revalidate(dentry, ibits);
-       if (rc != 0)
-               RETURN(rc);
-
-       /* if object isn't regular file, don't validate size */
-       if (!S_ISREG(inode->i_mode)) {
-               if (S_ISDIR(inode->i_mode) &&
-                   ll_i2info(inode)->lli_lsm_md != NULL) {
-                       rc = ll_merge_md_attr(inode);
-                       if (rc != 0)
-                               RETURN(rc);
-               }
-
-               LTIME_S(inode->i_atime) = ll_i2info(inode)->lli_atime;
-               LTIME_S(inode->i_mtime) = ll_i2info(inode)->lli_mtime;
-               LTIME_S(inode->i_ctime) = ll_i2info(inode)->lli_ctime;
-       } else {
-               /* In case of restore, the MDT has the right size and has
-                * already send it back without granting the layout lock,
-                * inode is up-to-date so glimpse is useless.
-                * Also to glimpse we need the layout, in case of a running
-                * restore the MDT holds the layout lock so the glimpse will
-                * block up to the end of restore (getattr will block)
-                */
-               if (!ll_file_test_flag(ll_i2info(inode), LLIF_FILE_RESTORING))
-                       rc = ll_glimpse_size(inode);
-       }
-       RETURN(rc);
-}
-
 static inline dev_t ll_compat_encode_dev(dev_t dev)
 {
        /* The compat_sys_*stat*() syscalls will fail unless the
@@ -4233,24 +4165,49 @@ static inline dev_t ll_compat_encode_dev(dev_t dev)
 #ifdef HAVE_INODEOPS_ENHANCED_GETATTR
 int ll_getattr(const struct path *path, struct kstat *stat,
               u32 request_mask, unsigned int flags)
-
 {
        struct dentry *de = path->dentry;
 #else
 int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat)
 {
 #endif
-        struct inode *inode = de->d_inode;
-        struct ll_sb_info *sbi = ll_i2sbi(inode);
-        struct ll_inode_info *lli = ll_i2info(inode);
-        int res = 0;
+       struct inode *inode = de->d_inode;
+       struct ll_sb_info *sbi = ll_i2sbi(inode);
+       struct ll_inode_info *lli = ll_i2info(inode);
+       int rc;
 
-       res = ll_inode_revalidate(de, MDS_INODELOCK_UPDATE |
-                                     MDS_INODELOCK_LOOKUP);
-        ll_stats_ops_tally(sbi, LPROC_LL_GETATTR, 1);
+       ll_stats_ops_tally(sbi, LPROC_LL_GETATTR, 1);
 
-        if (res)
-                return res;
+       rc = ll_inode_revalidate(de, IT_GETATTR);
+       if (rc < 0)
+               RETURN(rc);
+
+       if (S_ISREG(inode->i_mode)) {
+               /* In case of restore, the MDT has the right size and has
+                * already send it back without granting the layout lock,
+                * inode is up-to-date so glimpse is useless.
+                * Also to glimpse we need the layout, in case of a running
+                * restore the MDT holds the layout lock so the glimpse will
+                * block up to the end of restore (getattr will block)
+                */
+               if (!ll_file_test_flag(lli, LLIF_FILE_RESTORING)) {
+                       rc = ll_glimpse_size(inode);
+                       if (rc < 0)
+                               RETURN(rc);
+               }
+       } else {
+               /* If object isn't regular a file then don't validate size. */
+               if (S_ISDIR(inode->i_mode) &&
+                   lli->lli_lsm_md != NULL) {
+                       rc = ll_merge_md_attr(inode);
+                       if (rc < 0)
+                               RETURN(rc);
+               }
+
+               LTIME_S(inode->i_atime) = lli->lli_atime;
+               LTIME_S(inode->i_mtime) = lli->lli_mtime;
+               LTIME_S(inode->i_ctime) = lli->lli_ctime;
+       }
 
        OBD_FAIL_TIMEOUT(OBD_FAIL_GETATTR_DELAY, 30);
 
@@ -4447,8 +4404,7 @@ int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
         * need to do it before permission check. */
 
         if (inode == inode->i_sb->s_root->d_inode) {
-               rc = __ll_inode_revalidate(inode->i_sb->s_root,
-                                          MDS_INODELOCK_LOOKUP);
+               rc = ll_inode_revalidate(inode->i_sb->s_root, IT_LOOKUP);
                 if (rc)
                         RETURN(rc);
         }