Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b26a0bf authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFS: Ensure we return the dirent->d_type when it is known



Store the dirent->d_type in the struct nfs_cache_array_entry so that we
can use it in getdents() calls.

This fixes a regression with the new readdir code.

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 3020093f
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -162,6 +162,7 @@ struct nfs_cache_array_entry {
	u64 cookie;
	u64 ino;
	struct qstr string;
	unsigned char d_type;
};

struct nfs_cache_array {
@@ -265,6 +266,7 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)

	cache_entry->cookie = entry->prev_cookie;
	cache_entry->ino = entry->ino;
	cache_entry->d_type = entry->d_type;
	ret = nfs_readdir_make_qstr(&cache_entry->string, entry->name, entry->len);
	if (ret)
		goto out;
@@ -701,7 +703,6 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
	int i = 0;
	int res = 0;
	struct nfs_cache_array *array = NULL;
	unsigned int d_type = DT_UNKNOWN;

	array = nfs_readdir_get_array(desc->page);
	if (IS_ERR(array)) {
@@ -711,11 +712,11 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,

	for (i = desc->cache_entry_index; i < array->size; i++) {
		struct nfs_cache_array_entry *ent;
		d_type = DT_UNKNOWN;

		ent = &array->array[i];
		if (filldir(dirent, ent->string.name, ent->string.len,
		    file->f_pos, nfs_compat_user_ino64(ent->ino), d_type) < 0) {
		    file->f_pos, nfs_compat_user_ino64(ent->ino),
		    ent->d_type) < 0) {
			desc->eof = 1;
			break;
		}
+9 −0
Original line number Diff line number Diff line
@@ -361,6 +361,15 @@ unsigned int nfs_page_length(struct page *page)
	return 0;
}

/*
 * Convert a umode to a dirent->d_type
 */
static inline
unsigned char nfs_umode_to_dtype(umode_t mode)
{
	return (mode >> 12) & 15;
}

/*
 * Determine the number of pages in an array of length 'len' and
 * with a base offset of 'base'
+2 −0
Original line number Diff line number Diff line
@@ -485,6 +485,8 @@ nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_se
	entry->prev_cookie	  = entry->cookie;
	entry->cookie	  = ntohl(*p++);

	entry->d_type = DT_UNKNOWN;

	p = xdr_inline_peek(xdr, 8);
	if (p != NULL)
		entry->eof = !p[0] && p[1];
+2 −0
Original line number Diff line number Diff line
@@ -622,11 +622,13 @@ nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_s
	entry->prev_cookie = entry->cookie;
	p = xdr_decode_hyper(p, &entry->cookie);

	entry->d_type = DT_UNKNOWN;
	if (plus) {
		entry->fattr->valid = 0;
		p = xdr_decode_post_op_attr_stream(xdr, entry->fattr);
		if (IS_ERR(p))
			goto out_overflow_exit;
		entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
		/* In fact, a post_op_fh3: */
		p = xdr_inline_decode(xdr, 4);
		if (unlikely(!p))
+4 −0
Original line number Diff line number Diff line
@@ -6208,6 +6208,10 @@ __be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
	if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID)
		entry->ino = entry->fattr->fileid;

	entry->d_type = DT_UNKNOWN;
	if (entry->fattr->valid & NFS_ATTR_FATTR_TYPE)
		entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);

	if (verify_attr_len(xdr, p, len) < 0)
		goto out_overflow;

Loading