Whamcloud - gitweb
LU-11595 mdt: fix read-on-open for big PAGE_SIZE
[fs/lustre-release.git] / lustre / llite / file.c
index 157bd4b..f866fba 100644 (file)
@@ -443,8 +443,26 @@ void ll_dom_finish_open(struct inode *inode, struct ptlrpc_request *req,
        if (rnb == NULL || rnb->rnb_len == 0)
                RETURN_EXIT;
 
-       CDEBUG(D_INFO, "Get data buffer along with open, len %i, i_size %llu\n",
-              rnb->rnb_len, i_size_read(inode));
+       /* LU-11595: Server may return whole file and that is OK always or
+        * it may return just file tail and its offset must be aligned with
+        * client PAGE_SIZE to be used on that client, if server's PAGE_SIZE is
+        * smaller then offset may be not aligned and that data is just ignored.
+        */
+       if (rnb->rnb_offset % PAGE_SIZE)
+               RETURN_EXIT;
+
+       /* Server returns whole file or just file tail if it fills in
+        * reply buffer, in both cases total size should be inode size.
+        */
+       if (rnb->rnb_offset + rnb->rnb_len < i_size_read(inode)) {
+               CERROR("%s: server returns off/len %llu/%u < i_size %llu\n",
+                      ll_get_fsname(inode->i_sb, NULL, 0), rnb->rnb_offset,
+                      rnb->rnb_len, i_size_read(inode));
+               RETURN_EXIT;
+       }
+
+       CDEBUG(D_INFO, "Get data along with open at %llu len %i, i_size %llu\n",
+              rnb->rnb_offset, rnb->rnb_len, i_size_read(inode));
 
        data = (char *)rnb + sizeof(*rnb);
 
@@ -4914,7 +4932,6 @@ static int ll_layout_fetch(struct inode *inode, struct ldlm_lock *lock)
 {
        struct ll_sb_info *sbi = ll_i2sbi(inode);
        struct ptlrpc_request *req;
-       struct mdt_body *body;
        void *lvbdata;
        void *lmm;
        int lmmsize;
@@ -4934,17 +4951,16 @@ static int ll_layout_fetch(struct inode *inode, struct ldlm_lock *lock)
         * layout here. Please note that we can't use the LVB buffer in
         * completion AST because it doesn't have a large enough buffer */
        rc = ll_get_default_mdsize(sbi, &lmmsize);
-       if (rc == 0)
-               rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode),
-                               OBD_MD_FLXATTR, XATTR_NAME_LOV, lmmsize, &req);
        if (rc < 0)
                RETURN(rc);
 
-       body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
-       if (body == NULL)
-               GOTO(out, rc = -EPROTO);
+       rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), OBD_MD_FLXATTR,
+                        XATTR_NAME_LOV, lmmsize, &req);
+       if (rc < 0)
+               RETURN(rc);
 
-       lmmsize = body->mbo_eadatasize;
+       lmmsize = rc;
+       rc = 0;
        if (lmmsize == 0) /* empty layout */
                GOTO(out, rc = 0);