Whamcloud - gitweb
LU-4603 lmv: a few fixes about readdir of striped dir.
[fs/lustre-release.git] / lustre / llite / dir.c
index 9189cbd..22c4a42 100644 (file)
@@ -51,8 +51,8 @@
 #include <lustre/lustre_idl.h>
 #include <obd_support.h>
 #include <obd_class.h>
+#include <lustre_ioctl.h>
 #include <lustre_lib.h>
-#include <lustre/lustre_idl.h>
 #include <lustre_lite.h>
 #include <lustre_dlm.h>
 #include <lustre_fid.h>
@@ -162,16 +162,18 @@ struct lu_dirent *ll_dir_entry_start(struct inode *dir,
                                     struct md_op_data *op_data,
                                     struct page **ppage)
 {
-       struct lu_dirent *entry;
+       struct lu_dirent *entry = NULL;
        struct md_callback cb_op;
        int rc;
+       ENTRY;
 
        LASSERT(*ppage == NULL);
        cb_op.md_blocking_ast = ll_md_blocking_ast;
+       op_data->op_cli_flags &= ~CLI_NEXT_ENTRY;
        rc = md_read_entry(ll_i2mdexp(dir), op_data, &cb_op, &entry, ppage);
        if (rc != 0)
                entry = ERR_PTR(rc);
-       return entry;
+       RETURN(entry);
 }
 
 struct lu_dirent *ll_dir_entry_next(struct inode *dir,
@@ -179,20 +181,25 @@ struct lu_dirent *ll_dir_entry_next(struct inode *dir,
                                    struct lu_dirent *ent,
                                    struct page **ppage)
 {
-       struct lu_dirent *entry;
+       struct lu_dirent *entry = NULL;
        struct md_callback cb_op;
        int rc;
+       ENTRY;
 
-       LASSERT(*ppage != NULL);
-       cb_op.md_blocking_ast = ll_md_blocking_ast;
        op_data->op_hash_offset = le64_to_cpu(ent->lde_hash);
+
+       /* release last page */
+       LASSERT(*ppage != NULL);
        kunmap(*ppage);
        page_cache_release(*ppage);
-       *ppage = NULL;
+
+       cb_op.md_blocking_ast = ll_md_blocking_ast;
+       op_data->op_cli_flags |= CLI_NEXT_ENTRY;
        rc = md_read_entry(ll_i2mdexp(dir), op_data, &cb_op, &entry, ppage);
        if (rc != 0)
                entry = ERR_PTR(rc);
-       return entry;
+
+       RETURN(entry);
 }
 
 #ifdef HAVE_DIR_CONTEXT
@@ -212,7 +219,6 @@ int ll_dir_read(struct inode *inode, struct md_op_data *op_data,
        int                     done = 0;
        int                     rc = 0;
        __u64                   hash = MDS_DIR_END_OFF;
-       __u64                   last_hash = MDS_DIR_END_OFF;
        struct page             *page = NULL;
        ENTRY;
 
@@ -260,15 +266,15 @@ int ll_dir_read(struct inode *inode, struct md_op_data *op_data,
 #endif
                if (done) {
                        if (op_data->op_hash_offset != MDS_DIR_END_OFF)
-                               op_data->op_hash_offset = last_hash;
+                               op_data->op_hash_offset = hash;
                        break;
-               } else {
-                       last_hash = hash;
                }
        }
 
        if (IS_ERR(ent))
                rc = PTR_ERR(ent);
+       else if (ent == NULL)
+               op_data->op_hash_offset = MDS_DIR_END_OFF;
 
        if (page != NULL) {
                kunmap(page);
@@ -315,8 +321,29 @@ static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
        if (IS_ERR(op_data))
                GOTO(out, rc = PTR_ERR(op_data));
 
+       if (unlikely(op_data->op_mea1 != NULL)) {
+               /* This is only needed for striped dir to fill ..,
+                * see lmv_read_entry */
+               if (filp->f_dentry->d_parent != NULL &&
+                   filp->f_dentry->d_parent->d_inode != NULL) {
+                       __u64 ibits = MDS_INODELOCK_UPDATE;
+                       struct inode *parent =
+                               filp->f_dentry->d_parent->d_inode;
+
+                       if (ll_have_md_lock(parent, &ibits, LCK_MINMODE))
+                               op_data->op_fid3 = *ll_inode2fid(parent);
+               }
+
+               /* If it can not find in cache, do lookup .. on the master
+                * object */
+               if (fid_is_zero(&op_data->op_fid3)) {
+                       rc = ll_dir_get_parent_fid(inode, &op_data->op_fid3);
+                       if (rc != 0)
+                               RETURN(rc);
+               }
+       }
        op_data->op_hash_offset = pos;
-       op_data->op_max_pages = sbi->ll_md_brw_size >> PAGE_CACHE_SHIFT;
+       op_data->op_max_pages = sbi->ll_md_brw_pages;
 #ifdef HAVE_DIR_CONTEXT
        ctx->pos = pos;
        rc = ll_dir_read(inode, op_data, ctx);
@@ -353,7 +380,7 @@ out:
        RETURN(rc);
 }
 
-int ll_send_mgc_param(struct obd_export *mgc, char *string)
+static int ll_send_mgc_param(struct obd_export *mgc, char *string)
 {
         struct mgs_send_param *msp;
         int rc = 0;
@@ -590,9 +617,8 @@ int ll_dir_getstripe(struct inode *inode, void **plmm, int *plmm_size,
                if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
                        lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
                break;
-       case LMV_MAGIC:
-       case LMV_MAGIC_MIGRATE:
-               if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
+       case LMV_MAGIC_V1:
+               if (LMV_MAGIC != cpu_to_le32(LMV_MAGIC))
                        lustre_swab_lmv_mds_md((union lmv_mds_md *)lmm);
                break;
        case LMV_USER_MAGIC:
@@ -1184,7 +1210,7 @@ lmv_out_free:
 
                rc = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize, &request,
                                      valid);
-               if (rc != 0 && rc != -ENODATA)
+               if (rc != 0)
                        GOTO(finish_req, rc);
 
                /* Get default LMV EA */
@@ -1201,38 +1227,29 @@ lmv_out_free:
                        GOTO(finish_req, rc);
                }
 
-               /* Get normal LMV EA */
-               if (rc == -ENODATA) {
-                       stripe_count = 1;
-               } else {
-                       LASSERT(lmm != NULL);
-                       stripe_count = lmv_mds_md_stripe_count_get(lmm);
-               }
-
+               stripe_count = lmv_mds_md_stripe_count_get(lmm);
                lum_size = lmv_user_md_size(stripe_count, LMV_MAGIC_V1);
                OBD_ALLOC(tmp, lum_size);
                if (tmp == NULL)
                        GOTO(finish_req, rc = -ENOMEM);
 
-               tmp->lum_magic = LMV_MAGIC_V1;
-               tmp->lum_stripe_count = 1;
                mdt_index = ll_get_mdt_idx(inode);
                if (mdt_index < 0)
                        GOTO(out_tmp, rc = -ENOMEM);
+
+               tmp->lum_magic = LMV_MAGIC_V1;
+               tmp->lum_stripe_count = 0;
                tmp->lum_stripe_offset = mdt_index;
-               tmp->lum_objects[0].lum_mds = mdt_index;
-               tmp->lum_objects[0].lum_fid = *ll_inode2fid(inode);
-               for (i = 1; i < stripe_count; i++) {
-                       struct lmv_mds_md_v1 *lmm1;
-
-                       lmm1 = &lmm->lmv_md_v1;
-                       mdt_index = ll_get_mdt_idx_by_fid(sbi,
-                                                    &lmm1->lmv_stripe_fids[i]);
+               for (i = 0; i < stripe_count; i++) {
+                       struct lu_fid   *fid;
+
+                       fid = &lmm->lmv_md_v1.lmv_stripe_fids[i];
+                       mdt_index = ll_get_mdt_idx_by_fid(sbi, fid);
                        if (mdt_index < 0)
                                GOTO(out_tmp, rc = mdt_index);
 
                        tmp->lum_objects[i].lum_mds = mdt_index;
-                       tmp->lum_objects[i].lum_fid = lmm1->lmv_stripe_fids[i];
+                       tmp->lum_objects[i].lum_fid = *fid;
                        tmp->lum_stripe_count++;
                }
 
@@ -1274,8 +1291,8 @@ out_rmdir:
        }
        case LL_IOC_LOV_SWAP_LAYOUTS:
                RETURN(-EPERM);
-        case LL_IOC_OBD_STATFS:
-                RETURN(ll_obd_statfs(inode, (void *)arg));
+       case IOC_OBD_STATFS:
+               RETURN(ll_obd_statfs(inode, (void *)arg));
         case LL_IOC_LOV_GETSTRIPE:
         case LL_IOC_MDC_GETINFO:
         case IOC_MDC_GETFILEINFO:
@@ -1426,10 +1443,7 @@ out_rmdir:
                 OBD_FREE_LARGE(lmm, lmmsize);
                 return rc;
         }
-        case OBD_IOC_LLOG_CATINFO: {
-               RETURN(-EOPNOTSUPP);
-        }
-        case OBD_IOC_QUOTACHECK: {
+       case OBD_IOC_QUOTACHECK: {
                 struct obd_quotactl *oqctl;
                 int error = 0;
 
@@ -1454,7 +1468,7 @@ out_rmdir:
                 OBD_FREE_PTR(oqctl);
                 return error ?: rc;
         }
-        case OBD_IOC_POLL_QUOTACHECK: {
+       case OBD_IOC_POLL_QUOTACHECK: {
                 struct if_quotacheck *check;
 
                 if (!cfs_capable(CFS_CAP_SYS_ADMIN) ||
@@ -1542,7 +1556,7 @@ out_rmdir:
 #else
 #warning "remove old LL_IOC_QUOTACTL_18 compatibility code"
 #endif /* LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 7, 50, 0) */
-        case LL_IOC_QUOTACTL: {
+       case OBD_IOC_QUOTACTL: {
                 struct if_quotactl *qctl;
 
                 OBD_ALLOC_PTR(qctl);
@@ -1833,19 +1847,19 @@ out:
         return ret;
 }
 
-int ll_dir_open(struct inode *inode, struct file *file)
+static int ll_dir_open(struct inode *inode, struct file *file)
 {
         ENTRY;
         RETURN(ll_file_open(inode, file));
 }
 
-int ll_dir_release(struct inode *inode, struct file *file)
+static int ll_dir_release(struct inode *inode, struct file *file)
 {
         ENTRY;
         RETURN(ll_file_release(inode, file));
 }
 
-struct file_operations ll_dir_operations = {
+const struct file_operations ll_dir_operations = {
        .llseek         = ll_dir_seek,
        .open           = ll_dir_open,
        .release        = ll_dir_release,