1 /* 2 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com> 3 */ 4 #include <linux/fs.h> 5 #include <linux/sunrpc/sched.h> 6 #include <linux/nfs.h> 7 #include <linux/nfs3.h> 8 #include <linux/nfs4.h> 9 #include <linux/nfs_xdr.h> 10 #include <linux/nfs_fs.h> 11 #include "nfs4_fs.h" 12 #include "nfs42.h" 13 #include "iostat.h" 14 #include "pnfs.h" 15 #include "internal.h" 16 17 #define NFSDBG_FACILITY NFSDBG_PROC 18 19 static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, 20 struct nfs_lock_context *lock, loff_t offset, loff_t len) 21 { 22 struct inode *inode = file_inode(filep); 23 struct nfs_server *server = NFS_SERVER(inode); 24 struct nfs42_falloc_args args = { 25 .falloc_fh = NFS_FH(inode), 26 .falloc_offset = offset, 27 .falloc_length = len, 28 .falloc_bitmask = server->cache_consistency_bitmask, 29 }; 30 struct nfs42_falloc_res res = { 31 .falloc_server = server, 32 }; 33 int status; 34 35 msg->rpc_argp = &args; 36 msg->rpc_resp = &res; 37 38 status = nfs4_set_rw_stateid(&args.falloc_stateid, lock->open_context, 39 lock, FMODE_WRITE); 40 if (status) 41 return status; 42 43 res.falloc_fattr = nfs_alloc_fattr(); 44 if (!res.falloc_fattr) 45 return -ENOMEM; 46 47 status = nfs4_call_sync(server->client, server, msg, 48 &args.seq_args, &res.seq_res, 0); 49 if (status == 0) 50 status = nfs_post_op_update_inode(inode, res.falloc_fattr); 51 52 kfree(res.falloc_fattr); 53 return status; 54 } 55 56 static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, 57 loff_t offset, loff_t len) 58 { 59 struct nfs_server *server = NFS_SERVER(file_inode(filep)); 60 struct nfs4_exception exception = { }; 61 struct nfs_lock_context *lock; 62 int err; 63 64 lock = nfs_get_lock_context(nfs_file_open_context(filep)); 65 if (IS_ERR(lock)) 66 return PTR_ERR(lock); 67 68 exception.inode = file_inode(filep); 69 exception.state = lock->open_context->state; 70 71 do { 72 err = _nfs42_proc_fallocate(msg, filep, lock, offset, len); 73 if (err == -ENOTSUPP) { 74 err = -EOPNOTSUPP; 75 break; 76 } 77 err = nfs4_handle_exception(server, err, &exception); 78 } while (exception.retry); 79 80 nfs_put_lock_context(lock); 81 return err; 82 } 83 84 int nfs42_proc_allocate(struct file *filep, loff_t offset, loff_t len) 85 { 86 struct rpc_message msg = { 87 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ALLOCATE], 88 }; 89 struct inode *inode = file_inode(filep); 90 int err; 91 92 if (!nfs_server_capable(inode, NFS_CAP_ALLOCATE)) 93 return -EOPNOTSUPP; 94 95 inode_lock(inode); 96 97 err = nfs42_proc_fallocate(&msg, filep, offset, len); 98 if (err == -EOPNOTSUPP) 99 NFS_SERVER(inode)->caps &= ~NFS_CAP_ALLOCATE; 100 101 inode_unlock(inode); 102 return err; 103 } 104 105 int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len) 106 { 107 struct rpc_message msg = { 108 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DEALLOCATE], 109 }; 110 struct inode *inode = file_inode(filep); 111 int err; 112 113 if (!nfs_server_capable(inode, NFS_CAP_DEALLOCATE)) 114 return -EOPNOTSUPP; 115 116 nfs_wb_all(inode); 117 inode_lock(inode); 118 119 err = nfs42_proc_fallocate(&msg, filep, offset, len); 120 if (err == 0) 121 truncate_pagecache_range(inode, offset, (offset + len) -1); 122 if (err == -EOPNOTSUPP) 123 NFS_SERVER(inode)->caps &= ~NFS_CAP_DEALLOCATE; 124 125 inode_unlock(inode); 126 return err; 127 } 128 129 static loff_t _nfs42_proc_llseek(struct file *filep, 130 struct nfs_lock_context *lock, loff_t offset, int whence) 131 { 132 struct inode *inode = file_inode(filep); 133 struct nfs42_seek_args args = { 134 .sa_fh = NFS_FH(inode), 135 .sa_offset = offset, 136 .sa_what = (whence == SEEK_HOLE) ? 137 NFS4_CONTENT_HOLE : NFS4_CONTENT_DATA, 138 }; 139 struct nfs42_seek_res res; 140 struct rpc_message msg = { 141 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEEK], 142 .rpc_argp = &args, 143 .rpc_resp = &res, 144 }; 145 struct nfs_server *server = NFS_SERVER(inode); 146 int status; 147 148 if (!nfs_server_capable(inode, NFS_CAP_SEEK)) 149 return -ENOTSUPP; 150 151 status = nfs4_set_rw_stateid(&args.sa_stateid, lock->open_context, 152 lock, FMODE_READ); 153 if (status) 154 return status; 155 156 nfs_wb_all(inode); 157 status = nfs4_call_sync(server->client, server, &msg, 158 &args.seq_args, &res.seq_res, 0); 159 if (status == -ENOTSUPP) 160 server->caps &= ~NFS_CAP_SEEK; 161 if (status) 162 return status; 163 164 return vfs_setpos(filep, res.sr_offset, inode->i_sb->s_maxbytes); 165 } 166 167 loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence) 168 { 169 struct nfs_server *server = NFS_SERVER(file_inode(filep)); 170 struct nfs4_exception exception = { }; 171 struct nfs_lock_context *lock; 172 loff_t err; 173 174 lock = nfs_get_lock_context(nfs_file_open_context(filep)); 175 if (IS_ERR(lock)) 176 return PTR_ERR(lock); 177 178 exception.inode = file_inode(filep); 179 exception.state = lock->open_context->state; 180 181 do { 182 err = _nfs42_proc_llseek(filep, lock, offset, whence); 183 if (err >= 0) 184 break; 185 if (err == -ENOTSUPP) { 186 err = -EOPNOTSUPP; 187 break; 188 } 189 err = nfs4_handle_exception(server, err, &exception); 190 } while (exception.retry); 191 192 nfs_put_lock_context(lock); 193 return err; 194 } 195 196 197 static void 198 nfs42_layoutstat_prepare(struct rpc_task *task, void *calldata) 199 { 200 struct nfs42_layoutstat_data *data = calldata; 201 struct nfs_server *server = NFS_SERVER(data->args.inode); 202 203 nfs41_setup_sequence(nfs4_get_session(server), &data->args.seq_args, 204 &data->res.seq_res, task); 205 } 206 207 static void 208 nfs42_layoutstat_done(struct rpc_task *task, void *calldata) 209 { 210 struct nfs42_layoutstat_data *data = calldata; 211 struct inode *inode = data->inode; 212 struct pnfs_layout_hdr *lo; 213 214 if (!nfs4_sequence_done(task, &data->res.seq_res)) 215 return; 216 217 switch (task->tk_status) { 218 case 0: 219 break; 220 case -NFS4ERR_EXPIRED: 221 case -NFS4ERR_STALE_STATEID: 222 case -NFS4ERR_OLD_STATEID: 223 case -NFS4ERR_BAD_STATEID: 224 spin_lock(&inode->i_lock); 225 lo = NFS_I(inode)->layout; 226 if (lo && nfs4_stateid_match(&data->args.stateid, 227 &lo->plh_stateid)) { 228 LIST_HEAD(head); 229 230 /* 231 * Mark the bad layout state as invalid, then retry 232 * with the current stateid. 233 */ 234 set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); 235 pnfs_mark_matching_lsegs_invalid(lo, &head, NULL); 236 spin_unlock(&inode->i_lock); 237 pnfs_free_lseg_list(&head); 238 } else 239 spin_unlock(&inode->i_lock); 240 break; 241 case -ENOTSUPP: 242 case -EOPNOTSUPP: 243 NFS_SERVER(inode)->caps &= ~NFS_CAP_LAYOUTSTATS; 244 default: 245 break; 246 } 247 248 dprintk("%s server returns %d\n", __func__, task->tk_status); 249 } 250 251 static void 252 nfs42_layoutstat_release(void *calldata) 253 { 254 struct nfs42_layoutstat_data *data = calldata; 255 struct nfs_server *nfss = NFS_SERVER(data->args.inode); 256 257 if (nfss->pnfs_curr_ld->cleanup_layoutstats) 258 nfss->pnfs_curr_ld->cleanup_layoutstats(data); 259 260 pnfs_put_layout_hdr(NFS_I(data->args.inode)->layout); 261 smp_mb__before_atomic(); 262 clear_bit(NFS_INO_LAYOUTSTATS, &NFS_I(data->args.inode)->flags); 263 smp_mb__after_atomic(); 264 nfs_iput_and_deactive(data->inode); 265 kfree(data->args.devinfo); 266 kfree(data); 267 } 268 269 static const struct rpc_call_ops nfs42_layoutstat_ops = { 270 .rpc_call_prepare = nfs42_layoutstat_prepare, 271 .rpc_call_done = nfs42_layoutstat_done, 272 .rpc_release = nfs42_layoutstat_release, 273 }; 274 275 int nfs42_proc_layoutstats_generic(struct nfs_server *server, 276 struct nfs42_layoutstat_data *data) 277 { 278 struct rpc_message msg = { 279 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTSTATS], 280 .rpc_argp = &data->args, 281 .rpc_resp = &data->res, 282 }; 283 struct rpc_task_setup task_setup = { 284 .rpc_client = server->client, 285 .rpc_message = &msg, 286 .callback_ops = &nfs42_layoutstat_ops, 287 .callback_data = data, 288 .flags = RPC_TASK_ASYNC, 289 }; 290 struct rpc_task *task; 291 292 data->inode = nfs_igrab_and_active(data->args.inode); 293 if (!data->inode) { 294 nfs42_layoutstat_release(data); 295 return -EAGAIN; 296 } 297 nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0); 298 task = rpc_run_task(&task_setup); 299 if (IS_ERR(task)) 300 return PTR_ERR(task); 301 return 0; 302 } 303 304 static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f, 305 struct file *dst_f, struct nfs_lock_context *src_lock, 306 struct nfs_lock_context *dst_lock, loff_t src_offset, 307 loff_t dst_offset, loff_t count) 308 { 309 struct inode *src_inode = file_inode(src_f); 310 struct inode *dst_inode = file_inode(dst_f); 311 struct nfs_server *server = NFS_SERVER(dst_inode); 312 struct nfs42_clone_args args = { 313 .src_fh = NFS_FH(src_inode), 314 .dst_fh = NFS_FH(dst_inode), 315 .src_offset = src_offset, 316 .dst_offset = dst_offset, 317 .count = count, 318 .dst_bitmask = server->cache_consistency_bitmask, 319 }; 320 struct nfs42_clone_res res = { 321 .server = server, 322 }; 323 int status; 324 325 msg->rpc_argp = &args; 326 msg->rpc_resp = &res; 327 328 status = nfs4_set_rw_stateid(&args.src_stateid, src_lock->open_context, 329 src_lock, FMODE_READ); 330 if (status) 331 return status; 332 333 status = nfs4_set_rw_stateid(&args.dst_stateid, dst_lock->open_context, 334 dst_lock, FMODE_WRITE); 335 if (status) 336 return status; 337 338 res.dst_fattr = nfs_alloc_fattr(); 339 if (!res.dst_fattr) 340 return -ENOMEM; 341 342 status = nfs4_call_sync(server->client, server, msg, 343 &args.seq_args, &res.seq_res, 0); 344 if (status == 0) 345 status = nfs_post_op_update_inode(dst_inode, res.dst_fattr); 346 347 kfree(res.dst_fattr); 348 return status; 349 } 350 351 int nfs42_proc_clone(struct file *src_f, struct file *dst_f, 352 loff_t src_offset, loff_t dst_offset, loff_t count) 353 { 354 struct rpc_message msg = { 355 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLONE], 356 }; 357 struct inode *inode = file_inode(src_f); 358 struct nfs_server *server = NFS_SERVER(file_inode(src_f)); 359 struct nfs_lock_context *src_lock; 360 struct nfs_lock_context *dst_lock; 361 struct nfs4_exception src_exception = { }; 362 struct nfs4_exception dst_exception = { }; 363 int err, err2; 364 365 if (!nfs_server_capable(inode, NFS_CAP_CLONE)) 366 return -EOPNOTSUPP; 367 368 src_lock = nfs_get_lock_context(nfs_file_open_context(src_f)); 369 if (IS_ERR(src_lock)) 370 return PTR_ERR(src_lock); 371 372 src_exception.inode = file_inode(src_f); 373 src_exception.state = src_lock->open_context->state; 374 375 dst_lock = nfs_get_lock_context(nfs_file_open_context(dst_f)); 376 if (IS_ERR(dst_lock)) { 377 err = PTR_ERR(dst_lock); 378 goto out_put_src_lock; 379 } 380 381 dst_exception.inode = file_inode(dst_f); 382 dst_exception.state = dst_lock->open_context->state; 383 384 do { 385 err = _nfs42_proc_clone(&msg, src_f, dst_f, src_lock, dst_lock, 386 src_offset, dst_offset, count); 387 if (err == -ENOTSUPP || err == -EOPNOTSUPP) { 388 NFS_SERVER(inode)->caps &= ~NFS_CAP_CLONE; 389 err = -EOPNOTSUPP; 390 break; 391 } 392 393 err2 = nfs4_handle_exception(server, err, &src_exception); 394 err = nfs4_handle_exception(server, err, &dst_exception); 395 if (!err) 396 err = err2; 397 } while (src_exception.retry || dst_exception.retry); 398 399 nfs_put_lock_context(dst_lock); 400 out_put_src_lock: 401 nfs_put_lock_context(src_lock); 402 return err; 403 } 404