Whamcloud - gitweb
LU-14651 llite: extend inode methods with user namespace arg
[fs/lustre-release.git] / lustre / llite / dir.c
index ad94e5a..ae83d1b 100644 (file)
  *
  */
 struct page *ll_get_dir_page(struct inode *dir, struct md_op_data *op_data,
-                            __u64 offset)
+                            __u64 offset, int *partial_readdir_rc)
 {
-       struct md_callback      cb_op;
-       struct page             *page;
-       int                     rc;
+       struct md_readdir_info mrinfo = {
+                                       .mr_blocking_ast = ll_md_blocking_ast };
+       struct page *page;
+       int rc;
 
-       cb_op.md_blocking_ast = ll_md_blocking_ast;
-       rc = md_read_page(ll_i2mdexp(dir), op_data, &cb_op, offset, &page);
+       rc = md_read_page(ll_i2mdexp(dir), op_data, &mrinfo, offset, &page);
        if (rc != 0)
                return ERR_PTR(rc);
 
+       if (partial_readdir_rc && mrinfo.mr_partial_readdir_rc)
+               *partial_readdir_rc = mrinfo.mr_partial_readdir_rc;
+
        return page;
 }
 
@@ -180,11 +183,11 @@ void ll_release_page(struct inode *inode, struct page *page,
 
 #ifdef HAVE_DIR_CONTEXT
 int ll_dir_read(struct inode *inode, __u64 *ppos, struct md_op_data *op_data,
-               struct dir_context *ctx)
+               struct dir_context *ctx, int *partial_readdir_rc)
 {
 #else
 int ll_dir_read(struct inode *inode, __u64 *ppos, struct md_op_data *op_data,
-               void *cookie, filldir_t filldir)
+               void *cookie, filldir_t filldir, int *partial_readdir_rc)
 {
 #endif
        struct ll_sb_info *sbi = ll_i2sbi(inode);
@@ -203,7 +206,7 @@ int ll_dir_read(struct inode *inode, __u64 *ppos, struct md_op_data *op_data,
                        RETURN(rc);
        }
 
-       page = ll_get_dir_page(inode, op_data, pos);
+       page = ll_get_dir_page(inode, op_data, pos, partial_readdir_rc);
 
        while (rc == 0 && !done) {
                struct lu_dirpage *dp;
@@ -299,7 +302,8 @@ int ll_dir_read(struct inode *inode, __u64 *ppos, struct md_op_data *op_data,
                                        le32_to_cpu(dp->ldp_flags) &
                                        LDF_COLLIDE);
                        next = pos;
-                       page = ll_get_dir_page(inode, op_data, pos);
+                       page = ll_get_dir_page(inode, op_data, pos,
+                                              partial_readdir_rc);
                }
        }
 #ifdef HAVE_DIR_CONTEXT
@@ -325,14 +329,15 @@ static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
        struct md_op_data *op_data;
        struct lu_fid pfid = { 0 };
        ktime_t kstart = ktime_get();
+       /* result of possible partial readdir */
+       int partial_readdir_rc = 0;
        __u64 pos;
        int rc;
+
        ENTRY;
 
-       if (lfd != NULL)
-               pos = lfd->lfd_pos;
-       else
-               pos = 0;
+       LASSERT(lfd != NULL);
+       pos = lfd->lfd_pos;
 
        CDEBUG(D_VFSTRACE,
               "VFS Op:inode="DFID"(%p) pos/size%lu/%llu 32bit_api %d\n",
@@ -391,13 +396,15 @@ static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
 
 #ifdef HAVE_DIR_CONTEXT
        ctx->pos = pos;
-       rc = ll_dir_read(inode, &pos, op_data, ctx);
+       rc = ll_dir_read(inode, &pos, op_data, ctx, &partial_readdir_rc);
        pos = ctx->pos;
 #else
-       rc = ll_dir_read(inode, &pos, op_data, cookie, filldir);
+       rc = ll_dir_read(inode, &pos, op_data, cookie, filldir,
+                        &partial_readdir_rc);
 #endif
-       if (lfd != NULL)
-               lfd->lfd_pos = pos;
+       lfd->lfd_pos = pos;
+       if (!lfd->fd_partial_readdir_rc)
+               lfd->fd_partial_readdir_rc = partial_readdir_rc;
 
        if (pos == MDS_DIR_END_OFF) {
                if (api32)
@@ -511,7 +518,7 @@ static int ll_dir_setdirstripe(struct dentry *dparent, struct lmv_user_md *lump,
        if (IS_ERR(op_data))
                RETURN(PTR_ERR(op_data));
 
-       op_data->op_dir_depth = ll_i2info(parent)->lli_depth;
+       op_data->op_dir_depth = ll_i2info(parent)->lli_dir_depth;
 
        if (ll_sbi_has_encrypt(sbi) &&
            (IS_ENCRYPTED(parent) ||
@@ -1847,7 +1854,11 @@ out_rmdir:
                        st.st_uid       = body->mbo_uid;
                        st.st_gid       = body->mbo_gid;
                        st.st_rdev      = body->mbo_rdev;
-                       st.st_size      = body->mbo_size;
+                       if (llcrypt_require_key(inode) == -ENOKEY)
+                               st.st_size = round_up(st.st_size,
+                                                  LUSTRE_ENCRYPTION_UNIT_SIZE);
+                       else
+                               st.st_size = body->mbo_size;
                        st.st_blksize   = PAGE_SIZE;
                        st.st_blocks    = body->mbo_blocks;
                        st.st_atime     = body->mbo_atime;
@@ -1870,7 +1881,11 @@ out_rmdir:
                        stx.stx_mode = body->mbo_mode;
                        stx.stx_ino = cl_fid_build_ino(&body->mbo_fid1,
                                                       api32);
-                       stx.stx_size = body->mbo_size;
+                       if (llcrypt_require_key(inode) == -ENOKEY)
+                               stx.stx_size = round_up(stx.stx_size,
+                                                  LUSTRE_ENCRYPTION_UNIT_SIZE);
+                       else
+                               stx.stx_size = body->mbo_size;
                        stx.stx_blocks = body->mbo_blocks;
                        stx.stx_atime.tv_sec = body->mbo_atime;
                        stx.stx_ctime.tv_sec = body->mbo_ctime;
@@ -2212,7 +2227,7 @@ migrate_free:
                if (!S_ISREG(inode2->i_mode))
                        GOTO(out_iput, rc = -EINVAL);
 
-               if (!inode_owner_or_capable(inode2))
+               if (!inode_owner_or_capable(&init_user_ns, inode2))
                        GOTO(out_iput, rc = -EPERM);
 
                rc = pcc_ioctl_detach(inode2, detach->pccd_opt);
@@ -2321,6 +2336,17 @@ static int ll_dir_release(struct inode *inode, struct file *file)
         RETURN(ll_file_release(inode, file));
 }
 
+/* notify error if partially read striped directory */
+static int ll_dir_flush(struct file *file, fl_owner_t id)
+{
+       struct ll_file_data *lfd = file->private_data;
+       int rc = lfd->fd_partial_readdir_rc;
+
+       lfd->fd_partial_readdir_rc = 0;
+
+       return rc;
+}
+
 const struct file_operations ll_dir_operations = {
        .llseek         = ll_dir_seek,
        .open           = ll_dir_open,
@@ -2333,4 +2359,5 @@ const struct file_operations ll_dir_operations = {
 #endif
        .unlocked_ioctl = ll_dir_ioctl,
        .fsync          = ll_fsync,
+       .flush          = ll_dir_flush,
 };