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

Commit d4164973 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull NFS client bugfixes from Trond Myklebust:

 - Fix a bunch of deadlock situations:
   * State recovery can deadlock if we fail to release sequence ids
     before scheduling the recovery thread.
   * Calling deactivate_super() from an RPC workqueue thread can
     deadlock because of the call to rpc_shutdown_client.

 - Display the device name correctly in /proc/*/mounts

 - Fix a number of incorrect error return values:
   * When NFSv3 mounts fail due to a timeout.
   * On NFSv4.1 backchannel setup failure
   * On NFSv4 open access checks

 - pnfs_find_alloc_layout() must check the layout pointer for NULL

 - Fix a regression in the legacy DNS resolved

* tag 'nfs-for-3.7-4' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  NFS4: nfs4_opendata_access should return errno
  NFSv4: Initialise the NFSv4.1 slot table highest_used_slotid correctly
  SUNRPC: return proper errno from backchannel_rqst
  NFS: add nfs_sb_deactive_async to avoid deadlock
  nfs: Show original device name verbatim in /proc/*/mount{s,info}
  nfsv3: Make v3 mounts fail with ETIMEDOUTs instead EIO on mountd timeouts
  nfs: Check whether a layout pointer is NULL before free it
  NFS: fix bug in legacy DNS resolver.
  NFSv4: nfs4_locku_done must release the sequence id
  NFSv4.1: We must release the sequence id when we fail to get a session slot
  NFS: Wait for session recovery to finish before returning
parents 225ff868 998f40b5
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -217,7 +217,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen)
{
	char buf1[NFS_DNS_HOSTNAME_MAXLEN+1];
	struct nfs_dns_ent key, *item;
	unsigned long ttl;
	unsigned int ttl;
	ssize_t len;
	int ret = -EINVAL;

@@ -240,7 +240,8 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen)
	key.namelen = len;
	memset(&key.h, 0, sizeof(key.h));

	ttl = get_expiry(&buf);
	if (get_uint(&buf, &ttl) < 0)
		goto out;
	if (ttl == 0)
		goto out;
	key.h.expiry_time = ttl + seconds_since_boot();
+4 −1
Original line number Diff line number Diff line
@@ -685,7 +685,10 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
	if (ctx->cred != NULL)
		put_rpccred(ctx->cred);
	dput(ctx->dentry);
	if (is_sync)
		nfs_sb_deactive(sb);
	else
		nfs_sb_deactive_async(sb);
	kfree(ctx->mdsthreshold);
	kfree(ctx);
}
+4 −2
Original line number Diff line number Diff line
@@ -351,10 +351,12 @@ extern int __init register_nfs_fs(void);
extern void __exit unregister_nfs_fs(void);
extern void nfs_sb_active(struct super_block *sb);
extern void nfs_sb_deactive(struct super_block *sb);
extern void nfs_sb_deactive_async(struct super_block *sb);

/* namespace.c */
#define NFS_PATH_CANONICAL 1
extern char *nfs_path(char **p, struct dentry *dentry,
		      char *buffer, ssize_t buflen);
		      char *buffer, ssize_t buflen, unsigned flags);
extern struct vfsmount *nfs_d_automount(struct path *path);
struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *,
			      struct nfs_fh *, struct nfs_fattr *);
@@ -498,7 +500,7 @@ static inline char *nfs_devname(struct dentry *dentry,
				char *buffer, ssize_t buflen)
{
	char *dummy;
	return nfs_path(&dummy, dentry, buffer, buflen);
	return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL);
}

/*
+1 −1
Original line number Diff line number Diff line
@@ -181,7 +181,7 @@ int nfs_mount(struct nfs_mount_request *info)
	else
		msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT];

	status = rpc_call_sync(mnt_clnt, &msg, 0);
	status = rpc_call_sync(mnt_clnt, &msg, RPC_TASK_SOFT|RPC_TASK_TIMEOUT);
	rpc_shutdown_client(mnt_clnt);

	if (status < 0)
+14 −5
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
 * @dentry - pointer to dentry
 * @buffer - result buffer
 * @buflen - length of buffer
 * @flags - options (see below)
 *
 * Helper function for constructing the server pathname
 * by arbitrary hashed dentry.
@@ -40,8 +41,14 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
 * This is mainly for use in figuring out the path on the
 * server side when automounting on top of an existing partition
 * and in generating /proc/mounts and friends.
 *
 * Supported flags:
 * NFS_PATH_CANONICAL: ensure there is exactly one slash after
 *		       the original device (export) name
 *		       (if unset, the original name is returned verbatim)
 */
char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen)
char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen,
	       unsigned flags)
{
	char *end;
	int namelen;
@@ -74,7 +81,7 @@ rename_retry:
		rcu_read_unlock();
		goto rename_retry;
	}
	if (*end != '/') {
	if ((flags & NFS_PATH_CANONICAL) && *end != '/') {
		if (--buflen < 0) {
			spin_unlock(&dentry->d_lock);
			rcu_read_unlock();
@@ -91,9 +98,11 @@ rename_retry:
		return end;
	}
	namelen = strlen(base);
	if (flags & NFS_PATH_CANONICAL) {
		/* Strip off excess slashes in base string */
		while (namelen > 0 && base[namelen - 1] == '/')
			namelen--;
	}
	buflen -= namelen;
	if (buflen < 0) {
		spin_unlock(&dentry->d_lock);
Loading