diff options
author | Bernd Schubert <bernd.schubert@itwm.fraunhofer.de> | 2012-03-18 22:44:50 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-03-18 22:44:50 -0400 |
commit | 06effdbb49af5f6c7d20affaec74603914acc768 (patch) | |
tree | 6cb59cbb05565e6c23c8ecf5eb79618083f330f7 /fs/nfsd | |
parent | 999448a8c0202d8c41711c92385323520644527b (diff) |
nfsd: vfs_llseek() with 32 or 64 bit offsets (hashes)
Use 32-bit or 64-bit llseek() hashes for directory offsets depending on
the NFS version. NFSv2 gets 32-bit hashes only.
NOTE: This patch got rather complex as Christoph asked to set the
filp->f_mode flag in the open call or immediatly after dentry_open()
in nfsd_open() to avoid races.
Personally I still do not see a reason for that and in my opinion
FMODE_32BITHASH/FMODE_64BITHASH flags could be set nfsd_readdir(), as it
follows directly after nfsd_open() without a chance of races.
Signed-off-by: Bernd Schubert <bernd.schubert@itwm.fraunhofer.de>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Acked-by: J. Bruce Fields<bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/vfs.c | 15 | ||||
-rw-r--r-- | fs/nfsd/vfs.h | 2 |
2 files changed, 15 insertions, 2 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index a6db4cb874d5..7423d712eb8c 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -796,9 +796,15 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, | |||
796 | flags, current_cred()); | 796 | flags, current_cred()); |
797 | if (IS_ERR(*filp)) | 797 | if (IS_ERR(*filp)) |
798 | host_err = PTR_ERR(*filp); | 798 | host_err = PTR_ERR(*filp); |
799 | else | 799 | else { |
800 | host_err = ima_file_check(*filp, may_flags); | 800 | host_err = ima_file_check(*filp, may_flags); |
801 | 801 | ||
802 | if (may_flags & NFSD_MAY_64BIT_COOKIE) | ||
803 | (*filp)->f_mode |= FMODE_64BITHASH; | ||
804 | else | ||
805 | (*filp)->f_mode |= FMODE_32BITHASH; | ||
806 | } | ||
807 | |||
802 | out_nfserr: | 808 | out_nfserr: |
803 | err = nfserrno(host_err); | 809 | err = nfserrno(host_err); |
804 | out: | 810 | out: |
@@ -2022,8 +2028,13 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, | |||
2022 | __be32 err; | 2028 | __be32 err; |
2023 | struct file *file; | 2029 | struct file *file; |
2024 | loff_t offset = *offsetp; | 2030 | loff_t offset = *offsetp; |
2031 | int may_flags = NFSD_MAY_READ; | ||
2032 | |||
2033 | /* NFSv2 only supports 32 bit cookies */ | ||
2034 | if (rqstp->rq_vers > 2) | ||
2035 | may_flags |= NFSD_MAY_64BIT_COOKIE; | ||
2025 | 2036 | ||
2026 | err = nfsd_open(rqstp, fhp, S_IFDIR, NFSD_MAY_READ, &file); | 2037 | err = nfsd_open(rqstp, fhp, S_IFDIR, may_flags, &file); |
2027 | if (err) | 2038 | if (err) |
2028 | goto out; | 2039 | goto out; |
2029 | 2040 | ||
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index 1dcd238e11a0..ec0611b2b738 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h | |||
@@ -27,6 +27,8 @@ | |||
27 | #define NFSD_MAY_BYPASS_GSS 0x400 | 27 | #define NFSD_MAY_BYPASS_GSS 0x400 |
28 | #define NFSD_MAY_READ_IF_EXEC 0x800 | 28 | #define NFSD_MAY_READ_IF_EXEC 0x800 |
29 | 29 | ||
30 | #define NFSD_MAY_64BIT_COOKIE 0x1000 /* 64 bit readdir cookies for >= NFSv3 */ | ||
31 | |||
30 | #define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) | 32 | #define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) |
31 | #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) | 33 | #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) |
32 | 34 | ||