From: Benny Halevy <bhalevy@panasas.com>
To: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: linux-nfs@vger.kernel.org
Subject: Re: [RFC 03/27] pnfs: layoutreturn
Date: Fri, 22 Apr 2011 09:52:45 +0300 [thread overview]
Message-ID: <4DB125BD.3040703@panasas.com> (raw)
In-Reply-To: <1303329221.23206.22.camel@lade.trondhjem.org>
On 2011-04-20 22:53, Trond Myklebust wrote:
> On Wed, 2011-04-20 at 20:26 +0300, Benny Halevy wrote:
>> @@ -1424,9 +1424,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
>> */
>> void nfs4_evict_inode(struct inode *inode)
>> {
>> - pnfs_destroy_layout(NFS_I(inode));
>> + pnfs_return_layout(inode, NULL, true);
>
> Why does this want to come before the call to truncate_inode_pages()?
Actually, I don't see any good reason. :-/
> Is there any reason not to put pnfs_return_layout() and
> pnfs_destroy_layout into a single helper here?
>
Looks like an overkill to me for this one call site.
>> truncate_inode_pages(&inode->i_data, 0);
>> end_writeback(inode);
>> + pnfs_destroy_layout(NFS_I(inode));
>> /* If we are holding a delegation, return it! */
>> nfs_inode_return_delegation_noreclaim(inode);
>> /* First call standard NFS clear_inode() code */
>> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
>> index 9bf41ea..b03defb 100644
>> --- a/fs/nfs/nfs4proc.c
>> +++ b/fs/nfs/nfs4proc.c
>> @@ -5662,6 +5662,103 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp)
>> return status;
>> }
>>
>> +static void
>> +nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata)
>> +{
>> + struct nfs4_layoutreturn *lrp = calldata;
>> +
>> + dprintk("--> %s\n", __func__);
>> + if (nfs41_setup_sequence(lrp->clp->cl_session, &lrp->args.seq_args,
>> + &lrp->res.seq_res, 0, task))
>> + return;
>> + rpc_call_start(task);
>> +}
>> +
>> +static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
>> +{
>> + struct nfs4_layoutreturn *lrp = calldata;
>> + struct nfs_server *server;
>> +
>> + dprintk("--> %s\n", __func__);
>> +
>> + if (!nfs4_sequence_done(task, &lrp->res.seq_res))
>> + return;
>> +
>> + if (lrp->args.return_type == RETURN_FILE)
>> + server = NFS_SERVER(lrp->args.inode);
>> + else
>> + server = NULL;
>> + if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) {
>> + nfs_restart_rpc(task, lrp->clp);
>> + return;
>> + }
>> + if ((task->tk_status == 0) && (lrp->args.return_type == RETURN_FILE)) {
>> + struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout;
>> +
>> + spin_lock(&lo->plh_inode->i_lock);
>> + if (lrp->res.lrs_present)
>> + pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
>> + else
>> + BUG_ON(!list_empty(&lo->plh_segs));
>> + spin_unlock(&lo->plh_inode->i_lock);
>> + }
>> + dprintk("<-- %s\n", __func__);
>> +}
>> +
>> +static void nfs4_layoutreturn_release(void *calldata)
>> +{
>> + struct nfs4_layoutreturn *lrp = calldata;
>> +
>> + dprintk("--> %s return_type %d\n", __func__, lrp->args.return_type);
>> + if (lrp->args.return_type == RETURN_FILE) {
>> + struct inode *ino = lrp->args.inode;
>> + struct pnfs_layout_hdr *lo = NFS_I(ino)->layout;
>> +
>> + put_layout_hdr(lo);
>> + }
>> + kfree(calldata);
>> + dprintk("<-- %s\n", __func__);
>> +}
>> +
>> +static const struct rpc_call_ops nfs4_layoutreturn_call_ops = {
>> + .rpc_call_prepare = nfs4_layoutreturn_prepare,
>> + .rpc_call_done = nfs4_layoutreturn_done,
>> + .rpc_release = nfs4_layoutreturn_release,
>> +};
>> +
>> +int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool issync)
>
> Why the 'issync' parameter?
>
Hmm, you're right. Currently all call sites use it as sync.
>> +{
>> + struct rpc_task *task;
>> + struct rpc_message msg = {
>> + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTRETURN],
>> + .rpc_argp = &lrp->args,
>> + .rpc_resp = &lrp->res,
>> + };
>> + struct rpc_task_setup task_setup_data = {
>> + .rpc_client = lrp->clp->cl_rpcclient,
>> + .rpc_message = &msg,
>> + .callback_ops = &nfs4_layoutreturn_call_ops,
>> + .callback_data = lrp,
>> + .flags = RPC_TASK_ASYNC,
>> + };
>> + int status = 0;
>> +
>> + dprintk("--> %s\n", __func__);
>> + task = rpc_run_task(&task_setup_data);
>> + if (IS_ERR(task))
>> + return PTR_ERR(task);
>> + if (!issync)
>> + goto out;
>> + status = nfs4_wait_for_completion_rpc_task(task);
>> + if (status != 0)
>> + goto out;
>> + status = task->tk_status;
>> +out:
>> + dprintk("<-- %s\n", __func__);
>> + rpc_put_task(task);
>> + return status;
>> +}
>> +
>> static int
>> _nfs4_proc_getdeviceinfo(struct nfs_server *server, struct pnfs_device *pdev)
>> {
>> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
>> index dddfb57..53ea3e5 100644
>> --- a/fs/nfs/nfs4xdr.c
>> +++ b/fs/nfs/nfs4xdr.c
>> @@ -338,7 +338,12 @@ static int nfs4_stat_to_errno(int);
>> 1 /* layoutupdate4 layout type */ + \
>> 1 /* NULL filelayout layoutupdate4 payload */)
>> #define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3)
>> -
>> +#define encode_layoutreturn_maxsz (8 + op_encode_hdr_maxsz + \
>> + encode_stateid_maxsz + \
>> + 1 /* FIXME: opaque lrf_body always empty at
>> + *the moment */)
>> +#define decode_layoutreturn_maxsz (op_decode_hdr_maxsz + \
>> + 1 + decode_stateid_maxsz)
>> #else /* CONFIG_NFS_V4_1 */
>> #define encode_sequence_maxsz 0
>> #define decode_sequence_maxsz 0
>> @@ -760,7 +765,14 @@ static int nfs4_stat_to_errno(int);
>> decode_putfh_maxsz + \
>> decode_layoutcommit_maxsz + \
>> decode_getattr_maxsz)
>> -
>> +#define NFS4_enc_layoutreturn_sz (compound_encode_hdr_maxsz + \
>> + encode_sequence_maxsz + \
>> + encode_putfh_maxsz + \
>> + encode_layoutreturn_maxsz)
>> +#define NFS4_dec_layoutreturn_sz (compound_decode_hdr_maxsz + \
>> + decode_sequence_maxsz + \
>> + decode_putfh_maxsz + \
>> + decode_layoutreturn_maxsz)
>>
>> const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
>> compound_encode_hdr_maxsz +
>> @@ -1890,6 +1902,37 @@ encode_layoutcommit(struct xdr_stream *xdr,
>> hdr->replen += decode_layoutcommit_maxsz;
>> return 0;
>> }
>> +
>> +static void
>> +encode_layoutreturn(struct xdr_stream *xdr,
>> + const struct nfs4_layoutreturn_args *args,
>> + struct compound_hdr *hdr)
>> +{
>> + nfs4_stateid stateid;
>> + __be32 *p;
>> +
>> + p = reserve_space(xdr, 20);
>> + *p++ = cpu_to_be32(OP_LAYOUTRETURN);
>> + *p++ = cpu_to_be32(args->reclaim);
>> + *p++ = cpu_to_be32(args->layout_type);
>> + *p++ = cpu_to_be32(args->range.iomode);
>> + *p = cpu_to_be32(args->return_type);
>> + if (args->return_type == RETURN_FILE) {
>> + p = reserve_space(xdr, 16 + NFS4_STATEID_SIZE);
>> + p = xdr_encode_hyper(p, args->range.offset);
>> + p = xdr_encode_hyper(p, args->range.length);
>> + spin_lock(&args->inode->i_lock);
>> + memcpy(stateid.data, NFS_I(args->inode)->layout->plh_stateid.data,
>> + NFS4_STATEID_SIZE);
>> + spin_unlock(&args->inode->i_lock);
>> + p = xdr_encode_opaque_fixed(p, &stateid.data,
>> + NFS4_STATEID_SIZE);
>> + p = reserve_space(xdr, 4);
>> + *p = cpu_to_be32(0);
>> + }
>> + hdr->nops++;
>> + hdr->replen += decode_layoutreturn_maxsz;
>> +}
>> #endif /* CONFIG_NFS_V4_1 */
>>
>> /*
>> @@ -2707,9 +2750,9 @@ static void nfs4_xdr_enc_layoutget(struct rpc_rqst *req,
>> /*
>> * Encode LAYOUTCOMMIT request
>> */
>> -static int nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req,
>> - struct xdr_stream *xdr,
>> - struct nfs4_layoutcommit_args *args)
>> +static void nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req,
>> + struct xdr_stream *xdr,
>> + struct nfs4_layoutcommit_args *args)
>> {
>> struct compound_hdr hdr = {
>> .minorversion = nfs4_xdr_minorversion(&args->seq_args),
>> @@ -2721,7 +2764,24 @@ static int nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req,
>> encode_layoutcommit(xdr, args, &hdr);
>> encode_getfattr(xdr, args->bitmask, &hdr);
>> encode_nops(&hdr);
>> - return 0;
>> +}
>> +
>> +/*
>> + * Encode LAYOUTRETURN request
>> + */
>> +static void nfs4_xdr_enc_layoutreturn(struct rpc_rqst *req,
>> + struct xdr_stream *xdr,
>> + struct nfs4_layoutreturn_args *args)
>> +{
>> + struct compound_hdr hdr = {
>> + .minorversion = nfs4_xdr_minorversion(&args->seq_args),
>> + };
>> +
>> + encode_compound_hdr(xdr, req, &hdr);
>> + encode_sequence(xdr, &args->seq_args, &hdr);
>> + encode_putfh(xdr, NFS_FH(args->inode), &hdr);
>> + encode_layoutreturn(xdr, args, &hdr);
>> + encode_nops(&hdr);
>> }
>> #endif /* CONFIG_NFS_V4_1 */
>>
>> @@ -5202,6 +5262,27 @@ out_overflow:
>> return -EIO;
>> }
>>
>> +static int decode_layoutreturn(struct xdr_stream *xdr,
>> + struct nfs4_layoutreturn_res *res)
>> +{
>> + __be32 *p;
>> + int status;
>> +
>> + status = decode_op_hdr(xdr, OP_LAYOUTRETURN);
>> + if (status)
>> + return status;
>> + p = xdr_inline_decode(xdr, 4);
>> + if (unlikely(!p))
>> + goto out_overflow;
>> + res->lrs_present = be32_to_cpup(p);
>> + if (res->lrs_present)
>> + status = decode_stateid(xdr, &res->stateid);
>> + return status;
>> +out_overflow:
>> + print_overflow_msg(__func__, xdr);
>> + return -EIO;
>> +}
>> +
>> static int decode_layoutcommit(struct xdr_stream *xdr,
>> struct rpc_rqst *req,
>> struct nfs4_layoutcommit_res *res)
>> @@ -6319,6 +6400,30 @@ out:
>> }
>>
>> /*
>> + * Decode LAYOUTRETURN response
>> + */
>> +static int nfs4_xdr_dec_layoutreturn(struct rpc_rqst *rqstp,
>> + struct xdr_stream *xdr,
>> + struct nfs4_layoutreturn_res *res)
>> +{
>> + struct compound_hdr hdr;
>> + int status;
>> +
>> + status = decode_compound_hdr(xdr, &hdr);
>> + if (status)
>> + goto out;
>> + status = decode_sequence(xdr, &res->seq_res, rqstp);
>> + if (status)
>> + goto out;
>> + status = decode_putfh(xdr);
>> + if (status)
>> + goto out;
>> + status = decode_layoutreturn(xdr, res);
>> +out:
>> + return status;
>> +}
>> +
>> +/*
>> * Decode LAYOUTCOMMIT response
>> */
>> static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp,
>> @@ -6544,6 +6649,7 @@ struct rpc_procinfo nfs4_procedures[] = {
>> PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo),
>> PROC(LAYOUTGET, enc_layoutget, dec_layoutget),
>> PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit),
>> + PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn),
>> #endif /* CONFIG_NFS_V4_1 */
>> };
>>
>> diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
>> index d9ab972..89e7725 100644
>> --- a/fs/nfs/pnfs.c
>> +++ b/fs/nfs/pnfs.c
>> @@ -321,6 +321,36 @@ mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
>> return invalid - removed;
>> }
>>
>> +/* Returns false if there was nothing to do, true otherwise */
>> +static bool
>> +pnfs_clear_lseg_list(struct pnfs_layout_hdr *lo, struct list_head *tmp_list,
>> + struct pnfs_layout_range *range)
>> +{
>> + struct pnfs_layout_segment *lseg, *next;
>> + bool rv = false;
>> +
>> + dprintk("%s:Begin lo %p offset %llu length %llu iomode %d\n",
>> + __func__, lo, range->offset, range->length, range->iomode);
>> + assert_spin_locked(&lo->plh_inode->i_lock);
>
> Not needed in the case of nfs4_evict_inode.
>
True. I can remove the assert
but the lock better be taken if called while the inode is alive.
>> + if (list_empty(&lo->plh_segs)) {
>> + if (!test_and_set_bit(NFS_LAYOUT_DESTROYED, &lo->plh_flags))
>> + put_layout_hdr_locked(lo);
>> + return 0;
>> + }
>> + list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
>> + if (should_free_lseg(lseg->pls_range.iomode, range->iomode)) {
>> + dprintk("%s: freeing lseg %p iomode %d "
>> + "offset %llu length %llu\n", __func__,
>> + lseg, lseg->pls_range.iomode,
>> + lseg->pls_range.offset,
>> + lseg->pls_range.length);
>> + mark_lseg_invalid(lseg, tmp_list);
>> + rv = true;
>> + }
>> + dprintk("%s:Return %d\n", __func__, rv);
>> + return rv;
>> +}
>> +
>> /* note free_me must contain lsegs from a single layout_hdr */
>> void
>> pnfs_free_lseg_list(struct list_head *free_me)
>> @@ -539,6 +569,72 @@ out_err_free:
>> return NULL;
>> }
>>
>> +static int
>> +return_layout(struct inode *ino, struct pnfs_layout_range *range, bool wait)
>> +{
>> + struct nfs4_layoutreturn *lrp;
>> + struct nfs_server *server = NFS_SERVER(ino);
>> + int status = -ENOMEM;
>> +
>> + dprintk("--> %s\n", __func__);
>> +
>> + lrp = kzalloc(sizeof(*lrp), GFP_KERNEL);
>> + if (lrp == NULL) {
>> + put_layout_hdr(NFS_I(ino)->layout);
>> + goto out;
>> + }
>> + lrp->args.reclaim = 0;
>> + lrp->args.layout_type = server->pnfs_curr_ld->id;
>> + lrp->args.return_type = RETURN_FILE;
>> + lrp->args.range = *range;
>> + lrp->args.inode = ino;
>> + lrp->clp = server->nfs_client;
>> +
>> + status = nfs4_proc_layoutreturn(lrp, wait);
>> +out:
>> + dprintk("<-- %s status: %d\n", __func__, status);
>> + return status;
>> +}
>> +
>> +/* Initiates a LAYOUTRETURN(FILE) */
>> +int
>> +_pnfs_return_layout(struct inode *ino, struct pnfs_layout_range *range, bool wait)
>
> What are the 'range' and 'wait' parameters for? We don't have any users
> other than nfs4_evict_inode.
>
OK, I'll introduce these with their usage.
>> +{
>> + struct pnfs_layout_hdr *lo = NULL;
>> + struct nfs_inode *nfsi = NFS_I(ino);
>> + struct pnfs_layout_range arg;
>> + LIST_HEAD(tmp_list);
>> + int status = 0;
>> +
>> + dprintk("--> %s\n", __func__);
>> +
>> + arg.iomode = range ? range->iomode : IOMODE_ANY;
>> + arg.offset = 0;
>> + arg.length = NFS4_MAX_UINT64;
>> +
>> + spin_lock(&ino->i_lock);
>> + lo = nfsi->layout;
>> + if (!lo || !pnfs_clear_lseg_list(lo, &tmp_list, &arg)) {
>> + spin_unlock(&ino->i_lock);
>> + dprintk("%s: no layout segments to return\n", __func__);
>> + goto out;
>> + }
>> + /* Reference matched in nfs4_layoutreturn_release */
>> + get_layout_hdr(lo);
>> + spin_unlock(&ino->i_lock);
>> + pnfs_free_lseg_list(&tmp_list);
>> +
>> + /* Return layout even if layoutcommit fails */
>> + status = pnfs_layoutcommit_inode(ino, wait);
>
> Why is this needed? Again, by the time we get to nfs4_evict_inode, the
> inode is guaranteed to be clean.
>
OK, let me just add a WARN_ON if we get here and layout commit is
required. Does that work for you?
>> + if (status)
>> + dprintk("%s: layoutcommit failed, status=%d. Returning layout anyway\n",
>> + __func__, status);
>> + status = return_layout(ino, &arg, wait);
>> +out:
>> + dprintk("<-- %s status: %d\n", __func__, status);
>> + return status;
>> +}
>> +
>> bool pnfs_roc(struct inode *ino)
>> {
>> struct pnfs_layout_hdr *lo;
>> diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
>> index 4cb0a0d..a308f3c 100644
>> --- a/fs/nfs/pnfs.h
>> +++ b/fs/nfs/pnfs.h
>> @@ -123,6 +123,7 @@ extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *);
>> extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
>> struct pnfs_device *dev);
>> extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp);
>> +extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool wait);
>>
>> /* pnfs.c */
>> void get_layout_hdr(struct pnfs_layout_hdr *lo);
>> @@ -158,6 +159,7 @@ void pnfs_roc_set_barrier(struct inode *ino, u32 barrier);
>> bool pnfs_roc_drain(struct inode *ino, u32 *barrier);
>> void pnfs_set_layoutcommit(struct nfs_write_data *wdata);
>> int pnfs_layoutcommit_inode(struct inode *inode, bool sync);
>> +int _pnfs_return_layout(struct inode *, struct pnfs_layout_range *, bool wait);
>>
>> static inline int lo_fail_bit(u32 iomode)
>> {
>> @@ -226,6 +228,19 @@ static inline void pnfs_clear_request_commit(struct nfs_page *req)
>> put_lseg(req->wb_commit_lseg);
>> }
>>
>> +static inline int pnfs_return_layout(struct inode *ino,
>> + struct pnfs_layout_range *range,
>> + bool wait)
>> +{
>> + struct nfs_inode *nfsi = NFS_I(ino);
>> + struct nfs_server *nfss = NFS_SERVER(ino);
>> +
>> + if (pnfs_enabled_sb(nfss) && nfsi->layout)
>> + return _pnfs_return_layout(ino, range, wait);
>> +
>> + return 0;
>> +}
>> +
>> #else /* CONFIG_NFS_V4_1 */
>>
>> static inline void pnfs_destroy_all_layouts(struct nfs_client *clp)
>> @@ -267,6 +282,13 @@ pnfs_try_to_write_data(struct nfs_write_data *data,
>> return PNFS_NOT_ATTEMPTED;
>> }
>>
>> +static inline int pnfs_return_layout(struct inode *ino,
>> + struct pnfs_layout_range *range,
>> + bool wait)
>> +{
>> + return 0;
>> +}
>> +
>> static inline bool
>> pnfs_roc(struct inode *ino)
>> {
>> diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
>> index 178fafe..9376eaf 100644
>> --- a/include/linux/nfs4.h
>> +++ b/include/linux/nfs4.h
>> @@ -562,6 +562,7 @@ enum {
>> NFSPROC4_CLNT_LAYOUTGET,
>> NFSPROC4_CLNT_GETDEVICEINFO,
>> NFSPROC4_CLNT_LAYOUTCOMMIT,
>> + NFSPROC4_CLNT_LAYOUTRETURN,
>> };
>>
>> /* nfs41 types */
>> diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
>> index 78b101e..455ddfb 100644
>> --- a/include/linux/nfs_xdr.h
>> +++ b/include/linux/nfs_xdr.h
>> @@ -266,6 +266,29 @@ struct nfs4_layoutcommit_data {
>> struct nfs4_layoutcommit_res res;
>> };
>>
>> +struct nfs4_layoutreturn_args {
>> + __u32 reclaim;
>> + __u32 layout_type;
>> + __u32 return_type;
>
> Why do we need a 'return_type'? As far as I can see, this will always be
> RETURN_FILE.
>
Yeah, we can remove this for now.
Benny
>> + struct pnfs_layout_range range;
>> + struct inode *inode;
>> + struct nfs4_sequence_args seq_args;
>> +};
>> +
>> +struct nfs4_layoutreturn_res {
>> + struct nfs4_sequence_res seq_res;
>> + u32 lrs_present;
>> + nfs4_stateid stateid;
>> +};
>> +
>> +struct nfs4_layoutreturn {
>> + struct nfs4_layoutreturn_args args;
>> + struct nfs4_layoutreturn_res res;
>> + struct rpc_cred *cred;
>> + struct nfs_client *clp;
>> + int rpc_status;
>> +};
>> +
>> /*
>> * Arguments to the open call.
>> */
>
next prev parent reply other threads:[~2011-04-22 6:52 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-04-20 16:46 [RFC 0/27] pnfs-submit for 2.6.40 Benny Halevy
2011-04-20 17:26 ` [RFC 01/27] pnfs: CB_NOTIFY_DEVICEID Benny Halevy
2011-04-20 19:41 ` Trond Myklebust
2011-04-22 6:22 ` Benny Halevy
2011-04-20 17:26 ` [RFC 02/27] pnfs: direct i/o Benny Halevy
2011-04-20 17:26 ` [RFC 03/27] pnfs: layoutreturn Benny Halevy
2011-04-20 19:53 ` Trond Myklebust
2011-04-22 6:52 ` Benny Halevy [this message]
2011-04-22 8:04 ` [PATCH 1/6] SQUASHME: call pnfs_return_layout right before pnfs_destroy_layout Benny Halevy
2011-04-22 8:04 ` [PATCH 2/6] SQUASHME: remove assert_spin_locked from pnfs_clear_lseg_list Benny Halevy
2011-04-22 8:04 ` [PATCH 3/6] SQUASHME: remove wait parameter from the layoutreturn path Benny Halevy
2011-04-22 8:31 ` Benny Halevy
2011-04-22 8:05 ` [PATCH 4/6] SQUASHME: remove return_type field from nfs4_layoutreturn_args Benny Halevy
2011-04-22 8:05 ` [PATCH 5/6] SQUASHME: remove range " Benny Halevy
2011-04-22 8:05 ` [PATCH 6/6] SQUASHME: no need to send layoutcommit from _pnfs_return_layout Benny Halevy
2011-04-20 17:26 ` [RFC 04/27] pnfs: layoutret_on_setattr Benny Halevy
2011-04-20 20:03 ` Trond Myklebust
2011-04-22 8:23 ` Benny Halevy
2011-04-20 17:26 ` [RFC 05/27] pnfs: Use byte-range layout segments Benny Halevy
2011-04-20 17:26 ` [RFC 06/27] pnfs: encode_layoutreturn Benny Halevy
2011-04-20 20:16 ` Trond Myklebust
2011-04-22 8:26 ` Benny Halevy
2011-04-20 17:27 ` [RFC 07/27] pnfs: encode_layoutcommit Benny Halevy
2011-04-20 20:18 ` Trond Myklebust
2011-04-22 8:48 ` Benny Halevy
2011-04-20 17:27 ` [RFC 08/27] pnfs: {setup,cleanup}_layoutcommit Benny Halevy
2011-04-20 20:22 ` Trond Myklebust
2011-04-20 17:27 ` [RFC 09/27] pnfs: support for non-rpc layout drivers Benny Halevy
2011-04-20 20:34 ` Trond Myklebust
2011-04-22 9:03 ` Benny Halevy
2011-04-20 17:27 ` [RFC 10/27] pnfs: {,un}set_layoutdriver methods Benny Halevy
2011-04-20 17:27 ` [RFC 11/27] pnfs: per mount layout driver private data Benny Halevy
2011-04-20 20:36 ` Trond Myklebust
2011-04-22 9:05 ` Benny Halevy
2011-04-20 17:27 ` [RFC 12/27] pnfs: alloc and free layout_hdr layoutdriver methods Benny Halevy
2011-04-20 20:43 ` Trond Myklebust
2011-04-22 9:09 ` Benny Halevy
2011-04-20 17:27 ` [RFC 13/27] pnfs: client stats Benny Halevy
2011-04-20 17:28 ` [RFC 14/27] pnfsd: introduce exp_xdr.h Benny Halevy
2011-04-20 17:28 ` [RFC 15/27] pnfs-obj: pnfs_osd XDR definitions Benny Halevy
2011-04-20 20:49 ` Trond Myklebust
2011-04-22 9:11 ` Benny Halevy
2011-04-20 17:28 ` [RFC 16/27] pnfs-obj: pnfs_osd XDR client implementations Benny Halevy
2011-04-20 17:28 ` [RFC 17/27] exofs: pnfs-tree: Remove pnfs-osd private definitions Benny Halevy
2011-04-20 17:28 ` [RFC 18/27] pnfs-obj: Define PNFS_OBJLAYOUT Kconfig option Benny Halevy
2011-04-20 17:28 ` [RFC 19/27] pnfs-obj: objlayout driver skeleton Benny Halevy
2011-04-20 17:28 ` [RFC 20/27] pnfs-obj: objio_osd device information retrieval and caching Benny Halevy
2011-04-20 17:28 ` [RFC 21/27] pnfs-obj: objio_osd real IO implementation Benny Halevy
2011-04-20 17:29 ` [RFC 22/27] sunrpc: New xdr_rewind_stream() Benny Halevy
2011-04-20 17:29 ` [RFC 23/27] pnfs-obj: objlayout_encode_layoutreturn Implementation Benny Halevy
2011-04-20 17:29 ` [RFC 24/27] pnfs-obj: objio_osd report osd_errors for layoutreturn Benny Halevy
2011-04-20 17:29 ` [RFC 25/27] pnfs-obj: objlayout_encode_layoutcommit implementation Benny Halevy
2011-04-20 17:29 ` [RFC 26/27] pnfs-obj: objio_osd: RAID0 support Benny Halevy
2011-04-20 17:29 ` [RFC 27/27] pnfs-obj: objio_osd: groups support Benny Halevy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4DB125BD.3040703@panasas.com \
--to=bhalevy@panasas.com \
--cc=Trond.Myklebust@netapp.com \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.