|
@@ -725,14 +725,12 @@ out:
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Obtain the readahead parameters for the file
|
|
|
- * specified by (dev, ino).
|
|
|
- */
|
|
|
-
|
|
|
-static inline struct raparms *
|
|
|
-nfsd_get_raparms(dev_t dev, ino_t ino)
|
|
|
+struct raparms *
|
|
|
+nfsd_init_raparms(struct file *file)
|
|
|
{
|
|
|
+ struct inode *inode = file_inode(file);
|
|
|
+ dev_t dev = inode->i_sb->s_dev;
|
|
|
+ ino_t ino = inode->i_ino;
|
|
|
struct raparms *ra, **rap, **frap = NULL;
|
|
|
int depth = 0;
|
|
|
unsigned int hash;
|
|
@@ -769,9 +767,23 @@ found:
|
|
|
ra->p_count++;
|
|
|
nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++;
|
|
|
spin_unlock(&rab->pb_lock);
|
|
|
+
|
|
|
+ if (ra->p_set)
|
|
|
+ file->f_ra = ra->p_ra;
|
|
|
return ra;
|
|
|
}
|
|
|
|
|
|
+void nfsd_put_raparams(struct file *file, struct raparms *ra)
|
|
|
+{
|
|
|
+ struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
|
|
|
+
|
|
|
+ spin_lock(&rab->pb_lock);
|
|
|
+ ra->p_ra = file->f_ra;
|
|
|
+ ra->p_set = 1;
|
|
|
+ ra->p_count--;
|
|
|
+ spin_unlock(&rab->pb_lock);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Grab and keep cached pages associated with a file in the svc_rqst
|
|
|
* so that they can be passed to the network sendmsg/sendpage routines
|
|
@@ -964,40 +976,6 @@ out_nfserr:
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
-__be32 nfsd_get_tmp_read_open(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|
|
- struct file **file, struct raparms **ra)
|
|
|
-{
|
|
|
- struct inode *inode;
|
|
|
- __be32 err;
|
|
|
-
|
|
|
- err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, file);
|
|
|
- if (err)
|
|
|
- return err;
|
|
|
-
|
|
|
- inode = file_inode(*file);
|
|
|
-
|
|
|
- /* Get readahead parameters */
|
|
|
- *ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino);
|
|
|
-
|
|
|
- if (*ra && (*ra)->p_set)
|
|
|
- (*file)->f_ra = (*ra)->p_ra;
|
|
|
- return nfs_ok;
|
|
|
-}
|
|
|
-
|
|
|
-void nfsd_put_tmp_read_open(struct file *file, struct raparms *ra)
|
|
|
-{
|
|
|
- /* Write back readahead params */
|
|
|
- if (ra) {
|
|
|
- struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
|
|
|
- spin_lock(&rab->pb_lock);
|
|
|
- ra->p_ra = file->f_ra;
|
|
|
- ra->p_set = 1;
|
|
|
- ra->p_count--;
|
|
|
- spin_unlock(&rab->pb_lock);
|
|
|
- }
|
|
|
- fput(file);
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* Read data from a file. count must contain the requested read count
|
|
|
* on entry. On return, *count contains the number of bytes actually read.
|
|
@@ -1010,13 +988,15 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|
|
struct raparms *ra;
|
|
|
__be32 err;
|
|
|
|
|
|
- err = nfsd_get_tmp_read_open(rqstp, fhp, &file, &ra);
|
|
|
+ err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
|
+ ra = nfsd_init_raparms(file);
|
|
|
err = nfsd_vfs_read(rqstp, file, offset, vec, vlen, count);
|
|
|
-
|
|
|
- nfsd_put_tmp_read_open(file, ra);
|
|
|
+ if (ra)
|
|
|
+ nfsd_put_raparams(file, ra);
|
|
|
+ fput(file);
|
|
|
|
|
|
return err;
|
|
|
}
|