diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-16 18:25:31 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-16 18:25:31 -0500 |
commit | 0b233b7c79d2ba92c7fb5d60d4116693f1b3b0fe (patch) | |
tree | 440a6093bacfadf46782592fff22c4a2b2b51443 /fs | |
parent | 6f51ee709e4c6b56f2c2a071da2d056a109b9d26 (diff) | |
parent | bf7491f1be5e125eece2ec67e0f79d513caa6c7e (diff) |
Merge branch 'for-3.19' of git://linux-nfs.org/~bfields/linux
Pull nfsd updates from Bruce Fields:
"A comparatively quieter cycle for nfsd this time, but still with two
larger changes:
- RPC server scalability improvements from Jeff Layton (using RCU
instead of a spinlock to find idle threads).
- server-side NFSv4.2 ALLOCATE/DEALLOCATE support from Anna
Schumaker, enabling fallocate on new clients"
* 'for-3.19' of git://linux-nfs.org/~bfields/linux: (32 commits)
nfsd4: fix xdr4 count of server in fs_location4
nfsd4: fix xdr4 inclusion of escaped char
sunrpc/cache: convert to use string_escape_str()
sunrpc: only call test_bit once in svc_xprt_received
fs: nfsd: Fix signedness bug in compare_blob
sunrpc: add some tracepoints around enqueue and dequeue of svc_xprt
sunrpc: convert to lockless lookup of queued server threads
sunrpc: fix potential races in pool_stats collection
sunrpc: add a rcu_head to svc_rqst and use kfree_rcu to free it
sunrpc: require svc_create callers to pass in meaningful shutdown routine
sunrpc: have svc_wake_up only deal with pool 0
sunrpc: convert sp_task_pending flag to use atomic bitops
sunrpc: move rq_cachetype field to better optimize space
sunrpc: move rq_splice_ok flag into rq_flags
sunrpc: move rq_dropme flag into rq_flags
sunrpc: move rq_usedeferral flag to rq_flags
sunrpc: move rq_local field to rq_flags
sunrpc: add a generic rq_flags field to svc_rqst and move rq_secure to it
nfsd: minor off by one checks in __write_versions()
sunrpc: release svc_pool_map reference when serv allocation fails
...
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ioctl.c | 2 | ||||
-rw-r--r-- | fs/lockd/mon.c | 2 | ||||
-rw-r--r-- | fs/lockd/svc.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfs4proc.c | 57 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 68 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 34 | ||||
-rw-r--r-- | fs/nfsd/nfscache.c | 4 | ||||
-rw-r--r-- | fs/nfsd/nfsctl.c | 6 | ||||
-rw-r--r-- | fs/nfsd/nfsfh.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfssvc.c | 2 | ||||
-rw-r--r-- | fs/nfsd/state.h | 19 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 37 | ||||
-rw-r--r-- | fs/nfsd/vfs.h | 2 | ||||
-rw-r--r-- | fs/nfsd/xdr4.h | 9 | ||||
-rw-r--r-- | fs/open.c | 5 |
15 files changed, 186 insertions, 65 deletions
diff --git a/fs/ioctl.c b/fs/ioctl.c index 77c9a7812542..214c3c11fbc2 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -443,7 +443,7 @@ int ioctl_preallocate(struct file *filp, void __user *argp) | |||
443 | return -EINVAL; | 443 | return -EINVAL; |
444 | } | 444 | } |
445 | 445 | ||
446 | return do_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len); | 446 | return vfs_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len); |
447 | } | 447 | } |
448 | 448 | ||
449 | static int file_ioctl(struct file *filp, unsigned int cmd, | 449 | static int file_ioctl(struct file *filp, unsigned int cmd, |
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 9106f42c472c..1cc6ec51e6b1 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
@@ -214,7 +214,7 @@ int nsm_monitor(const struct nlm_host *host) | |||
214 | if (unlikely(res.status != 0)) | 214 | if (unlikely(res.status != 0)) |
215 | status = -EIO; | 215 | status = -EIO; |
216 | if (unlikely(status < 0)) { | 216 | if (unlikely(status < 0)) { |
217 | printk(KERN_NOTICE "lockd: cannot monitor %s\n", nsm->sm_name); | 217 | pr_notice_ratelimited("lockd: cannot monitor %s\n", nsm->sm_name); |
218 | return status; | 218 | return status; |
219 | } | 219 | } |
220 | 220 | ||
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index d1bb7ecfd201..e94c887da2d7 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -350,7 +350,7 @@ static struct svc_serv *lockd_create_svc(void) | |||
350 | printk(KERN_WARNING | 350 | printk(KERN_WARNING |
351 | "lockd_up: no pid, %d users??\n", nlmsvc_users); | 351 | "lockd_up: no pid, %d users??\n", nlmsvc_users); |
352 | 352 | ||
353 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL); | 353 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, svc_rpcb_cleanup); |
354 | if (!serv) { | 354 | if (!serv) { |
355 | printk(KERN_WARNING "lockd_up: create service failed\n"); | 355 | printk(KERN_WARNING "lockd_up: create service failed\n"); |
356 | return ERR_PTR(-ENOMEM); | 356 | return ERR_PTR(-ENOMEM); |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 0beb023f25ac..ac71d13c69ef 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -33,6 +33,7 @@ | |||
33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
34 | */ | 34 | */ |
35 | #include <linux/file.h> | 35 | #include <linux/file.h> |
36 | #include <linux/falloc.h> | ||
36 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
37 | 38 | ||
38 | #include "idmap.h" | 39 | #include "idmap.h" |
@@ -772,7 +773,7 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
772 | * the client wants us to do more in this compound: | 773 | * the client wants us to do more in this compound: |
773 | */ | 774 | */ |
774 | if (!nfsd4_last_compound_op(rqstp)) | 775 | if (!nfsd4_last_compound_op(rqstp)) |
775 | rqstp->rq_splice_ok = false; | 776 | clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags); |
776 | 777 | ||
777 | /* check stateid */ | 778 | /* check stateid */ |
778 | if ((status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), | 779 | if ((status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), |
@@ -1014,6 +1015,44 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
1014 | } | 1015 | } |
1015 | 1016 | ||
1016 | static __be32 | 1017 | static __be32 |
1018 | nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | ||
1019 | struct nfsd4_fallocate *fallocate, int flags) | ||
1020 | { | ||
1021 | __be32 status = nfserr_notsupp; | ||
1022 | struct file *file; | ||
1023 | |||
1024 | status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate, | ||
1025 | &fallocate->falloc_stateid, | ||
1026 | WR_STATE, &file); | ||
1027 | if (status != nfs_ok) { | ||
1028 | dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n"); | ||
1029 | return status; | ||
1030 | } | ||
1031 | |||
1032 | status = nfsd4_vfs_fallocate(rqstp, &cstate->current_fh, file, | ||
1033 | fallocate->falloc_offset, | ||
1034 | fallocate->falloc_length, | ||
1035 | flags); | ||
1036 | fput(file); | ||
1037 | return status; | ||
1038 | } | ||
1039 | |||
1040 | static __be32 | ||
1041 | nfsd4_allocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | ||
1042 | struct nfsd4_fallocate *fallocate) | ||
1043 | { | ||
1044 | return nfsd4_fallocate(rqstp, cstate, fallocate, 0); | ||
1045 | } | ||
1046 | |||
1047 | static __be32 | ||
1048 | nfsd4_deallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | ||
1049 | struct nfsd4_fallocate *fallocate) | ||
1050 | { | ||
1051 | return nfsd4_fallocate(rqstp, cstate, fallocate, | ||
1052 | FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE); | ||
1053 | } | ||
1054 | |||
1055 | static __be32 | ||
1017 | nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | 1056 | nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
1018 | struct nfsd4_seek *seek) | 1057 | struct nfsd4_seek *seek) |
1019 | { | 1058 | { |
@@ -1331,7 +1370,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
1331 | * Don't use the deferral mechanism for NFSv4; compounds make it | 1370 | * Don't use the deferral mechanism for NFSv4; compounds make it |
1332 | * too hard to avoid non-idempotency problems. | 1371 | * too hard to avoid non-idempotency problems. |
1333 | */ | 1372 | */ |
1334 | rqstp->rq_usedeferral = false; | 1373 | clear_bit(RQ_USEDEFERRAL, &rqstp->rq_flags); |
1335 | 1374 | ||
1336 | /* | 1375 | /* |
1337 | * According to RFC3010, this takes precedence over all other errors. | 1376 | * According to RFC3010, this takes precedence over all other errors. |
@@ -1447,7 +1486,7 @@ encode_op: | |||
1447 | BUG_ON(cstate->replay_owner); | 1486 | BUG_ON(cstate->replay_owner); |
1448 | out: | 1487 | out: |
1449 | /* Reset deferral mechanism for RPC deferrals */ | 1488 | /* Reset deferral mechanism for RPC deferrals */ |
1450 | rqstp->rq_usedeferral = true; | 1489 | set_bit(RQ_USEDEFERRAL, &rqstp->rq_flags); |
1451 | dprintk("nfsv4 compound returned %d\n", ntohl(status)); | 1490 | dprintk("nfsv4 compound returned %d\n", ntohl(status)); |
1452 | return status; | 1491 | return status; |
1453 | } | 1492 | } |
@@ -1929,6 +1968,18 @@ static struct nfsd4_operation nfsd4_ops[] = { | |||
1929 | }, | 1968 | }, |
1930 | 1969 | ||
1931 | /* NFSv4.2 operations */ | 1970 | /* NFSv4.2 operations */ |
1971 | [OP_ALLOCATE] = { | ||
1972 | .op_func = (nfsd4op_func)nfsd4_allocate, | ||
1973 | .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, | ||
1974 | .op_name = "OP_ALLOCATE", | ||
1975 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize, | ||
1976 | }, | ||
1977 | [OP_DEALLOCATE] = { | ||
1978 | .op_func = (nfsd4op_func)nfsd4_deallocate, | ||
1979 | .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, | ||
1980 | .op_name = "OP_DEALLOCATE", | ||
1981 | .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize, | ||
1982 | }, | ||
1932 | [OP_SEEK] = { | 1983 | [OP_SEEK] = { |
1933 | .op_func = (nfsd4op_func)nfsd4_seek, | 1984 | .op_func = (nfsd4op_func)nfsd4_seek, |
1934 | .op_name = "OP_SEEK", | 1985 | .op_name = "OP_SEEK", |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 4e1d7268b004..3550a9c87616 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -275,9 +275,11 @@ opaque_hashval(const void *ptr, int nbytes) | |||
275 | return x; | 275 | return x; |
276 | } | 276 | } |
277 | 277 | ||
278 | static void nfsd4_free_file(struct nfs4_file *f) | 278 | static void nfsd4_free_file_rcu(struct rcu_head *rcu) |
279 | { | 279 | { |
280 | kmem_cache_free(file_slab, f); | 280 | struct nfs4_file *fp = container_of(rcu, struct nfs4_file, fi_rcu); |
281 | |||
282 | kmem_cache_free(file_slab, fp); | ||
281 | } | 283 | } |
282 | 284 | ||
283 | static inline void | 285 | static inline void |
@@ -286,9 +288,10 @@ put_nfs4_file(struct nfs4_file *fi) | |||
286 | might_lock(&state_lock); | 288 | might_lock(&state_lock); |
287 | 289 | ||
288 | if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) { | 290 | if (atomic_dec_and_lock(&fi->fi_ref, &state_lock)) { |
289 | hlist_del(&fi->fi_hash); | 291 | hlist_del_rcu(&fi->fi_hash); |
290 | spin_unlock(&state_lock); | 292 | spin_unlock(&state_lock); |
291 | nfsd4_free_file(fi); | 293 | WARN_ON_ONCE(!list_empty(&fi->fi_delegations)); |
294 | call_rcu(&fi->fi_rcu, nfsd4_free_file_rcu); | ||
292 | } | 295 | } |
293 | } | 296 | } |
294 | 297 | ||
@@ -1440,7 +1443,7 @@ static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, stru | |||
1440 | list_add(&new->se_perclnt, &clp->cl_sessions); | 1443 | list_add(&new->se_perclnt, &clp->cl_sessions); |
1441 | spin_unlock(&clp->cl_lock); | 1444 | spin_unlock(&clp->cl_lock); |
1442 | 1445 | ||
1443 | if (cses->flags & SESSION4_BACK_CHAN) { | 1446 | { |
1444 | struct sockaddr *sa = svc_addr(rqstp); | 1447 | struct sockaddr *sa = svc_addr(rqstp); |
1445 | /* | 1448 | /* |
1446 | * This is a little silly; with sessions there's no real | 1449 | * This is a little silly; with sessions there's no real |
@@ -1711,15 +1714,14 @@ static int copy_cred(struct svc_cred *target, struct svc_cred *source) | |||
1711 | return 0; | 1714 | return 0; |
1712 | } | 1715 | } |
1713 | 1716 | ||
1714 | static long long | 1717 | static int |
1715 | compare_blob(const struct xdr_netobj *o1, const struct xdr_netobj *o2) | 1718 | compare_blob(const struct xdr_netobj *o1, const struct xdr_netobj *o2) |
1716 | { | 1719 | { |
1717 | long long res; | 1720 | if (o1->len < o2->len) |
1718 | 1721 | return -1; | |
1719 | res = o1->len - o2->len; | 1722 | if (o1->len > o2->len) |
1720 | if (res) | 1723 | return 1; |
1721 | return res; | 1724 | return memcmp(o1->data, o2->data, o1->len); |
1722 | return (long long)memcmp(o1->data, o2->data, o1->len); | ||
1723 | } | 1725 | } |
1724 | 1726 | ||
1725 | static int same_name(const char *n1, const char *n2) | 1727 | static int same_name(const char *n1, const char *n2) |
@@ -1907,7 +1909,7 @@ add_clp_to_name_tree(struct nfs4_client *new_clp, struct rb_root *root) | |||
1907 | static struct nfs4_client * | 1909 | static struct nfs4_client * |
1908 | find_clp_in_name_tree(struct xdr_netobj *name, struct rb_root *root) | 1910 | find_clp_in_name_tree(struct xdr_netobj *name, struct rb_root *root) |
1909 | { | 1911 | { |
1910 | long long cmp; | 1912 | int cmp; |
1911 | struct rb_node *node = root->rb_node; | 1913 | struct rb_node *node = root->rb_node; |
1912 | struct nfs4_client *clp; | 1914 | struct nfs4_client *clp; |
1913 | 1915 | ||
@@ -3057,10 +3059,9 @@ static struct nfs4_file *nfsd4_alloc_file(void) | |||
3057 | } | 3059 | } |
3058 | 3060 | ||
3059 | /* OPEN Share state helper functions */ | 3061 | /* OPEN Share state helper functions */ |
3060 | static void nfsd4_init_file(struct nfs4_file *fp, struct knfsd_fh *fh) | 3062 | static void nfsd4_init_file(struct knfsd_fh *fh, unsigned int hashval, |
3063 | struct nfs4_file *fp) | ||
3061 | { | 3064 | { |
3062 | unsigned int hashval = file_hashval(fh); | ||
3063 | |||
3064 | lockdep_assert_held(&state_lock); | 3065 | lockdep_assert_held(&state_lock); |
3065 | 3066 | ||
3066 | atomic_set(&fp->fi_ref, 1); | 3067 | atomic_set(&fp->fi_ref, 1); |
@@ -3073,7 +3074,7 @@ static void nfsd4_init_file(struct nfs4_file *fp, struct knfsd_fh *fh) | |||
3073 | fp->fi_share_deny = 0; | 3074 | fp->fi_share_deny = 0; |
3074 | memset(fp->fi_fds, 0, sizeof(fp->fi_fds)); | 3075 | memset(fp->fi_fds, 0, sizeof(fp->fi_fds)); |
3075 | memset(fp->fi_access, 0, sizeof(fp->fi_access)); | 3076 | memset(fp->fi_access, 0, sizeof(fp->fi_access)); |
3076 | hlist_add_head(&fp->fi_hash, &file_hashtbl[hashval]); | 3077 | hlist_add_head_rcu(&fp->fi_hash, &file_hashtbl[hashval]); |
3077 | } | 3078 | } |
3078 | 3079 | ||
3079 | void | 3080 | void |
@@ -3294,17 +3295,14 @@ move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net) | |||
3294 | 3295 | ||
3295 | /* search file_hashtbl[] for file */ | 3296 | /* search file_hashtbl[] for file */ |
3296 | static struct nfs4_file * | 3297 | static struct nfs4_file * |
3297 | find_file_locked(struct knfsd_fh *fh) | 3298 | find_file_locked(struct knfsd_fh *fh, unsigned int hashval) |
3298 | { | 3299 | { |
3299 | unsigned int hashval = file_hashval(fh); | ||
3300 | struct nfs4_file *fp; | 3300 | struct nfs4_file *fp; |
3301 | 3301 | ||
3302 | lockdep_assert_held(&state_lock); | 3302 | hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash) { |
3303 | |||
3304 | hlist_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) { | ||
3305 | if (nfsd_fh_match(&fp->fi_fhandle, fh)) { | 3303 | if (nfsd_fh_match(&fp->fi_fhandle, fh)) { |
3306 | get_nfs4_file(fp); | 3304 | if (atomic_inc_not_zero(&fp->fi_ref)) |
3307 | return fp; | 3305 | return fp; |
3308 | } | 3306 | } |
3309 | } | 3307 | } |
3310 | return NULL; | 3308 | return NULL; |
@@ -3314,10 +3312,11 @@ static struct nfs4_file * | |||
3314 | find_file(struct knfsd_fh *fh) | 3312 | find_file(struct knfsd_fh *fh) |
3315 | { | 3313 | { |
3316 | struct nfs4_file *fp; | 3314 | struct nfs4_file *fp; |
3315 | unsigned int hashval = file_hashval(fh); | ||
3317 | 3316 | ||
3318 | spin_lock(&state_lock); | 3317 | rcu_read_lock(); |
3319 | fp = find_file_locked(fh); | 3318 | fp = find_file_locked(fh, hashval); |
3320 | spin_unlock(&state_lock); | 3319 | rcu_read_unlock(); |
3321 | return fp; | 3320 | return fp; |
3322 | } | 3321 | } |
3323 | 3322 | ||
@@ -3325,11 +3324,18 @@ static struct nfs4_file * | |||
3325 | find_or_add_file(struct nfs4_file *new, struct knfsd_fh *fh) | 3324 | find_or_add_file(struct nfs4_file *new, struct knfsd_fh *fh) |
3326 | { | 3325 | { |
3327 | struct nfs4_file *fp; | 3326 | struct nfs4_file *fp; |
3327 | unsigned int hashval = file_hashval(fh); | ||
3328 | |||
3329 | rcu_read_lock(); | ||
3330 | fp = find_file_locked(fh, hashval); | ||
3331 | rcu_read_unlock(); | ||
3332 | if (fp) | ||
3333 | return fp; | ||
3328 | 3334 | ||
3329 | spin_lock(&state_lock); | 3335 | spin_lock(&state_lock); |
3330 | fp = find_file_locked(fh); | 3336 | fp = find_file_locked(fh, hashval); |
3331 | if (fp == NULL) { | 3337 | if (likely(fp == NULL)) { |
3332 | nfsd4_init_file(new, fh); | 3338 | nfsd4_init_file(fh, hashval, new); |
3333 | fp = new; | 3339 | fp = new; |
3334 | } | 3340 | } |
3335 | spin_unlock(&state_lock); | 3341 | spin_unlock(&state_lock); |
@@ -4127,7 +4133,7 @@ void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate, | |||
4127 | nfs4_put_stateowner(so); | 4133 | nfs4_put_stateowner(so); |
4128 | } | 4134 | } |
4129 | if (open->op_file) | 4135 | if (open->op_file) |
4130 | nfsd4_free_file(open->op_file); | 4136 | kmem_cache_free(file_slab, open->op_file); |
4131 | if (open->op_stp) | 4137 | if (open->op_stp) |
4132 | nfs4_put_stid(&open->op_stp->st_stid); | 4138 | nfs4_put_stid(&open->op_stp->st_stid); |
4133 | } | 4139 | } |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index b1eed4dd2eab..15f7b73e0c0f 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -1514,6 +1514,23 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str | |||
1514 | } | 1514 | } |
1515 | 1515 | ||
1516 | static __be32 | 1516 | static __be32 |
1517 | nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp, | ||
1518 | struct nfsd4_fallocate *fallocate) | ||
1519 | { | ||
1520 | DECODE_HEAD; | ||
1521 | |||
1522 | status = nfsd4_decode_stateid(argp, &fallocate->falloc_stateid); | ||
1523 | if (status) | ||
1524 | return status; | ||
1525 | |||
1526 | READ_BUF(16); | ||
1527 | p = xdr_decode_hyper(p, &fallocate->falloc_offset); | ||
1528 | xdr_decode_hyper(p, &fallocate->falloc_length); | ||
1529 | |||
1530 | DECODE_TAIL; | ||
1531 | } | ||
1532 | |||
1533 | static __be32 | ||
1517 | nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek) | 1534 | nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek) |
1518 | { | 1535 | { |
1519 | DECODE_HEAD; | 1536 | DECODE_HEAD; |
@@ -1604,10 +1621,10 @@ static nfsd4_dec nfsd4_dec_ops[] = { | |||
1604 | [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, | 1621 | [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, |
1605 | 1622 | ||
1606 | /* new operations for NFSv4.2 */ | 1623 | /* new operations for NFSv4.2 */ |
1607 | [OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_notsupp, | 1624 | [OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, |
1608 | [OP_COPY] = (nfsd4_dec)nfsd4_decode_notsupp, | 1625 | [OP_COPY] = (nfsd4_dec)nfsd4_decode_notsupp, |
1609 | [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_notsupp, | 1626 | [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_notsupp, |
1610 | [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_notsupp, | 1627 | [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, |
1611 | [OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp, | 1628 | [OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp, |
1612 | [OP_LAYOUTERROR] = (nfsd4_dec)nfsd4_decode_notsupp, | 1629 | [OP_LAYOUTERROR] = (nfsd4_dec)nfsd4_decode_notsupp, |
1613 | [OP_LAYOUTSTATS] = (nfsd4_dec)nfsd4_decode_notsupp, | 1630 | [OP_LAYOUTSTATS] = (nfsd4_dec)nfsd4_decode_notsupp, |
@@ -1714,7 +1731,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | |||
1714 | argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE; | 1731 | argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE; |
1715 | 1732 | ||
1716 | if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack) | 1733 | if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack) |
1717 | argp->rqstp->rq_splice_ok = false; | 1734 | clear_bit(RQ_SPLICE_OK, &argp->rqstp->rq_flags); |
1718 | 1735 | ||
1719 | DECODE_TAIL; | 1736 | DECODE_TAIL; |
1720 | } | 1737 | } |
@@ -1795,9 +1812,12 @@ static __be32 nfsd4_encode_components_esc(struct xdr_stream *xdr, char sep, | |||
1795 | } | 1812 | } |
1796 | else | 1813 | else |
1797 | end++; | 1814 | end++; |
1815 | if (found_esc) | ||
1816 | end = next; | ||
1817 | |||
1798 | str = end; | 1818 | str = end; |
1799 | } | 1819 | } |
1800 | pathlen = htonl(xdr->buf->len - pathlen_offset); | 1820 | pathlen = htonl(count); |
1801 | write_bytes_to_xdr_buf(xdr->buf, pathlen_offset, &pathlen, 4); | 1821 | write_bytes_to_xdr_buf(xdr->buf, pathlen_offset, &pathlen, 4); |
1802 | return 0; | 1822 | return 0; |
1803 | } | 1823 | } |
@@ -3236,10 +3256,10 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, | |||
3236 | 3256 | ||
3237 | p = xdr_reserve_space(xdr, 8); /* eof flag and byte count */ | 3257 | p = xdr_reserve_space(xdr, 8); /* eof flag and byte count */ |
3238 | if (!p) { | 3258 | if (!p) { |
3239 | WARN_ON_ONCE(resp->rqstp->rq_splice_ok); | 3259 | WARN_ON_ONCE(test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)); |
3240 | return nfserr_resource; | 3260 | return nfserr_resource; |
3241 | } | 3261 | } |
3242 | if (resp->xdr.buf->page_len && resp->rqstp->rq_splice_ok) { | 3262 | if (resp->xdr.buf->page_len && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)) { |
3243 | WARN_ON_ONCE(1); | 3263 | WARN_ON_ONCE(1); |
3244 | return nfserr_resource; | 3264 | return nfserr_resource; |
3245 | } | 3265 | } |
@@ -3256,7 +3276,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, | |||
3256 | goto err_truncate; | 3276 | goto err_truncate; |
3257 | } | 3277 | } |
3258 | 3278 | ||
3259 | if (file->f_op->splice_read && resp->rqstp->rq_splice_ok) | 3279 | if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)) |
3260 | err = nfsd4_encode_splice_read(resp, read, file, maxcount); | 3280 | err = nfsd4_encode_splice_read(resp, read, file, maxcount); |
3261 | else | 3281 | else |
3262 | err = nfsd4_encode_readv(resp, read, file, maxcount); | 3282 | err = nfsd4_encode_readv(resp, read, file, maxcount); |
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index 122f69185ef5..83a9694ec485 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c | |||
@@ -490,7 +490,7 @@ found_entry: | |||
490 | /* From the hall of fame of impractical attacks: | 490 | /* From the hall of fame of impractical attacks: |
491 | * Is this a user who tries to snoop on the cache? */ | 491 | * Is this a user who tries to snoop on the cache? */ |
492 | rtn = RC_DOIT; | 492 | rtn = RC_DOIT; |
493 | if (!rqstp->rq_secure && rp->c_secure) | 493 | if (!test_bit(RQ_SECURE, &rqstp->rq_flags) && rp->c_secure) |
494 | goto out; | 494 | goto out; |
495 | 495 | ||
496 | /* Compose RPC reply header */ | 496 | /* Compose RPC reply header */ |
@@ -579,7 +579,7 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp) | |||
579 | spin_lock(&b->cache_lock); | 579 | spin_lock(&b->cache_lock); |
580 | drc_mem_usage += bufsize; | 580 | drc_mem_usage += bufsize; |
581 | lru_put_end(b, rp); | 581 | lru_put_end(b, rp); |
582 | rp->c_secure = rqstp->rq_secure; | 582 | rp->c_secure = test_bit(RQ_SECURE, &rqstp->rq_flags); |
583 | rp->c_type = cachetype; | 583 | rp->c_type = cachetype; |
584 | rp->c_state = RC_DONE; | 584 | rp->c_state = RC_DONE; |
585 | spin_unlock(&b->cache_lock); | 585 | spin_unlock(&b->cache_lock); |
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 9506ea565610..19ace74d35f6 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -608,7 +608,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) | |||
608 | num); | 608 | num); |
609 | sep = " "; | 609 | sep = " "; |
610 | 610 | ||
611 | if (len > remaining) | 611 | if (len >= remaining) |
612 | break; | 612 | break; |
613 | remaining -= len; | 613 | remaining -= len; |
614 | buf += len; | 614 | buf += len; |
@@ -623,7 +623,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) | |||
623 | '+' : '-', | 623 | '+' : '-', |
624 | minor); | 624 | minor); |
625 | 625 | ||
626 | if (len > remaining) | 626 | if (len >= remaining) |
627 | break; | 627 | break; |
628 | remaining -= len; | 628 | remaining -= len; |
629 | buf += len; | 629 | buf += len; |
@@ -631,7 +631,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size) | |||
631 | } | 631 | } |
632 | 632 | ||
633 | len = snprintf(buf, remaining, "\n"); | 633 | len = snprintf(buf, remaining, "\n"); |
634 | if (len > remaining) | 634 | if (len >= remaining) |
635 | return -EINVAL; | 635 | return -EINVAL; |
636 | return tlen + len; | 636 | return tlen + len; |
637 | } | 637 | } |
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 88026fc6a981..965b478d50fc 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -86,7 +86,7 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, | |||
86 | int flags = nfsexp_flags(rqstp, exp); | 86 | int flags = nfsexp_flags(rqstp, exp); |
87 | 87 | ||
88 | /* Check if the request originated from a secure port. */ | 88 | /* Check if the request originated from a secure port. */ |
89 | if (!rqstp->rq_secure && !(flags & NFSEXP_INSECURE_PORT)) { | 89 | if (!test_bit(RQ_SECURE, &rqstp->rq_flags) && !(flags & NFSEXP_INSECURE_PORT)) { |
90 | RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); | 90 | RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); |
91 | dprintk("nfsd: request from insecure port %s!\n", | 91 | dprintk("nfsd: request from insecure port %s!\n", |
92 | svc_print_addr(rqstp, buf, sizeof(buf))); | 92 | svc_print_addr(rqstp, buf, sizeof(buf))); |
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 752d56bbe0ba..314f5c8f8f1a 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
@@ -692,7 +692,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) | |||
692 | /* Now call the procedure handler, and encode NFS status. */ | 692 | /* Now call the procedure handler, and encode NFS status. */ |
693 | nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); | 693 | nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); |
694 | nfserr = map_new_errors(rqstp->rq_vers, nfserr); | 694 | nfserr = map_new_errors(rqstp->rq_vers, nfserr); |
695 | if (nfserr == nfserr_dropit || rqstp->rq_dropme) { | 695 | if (nfserr == nfserr_dropit || test_bit(RQ_DROPME, &rqstp->rq_flags)) { |
696 | dprintk("nfsd: Dropping request; may be revisited later\n"); | 696 | dprintk("nfsd: Dropping request; may be revisited later\n"); |
697 | nfsd_cache_update(rqstp, RC_NOCACHE, NULL); | 697 | nfsd_cache_update(rqstp, RC_NOCACHE, NULL); |
698 | return 0; | 698 | return 0; |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 2712042a66b1..9d3be371240a 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
@@ -463,17 +463,24 @@ static inline struct nfs4_lockowner * lockowner(struct nfs4_stateowner *so) | |||
463 | /* | 463 | /* |
464 | * nfs4_file: a file opened by some number of (open) nfs4_stateowners. | 464 | * nfs4_file: a file opened by some number of (open) nfs4_stateowners. |
465 | * | 465 | * |
466 | * These objects are global. nfsd only keeps one instance of a nfs4_file per | 466 | * These objects are global. nfsd keeps one instance of a nfs4_file per |
467 | * inode (though it may keep multiple file descriptors open per inode). These | 467 | * filehandle (though it may keep multiple file descriptors for each). Each |
468 | * are tracked in the file_hashtbl which is protected by the state_lock | 468 | * inode can have multiple filehandles associated with it, so there is |
469 | * spinlock. | 469 | * (potentially) a many to one relationship between this struct and struct |
470 | * inode. | ||
471 | * | ||
472 | * These are hashed by filehandle in the file_hashtbl, which is protected by | ||
473 | * the global state_lock spinlock. | ||
470 | */ | 474 | */ |
471 | struct nfs4_file { | 475 | struct nfs4_file { |
472 | atomic_t fi_ref; | 476 | atomic_t fi_ref; |
473 | spinlock_t fi_lock; | 477 | spinlock_t fi_lock; |
474 | struct hlist_node fi_hash; /* hash by "struct inode *" */ | 478 | struct hlist_node fi_hash; /* hash on fi_fhandle */ |
475 | struct list_head fi_stateids; | 479 | struct list_head fi_stateids; |
476 | struct list_head fi_delegations; | 480 | union { |
481 | struct list_head fi_delegations; | ||
482 | struct rcu_head fi_rcu; | ||
483 | }; | ||
477 | /* One each for O_RDONLY, O_WRONLY, O_RDWR: */ | 484 | /* One each for O_RDONLY, O_WRONLY, O_RDWR: */ |
478 | struct file * fi_fds[3]; | 485 | struct file * fi_fds[3]; |
479 | /* | 486 | /* |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 0a82e3c033ee..5685c679dd93 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
17 | #include <linux/file.h> | 17 | #include <linux/file.h> |
18 | #include <linux/splice.h> | 18 | #include <linux/splice.h> |
19 | #include <linux/falloc.h> | ||
19 | #include <linux/fcntl.h> | 20 | #include <linux/fcntl.h> |
20 | #include <linux/namei.h> | 21 | #include <linux/namei.h> |
21 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
@@ -533,6 +534,26 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
533 | } | 534 | } |
534 | #endif | 535 | #endif |
535 | 536 | ||
537 | __be32 nfsd4_vfs_fallocate(struct svc_rqst *rqstp, struct svc_fh *fhp, | ||
538 | struct file *file, loff_t offset, loff_t len, | ||
539 | int flags) | ||
540 | { | ||
541 | __be32 err; | ||
542 | int error; | ||
543 | |||
544 | if (!S_ISREG(file_inode(file)->i_mode)) | ||
545 | return nfserr_inval; | ||
546 | |||
547 | err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry, NFSD_MAY_WRITE); | ||
548 | if (err) | ||
549 | return err; | ||
550 | |||
551 | error = vfs_fallocate(file, flags, offset, len); | ||
552 | if (!error) | ||
553 | error = commit_metadata(fhp); | ||
554 | |||
555 | return nfserrno(error); | ||
556 | } | ||
536 | #endif /* defined(CONFIG_NFSD_V4) */ | 557 | #endif /* defined(CONFIG_NFSD_V4) */ |
537 | 558 | ||
538 | #ifdef CONFIG_NFSD_V3 | 559 | #ifdef CONFIG_NFSD_V3 |
@@ -881,7 +902,7 @@ static __be32 | |||
881 | nfsd_vfs_read(struct svc_rqst *rqstp, struct file *file, | 902 | nfsd_vfs_read(struct svc_rqst *rqstp, struct file *file, |
882 | loff_t offset, struct kvec *vec, int vlen, unsigned long *count) | 903 | loff_t offset, struct kvec *vec, int vlen, unsigned long *count) |
883 | { | 904 | { |
884 | if (file->f_op->splice_read && rqstp->rq_splice_ok) | 905 | if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &rqstp->rq_flags)) |
885 | return nfsd_splice_read(rqstp, file, offset, count); | 906 | return nfsd_splice_read(rqstp, file, offset, count); |
886 | else | 907 | else |
887 | return nfsd_readv(file, offset, vec, vlen, count); | 908 | return nfsd_readv(file, offset, vec, vlen, count); |
@@ -937,9 +958,10 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
937 | int stable = *stablep; | 958 | int stable = *stablep; |
938 | int use_wgather; | 959 | int use_wgather; |
939 | loff_t pos = offset; | 960 | loff_t pos = offset; |
961 | loff_t end = LLONG_MAX; | ||
940 | unsigned int pflags = current->flags; | 962 | unsigned int pflags = current->flags; |
941 | 963 | ||
942 | if (rqstp->rq_local) | 964 | if (test_bit(RQ_LOCAL, &rqstp->rq_flags)) |
943 | /* | 965 | /* |
944 | * We want less throttling in balance_dirty_pages() | 966 | * We want less throttling in balance_dirty_pages() |
945 | * and shrink_inactive_list() so that nfs to | 967 | * and shrink_inactive_list() so that nfs to |
@@ -967,10 +989,13 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
967 | fsnotify_modify(file); | 989 | fsnotify_modify(file); |
968 | 990 | ||
969 | if (stable) { | 991 | if (stable) { |
970 | if (use_wgather) | 992 | if (use_wgather) { |
971 | host_err = wait_for_concurrent_writes(file); | 993 | host_err = wait_for_concurrent_writes(file); |
972 | else | 994 | } else { |
973 | host_err = vfs_fsync_range(file, offset, offset+*cnt, 0); | 995 | if (*cnt) |
996 | end = offset + *cnt - 1; | ||
997 | host_err = vfs_fsync_range(file, offset, end, 0); | ||
998 | } | ||
974 | } | 999 | } |
975 | 1000 | ||
976 | out_nfserr: | 1001 | out_nfserr: |
@@ -979,7 +1004,7 @@ out_nfserr: | |||
979 | err = 0; | 1004 | err = 0; |
980 | else | 1005 | else |
981 | err = nfserrno(host_err); | 1006 | err = nfserrno(host_err); |
982 | if (rqstp->rq_local) | 1007 | if (test_bit(RQ_LOCAL, &rqstp->rq_flags)) |
983 | tsk_restore_flags(current, pflags, PF_LESS_THROTTLE); | 1008 | tsk_restore_flags(current, pflags, PF_LESS_THROTTLE); |
984 | return err; | 1009 | return err; |
985 | } | 1010 | } |
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index b1796d6ee538..2050cb016998 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h | |||
@@ -54,6 +54,8 @@ int nfsd_mountpoint(struct dentry *, struct svc_export *); | |||
54 | #ifdef CONFIG_NFSD_V4 | 54 | #ifdef CONFIG_NFSD_V4 |
55 | __be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *, | 55 | __be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *, |
56 | struct xdr_netobj *); | 56 | struct xdr_netobj *); |
57 | __be32 nfsd4_vfs_fallocate(struct svc_rqst *, struct svc_fh *, | ||
58 | struct file *, loff_t, loff_t, int); | ||
57 | #endif /* CONFIG_NFSD_V4 */ | 59 | #endif /* CONFIG_NFSD_V4 */ |
58 | __be32 nfsd_create(struct svc_rqst *, struct svc_fh *, | 60 | __be32 nfsd_create(struct svc_rqst *, struct svc_fh *, |
59 | char *name, int len, struct iattr *attrs, | 61 | char *name, int len, struct iattr *attrs, |
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 5720e9457f33..90a5925bd6ab 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h | |||
@@ -428,6 +428,13 @@ struct nfsd4_reclaim_complete { | |||
428 | u32 rca_one_fs; | 428 | u32 rca_one_fs; |
429 | }; | 429 | }; |
430 | 430 | ||
431 | struct nfsd4_fallocate { | ||
432 | /* request */ | ||
433 | stateid_t falloc_stateid; | ||
434 | loff_t falloc_offset; | ||
435 | u64 falloc_length; | ||
436 | }; | ||
437 | |||
431 | struct nfsd4_seek { | 438 | struct nfsd4_seek { |
432 | /* request */ | 439 | /* request */ |
433 | stateid_t seek_stateid; | 440 | stateid_t seek_stateid; |
@@ -486,6 +493,8 @@ struct nfsd4_op { | |||
486 | struct nfsd4_free_stateid free_stateid; | 493 | struct nfsd4_free_stateid free_stateid; |
487 | 494 | ||
488 | /* NFSv4.2 */ | 495 | /* NFSv4.2 */ |
496 | struct nfsd4_fallocate allocate; | ||
497 | struct nfsd4_fallocate deallocate; | ||
489 | struct nfsd4_seek seek; | 498 | struct nfsd4_seek seek; |
490 | } u; | 499 | } u; |
491 | struct nfs4_replay * replay; | 500 | struct nfs4_replay * replay; |
@@ -222,7 +222,7 @@ SYSCALL_DEFINE2(ftruncate64, unsigned int, fd, loff_t, length) | |||
222 | #endif /* BITS_PER_LONG == 32 */ | 222 | #endif /* BITS_PER_LONG == 32 */ |
223 | 223 | ||
224 | 224 | ||
225 | int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | 225 | int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len) |
226 | { | 226 | { |
227 | struct inode *inode = file_inode(file); | 227 | struct inode *inode = file_inode(file); |
228 | long ret; | 228 | long ret; |
@@ -309,6 +309,7 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | |||
309 | sb_end_write(inode->i_sb); | 309 | sb_end_write(inode->i_sb); |
310 | return ret; | 310 | return ret; |
311 | } | 311 | } |
312 | EXPORT_SYMBOL_GPL(vfs_fallocate); | ||
312 | 313 | ||
313 | SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) | 314 | SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) |
314 | { | 315 | { |
@@ -316,7 +317,7 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len) | |||
316 | int error = -EBADF; | 317 | int error = -EBADF; |
317 | 318 | ||
318 | if (f.file) { | 319 | if (f.file) { |
319 | error = do_fallocate(f.file, mode, offset, len); | 320 | error = vfs_fallocate(f.file, mode, offset, len); |
320 | fdput(f); | 321 | fdput(f); |
321 | } | 322 | } |
322 | return error; | 323 | return error; |