Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 5866
b: refs/heads/master
c: 412d582
h: refs/heads/master
v: v3
  • Loading branch information
Chuck Lever authored and Linus Torvalds committed Aug 18, 2005
1 parent ffbed54 commit 07fdc88
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 40 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5529680981807b44abf3be30fb6d612ff04f68ff
refs/heads/master: 412d582ec1dd59aab2353f8cb7e74f2c79cd20b9
4 changes: 2 additions & 2 deletions trunk/fs/nfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
/* We requested READDIRPLUS, but the server doesn't grok it */
if (error == -ENOTSUPP && desc->plus) {
NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS;
NFS_FLAGS(inode) &= ~NFS_INO_ADVISE_RDPLUS;
clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
desc->plus = 0;
goto again;
}
Expand Down Expand Up @@ -545,7 +545,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
break;
}
if (res == -ETOOSMALL && desc->plus) {
NFS_FLAGS(inode) &= ~NFS_INO_ADVISE_RDPLUS;
clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
nfs_zap_caches(inode);
desc->plus = 0;
desc->entry->eof = 0;
Expand Down
69 changes: 43 additions & 26 deletions trunk/fs/nfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
inode->i_fop = &nfs_dir_operations;
if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS)
&& fattr->size <= NFS_LIMIT_READDIRPLUS)
NFS_FLAGS(inode) |= NFS_INO_ADVISE_RDPLUS;
set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
} else if (S_ISLNK(inode->i_mode))
inode->i_op = &nfs_symlink_inode_operations;
else
Expand Down Expand Up @@ -849,26 +849,43 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
}
}

static int nfs_wait_schedule(void *word)
{
if (signal_pending(current))
return -ERESTARTSYS;
schedule();
return 0;
}

/*
* Wait for the inode to get unlocked.
* (Used for NFS_INO_LOCKED and NFS_INO_REVALIDATING).
*/
static int
nfs_wait_on_inode(struct inode *inode, int flag)
static int nfs_wait_on_inode(struct inode *inode)
{
struct rpc_clnt *clnt = NFS_CLIENT(inode);
struct nfs_inode *nfsi = NFS_I(inode);

sigset_t oldmask;
int error;
if (!(NFS_FLAGS(inode) & flag))
return 0;

atomic_inc(&inode->i_count);
error = nfs_wait_event(clnt, nfsi->nfs_i_wait,
!(NFS_FLAGS(inode) & flag));
rpc_clnt_sigmask(clnt, &oldmask);
error = wait_on_bit_lock(&nfsi->flags, NFS_INO_REVALIDATING,
nfs_wait_schedule, TASK_INTERRUPTIBLE);
rpc_clnt_sigunmask(clnt, &oldmask);
iput(inode);

return error;
}

static void nfs_wake_up_inode(struct inode *inode)
{
struct nfs_inode *nfsi = NFS_I(inode);

clear_bit(NFS_INO_REVALIDATING, &nfsi->flags);
smp_mb__after_clear_bit();
wake_up_bit(&nfsi->flags, NFS_INO_REVALIDATING);
}

int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
{
struct inode *inode = dentry->d_inode;
Expand Down Expand Up @@ -1029,18 +1046,19 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
if (NFS_STALE(inode))
goto out_nowait;

while (NFS_REVALIDATING(inode)) {
status = nfs_wait_on_inode(inode, NFS_INO_REVALIDATING);
if (status < 0)
goto out_nowait;
if (NFS_ATTRTIMEO(inode) == 0)
continue;
if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ATIME))
continue;
status = NFS_STALE(inode) ? -ESTALE : 0;
goto out_nowait;
status = nfs_wait_on_inode(inode);
if (status < 0)
goto out;
if (NFS_STALE(inode)) {
status = -ESTALE;
/* Do we trust the cached ESTALE? */
if (NFS_ATTRTIMEO(inode) != 0) {
if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ATIME)) {
/* no */
} else
goto out;
}
}
NFS_FLAGS(inode) |= NFS_INO_REVALIDATING;

/* Protect against RPC races by saving the change attribute */
verifier = nfs_save_change_attribute(inode);
Expand All @@ -1052,7 +1070,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
if (status == -ESTALE) {
nfs_zap_caches(inode);
if (!S_ISDIR(inode->i_mode))
NFS_FLAGS(inode) |= NFS_INO_STALE;
set_bit(NFS_INO_STALE, &NFS_FLAGS(inode));
}
goto out;
}
Expand Down Expand Up @@ -1083,9 +1101,9 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
inode->i_sb->s_id,
(long long)NFS_FILEID(inode));

out:
NFS_FLAGS(inode) &= ~NFS_INO_REVALIDATING;
wake_up(&nfsi->nfs_i_wait);
out:
nfs_wake_up_inode(inode);

out_nowait:
unlock_kernel();
return status;
Expand Down Expand Up @@ -1404,7 +1422,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
*/
nfs_invalidate_inode(inode);
out_err:
NFS_FLAGS(inode) |= NFS_INO_STALE;
set_bit(NFS_INO_STALE, &NFS_FLAGS(inode));
return -ESTALE;
}

Expand Down Expand Up @@ -1996,7 +2014,6 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
nfsi->ndirty = 0;
nfsi->ncommit = 0;
nfsi->npages = 0;
init_waitqueue_head(&nfsi->nfs_i_wait);
nfs4_init_once(nfsi);
}
}
Expand Down
19 changes: 8 additions & 11 deletions trunk/include/linux/nfs_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ struct nfs_inode {
/*
* Various flags
*/
unsigned int flags;
unsigned long cache_validity;
unsigned long flags; /* atomic bit ops */
unsigned long cache_validity; /* bit mask */

/*
* read_cache_jiffies is when we started read-caching this inode,
Expand Down Expand Up @@ -175,8 +175,6 @@ struct nfs_inode {
/* Open contexts for shared mmap writes */
struct list_head open_files;

wait_queue_head_t nfs_i_wait;

#ifdef CONFIG_NFS_V4
struct nfs4_cached_acl *nfs4_acl;
/* NFSv4 state */
Expand All @@ -199,11 +197,11 @@ struct nfs_inode {
#define NFS_INO_REVAL_PAGECACHE 0x0020 /* must revalidate pagecache */

/*
* Legal values of flags field
* Bit offsets in flags field
*/
#define NFS_INO_REVALIDATING 0x0001 /* revalidating attrs */
#define NFS_INO_ADVISE_RDPLUS 0x0002 /* advise readdirplus */
#define NFS_INO_STALE 0x0004 /* possible stale inode */
#define NFS_INO_REVALIDATING (0) /* revalidating attrs */
#define NFS_INO_ADVISE_RDPLUS (1) /* advise readdirplus */
#define NFS_INO_STALE (2) /* possible stale inode */

static inline struct nfs_inode *NFS_I(struct inode *inode)
{
Expand All @@ -229,8 +227,7 @@ static inline struct nfs_inode *NFS_I(struct inode *inode)
#define NFS_ATTRTIMEO_UPDATE(inode) (NFS_I(inode)->attrtimeo_timestamp)

#define NFS_FLAGS(inode) (NFS_I(inode)->flags)
#define NFS_REVALIDATING(inode) (NFS_FLAGS(inode) & NFS_INO_REVALIDATING)
#define NFS_STALE(inode) (NFS_FLAGS(inode) & NFS_INO_STALE)
#define NFS_STALE(inode) (test_bit(NFS_INO_STALE, &NFS_FLAGS(inode)))

#define NFS_FILEID(inode) (NFS_I(inode)->fileid)

Expand All @@ -252,7 +249,7 @@ static inline int nfs_server_capable(struct inode *inode, int cap)

static inline int NFS_USE_READDIRPLUS(struct inode *inode)
{
return NFS_FLAGS(inode) & NFS_INO_ADVISE_RDPLUS;
return test_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
}

/**
Expand Down

0 comments on commit 07fdc88

Please sign in to comment.