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