Skip to content

Commit

Permalink
Merge tag 'nfs-for-3.5-3' of git://git.linux-nfs.org/projects/trondmy…
Browse files Browse the repository at this point in the history
…/linux-nfs

Pull NFS client bugfixes from Trond Myklebust:
 - Fix a write hang due to an uninitalised variable when
   !defined(CONFIG_NFS_V4)
 - Address upcall races in the legacy NFSv4 idmapper
 - Remove an O_DIRECT refcounting issue
 - Fix a pNFS refcounting bug when the file layout metadata server is
   also acting as a data server
 - Fix a pNFS module loading race.

* tag 'nfs-for-3.5-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  NFS: Force the legacy idmapper to be single threaded
  NFS: Initialise commit_info.rpc_out when !defined(CONFIG_NFS_V4)
  NFS: Fix a refcounting issue in O_DIRECT
  NFSv4.1: Fix a race in set_pnfs_layoutdriver
  NFSv4.1: Fix umount when filelayout DS is also the MDS
  • Loading branch information
torvalds committed Jun 21, 2012
2 parents 8874e81 + b102743 commit 636040b
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 11 deletions.
1 change: 0 additions & 1 deletion fs/nfs/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,6 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
static void nfs4_shutdown_session(struct nfs_client *clp)
{
if (nfs4_has_session(clp)) {
nfs4_deviceid_purge_client(clp);
nfs4_destroy_session(clp->cl_session);
nfs4_destroy_clientid(clp);
}
Expand Down
1 change: 1 addition & 0 deletions fs/nfs/direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
dreq->error = -EIO;
spin_unlock(cinfo.lock);
}
nfs_release_request(req);
}
nfs_pageio_complete(&desc);

Expand Down
13 changes: 8 additions & 5 deletions fs/nfs/idmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ unsigned int nfs_idmap_cache_timeout = 600;
static const struct cred *id_resolver_cache;
static struct key_type key_type_id_resolver_legacy;

struct idmap {
struct rpc_pipe *idmap_pipe;
struct key_construction *idmap_key_cons;
struct mutex idmap_mutex;
};

/**
* nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields
Expand Down Expand Up @@ -310,9 +315,11 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen,
name, namelen, type, data,
data_size, NULL);
if (ret < 0) {
mutex_lock(&idmap->idmap_mutex);
ret = nfs_idmap_request_key(&key_type_id_resolver_legacy,
name, namelen, type, data,
data_size, idmap);
mutex_unlock(&idmap->idmap_mutex);
}
return ret;
}
Expand Down Expand Up @@ -354,11 +361,6 @@ static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *typ
/* idmap classic begins here */
module_param(nfs_idmap_cache_timeout, int, 0644);

struct idmap {
struct rpc_pipe *idmap_pipe;
struct key_construction *idmap_key_cons;
};

enum {
Opt_find_uid, Opt_find_gid, Opt_find_user, Opt_find_group, Opt_find_err
};
Expand Down Expand Up @@ -469,6 +471,7 @@ nfs_idmap_new(struct nfs_client *clp)
return error;
}
idmap->idmap_pipe = pipe;
mutex_init(&idmap->idmap_mutex);

clp->cl_idmap = idmap;
return 0;
Expand Down
2 changes: 1 addition & 1 deletion fs/nfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1530,7 +1530,6 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi)
nfsi->delegation_state = 0;
init_rwsem(&nfsi->rwsem);
nfsi->layout = NULL;
atomic_set(&nfsi->commit_info.rpcs_out, 0);
#endif
}

Expand All @@ -1545,6 +1544,7 @@ static void init_once(void *foo)
INIT_LIST_HEAD(&nfsi->commit_info.list);
nfsi->npages = 0;
nfsi->commit_info.ncommit = 0;
atomic_set(&nfsi->commit_info.rpcs_out, 0);
atomic_set(&nfsi->silly_count, 1);
INIT_HLIST_HEAD(&nfsi->silly_list);
init_waitqueue_head(&nfsi->waitqueue);
Expand Down
13 changes: 9 additions & 4 deletions fs/nfs/pnfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ find_pnfs_driver(u32 id)

spin_lock(&pnfs_spinlock);
local = find_pnfs_driver_locked(id);
if (local != NULL && !try_module_get(local->owner)) {
dprintk("%s: Could not grab reference on module\n", __func__);
local = NULL;
}
spin_unlock(&pnfs_spinlock);
return local;
}
Expand All @@ -80,6 +84,9 @@ unset_pnfs_layoutdriver(struct nfs_server *nfss)
if (nfss->pnfs_curr_ld) {
if (nfss->pnfs_curr_ld->clear_layoutdriver)
nfss->pnfs_curr_ld->clear_layoutdriver(nfss);
/* Decrement the MDS count. Purge the deviceid cache if zero */
if (atomic_dec_and_test(&nfss->nfs_client->cl_mds_count))
nfs4_deviceid_purge_client(nfss->nfs_client);
module_put(nfss->pnfs_curr_ld->owner);
}
nfss->pnfs_curr_ld = NULL;
Expand Down Expand Up @@ -115,10 +122,6 @@ set_pnfs_layoutdriver(struct nfs_server *server, const struct nfs_fh *mntfh,
goto out_no_driver;
}
}
if (!try_module_get(ld_type->owner)) {
dprintk("%s: Could not grab reference on module\n", __func__);
goto out_no_driver;
}
server->pnfs_curr_ld = ld_type;
if (ld_type->set_layoutdriver
&& ld_type->set_layoutdriver(server, mntfh)) {
Expand All @@ -127,6 +130,8 @@ set_pnfs_layoutdriver(struct nfs_server *server, const struct nfs_fh *mntfh,
module_put(ld_type->owner);
goto out_no_driver;
}
/* Bump the MDS count */
atomic_inc(&server->nfs_client->cl_mds_count);

dprintk("%s: pNFS module for %u set\n", __func__, id);
return;
Expand Down
1 change: 1 addition & 0 deletions include/linux/nfs_fs_sb.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct nfs41_impl_id;
*/
struct nfs_client {
atomic_t cl_count;
atomic_t cl_mds_count;
int cl_cons_state; /* current construction state (-ve: init error) */
#define NFS_CS_READY 0 /* ready to be used */
#define NFS_CS_INITING 1 /* busy initialising */
Expand Down

0 comments on commit 636040b

Please sign in to comment.