diff options
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/auth.c | 3 | ||||
-rw-r--r-- | fs/nfsd/export.c | 17 | ||||
-rw-r--r-- | fs/nfsd/nfs4idmap.c | 6 | ||||
-rw-r--r-- | fs/nfsd/nfs4proc.c | 10 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 18 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfsfh.c | 20 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 21 |
8 files changed, 63 insertions, 34 deletions
diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c index cf61dc8ae94..21928056e35 100644 --- a/fs/nfsd/auth.c +++ b/fs/nfsd/auth.c @@ -9,10 +9,11 @@ #include <linux/sunrpc/svc.h> #include <linux/sunrpc/svcauth.h> #include <linux/nfsd/nfsd.h> +#include <linux/nfsd/export.h> #define CAP_NFSD_MASK (CAP_FS_MASK|CAP_TO_MASK(CAP_SYS_RESOURCE)) -static int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp) +int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp) { struct exp_flavor_info *f; struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors; diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index c7bbf460b00..cba899a3494 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -564,9 +564,10 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) /* flags */ err = get_int(&mesg, &an_int); - if (err == -ENOENT) + if (err == -ENOENT) { + err = 0; set_bit(CACHE_NEGATIVE, &exp.h.flags); - else { + } else { if (err || an_int < 0) goto out; exp.ex_flags= an_int; @@ -1265,7 +1266,7 @@ struct svc_export * rqst_exp_get_by_name(struct svc_rqst *rqstp, struct vfsmount *mnt, struct dentry *dentry) { - struct svc_export *gssexp, *exp = NULL; + struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); if (rqstp->rq_client == NULL) goto gss; @@ -1288,7 +1289,7 @@ gss: &rqstp->rq_chandle); if (PTR_ERR(gssexp) == -ENOENT) return exp; - if (exp && !IS_ERR(exp)) + if (!IS_ERR(exp)) exp_put(exp); return gssexp; } @@ -1296,7 +1297,7 @@ gss: struct svc_export * rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv) { - struct svc_export *gssexp, *exp = NULL; + struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); if (rqstp->rq_client == NULL) goto gss; @@ -1318,7 +1319,7 @@ gss: &rqstp->rq_chandle); if (PTR_ERR(gssexp) == -ENOENT) return exp; - if (exp && !IS_ERR(exp)) + if (!IS_ERR(exp)) exp_put(exp); return gssexp; } @@ -1503,9 +1504,9 @@ static void exp_flags(struct seq_file *m, int flag, int fsid, if (flag & NFSEXP_FSID) seq_printf(m, ",fsid=%d", fsid); if (anonu != (uid_t)-2 && anonu != (0x10000-2)) - seq_printf(m, ",sanonuid=%d", anonu); + seq_printf(m, ",anonuid=%u", anonu); if (anong != (gid_t)-2 && anong != (0x10000-2)) - seq_printf(m, ",sanongid=%d", anong); + seq_printf(m, ",anongid=%u", anong); if (fsloc && fsloc->locations_count > 0) { char *loctype = (fsloc->migrated) ? "refer" : "replicas"; int i; diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index 2cf9a9a2d89..2ccffde81b8 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c @@ -138,7 +138,7 @@ idtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp, char idstr[11]; qword_add(bpp, blen, ent->authname); - snprintf(idstr, sizeof(idstr), "%d", ent->id); + snprintf(idstr, sizeof(idstr), "%u", ent->id); qword_add(bpp, blen, ent->type == IDMAP_TYPE_GROUP ? "group" : "user"); qword_add(bpp, blen, idstr); @@ -165,7 +165,7 @@ idtoname_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h) return 0; } ent = container_of(h, struct ent, h); - seq_printf(m, "%s %s %d", ent->authname, + seq_printf(m, "%s %s %u", ent->authname, ent->type == IDMAP_TYPE_GROUP ? "group" : "user", ent->id); if (test_bit(CACHE_VALID, &h->flags)) @@ -349,7 +349,7 @@ nametoid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h) ent->type == IDMAP_TYPE_GROUP ? "group" : "user", ent->name); if (test_bit(CACHE_VALID, &h->flags)) - seq_printf(m, " %d", ent->id); + seq_printf(m, " %u", ent->id); seq_printf(m, "\n"); return 0; } diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 3c627128e20..29b7e63cb32 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -100,7 +100,15 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data, open->op_fname.len, &open->op_iattr, &resfh, open->op_createmode, - (u32 *)open->op_verf.data, &open->op_truncate, &created); + (u32 *)open->op_verf.data, + &open->op_truncate, &created); + + /* If we ever decide to use different attrs to store the + * verifier in nfsd_create_v3, then we'll need to change this + */ + if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0) + open->op_bmval[1] |= (FATTR4_WORD1_TIME_ACCESS | + FATTR4_WORD1_TIME_MODIFY); } else { status = nfsd_lookup(rqstp, current_fh, open->op_fname.data, open->op_fname.len, &resfh); diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index e4a4c87ec8c..3f559700788 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -256,7 +256,7 @@ nfs4_close_delegation(struct nfs4_delegation *dp) /* The following nfsd_close may not actually close the file, * but we want to remove the lease in any case. */ if (dp->dl_flock) - setlease(filp, F_UNLCK, &dp->dl_flock); + vfs_setlease(filp, F_UNLCK, &dp->dl_flock); nfsd_close(filp); } @@ -1032,19 +1032,19 @@ static int nfsd4_init_slabs(void) { stateowner_slab = kmem_cache_create("nfsd4_stateowners", - sizeof(struct nfs4_stateowner), 0, 0, NULL, NULL); + sizeof(struct nfs4_stateowner), 0, 0, NULL); if (stateowner_slab == NULL) goto out_nomem; file_slab = kmem_cache_create("nfsd4_files", - sizeof(struct nfs4_file), 0, 0, NULL, NULL); + sizeof(struct nfs4_file), 0, 0, NULL); if (file_slab == NULL) goto out_nomem; stateid_slab = kmem_cache_create("nfsd4_stateids", - sizeof(struct nfs4_stateid), 0, 0, NULL, NULL); + sizeof(struct nfs4_stateid), 0, 0, NULL); if (stateid_slab == NULL) goto out_nomem; deleg_slab = kmem_cache_create("nfsd4_delegations", - sizeof(struct nfs4_delegation), 0, 0, NULL, NULL); + sizeof(struct nfs4_delegation), 0, 0, NULL); if (deleg_slab == NULL) goto out_nomem; return 0; @@ -1402,7 +1402,7 @@ void nfsd_release_deleg_cb(struct file_lock *fl) /* * Set the delegation file_lock back pointer. * - * Called from __setlease() with lock_kernel() held. + * Called from setlease() with lock_kernel() held. */ static void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl) @@ -1416,7 +1416,7 @@ void nfsd_copy_lock_deleg_cb(struct file_lock *new, struct file_lock *fl) } /* - * Called from __setlease() with lock_kernel() held + * Called from setlease() with lock_kernel() held */ static int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try) @@ -1716,10 +1716,10 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta fl.fl_file = stp->st_vfs_file; fl.fl_pid = current->tgid; - /* setlease checks to see if delegation should be handed out. + /* vfs_setlease checks to see if delegation should be handed out. * the lock_manager callbacks fl_mylease and fl_change are used */ - if ((status = setlease(stp->st_vfs_file, + if ((status = vfs_setlease(stp->st_vfs_file, flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK, &flp))) { dprintk("NFSD: setlease failed [%d], no delegation\n", status); unhash_delegation(dp); diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index b3d55c6747f..8ef0964179b 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2450,7 +2450,7 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ } static void -nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, int nfserr, +nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_secinfo *secinfo) { int i = 0; diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 0eb464a39aa..7011d62acfc 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -566,13 +566,23 @@ enum fsid_source fsid_source(struct svc_fh *fhp) case FSID_DEV: case FSID_ENCODE_DEV: case FSID_MAJOR_MINOR: - return FSIDSOURCE_DEV; + if (fhp->fh_export->ex_dentry->d_inode->i_sb->s_type->fs_flags + & FS_REQUIRES_DEV) + return FSIDSOURCE_DEV; + break; case FSID_NUM: - return FSIDSOURCE_FSID; - default: if (fhp->fh_export->ex_flags & NFSEXP_FSID) return FSIDSOURCE_FSID; - else - return FSIDSOURCE_UUID; + break; + default: + break; } + /* either a UUID type filehandle, or the filehandle doesn't + * match the export. + */ + if (fhp->fh_export->ex_flags & NFSEXP_FSID) + return FSIDSOURCE_FSID; + if (fhp->fh_export->ex_uuid) + return FSIDSOURCE_UUID; + return FSIDSOURCE_DEV; } diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index e90f4a8a1d0..7867151ebb8 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -115,19 +115,20 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, exp2 = rqst_exp_get_by_name(rqstp, mnt, mounts); if (IS_ERR(exp2)) { - err = PTR_ERR(exp2); + if (PTR_ERR(exp2) != -ENOENT) + err = PTR_ERR(exp2); dput(mounts); mntput(mnt); goto out; } - if (exp2 && ((exp->ex_flags & NFSEXP_CROSSMOUNT) || EX_NOHIDE(exp2))) { + if ((exp->ex_flags & NFSEXP_CROSSMOUNT) || EX_NOHIDE(exp2)) { /* successfully crossed mount point */ exp_put(exp); *expp = exp2; dput(dentry); *dpp = mounts; } else { - if (exp2) exp_put(exp2); + exp_put(exp2); dput(mounts); } mntput(mnt); @@ -1309,7 +1310,10 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, if (createmode == NFS3_CREATE_EXCLUSIVE) { /* solaris7 gets confused (bugid 4218508) if these have - * the high bit set, so just clear the high bits. + * the high bit set, so just clear the high bits. If this is + * ever changed to use different attrs for storing the + * verifier, then do_open_lookup() will also need to be fixed + * accordingly. */ v_mtime = verifier[0]&0x7fffffff; v_atime = verifier[1]&0x7fffffff; @@ -1797,6 +1801,11 @@ nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat) return err; } +static int exp_rdonly(struct svc_rqst *rqstp, struct svc_export *exp) +{ + return nfsexp_flags(rqstp, exp) & NFSEXP_READONLY; +} + /* * Check for a user's access permissions to this inode. */ @@ -1833,7 +1842,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, */ if (!(acc & MAY_LOCAL_ACCESS)) if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) { - if (EX_RDONLY(exp, rqstp) || IS_RDONLY(inode)) + if (exp_rdonly(rqstp, exp) || IS_RDONLY(inode)) return nfserr_rofs; if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode)) return nfserr_perm; @@ -1916,7 +1925,7 @@ nfsd_racache_init(int cache_size) raparm_hash[i].pb_head = NULL; spin_lock_init(&raparm_hash[i].pb_lock); } - nperbucket = cache_size >> RAPARM_HASH_BITS; + nperbucket = DIV_ROUND_UP(cache_size, RAPARM_HASH_SIZE); for (i = 0; i < cache_size - 1; i++) { if (i % nperbucket == 0) raparm_hash[j++].pb_head = raparml + i; |