file.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. /*
  2. * (C) 2001 Clemson University and The University of Chicago
  3. *
  4. * See COPYING in top-level directory.
  5. */
  6. /*
  7. * Linux VFS file operations.
  8. */
  9. #include "protocol.h"
  10. #include "orangefs-kernel.h"
  11. #include "orangefs-bufmap.h"
  12. #include <linux/fs.h>
  13. #include <linux/pagemap.h>
  14. /*
  15. * Copy to client-core's address space from the buffers specified
  16. * by the iovec upto total_size bytes.
  17. * NOTE: the iovector can either contain addresses which
  18. * can futher be kernel-space or user-space addresses.
  19. * or it can pointers to struct page's
  20. */
  21. static int precopy_buffers(int buffer_index,
  22. struct iov_iter *iter,
  23. size_t total_size)
  24. {
  25. int ret = 0;
  26. /*
  27. * copy data from application/kernel by pulling it out
  28. * of the iovec.
  29. */
  30. if (total_size) {
  31. ret = orangefs_bufmap_copy_from_iovec(iter,
  32. buffer_index,
  33. total_size);
  34. if (ret < 0)
  35. gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n",
  36. __func__,
  37. (long)ret);
  38. }
  39. if (ret < 0)
  40. gossip_err("%s: Failed to copy-in buffers. Please make sure that the pvfs2-client is running. %ld\n",
  41. __func__,
  42. (long)ret);
  43. return ret;
  44. }
  45. /*
  46. * Copy from client-core's address space to the buffers specified
  47. * by the iovec upto total_size bytes.
  48. * NOTE: the iovector can either contain addresses which
  49. * can futher be kernel-space or user-space addresses.
  50. * or it can pointers to struct page's
  51. */
  52. static int postcopy_buffers(int buffer_index,
  53. struct iov_iter *iter,
  54. size_t total_size)
  55. {
  56. int ret = 0;
  57. /*
  58. * copy data to application/kernel by pushing it out to
  59. * the iovec. NOTE; target buffers can be addresses or
  60. * struct page pointers.
  61. */
  62. if (total_size) {
  63. ret = orangefs_bufmap_copy_to_iovec(iter,
  64. buffer_index,
  65. total_size);
  66. if (ret < 0)
  67. gossip_err("%s: Failed to copy-out buffers. Please make sure that the pvfs2-client is running (%ld)\n",
  68. __func__,
  69. (long)ret);
  70. }
  71. return ret;
  72. }
  73. /*
  74. * Post and wait for the I/O upcall to finish
  75. */
  76. static ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inode,
  77. loff_t *offset, struct iov_iter *iter,
  78. size_t total_size, loff_t readahead_size)
  79. {
  80. struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  81. struct orangefs_khandle *handle = &orangefs_inode->refn.khandle;
  82. struct orangefs_kernel_op_s *new_op = NULL;
  83. struct iov_iter saved = *iter;
  84. int buffer_index = -1;
  85. ssize_t ret;
  86. new_op = op_alloc(ORANGEFS_VFS_OP_FILE_IO);
  87. if (!new_op)
  88. return -ENOMEM;
  89. /* synchronous I/O */
  90. new_op->upcall.req.io.readahead_size = readahead_size;
  91. new_op->upcall.req.io.io_type = type;
  92. new_op->upcall.req.io.refn = orangefs_inode->refn;
  93. populate_shared_memory:
  94. /* get a shared buffer index */
  95. buffer_index = orangefs_bufmap_get();
  96. if (buffer_index < 0) {
  97. ret = buffer_index;
  98. gossip_debug(GOSSIP_FILE_DEBUG,
  99. "%s: orangefs_bufmap_get failure (%zd)\n",
  100. __func__, ret);
  101. goto out;
  102. }
  103. gossip_debug(GOSSIP_FILE_DEBUG,
  104. "%s(%pU): GET op %p -> buffer_index %d\n",
  105. __func__,
  106. handle,
  107. new_op,
  108. buffer_index);
  109. new_op->uses_shared_memory = 1;
  110. new_op->upcall.req.io.buf_index = buffer_index;
  111. new_op->upcall.req.io.count = total_size;
  112. new_op->upcall.req.io.offset = *offset;
  113. gossip_debug(GOSSIP_FILE_DEBUG,
  114. "%s(%pU): offset: %llu total_size: %zd\n",
  115. __func__,
  116. handle,
  117. llu(*offset),
  118. total_size);
  119. /*
  120. * Stage 1: copy the buffers into client-core's address space
  121. * precopy_buffers only pertains to writes.
  122. */
  123. if (type == ORANGEFS_IO_WRITE) {
  124. ret = precopy_buffers(buffer_index,
  125. iter,
  126. total_size);
  127. if (ret < 0)
  128. goto out;
  129. }
  130. gossip_debug(GOSSIP_FILE_DEBUG,
  131. "%s(%pU): Calling post_io_request with tag (%llu)\n",
  132. __func__,
  133. handle,
  134. llu(new_op->tag));
  135. /* Stage 2: Service the I/O operation */
  136. ret = service_operation(new_op,
  137. type == ORANGEFS_IO_WRITE ?
  138. "file_write" :
  139. "file_read",
  140. get_interruptible_flag(inode));
  141. /*
  142. * If service_operation() returns -EAGAIN #and# the operation was
  143. * purged from orangefs_request_list or htable_ops_in_progress, then
  144. * we know that the client was restarted, causing the shared memory
  145. * area to be wiped clean. To restart a write operation in this
  146. * case, we must re-copy the data from the user's iovec to a NEW
  147. * shared memory location. To restart a read operation, we must get
  148. * a new shared memory location.
  149. */
  150. if (ret == -EAGAIN && op_state_purged(new_op)) {
  151. orangefs_bufmap_put(buffer_index);
  152. buffer_index = -1;
  153. if (type == ORANGEFS_IO_WRITE)
  154. *iter = saved;
  155. gossip_debug(GOSSIP_FILE_DEBUG,
  156. "%s:going to repopulate_shared_memory.\n",
  157. __func__);
  158. goto populate_shared_memory;
  159. }
  160. if (ret < 0) {
  161. if (ret == -EINTR) {
  162. /*
  163. * We can't return EINTR if any data was written,
  164. * it's not POSIX. It is minimally acceptable
  165. * to give a partial write, the way NFS does.
  166. *
  167. * It would be optimal to return all or nothing,
  168. * but if a userspace write is bigger than
  169. * an IO buffer, and the interrupt occurs
  170. * between buffer writes, that would not be
  171. * possible.
  172. */
  173. switch (new_op->op_state - OP_VFS_STATE_GIVEN_UP) {
  174. /*
  175. * If the op was waiting when the interrupt
  176. * occurred, then the client-core did not
  177. * trigger the write.
  178. */
  179. case OP_VFS_STATE_WAITING:
  180. if (*offset == 0)
  181. ret = -EINTR;
  182. else
  183. ret = 0;
  184. break;
  185. /*
  186. * If the op was in progress when the interrupt
  187. * occurred, then the client-core was able to
  188. * trigger the write.
  189. */
  190. case OP_VFS_STATE_INPROGR:
  191. ret = total_size;
  192. break;
  193. default:
  194. gossip_err("%s: unexpected op state :%d:.\n",
  195. __func__,
  196. new_op->op_state);
  197. ret = 0;
  198. break;
  199. }
  200. gossip_debug(GOSSIP_FILE_DEBUG,
  201. "%s: got EINTR, state:%d: %p\n",
  202. __func__,
  203. new_op->op_state,
  204. new_op);
  205. } else {
  206. gossip_err("%s: error in %s handle %pU, returning %zd\n",
  207. __func__,
  208. type == ORANGEFS_IO_READ ?
  209. "read from" : "write to",
  210. handle, ret);
  211. }
  212. if (orangefs_cancel_op_in_progress(new_op))
  213. return ret;
  214. goto out;
  215. }
  216. /*
  217. * Stage 3: Post copy buffers from client-core's address space
  218. * postcopy_buffers only pertains to reads.
  219. */
  220. if (type == ORANGEFS_IO_READ) {
  221. ret = postcopy_buffers(buffer_index,
  222. iter,
  223. new_op->downcall.resp.io.amt_complete);
  224. if (ret < 0)
  225. goto out;
  226. }
  227. gossip_debug(GOSSIP_FILE_DEBUG,
  228. "%s(%pU): Amount %s, returned by the sys-io call:%d\n",
  229. __func__,
  230. handle,
  231. type == ORANGEFS_IO_READ ? "read" : "written",
  232. (int)new_op->downcall.resp.io.amt_complete);
  233. ret = new_op->downcall.resp.io.amt_complete;
  234. out:
  235. if (buffer_index >= 0) {
  236. orangefs_bufmap_put(buffer_index);
  237. gossip_debug(GOSSIP_FILE_DEBUG,
  238. "%s(%pU): PUT buffer_index %d\n",
  239. __func__, handle, buffer_index);
  240. buffer_index = -1;
  241. }
  242. op_release(new_op);
  243. return ret;
  244. }
  245. /*
  246. * Common entry point for read/write/readv/writev
  247. * This function will dispatch it to either the direct I/O
  248. * or buffered I/O path depending on the mount options and/or
  249. * augmented/extended metadata attached to the file.
  250. * Note: File extended attributes override any mount options.
  251. */
  252. static ssize_t do_readv_writev(enum ORANGEFS_io_type type, struct file *file,
  253. loff_t *offset, struct iov_iter *iter)
  254. {
  255. struct inode *inode = file->f_mapping->host;
  256. struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  257. struct orangefs_khandle *handle = &orangefs_inode->refn.khandle;
  258. size_t count = iov_iter_count(iter);
  259. ssize_t total_count = 0;
  260. ssize_t ret = -EINVAL;
  261. gossip_debug(GOSSIP_FILE_DEBUG,
  262. "%s-BEGIN(%pU): count(%d) after estimate_max_iovecs.\n",
  263. __func__,
  264. handle,
  265. (int)count);
  266. if (type == ORANGEFS_IO_WRITE) {
  267. gossip_debug(GOSSIP_FILE_DEBUG,
  268. "%s(%pU): proceeding with offset : %llu, "
  269. "size %d\n",
  270. __func__,
  271. handle,
  272. llu(*offset),
  273. (int)count);
  274. }
  275. if (count == 0) {
  276. ret = 0;
  277. goto out;
  278. }
  279. while (iov_iter_count(iter)) {
  280. size_t each_count = iov_iter_count(iter);
  281. size_t amt_complete;
  282. /* how much to transfer in this loop iteration */
  283. if (each_count > orangefs_bufmap_size_query())
  284. each_count = orangefs_bufmap_size_query();
  285. gossip_debug(GOSSIP_FILE_DEBUG,
  286. "%s(%pU): size of each_count(%d)\n",
  287. __func__,
  288. handle,
  289. (int)each_count);
  290. gossip_debug(GOSSIP_FILE_DEBUG,
  291. "%s(%pU): BEFORE wait_for_io: offset is %d\n",
  292. __func__,
  293. handle,
  294. (int)*offset);
  295. ret = wait_for_direct_io(type, inode, offset, iter,
  296. each_count, 0);
  297. gossip_debug(GOSSIP_FILE_DEBUG,
  298. "%s(%pU): return from wait_for_io:%d\n",
  299. __func__,
  300. handle,
  301. (int)ret);
  302. if (ret < 0)
  303. goto out;
  304. *offset += ret;
  305. total_count += ret;
  306. amt_complete = ret;
  307. gossip_debug(GOSSIP_FILE_DEBUG,
  308. "%s(%pU): AFTER wait_for_io: offset is %d\n",
  309. __func__,
  310. handle,
  311. (int)*offset);
  312. /*
  313. * if we got a short I/O operations,
  314. * fall out and return what we got so far
  315. */
  316. if (amt_complete < each_count)
  317. break;
  318. } /*end while */
  319. out:
  320. if (total_count > 0)
  321. ret = total_count;
  322. if (ret > 0) {
  323. if (type == ORANGEFS_IO_READ) {
  324. file_accessed(file);
  325. } else {
  326. SetMtimeFlag(orangefs_inode);
  327. inode->i_mtime = CURRENT_TIME;
  328. mark_inode_dirty_sync(inode);
  329. }
  330. }
  331. gossip_debug(GOSSIP_FILE_DEBUG,
  332. "%s(%pU): Value(%d) returned.\n",
  333. __func__,
  334. handle,
  335. (int)ret);
  336. return ret;
  337. }
  338. /*
  339. * Read data from a specified offset in a file (referenced by inode).
  340. * Data may be placed either in a user or kernel buffer.
  341. */
  342. ssize_t orangefs_inode_read(struct inode *inode,
  343. struct iov_iter *iter,
  344. loff_t *offset,
  345. loff_t readahead_size)
  346. {
  347. struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  348. size_t count = iov_iter_count(iter);
  349. size_t bufmap_size;
  350. ssize_t ret = -EINVAL;
  351. g_orangefs_stats.reads++;
  352. bufmap_size = orangefs_bufmap_size_query();
  353. if (count > bufmap_size) {
  354. gossip_debug(GOSSIP_FILE_DEBUG,
  355. "%s: count is too large (%zd/%zd)!\n",
  356. __func__, count, bufmap_size);
  357. return -EINVAL;
  358. }
  359. gossip_debug(GOSSIP_FILE_DEBUG,
  360. "%s(%pU) %zd@%llu\n",
  361. __func__,
  362. &orangefs_inode->refn.khandle,
  363. count,
  364. llu(*offset));
  365. ret = wait_for_direct_io(ORANGEFS_IO_READ, inode, offset, iter,
  366. count, readahead_size);
  367. if (ret > 0)
  368. *offset += ret;
  369. gossip_debug(GOSSIP_FILE_DEBUG,
  370. "%s(%pU): Value(%zd) returned.\n",
  371. __func__,
  372. &orangefs_inode->refn.khandle,
  373. ret);
  374. return ret;
  375. }
  376. static ssize_t orangefs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
  377. {
  378. struct file *file = iocb->ki_filp;
  379. loff_t pos = *(&iocb->ki_pos);
  380. ssize_t rc = 0;
  381. BUG_ON(iocb->private);
  382. gossip_debug(GOSSIP_FILE_DEBUG, "orangefs_file_read_iter\n");
  383. g_orangefs_stats.reads++;
  384. rc = do_readv_writev(ORANGEFS_IO_READ, file, &pos, iter);
  385. iocb->ki_pos = pos;
  386. return rc;
  387. }
  388. static ssize_t orangefs_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
  389. {
  390. struct file *file = iocb->ki_filp;
  391. loff_t pos;
  392. ssize_t rc;
  393. BUG_ON(iocb->private);
  394. gossip_debug(GOSSIP_FILE_DEBUG, "orangefs_file_write_iter\n");
  395. inode_lock(file->f_mapping->host);
  396. /* Make sure generic_write_checks sees an up to date inode size. */
  397. if (file->f_flags & O_APPEND) {
  398. rc = orangefs_inode_getattr(file->f_mapping->host, 0, 1);
  399. if (rc == -ESTALE)
  400. rc = -EIO;
  401. if (rc) {
  402. gossip_err("%s: orangefs_inode_getattr failed, "
  403. "rc:%zd:.\n", __func__, rc);
  404. goto out;
  405. }
  406. }
  407. if (file->f_pos > i_size_read(file->f_mapping->host))
  408. orangefs_i_size_write(file->f_mapping->host, file->f_pos);
  409. rc = generic_write_checks(iocb, iter);
  410. if (rc <= 0) {
  411. gossip_err("%s: generic_write_checks failed, rc:%zd:.\n",
  412. __func__, rc);
  413. goto out;
  414. }
  415. /*
  416. * if we are appending, generic_write_checks would have updated
  417. * pos to the end of the file, so we will wait till now to set
  418. * pos...
  419. */
  420. pos = *(&iocb->ki_pos);
  421. rc = do_readv_writev(ORANGEFS_IO_WRITE,
  422. file,
  423. &pos,
  424. iter);
  425. if (rc < 0) {
  426. gossip_err("%s: do_readv_writev failed, rc:%zd:.\n",
  427. __func__, rc);
  428. goto out;
  429. }
  430. iocb->ki_pos = pos;
  431. g_orangefs_stats.writes++;
  432. out:
  433. inode_unlock(file->f_mapping->host);
  434. return rc;
  435. }
  436. /*
  437. * Perform a miscellaneous operation on a file.
  438. */
  439. static long orangefs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  440. {
  441. int ret = -ENOTTY;
  442. __u64 val = 0;
  443. unsigned long uval;
  444. gossip_debug(GOSSIP_FILE_DEBUG,
  445. "orangefs_ioctl: called with cmd %d\n",
  446. cmd);
  447. /*
  448. * we understand some general ioctls on files, such as the immutable
  449. * and append flags
  450. */
  451. if (cmd == FS_IOC_GETFLAGS) {
  452. val = 0;
  453. ret = orangefs_inode_getxattr(file_inode(file),
  454. "user.pvfs2.meta_hint",
  455. &val, sizeof(val));
  456. if (ret < 0 && ret != -ENODATA)
  457. return ret;
  458. else if (ret == -ENODATA)
  459. val = 0;
  460. uval = val;
  461. gossip_debug(GOSSIP_FILE_DEBUG,
  462. "orangefs_ioctl: FS_IOC_GETFLAGS: %llu\n",
  463. (unsigned long long)uval);
  464. return put_user(uval, (int __user *)arg);
  465. } else if (cmd == FS_IOC_SETFLAGS) {
  466. ret = 0;
  467. if (get_user(uval, (int __user *)arg))
  468. return -EFAULT;
  469. /*
  470. * ORANGEFS_MIRROR_FL is set internally when the mirroring mode
  471. * is turned on for a file. The user is not allowed to turn
  472. * on this bit, but the bit is present if the user first gets
  473. * the flags and then updates the flags with some new
  474. * settings. So, we ignore it in the following edit. bligon.
  475. */
  476. if ((uval & ~ORANGEFS_MIRROR_FL) &
  477. (~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NOATIME_FL))) {
  478. gossip_err("orangefs_ioctl: the FS_IOC_SETFLAGS only supports setting one of FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NOATIME_FL\n");
  479. return -EINVAL;
  480. }
  481. val = uval;
  482. gossip_debug(GOSSIP_FILE_DEBUG,
  483. "orangefs_ioctl: FS_IOC_SETFLAGS: %llu\n",
  484. (unsigned long long)val);
  485. ret = orangefs_inode_setxattr(file_inode(file),
  486. "user.pvfs2.meta_hint",
  487. &val, sizeof(val), 0);
  488. }
  489. return ret;
  490. }
  491. /*
  492. * Memory map a region of a file.
  493. */
  494. static int orangefs_file_mmap(struct file *file, struct vm_area_struct *vma)
  495. {
  496. gossip_debug(GOSSIP_FILE_DEBUG,
  497. "orangefs_file_mmap: called on %s\n",
  498. (file ?
  499. (char *)file->f_path.dentry->d_name.name :
  500. (char *)"Unknown"));
  501. /* set the sequential readahead hint */
  502. vma->vm_flags |= VM_SEQ_READ;
  503. vma->vm_flags &= ~VM_RAND_READ;
  504. /* Use readonly mmap since we cannot support writable maps. */
  505. return generic_file_readonly_mmap(file, vma);
  506. }
  507. #define mapping_nrpages(idata) ((idata)->nrpages)
  508. /*
  509. * Called to notify the module that there are no more references to
  510. * this file (i.e. no processes have it open).
  511. *
  512. * \note Not called when each file is closed.
  513. */
  514. static int orangefs_file_release(struct inode *inode, struct file *file)
  515. {
  516. gossip_debug(GOSSIP_FILE_DEBUG,
  517. "orangefs_file_release: called on %s\n",
  518. file->f_path.dentry->d_name.name);
  519. orangefs_flush_inode(inode);
  520. /*
  521. * remove all associated inode pages from the page cache and mmap
  522. * readahead cache (if any); this forces an expensive refresh of
  523. * data for the next caller of mmap (or 'get_block' accesses)
  524. */
  525. if (file->f_path.dentry->d_inode &&
  526. file->f_path.dentry->d_inode->i_mapping &&
  527. mapping_nrpages(&file->f_path.dentry->d_inode->i_data))
  528. truncate_inode_pages(file->f_path.dentry->d_inode->i_mapping,
  529. 0);
  530. return 0;
  531. }
  532. /*
  533. * Push all data for a specific file onto permanent storage.
  534. */
  535. static int orangefs_fsync(struct file *file,
  536. loff_t start,
  537. loff_t end,
  538. int datasync)
  539. {
  540. int ret = -EINVAL;
  541. struct orangefs_inode_s *orangefs_inode =
  542. ORANGEFS_I(file->f_path.dentry->d_inode);
  543. struct orangefs_kernel_op_s *new_op = NULL;
  544. /* required call */
  545. filemap_write_and_wait_range(file->f_mapping, start, end);
  546. new_op = op_alloc(ORANGEFS_VFS_OP_FSYNC);
  547. if (!new_op)
  548. return -ENOMEM;
  549. new_op->upcall.req.fsync.refn = orangefs_inode->refn;
  550. ret = service_operation(new_op,
  551. "orangefs_fsync",
  552. get_interruptible_flag(file->f_path.dentry->d_inode));
  553. gossip_debug(GOSSIP_FILE_DEBUG,
  554. "orangefs_fsync got return value of %d\n",
  555. ret);
  556. op_release(new_op);
  557. orangefs_flush_inode(file->f_path.dentry->d_inode);
  558. return ret;
  559. }
  560. /*
  561. * Change the file pointer position for an instance of an open file.
  562. *
  563. * \note If .llseek is overriden, we must acquire lock as described in
  564. * Documentation/filesystems/Locking.
  565. *
  566. * Future upgrade could support SEEK_DATA and SEEK_HOLE but would
  567. * require much changes to the FS
  568. */
  569. static loff_t orangefs_file_llseek(struct file *file, loff_t offset, int origin)
  570. {
  571. int ret = -EINVAL;
  572. struct inode *inode = file_inode(file);
  573. if (origin == SEEK_END) {
  574. /*
  575. * revalidate the inode's file size.
  576. * NOTE: We are only interested in file size here,
  577. * so we set mask accordingly.
  578. */
  579. ret = orangefs_inode_getattr(file->f_mapping->host, 0, 1);
  580. if (ret == -ESTALE)
  581. ret = -EIO;
  582. if (ret) {
  583. gossip_debug(GOSSIP_FILE_DEBUG,
  584. "%s:%s:%d calling make bad inode\n",
  585. __FILE__,
  586. __func__,
  587. __LINE__);
  588. return ret;
  589. }
  590. }
  591. gossip_debug(GOSSIP_FILE_DEBUG,
  592. "orangefs_file_llseek: offset is %ld | origin is %d"
  593. " | inode size is %lu\n",
  594. (long)offset,
  595. origin,
  596. (unsigned long)i_size_read(inode));
  597. return generic_file_llseek(file, offset, origin);
  598. }
  599. /*
  600. * Support local locks (locks that only this kernel knows about)
  601. * if Orangefs was mounted -o local_lock.
  602. */
  603. static int orangefs_lock(struct file *filp, int cmd, struct file_lock *fl)
  604. {
  605. int rc = -EINVAL;
  606. if (ORANGEFS_SB(filp->f_inode->i_sb)->flags & ORANGEFS_OPT_LOCAL_LOCK) {
  607. if (cmd == F_GETLK) {
  608. rc = 0;
  609. posix_test_lock(filp, fl);
  610. } else {
  611. rc = posix_lock_file(filp, fl, NULL);
  612. }
  613. }
  614. return rc;
  615. }
  616. /** ORANGEFS implementation of VFS file operations */
  617. const struct file_operations orangefs_file_operations = {
  618. .llseek = orangefs_file_llseek,
  619. .read_iter = orangefs_file_read_iter,
  620. .write_iter = orangefs_file_write_iter,
  621. .lock = orangefs_lock,
  622. .unlocked_ioctl = orangefs_ioctl,
  623. .mmap = orangefs_file_mmap,
  624. .open = generic_file_open,
  625. .release = orangefs_file_release,
  626. .fsync = orangefs_fsync,
  627. };