forked from luck/tmp_suning_uos_patched
Merge git://git.linux-nfs.org/pub/linux/nfs-2.6
* git://git.linux-nfs.org/pub/linux/nfs-2.6: NFS: Kill the obsolete NFS_PARANOIA NFS: use __set_current_state() sunrpc: fix crash in rpc_malloc() NFS: Clean up NFSv4 XDR error message NFS: NFS client underestimates how large an NFSv4 SETATTR reply can be SUNRPC: Fix pointer arithmetic bug recently introduced in rpc_malloc/free NFS: Remove redundant check in nfs_check_verifier() NFS: Fix a jiffie wraparound issue
This commit is contained in:
commit
d0b6e0e380
37
fs/nfs/dir.c
37
fs/nfs/dir.c
|
@ -38,7 +38,6 @@
|
||||||
#include "delegation.h"
|
#include "delegation.h"
|
||||||
#include "iostat.h"
|
#include "iostat.h"
|
||||||
|
|
||||||
#define NFS_PARANOIA 1
|
|
||||||
/* #define NFS_DEBUG_VERBOSE 1 */
|
/* #define NFS_DEBUG_VERBOSE 1 */
|
||||||
|
|
||||||
static int nfs_opendir(struct inode *, struct file *);
|
static int nfs_opendir(struct inode *, struct file *);
|
||||||
|
@ -650,12 +649,15 @@ int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync)
|
||||||
*/
|
*/
|
||||||
static int nfs_check_verifier(struct inode *dir, struct dentry *dentry)
|
static int nfs_check_verifier(struct inode *dir, struct dentry *dentry)
|
||||||
{
|
{
|
||||||
|
unsigned long verf;
|
||||||
|
|
||||||
if (IS_ROOT(dentry))
|
if (IS_ROOT(dentry))
|
||||||
return 1;
|
return 1;
|
||||||
if ((NFS_I(dir)->cache_validity & NFS_INO_INVALID_ATTR) != 0
|
verf = (unsigned long)dentry->d_fsdata;
|
||||||
|| nfs_attribute_timeout(dir))
|
if (nfs_caches_unstable(dir)
|
||||||
|
|| verf != NFS_I(dir)->cache_change_attribute)
|
||||||
return 0;
|
return 0;
|
||||||
return nfs_verify_change_attribute(dir, (unsigned long)dentry->d_fsdata);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void nfs_set_verifier(struct dentry * dentry, unsigned long verf)
|
static inline void nfs_set_verifier(struct dentry * dentry, unsigned long verf)
|
||||||
|
@ -665,8 +667,7 @@ static inline void nfs_set_verifier(struct dentry * dentry, unsigned long verf)
|
||||||
|
|
||||||
static void nfs_refresh_verifier(struct dentry * dentry, unsigned long verf)
|
static void nfs_refresh_verifier(struct dentry * dentry, unsigned long verf)
|
||||||
{
|
{
|
||||||
if (time_after(verf, (unsigned long)dentry->d_fsdata))
|
nfs_set_verifier(dentry, verf);
|
||||||
nfs_set_verifier(dentry, verf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -765,6 +766,10 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
|
||||||
nfs_inc_stats(dir, NFSIOS_DENTRYREVALIDATE);
|
nfs_inc_stats(dir, NFSIOS_DENTRYREVALIDATE);
|
||||||
inode = dentry->d_inode;
|
inode = dentry->d_inode;
|
||||||
|
|
||||||
|
/* Revalidate parent directory attribute cache */
|
||||||
|
if (nfs_revalidate_inode(NFS_SERVER(dir), dir) < 0)
|
||||||
|
goto out_zap_parent;
|
||||||
|
|
||||||
if (!inode) {
|
if (!inode) {
|
||||||
if (nfs_neg_need_reval(dir, dentry, nd))
|
if (nfs_neg_need_reval(dir, dentry, nd))
|
||||||
goto out_bad;
|
goto out_bad;
|
||||||
|
@ -778,10 +783,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
|
||||||
goto out_bad;
|
goto out_bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Revalidate parent directory attribute cache */
|
|
||||||
if (nfs_revalidate_inode(NFS_SERVER(dir), dir) < 0)
|
|
||||||
goto out_zap_parent;
|
|
||||||
|
|
||||||
/* Force a full look up iff the parent directory has changed */
|
/* Force a full look up iff the parent directory has changed */
|
||||||
if (nfs_check_verifier(dir, dentry)) {
|
if (nfs_check_verifier(dir, dentry)) {
|
||||||
if (nfs_lookup_verify_inode(inode, nd))
|
if (nfs_lookup_verify_inode(inode, nd))
|
||||||
|
@ -1360,11 +1361,6 @@ static int nfs_sillyrename(struct inode *dir, struct dentry *dentry)
|
||||||
atomic_read(&dentry->d_count));
|
atomic_read(&dentry->d_count));
|
||||||
nfs_inc_stats(dir, NFSIOS_SILLYRENAME);
|
nfs_inc_stats(dir, NFSIOS_SILLYRENAME);
|
||||||
|
|
||||||
#ifdef NFS_PARANOIA
|
|
||||||
if (!dentry->d_inode)
|
|
||||||
printk("NFS: silly-renaming %s/%s, negative dentry??\n",
|
|
||||||
dentry->d_parent->d_name.name, dentry->d_name.name);
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* We don't allow a dentry to be silly-renamed twice.
|
* We don't allow a dentry to be silly-renamed twice.
|
||||||
*/
|
*/
|
||||||
|
@ -1681,16 +1677,9 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||||
new_inode = NULL;
|
new_inode = NULL;
|
||||||
/* instantiate the replacement target */
|
/* instantiate the replacement target */
|
||||||
d_instantiate(new_dentry, NULL);
|
d_instantiate(new_dentry, NULL);
|
||||||
} else if (atomic_read(&new_dentry->d_count) > 1) {
|
} else if (atomic_read(&new_dentry->d_count) > 1)
|
||||||
/* dentry still busy? */
|
/* dentry still busy? */
|
||||||
#ifdef NFS_PARANOIA
|
|
||||||
printk("nfs_rename: target %s/%s busy, d_count=%d\n",
|
|
||||||
new_dentry->d_parent->d_name.name,
|
|
||||||
new_dentry->d_name.name,
|
|
||||||
atomic_read(&new_dentry->d_count));
|
|
||||||
#endif
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
drop_nlink(new_inode);
|
drop_nlink(new_inode);
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#define NFSDBG_FACILITY NFSDBG_CLIENT
|
#define NFSDBG_FACILITY NFSDBG_CLIENT
|
||||||
#define NFS_PARANOIA 1
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get an NFS2/NFS3 root dentry from the root filehandle
|
* get an NFS2/NFS3 root dentry from the root filehandle
|
||||||
|
|
|
@ -272,7 +272,7 @@ nfs_idmap_id(struct idmap *idmap, struct idmap_hashtable *h,
|
||||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||||
mutex_unlock(&idmap->idmap_im_lock);
|
mutex_unlock(&idmap->idmap_im_lock);
|
||||||
schedule();
|
schedule();
|
||||||
current->state = TASK_RUNNING;
|
__set_current_state(TASK_RUNNING);
|
||||||
remove_wait_queue(&idmap->idmap_wq, &wq);
|
remove_wait_queue(&idmap->idmap_wq, &wq);
|
||||||
mutex_lock(&idmap->idmap_im_lock);
|
mutex_lock(&idmap->idmap_im_lock);
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h,
|
||||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||||
mutex_unlock(&idmap->idmap_im_lock);
|
mutex_unlock(&idmap->idmap_im_lock);
|
||||||
schedule();
|
schedule();
|
||||||
current->state = TASK_RUNNING;
|
__set_current_state(TASK_RUNNING);
|
||||||
remove_wait_queue(&idmap->idmap_wq, &wq);
|
remove_wait_queue(&idmap->idmap_wq, &wq);
|
||||||
mutex_lock(&idmap->idmap_im_lock);
|
mutex_lock(&idmap->idmap_im_lock);
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,6 @@
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#define NFSDBG_FACILITY NFSDBG_VFS
|
#define NFSDBG_FACILITY NFSDBG_VFS
|
||||||
#define NFS_PARANOIA 1
|
|
||||||
|
|
||||||
static void nfs_invalidate_inode(struct inode *);
|
static void nfs_invalidate_inode(struct inode *);
|
||||||
static int nfs_update_inode(struct inode *, struct nfs_fattr *);
|
static int nfs_update_inode(struct inode *, struct nfs_fattr *);
|
||||||
|
@ -1075,10 +1074,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
||||||
/*
|
/*
|
||||||
* Big trouble! The inode has become a different object.
|
* Big trouble! The inode has become a different object.
|
||||||
*/
|
*/
|
||||||
#ifdef NFS_PARANOIA
|
|
||||||
printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n",
|
printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n",
|
||||||
__FUNCTION__, inode->i_ino, inode->i_mode, fattr->mode);
|
__FUNCTION__, inode->i_ino, inode->i_mode, fattr->mode);
|
||||||
#endif
|
|
||||||
out_err:
|
out_err:
|
||||||
/*
|
/*
|
||||||
* No need to worry about unhashing the dentry, as the
|
* No need to worry about unhashing the dentry, as the
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#define NFSDBG_FACILITY NFSDBG_XDR
|
#define NFSDBG_FACILITY NFSDBG_XDR
|
||||||
/* #define NFS_PARANOIA 1 */
|
|
||||||
|
|
||||||
/* Mapping from NFS error code to "errno" error code. */
|
/* Mapping from NFS error code to "errno" error code. */
|
||||||
#define errno_NFSERR_IO EIO
|
#define errno_NFSERR_IO EIO
|
||||||
|
|
|
@ -224,7 +224,8 @@ static int nfs4_stat_to_errno(int);
|
||||||
encode_getattr_maxsz)
|
encode_getattr_maxsz)
|
||||||
#define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \
|
#define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \
|
||||||
decode_putfh_maxsz + \
|
decode_putfh_maxsz + \
|
||||||
op_decode_hdr_maxsz + 3)
|
op_decode_hdr_maxsz + 3 + \
|
||||||
|
nfs4_fattr_maxsz)
|
||||||
#define NFS4_enc_fsinfo_sz (compound_encode_hdr_maxsz + \
|
#define NFS4_enc_fsinfo_sz (compound_encode_hdr_maxsz + \
|
||||||
encode_putfh_maxsz + \
|
encode_putfh_maxsz + \
|
||||||
encode_fsinfo_maxsz)
|
encode_fsinfo_maxsz)
|
||||||
|
@ -2079,9 +2080,11 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
|
||||||
|
|
||||||
#define READ_BUF(nbytes) do { \
|
#define READ_BUF(nbytes) do { \
|
||||||
p = xdr_inline_decode(xdr, nbytes); \
|
p = xdr_inline_decode(xdr, nbytes); \
|
||||||
if (!p) { \
|
if (unlikely(!p)) { \
|
||||||
printk(KERN_WARNING "%s: reply buffer overflowed in line %d.", \
|
printk(KERN_INFO "%s: prematurely hit end of receive" \
|
||||||
__FUNCTION__, __LINE__); \
|
" buffer\n", __FUNCTION__); \
|
||||||
|
printk(KERN_INFO "%s: xdr->p=%p, bytes=%u, xdr->end=%p\n", \
|
||||||
|
__FUNCTION__, xdr->p, nbytes, xdr->end); \
|
||||||
return -EIO; \
|
return -EIO; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#define NFS_PARANOIA 1
|
|
||||||
|
|
||||||
static struct kmem_cache *nfs_page_cachep;
|
static struct kmem_cache *nfs_page_cachep;
|
||||||
|
|
||||||
static inline struct nfs_page *
|
static inline struct nfs_page *
|
||||||
|
@ -167,11 +165,6 @@ nfs_release_request(struct nfs_page *req)
|
||||||
if (!atomic_dec_and_test(&req->wb_count))
|
if (!atomic_dec_and_test(&req->wb_count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef NFS_PARANOIA
|
|
||||||
BUG_ON (!list_empty(&req->wb_list));
|
|
||||||
BUG_ON (NFS_WBACK_BUSY(req));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Release struct file or cached credential */
|
/* Release struct file or cached credential */
|
||||||
nfs_clear_request(req);
|
nfs_clear_request(req);
|
||||||
put_nfs_open_context(req->wb_context);
|
put_nfs_open_context(req->wb_context);
|
||||||
|
|
|
@ -736,6 +736,11 @@ static void rpc_async_schedule(struct work_struct *work)
|
||||||
__rpc_execute(container_of(work, struct rpc_task, u.tk_work));
|
__rpc_execute(container_of(work, struct rpc_task, u.tk_work));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct rpc_buffer {
|
||||||
|
size_t len;
|
||||||
|
char data[];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rpc_malloc - allocate an RPC buffer
|
* rpc_malloc - allocate an RPC buffer
|
||||||
* @task: RPC task that will use this buffer
|
* @task: RPC task that will use this buffer
|
||||||
|
@ -754,18 +759,22 @@ static void rpc_async_schedule(struct work_struct *work)
|
||||||
*/
|
*/
|
||||||
void *rpc_malloc(struct rpc_task *task, size_t size)
|
void *rpc_malloc(struct rpc_task *task, size_t size)
|
||||||
{
|
{
|
||||||
size_t *buf;
|
struct rpc_buffer *buf;
|
||||||
gfp_t gfp = RPC_IS_SWAPPER(task) ? GFP_ATOMIC : GFP_NOWAIT;
|
gfp_t gfp = RPC_IS_SWAPPER(task) ? GFP_ATOMIC : GFP_NOWAIT;
|
||||||
|
|
||||||
size += sizeof(size_t);
|
size += sizeof(struct rpc_buffer);
|
||||||
if (size <= RPC_BUFFER_MAXSIZE)
|
if (size <= RPC_BUFFER_MAXSIZE)
|
||||||
buf = mempool_alloc(rpc_buffer_mempool, gfp);
|
buf = mempool_alloc(rpc_buffer_mempool, gfp);
|
||||||
else
|
else
|
||||||
buf = kmalloc(size, gfp);
|
buf = kmalloc(size, gfp);
|
||||||
*buf = size;
|
|
||||||
|
if (!buf)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
buf->len = size;
|
||||||
dprintk("RPC: %5u allocated buffer of size %zu at %p\n",
|
dprintk("RPC: %5u allocated buffer of size %zu at %p\n",
|
||||||
task->tk_pid, size, buf);
|
task->tk_pid, size, buf);
|
||||||
return ++buf;
|
return &buf->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -775,15 +784,18 @@ void *rpc_malloc(struct rpc_task *task, size_t size)
|
||||||
*/
|
*/
|
||||||
void rpc_free(void *buffer)
|
void rpc_free(void *buffer)
|
||||||
{
|
{
|
||||||
size_t size, *buf = buffer;
|
size_t size;
|
||||||
|
struct rpc_buffer *buf;
|
||||||
|
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return;
|
return;
|
||||||
size = *buf;
|
|
||||||
buf--;
|
buf = container_of(buffer, struct rpc_buffer, data);
|
||||||
|
size = buf->len;
|
||||||
|
|
||||||
dprintk("RPC: freeing buffer of size %zu at %p\n",
|
dprintk("RPC: freeing buffer of size %zu at %p\n",
|
||||||
size, buf);
|
size, buf);
|
||||||
|
|
||||||
if (size <= RPC_BUFFER_MAXSIZE)
|
if (size <= RPC_BUFFER_MAXSIZE)
|
||||||
mempool_free(buf, rpc_buffer_mempool);
|
mempool_free(buf, rpc_buffer_mempool);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue
Block a user