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

Commit e655f945 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

Merge branch 'bugfixes' into linux-next

* bugfixes:
  NFS: Don't reset pg_moreio in __nfs_pageio_add_request
  NFS: Remove 2 unused variables
  nfs: handle multiple reqs in nfs_wb_page_cancel
  nfs: handle multiple reqs in nfs_page_async_flush
  nfs: change find_request to find_head_request
  nfs: nfs_page should take a ref on the head req
  nfs: mark nfs_page reqs with flag for extra ref
  nfs: only show Posix ACLs in listxattr if actually present

Conflicts:
	fs/nfs/write.c
parents 00cfaa94 f563b89b
Loading
Loading
Loading
Loading
+0 −2
Original line number Original line Diff line number Diff line
@@ -749,14 +749,12 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
	spin_unlock(&dreq->lock);
	spin_unlock(&dreq->lock);


	while (!list_empty(&hdr->pages)) {
	while (!list_empty(&hdr->pages)) {
		bool do_destroy = true;


		req = nfs_list_entry(hdr->pages.next);
		req = nfs_list_entry(hdr->pages.next);
		nfs_list_remove_request(req);
		nfs_list_remove_request(req);
		if (request_commit) {
		if (request_commit) {
			kref_get(&req->wb_kref);
			kref_get(&req->wb_kref);
			nfs_mark_request_commit(req, hdr->lseg, &cinfo);
			nfs_mark_request_commit(req, hdr->lseg, &cinfo);
			do_destroy = false;
		}
		}
		nfs_unlock_and_release_request(req);
		nfs_unlock_and_release_request(req);
	}
	}
+1 −0
Original line number Original line Diff line number Diff line
@@ -244,6 +244,7 @@ void nfs_pgio_data_destroy(struct nfs_pgio_header *);
int nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *);
int nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *);
int nfs_initiate_pgio(struct rpc_clnt *, struct nfs_pgio_header *,
int nfs_initiate_pgio(struct rpc_clnt *, struct nfs_pgio_header *,
		      const struct rpc_call_ops *, int, int);
		      const struct rpc_call_ops *, int, int);
void nfs_free_request(struct nfs_page *req);


static inline void nfs_iocounter_init(struct nfs_io_counter *c)
static inline void nfs_iocounter_init(struct nfs_io_counter *c)
{
{
+43 −0
Original line number Original line Diff line number Diff line
@@ -247,3 +247,46 @@ const struct xattr_handler *nfs3_xattr_handlers[] = {
	&posix_acl_default_xattr_handler,
	&posix_acl_default_xattr_handler,
	NULL,
	NULL,
};
};

static int
nfs3_list_one_acl(struct inode *inode, int type, const char *name, void *data,
		size_t size, ssize_t *result)
{
	struct posix_acl *acl;
	char *p = data + *result;

	acl = get_acl(inode, type);
	if (!acl)
		return 0;

	posix_acl_release(acl);

	*result += strlen(name);
	*result += 1;
	if (!size)
		return 0;
	if (*result > size)
		return -ERANGE;

	strcpy(p, name);
	return 0;
}

ssize_t
nfs3_listxattr(struct dentry *dentry, char *data, size_t size)
{
	struct inode *inode = dentry->d_inode;
	ssize_t result = 0;
	int error;

	error = nfs3_list_one_acl(inode, ACL_TYPE_ACCESS,
			POSIX_ACL_XATTR_ACCESS, data, size, &result);
	if (error)
		return error;

	error = nfs3_list_one_acl(inode, ACL_TYPE_DEFAULT,
			POSIX_ACL_XATTR_DEFAULT, data, size, &result);
	if (error)
		return error;
	return result;
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -888,7 +888,7 @@ static const struct inode_operations nfs3_dir_inode_operations = {
	.getattr	= nfs_getattr,
	.getattr	= nfs_getattr,
	.setattr	= nfs_setattr,
	.setattr	= nfs_setattr,
#ifdef CONFIG_NFS_V3_ACL
#ifdef CONFIG_NFS_V3_ACL
	.listxattr	= generic_listxattr,
	.listxattr	= nfs3_listxattr,
	.getxattr	= generic_getxattr,
	.getxattr	= generic_getxattr,
	.setxattr	= generic_setxattr,
	.setxattr	= generic_setxattr,
	.removexattr	= generic_removexattr,
	.removexattr	= generic_removexattr,
@@ -902,7 +902,7 @@ static const struct inode_operations nfs3_file_inode_operations = {
	.getattr	= nfs_getattr,
	.getattr	= nfs_getattr,
	.setattr	= nfs_setattr,
	.setattr	= nfs_setattr,
#ifdef CONFIG_NFS_V3_ACL
#ifdef CONFIG_NFS_V3_ACL
	.listxattr	= generic_listxattr,
	.listxattr	= nfs3_listxattr,
	.getxattr	= generic_getxattr,
	.getxattr	= generic_getxattr,
	.setxattr	= generic_setxattr,
	.setxattr	= generic_setxattr,
	.removexattr	= generic_removexattr,
	.removexattr	= generic_removexattr,
+15 −5
Original line number Original line Diff line number Diff line
@@ -29,8 +29,6 @@
static struct kmem_cache *nfs_page_cachep;
static struct kmem_cache *nfs_page_cachep;
static const struct rpc_call_ops nfs_pgio_common_ops;
static const struct rpc_call_ops nfs_pgio_common_ops;


static void nfs_free_request(struct nfs_page *);

static bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount)
static bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount)
{
{
	p->npages = pagecount;
	p->npages = pagecount;
@@ -239,22 +237,30 @@ nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev)
	WARN_ON_ONCE(prev == req);
	WARN_ON_ONCE(prev == req);


	if (!prev) {
	if (!prev) {
		/* a head request */
		req->wb_head = req;
		req->wb_head = req;
		req->wb_this_page = req;
		req->wb_this_page = req;
	} else {
	} else {
		/* a subrequest */
		WARN_ON_ONCE(prev->wb_this_page != prev->wb_head);
		WARN_ON_ONCE(prev->wb_this_page != prev->wb_head);
		WARN_ON_ONCE(!test_bit(PG_HEADLOCK, &prev->wb_head->wb_flags));
		WARN_ON_ONCE(!test_bit(PG_HEADLOCK, &prev->wb_head->wb_flags));
		req->wb_head = prev->wb_head;
		req->wb_head = prev->wb_head;
		req->wb_this_page = prev->wb_this_page;
		req->wb_this_page = prev->wb_this_page;
		prev->wb_this_page = req;
		prev->wb_this_page = req;


		/* All subrequests take a ref on the head request until
		 * nfs_page_group_destroy is called */
		kref_get(&req->wb_head->wb_kref);

		/* grab extra ref if head request has extra ref from
		/* grab extra ref if head request has extra ref from
		 * the write/commit path to handle handoff between write
		 * the write/commit path to handle handoff between write
		 * and commit lists */
		 * and commit lists */
		if (test_bit(PG_INODE_REF, &prev->wb_head->wb_flags))
		if (test_bit(PG_INODE_REF, &prev->wb_head->wb_flags)) {
			set_bit(PG_INODE_REF, &req->wb_flags);
			kref_get(&req->wb_kref);
			kref_get(&req->wb_kref);
		}
		}
	}
	}
}


/*
/*
 * nfs_page_group_destroy - sync the destruction of page groups
 * nfs_page_group_destroy - sync the destruction of page groups
@@ -269,6 +275,10 @@ nfs_page_group_destroy(struct kref *kref)
	struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref);
	struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref);
	struct nfs_page *tmp, *next;
	struct nfs_page *tmp, *next;


	/* subrequests must release the ref on the head request */
	if (req->wb_head != req)
		nfs_release_request(req->wb_head);

	if (!nfs_page_group_sync_on_bit(req, PG_TEARDOWN))
	if (!nfs_page_group_sync_on_bit(req, PG_TEARDOWN))
		return;
		return;


@@ -394,7 +404,7 @@ static void nfs_clear_request(struct nfs_page *req)
 *
 *
 * Note: Should never be called with the spinlock held!
 * Note: Should never be called with the spinlock held!
 */
 */
static void nfs_free_request(struct nfs_page *req)
void nfs_free_request(struct nfs_page *req)
{
{
	WARN_ON_ONCE(req->wb_this_page != req);
	WARN_ON_ONCE(req->wb_this_page != req);


@@ -868,7 +878,6 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
			nfs_pageio_doio(desc);
			nfs_pageio_doio(desc);
			if (desc->pg_error < 0)
			if (desc->pg_error < 0)
				return 0;
				return 0;
			desc->pg_moreio = 0;
			if (desc->pg_recoalesce)
			if (desc->pg_recoalesce)
				return 0;
				return 0;
			/* retry add_request for this subreq */
			/* retry add_request for this subreq */
@@ -915,6 +924,7 @@ static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc)
		desc->pg_count = 0;
		desc->pg_count = 0;
		desc->pg_base = 0;
		desc->pg_base = 0;
		desc->pg_recoalesce = 0;
		desc->pg_recoalesce = 0;
		desc->pg_moreio = 0;


		while (!list_empty(&head)) {
		while (!list_empty(&head)) {
			struct nfs_page *req;
			struct nfs_page *req;
Loading