From patchwork Tue Feb 19 11:51:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boaz Harrosh X-Patchwork-Id: 10819735 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EA0231399 for ; Tue, 19 Feb 2019 11:52:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D877F2BA98 for ; Tue, 19 Feb 2019 11:52:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CD1152BB20; Tue, 19 Feb 2019 11:52:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7BFC12BBB7 for ; Tue, 19 Feb 2019 11:52:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727601AbfBSLwA (ORCPT ); Tue, 19 Feb 2019 06:52:00 -0500 Received: from mail-wm1-f65.google.com ([209.85.128.65]:39596 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726397AbfBSLv7 (ORCPT ); Tue, 19 Feb 2019 06:51:59 -0500 Received: by mail-wm1-f65.google.com with SMTP id z84so2296339wmg.4 for ; Tue, 19 Feb 2019 03:51:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=plexistor-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=kE2zS4OXYkzu5Nia97TQ0xlS69Tk+FDNRDye1Cc7El4=; b=wXkw/3Xea80+DEfwDvctzQVujj3je/0sk1OODa+Y/mKspeBoRAsUcVyFXdJKfu9b62 cB7gtN5VVJ1fDZRA/Zcr3u9m4nx8E6kMrTQmfgUUNdw/liKMNGfP9NMx/qSB0hC0yHEr vnI7suUGqkGwe3YDHMYfX2ulEnmU4F8a5DcAA8M3cVvOY0Hw4xisv1JhNmGNgKMPamDK iv3BETRRdWoOswGTdN56gE9q1KjtzNODE4lmxjL0mu4MSo3DwtfHO7mZVKtKLjD3W8/l R0WW47PDQWqBSFP91ymTw/NHXrmdprFMrNfrsHK4ZHVQWh9QrgMehfZFlGG/17UecZNp iU9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=kE2zS4OXYkzu5Nia97TQ0xlS69Tk+FDNRDye1Cc7El4=; b=KttpGC130KqosUNejk9yFW7BbwKv2EIh7uz07aXZSicpQB0cVTJuA2IwyF3ZoALr/Y gI47dg2xU0y7VhQjlUKt4H9BP5D2vvD01Fg9JHZUB7TioR8tRKIpzKGMFtRZML3BPnbo SBfQC5/L/fLSK4KL5V/mu7X8H3LWoT+HmMnZNvWFkUY0OyHqZGdnVXdSzJEmglUPNx2F FgqYp2/LpHdfdp9a6OQGP+ken0WFsDGZt/dE3ztf2cWh+Hj8KXmSeYgguRrCscBnLze2 MkDRg1+j4LcAqjiW+yzPCizhODFiw6Ti9lY3RyNaZwAlAnjcZq6NDJrZf11OozF7jyzT niBA== X-Gm-Message-State: AHQUAuafukYCCRxCVf5D5QPK541T1uXNkt6xf3MrsxcG/5yOZcDJkKA2 qL2iEPSNvsVJwDPIUWRSkKOCFf30Khs= X-Google-Smtp-Source: AHgI3IaJTgEy/Kf4jsf4UEvMrxzgLyJAV3QW95M1pJeXH9fIWmKaJHpjq8Lh+6423JgepXycnp+keQ== X-Received: by 2002:adf:c543:: with SMTP id s3mr16492665wrf.192.1550577116940; Tue, 19 Feb 2019 03:51:56 -0800 (PST) Received: from Bfire.plexistor.com ([207.232.55.62]) by smtp.gmail.com with ESMTPSA id t18sm3605830wmt.8.2019.02.19.03.51.55 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Tue, 19 Feb 2019 03:51:56 -0800 (PST) From: Boaz harrosh To: linux-fsdevel , Anna Schumaker , Al Viro Cc: Ric Wheeler , Miklos Szeredi , Steven Whitehouse , Jefff moyer , Amir Goldstein , Amit Golander , Sagi Manole Subject: [RFC PATCH 08/17] zuf: readdir operation Date: Tue, 19 Feb 2019 13:51:27 +0200 Message-Id: <20190219115136.29952-9-boaz@plexistor.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190219115136.29952-1-boaz@plexistor.com> References: <20190219115136.29952-1-boaz@plexistor.com> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Boaz Harrosh Establish protocol with Server for readdir Signed-off-by: Boaz Harrosh --- fs/zuf/_extern.h | 3 ++ fs/zuf/directory.c | 69 +++++++++++++++++++++++++++++++++ fs/zuf/zuf-core.c | 1 + fs/zuf/zus_api.h | 96 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 169 insertions(+) diff --git a/fs/zuf/_extern.h b/fs/zuf/_extern.h index 76634904eca3..ec9816d51aa3 100644 --- a/fs/zuf/_extern.h +++ b/fs/zuf/_extern.h @@ -39,6 +39,9 @@ int zuf_setattr(struct dentry *dentry, struct iattr *attr); int zuf_getattr(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags); void zuf_set_inode_flags(struct inode *inode, struct zus_inode *zi); +bool zuf_dir_emit(struct super_block *sb, struct dir_context *ctx, + ulong ino, const char *name, int length); + /* rw.c */ int zuf_trim_edge(struct inode *inode, ulong filepos, uint len); diff --git a/fs/zuf/directory.c b/fs/zuf/directory.c index eb73a5c7cabf..645dd367fd8c 100644 --- a/fs/zuf/directory.c +++ b/fs/zuf/directory.c @@ -17,6 +17,74 @@ #include #include "zuf.h" +static int zuf_readdir(struct file *file, struct dir_context *ctx) +{ + struct inode *inode = file_inode(file); + struct super_block *sb = inode->i_sb; + loff_t i_size = i_size_read(inode); + struct zufs_ioc_readdir ioc_readdir = { + .hdr.in_len = sizeof(ioc_readdir), + .hdr.out_len = sizeof(ioc_readdir), + .hdr.operation = ZUFS_OP_READDIR, + .dir_ii = ZUII(inode)->zus_ii, + }; + struct zufs_readdir_iter rdi; + struct page *pages[ZUS_API_MAP_MAX_PAGES]; + struct zufs_dir_entry *zde; + void *addr, *__a; + uint nump, i; + int err; + + if (ctx->pos && i_size <= ctx->pos) + return 0; + if (!i_size) + i_size = PAGE_SIZE; /* Just for the . && .. */ + if (i_size - ctx->pos < PAGE_SIZE) + ioc_readdir.hdr.len = PAGE_SIZE; + else + ioc_readdir.hdr.len = min_t(loff_t, i_size - ctx->pos, + ZUS_API_MAP_MAX_SIZE); + nump = md_o2p_up(ioc_readdir.hdr.len); + addr = vzalloc(md_p2o(nump)); + if (unlikely(!addr)) + return -ENOMEM; + + WARN_ON((ulong)addr & (PAGE_SIZE - 1)); + + __a = addr; + for (i = 0; i < nump; ++i) { + pages[i] = vmalloc_to_page(__a); + __a += PAGE_SIZE; + } + +more: + ioc_readdir.pos = ctx->pos; + + err = zufc_dispatch(ZUF_ROOT(SBI(sb)), &ioc_readdir.hdr, pages, nump); + if (unlikely(err && err != -EINTR)) { + zuf_err("zufc_dispatch failed => %d\n", err); + goto out; + } + + zufs_readdir_iter_init(&rdi, &ioc_readdir, addr); + while ((zde = zufs_next_zde(&rdi)) != NULL) { + zuf_dbg_verbose("%s pos=0x%lx\n", + zde->zstr.name, (ulong)zde->pos); + ctx->pos = zde->pos; + if (!dir_emit(ctx, zde->zstr.name, zde->zstr.len, zde->ino, + zde->type)) + goto out; + } + ctx->pos = ioc_readdir.pos; + if (ioc_readdir.more) { + zuf_dbg_err("more\n"); + goto more; + } +out: + vfree(addr); + return err; +} + /* *FIXME comment to full git diff */ @@ -90,5 +158,6 @@ int zuf_remove_dentry(struct inode *dir, struct qstr *str, struct inode *inode) const struct file_operations zuf_dir_operations = { .llseek = generic_file_llseek, .read = generic_read_dir, + .iterate_shared = zuf_readdir, .fsync = noop_fsync, }; diff --git a/fs/zuf/zuf-core.c b/fs/zuf/zuf-core.c index 3b61a4845af7..3d38f284d387 100644 --- a/fs/zuf/zuf-core.c +++ b/fs/zuf/zuf-core.c @@ -773,6 +773,7 @@ const char *zuf_op_name(enum e_zufs_operation op) CASE_ENUM_NAME(ZUFS_OP_ADD_DENTRY ); CASE_ENUM_NAME(ZUFS_OP_REMOVE_DENTRY ); CASE_ENUM_NAME(ZUFS_OP_RENAME ); + CASE_ENUM_NAME(ZUFS_OP_READDIR ); CASE_ENUM_NAME(ZUFS_OP_SETATTR ); CASE_ENUM_NAME(ZUFS_OP_BREAK ); default: diff --git a/fs/zuf/zus_api.h b/fs/zuf/zus_api.h index 9d66a38ab585..8a4e597414a8 100644 --- a/fs/zuf/zus_api.h +++ b/fs/zuf/zus_api.h @@ -336,6 +336,7 @@ enum e_zufs_operation { ZUFS_OP_ADD_DENTRY, ZUFS_OP_REMOVE_DENTRY, ZUFS_OP_RENAME, + ZUFS_OP_READDIR, ZUFS_OP_SETATTR, @@ -421,6 +422,101 @@ struct zufs_ioc_rename { __u32 flags; }; +/* ZUFS_OP_READDIR */ +struct zufs_ioc_readdir { + struct zufs_ioc_hdr hdr; + /* IN */ + struct zus_inode_info *dir_ii; + loff_t pos; + + /* OUT */ + __u8 more; +}; + +struct zufs_dir_entry { + __le64 ino; + struct { + unsigned type : 8; + ulong pos : 56; + }; + struct zufs_str zstr; +}; + +struct zufs_readdir_iter { + void *__zde, *last; + struct zufs_ioc_readdir *ioc_readdir; +}; + +enum {E_ZDE_HDR_SIZE = + offsetof(struct zufs_dir_entry, zstr) + offsetof(struct zufs_str, name), +}; + +static inline void zufs_readdir_iter_init(struct zufs_readdir_iter *rdi, + struct zufs_ioc_readdir *ioc_readdir, + void *app_ptr) +{ + rdi->__zde = app_ptr; + rdi->last = app_ptr + ioc_readdir->hdr.len; + rdi->ioc_readdir = ioc_readdir; + ioc_readdir->more = false; +} + +static inline uint zufs_dir_entry_len(__u8 name_len) +{ + return ALIGN(E_ZDE_HDR_SIZE + name_len, sizeof(__u64)); +} + +static inline +struct zufs_dir_entry *zufs_next_zde(struct zufs_readdir_iter *rdi) +{ + struct zufs_dir_entry *zde = rdi->__zde; + uint len; + + if (rdi->last <= rdi->__zde + E_ZDE_HDR_SIZE) + return NULL; + if (zde->zstr.len == 0) + return NULL; + len = zufs_dir_entry_len(zde->zstr.len); + if (rdi->last <= rdi->__zde + len) + return NULL; + + rdi->__zde += len; + return zde; +} + +static inline bool zufs_zde_emit(struct zufs_readdir_iter *rdi, __u64 ino, + __u8 type, __u64 pos, const char *name, + __u8 len) +{ + struct zufs_dir_entry *zde = rdi->__zde; + + if (rdi->last <= rdi->__zde + zufs_dir_entry_len(len)) { + rdi->ioc_readdir->more = true; + return false; + } + + rdi->ioc_readdir->more = 0; + zde->ino = ino; + zde->type = type; + /*ASSERT(0 == (pos && (1 << 56 - 1)));*/ + zde->pos = pos; + strncpy(zde->zstr.name, name, len); + zde->zstr.len = len; + zufs_next_zde(rdi); + + return true; +} + +/* ZUFS_OP_GET_SYMLINK */ +struct zufs_ioc_get_link { + struct zufs_ioc_hdr hdr; + /* IN */ + struct zus_inode_info *zus_ii; + + /* OUT */ + zu_dpp_t _link; +}; + /* ZUFS_OP_SETATTR */ struct zufs_ioc_attr { struct zufs_ioc_hdr hdr;