Whamcloud - gitweb
LU-1431 ptlrpc: Support for over 1MB bulk I/O RPC
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_io.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2011, 2012, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/osd/osd_io.c
37  *
38  * body operations
39  *
40  * Author: Nikita Danilov <nikita@clusterfs.com>
41  * Author: Alex Zhuravlev <bzzz@whamcloud.com>
42  *
43  */
44
45 /* LUSTRE_VERSION_CODE */
46 #include <lustre_ver.h>
47 /* prerequisite for linux/xattr.h */
48 #include <linux/types.h>
49 /* prerequisite for linux/xattr.h */
50 #include <linux/fs.h>
51
52 /* ext_depth() */
53 #include <ldiskfs/ldiskfs.h>
54 #include <ldiskfs/ldiskfs_jbd2.h>
55 #include <ldiskfs/ldiskfs_extents.h>
56
57 /*
58  * struct OBD_{ALLOC,FREE}*()
59  * OBD_FAIL_CHECK
60  */
61 #include <obd_support.h>
62
63 #include "osd_internal.h"
64
65 #ifndef HAVE_PAGE_CONSTANT
66 #define mapping_cap_page_constant_write(mapping) 0
67 #define SetPageConstant(page) do {} while (0)
68 #define ClearPageConstant(page) do {} while (0)
69 #endif
70
71 #ifndef HAS_GENERIC_ERROR_REMOVE_PAGE
72 int generic_error_remove_page(struct address_space *mapping, struct page *page)
73 {
74         if (mapping == NULL)
75                 return -EINVAL;
76
77         if (mapping != page->mapping)
78                 return -EIO;
79         /*
80          * Only punch for normal data pages for now.
81          * Handling other types like directories would need more auditing.
82          */
83         if (!S_ISREG(mapping->host->i_mode))
84                 return -EIO;
85
86         if (page_mapped(page)) {
87                 unmap_mapping_range(mapping,
88                                     (loff_t)page->index << PAGE_CACHE_SHIFT,
89                                     PAGE_CACHE_SIZE, 0);
90         }
91         truncate_complete_page(mapping, page);
92         return 0;
93 }
94 #endif
95
96 static void __osd_init_iobuf(struct osd_device *d, struct osd_iobuf *iobuf,
97                              int rw, int line)
98 {
99         LASSERTF(iobuf->dr_elapsed_valid == 0,
100                  "iobuf %p, reqs %d, rw %d, line %d\n", iobuf,
101                  cfs_atomic_read(&iobuf->dr_numreqs), iobuf->dr_rw,
102                  iobuf->dr_init_at);
103
104         cfs_waitq_init(&iobuf->dr_wait);
105         cfs_atomic_set(&iobuf->dr_numreqs, 0);
106         iobuf->dr_max_pages = PTLRPC_MAX_BRW_PAGES;
107         iobuf->dr_npages = 0;
108         iobuf->dr_error = 0;
109         iobuf->dr_dev = d;
110         iobuf->dr_frags = 0;
111         iobuf->dr_elapsed = 0;
112         /* must be counted before, so assert */
113         iobuf->dr_rw = rw;
114         iobuf->dr_init_at = line;
115 }
116 #define osd_init_iobuf(dev,iobuf,rw) __osd_init_iobuf(dev, iobuf, rw, __LINE__)
117
118 static void osd_iobuf_add_page(struct osd_iobuf *iobuf, struct page *page)
119 {
120         LASSERT(iobuf->dr_npages < iobuf->dr_max_pages);
121         iobuf->dr_pages[iobuf->dr_npages++] = page;
122 }
123
124 void osd_fini_iobuf(struct osd_device *d, struct osd_iobuf *iobuf)
125 {
126         int rw = iobuf->dr_rw;
127
128         if (iobuf->dr_elapsed_valid) {
129                 iobuf->dr_elapsed_valid = 0;
130                 LASSERT(iobuf->dr_dev == d);
131                 LASSERT(iobuf->dr_frags > 0);
132                 lprocfs_oh_tally(&d->od_brw_stats.
133                                  hist[BRW_R_DIO_FRAGS+rw],
134                                  iobuf->dr_frags);
135                 lprocfs_oh_tally_log2(&d->od_brw_stats.hist[BRW_R_IO_TIME+rw],
136                                       iobuf->dr_elapsed);
137         }
138 }
139
140 #ifdef HAVE_BIO_ENDIO_2ARG
141 #define DIO_RETURN(a)
142 static void dio_complete_routine(struct bio *bio, int error)
143 #else
144 #define DIO_RETURN(a)   return(a)
145 static int dio_complete_routine(struct bio *bio, unsigned int done, int error)
146 #endif
147 {
148         struct osd_iobuf *iobuf = bio->bi_private;
149         struct bio_vec *bvl;
150         int i;
151
152         /* CAVEAT EMPTOR: possibly in IRQ context
153          * DO NOT record procfs stats here!!! */
154
155         if (unlikely(iobuf == NULL)) {
156                 CERROR("***** bio->bi_private is NULL!  This should never "
157                        "happen.  Normally, I would crash here, but instead I "
158                        "will dump the bio contents to the console.  Please "
159                        "report this to <http://jira.whamcloud.com/> , along "
160                        "with any interesting messages leading up to this point "
161                        "(like SCSI errors, perhaps).  Because bi_private is "
162                        "NULL, I can't wake up the thread that initiated this "
163                        "IO - you will probably have to reboot this node.\n");
164                 CERROR("bi_next: %p, bi_flags: %lx, bi_rw: %lu, bi_vcnt: %d, "
165                        "bi_idx: %d, bi->size: %d, bi_end_io: %p, bi_cnt: %d, "
166                        "bi_private: %p\n", bio->bi_next, bio->bi_flags,
167                        bio->bi_rw, bio->bi_vcnt, bio->bi_idx, bio->bi_size,
168                        bio->bi_end_io, cfs_atomic_read(&bio->bi_cnt),
169                        bio->bi_private);
170                 DIO_RETURN(0);
171         }
172
173         /* the check is outside of the cycle for performance reason -bzzz */
174         if (!test_bit(BIO_RW, &bio->bi_rw)) {
175                 bio_for_each_segment(bvl, bio, i) {
176                         if (likely(error == 0))
177                                 SetPageUptodate(bvl->bv_page);
178                         LASSERT(PageLocked(bvl->bv_page));
179                         ClearPageConstant(bvl->bv_page);
180                 }
181                 cfs_atomic_dec(&iobuf->dr_dev->od_r_in_flight);
182         } else {
183                 struct page *p = iobuf->dr_pages[0];
184                 if (p->mapping) {
185                         if (mapping_cap_page_constant_write(p->mapping)) {
186                                 bio_for_each_segment(bvl, bio, i) {
187                                         ClearPageConstant(bvl->bv_page);
188                                 }
189                         }
190                 }
191                 cfs_atomic_dec(&iobuf->dr_dev->od_w_in_flight);
192         }
193
194         /* any real error is good enough -bzzz */
195         if (error != 0 && iobuf->dr_error == 0)
196                 iobuf->dr_error = error;
197
198         /*
199          * set dr_elapsed before dr_numreqs turns to 0, otherwise
200          * it's possible that service thread will see dr_numreqs
201          * is zero, but dr_elapsed is not set yet, leading to lost
202          * data in this processing and an assertion in a subsequent
203          * call to OSD.
204          */
205         if (cfs_atomic_read(&iobuf->dr_numreqs) == 1) {
206                 iobuf->dr_elapsed = jiffies - iobuf->dr_start_time;
207                 iobuf->dr_elapsed_valid = 1;
208         }
209         if (cfs_atomic_dec_and_test(&iobuf->dr_numreqs))
210                 cfs_waitq_signal(&iobuf->dr_wait);
211
212         /* Completed bios used to be chained off iobuf->dr_bios and freed in
213          * filter_clear_dreq().  It was then possible to exhaust the biovec-256
214          * mempool when serious on-disk fragmentation was encountered,
215          * deadlocking the OST.  The bios are now released as soon as complete
216          * so the pool cannot be exhausted while IOs are competing. bug 10076 */
217         bio_put(bio);
218         DIO_RETURN(0);
219 }
220
221 static void record_start_io(struct osd_iobuf *iobuf, int size)
222 {
223         struct osd_device    *osd = iobuf->dr_dev;
224         struct obd_histogram *h = osd->od_brw_stats.hist;
225
226         iobuf->dr_frags++;
227         cfs_atomic_inc(&iobuf->dr_numreqs);
228
229         if (iobuf->dr_rw == 0) {
230                 cfs_atomic_inc(&osd->od_r_in_flight);
231                 lprocfs_oh_tally(&h[BRW_R_RPC_HIST],
232                                  cfs_atomic_read(&osd->od_r_in_flight));
233                 lprocfs_oh_tally_log2(&h[BRW_R_DISK_IOSIZE], size);
234         } else if (iobuf->dr_rw == 1) {
235                 cfs_atomic_inc(&osd->od_w_in_flight);
236                 lprocfs_oh_tally(&h[BRW_W_RPC_HIST],
237                                  cfs_atomic_read(&osd->od_w_in_flight));
238                 lprocfs_oh_tally_log2(&h[BRW_W_DISK_IOSIZE], size);
239         } else {
240                 LBUG();
241         }
242 }
243
244 static void osd_submit_bio(int rw, struct bio *bio)
245 {
246         LASSERTF(rw == 0 || rw == 1, "%x\n", rw);
247         if (rw == 0)
248                 submit_bio(READ, bio);
249         else
250                 submit_bio(WRITE, bio);
251 }
252
253 static int can_be_merged(struct bio *bio, sector_t sector)
254 {
255         unsigned int size;
256
257         if (!bio)
258                 return 0;
259
260         size = bio->bi_size >> 9;
261         return bio->bi_sector + size == sector ? 1 : 0;
262 }
263
264 static int osd_do_bio(struct osd_device *osd, struct inode *inode,
265                       struct osd_iobuf *iobuf)
266 {
267         int            blocks_per_page = CFS_PAGE_SIZE >> inode->i_blkbits;
268         struct page  **pages = iobuf->dr_pages;
269         int            npages = iobuf->dr_npages;
270         unsigned long *blocks = iobuf->dr_blocks;
271         int            total_blocks = npages * blocks_per_page;
272         int            sector_bits = inode->i_sb->s_blocksize_bits - 9;
273         unsigned int   blocksize = inode->i_sb->s_blocksize;
274         struct bio    *bio = NULL;
275         struct page   *page;
276         unsigned int   page_offset;
277         sector_t       sector;
278         int            nblocks;
279         int            block_idx;
280         int            page_idx;
281         int            i;
282         int            rc = 0;
283         ENTRY;
284
285         LASSERT(iobuf->dr_npages == npages);
286
287         osd_brw_stats_update(osd, iobuf);
288         iobuf->dr_start_time = cfs_time_current();
289
290         for (page_idx = 0, block_idx = 0;
291              page_idx < npages;
292              page_idx++, block_idx += blocks_per_page) {
293
294                 page = pages[page_idx];
295                 LASSERT(block_idx + blocks_per_page <= total_blocks);
296
297                 for (i = 0, page_offset = 0;
298                      i < blocks_per_page;
299                      i += nblocks, page_offset += blocksize * nblocks) {
300
301                         nblocks = 1;
302
303                         if (blocks[block_idx + i] == 0) {  /* hole */
304                                 LASSERTF(iobuf->dr_rw == 0,
305                                          "page_idx %u, block_idx %u, i %u\n",
306                                          page_idx, block_idx, i);
307                                 memset(kmap(page) + page_offset, 0, blocksize);
308                                 kunmap(page);
309                                 continue;
310                         }
311
312                         sector = (sector_t)blocks[block_idx + i] << sector_bits;
313
314                         /* Additional contiguous file blocks? */
315                         while (i + nblocks < blocks_per_page &&
316                                (sector + (nblocks << sector_bits)) ==
317                                ((sector_t)blocks[block_idx + i + nblocks] <<
318                                 sector_bits))
319                                 nblocks++;
320
321                         /* I only set the page to be constant only if it
322                          * is mapped to a contiguous underlying disk block(s).
323                          * It will then make sure the corresponding device
324                          * cache of raid5 will be overwritten by this page.
325                          * - jay */
326                         if (iobuf->dr_rw && (nblocks == blocks_per_page) &&
327                             mapping_cap_page_constant_write(inode->i_mapping))
328                                 SetPageConstant(page);
329
330                         if (bio != NULL &&
331                             can_be_merged(bio, sector) &&
332                             bio_add_page(bio, page,
333                                          blocksize * nblocks, page_offset) != 0)
334                                 continue;       /* added this frag OK */
335
336                         if (bio != NULL) {
337                                 struct request_queue *q =
338                                         bdev_get_queue(bio->bi_bdev);
339
340                                 /* Dang! I have to fragment this I/O */
341                                 CDEBUG(D_INODE, "bio++ sz %d vcnt %d(%d) "
342                                        "sectors %d(%d) psg %d(%d) hsg %d(%d)\n",
343                                        bio->bi_size,
344                                        bio->bi_vcnt, bio->bi_max_vecs,
345                                        bio->bi_size >> 9, queue_max_sectors(q),
346                                        bio_phys_segments(q, bio),
347                                        queue_max_phys_segments(q),
348                                        bio_hw_segments(q, bio),
349                                        queue_max_hw_segments(q));
350
351                                 record_start_io(iobuf, bio->bi_size);
352                                 osd_submit_bio(iobuf->dr_rw, bio);
353                         }
354
355                         /* allocate new bio */
356                         bio = bio_alloc(GFP_NOIO, min(BIO_MAX_PAGES,
357                                                       (npages - page_idx) *
358                                                       blocks_per_page));
359                         if (bio == NULL) {
360                                 CERROR("Can't allocate bio %u*%u = %u pages\n",
361                                        (npages - page_idx), blocks_per_page,
362                                        (npages - page_idx) * blocks_per_page);
363                                 rc = -ENOMEM;
364                                 goto out;
365                         }
366
367                         bio->bi_bdev = inode->i_sb->s_bdev;
368                         bio->bi_sector = sector;
369                         bio->bi_rw = (iobuf->dr_rw == 0) ? READ : WRITE;
370                         bio->bi_end_io = dio_complete_routine;
371                         bio->bi_private = iobuf;
372
373                         rc = bio_add_page(bio, page,
374                                           blocksize * nblocks, page_offset);
375                         LASSERT(rc != 0);
376                 }
377         }
378
379         if (bio != NULL) {
380                 record_start_io(iobuf, bio->bi_size);
381                 osd_submit_bio(iobuf->dr_rw, bio);
382                 rc = 0;
383         }
384
385  out:
386         /* in order to achieve better IO throughput, we don't wait for writes
387          * completion here. instead we proceed with transaction commit in
388          * parallel and wait for IO completion once transaction is stopped
389          * see osd_trans_stop() for more details -bzzz */
390         if (iobuf->dr_rw == 0) {
391                 cfs_wait_event(iobuf->dr_wait,
392                                cfs_atomic_read(&iobuf->dr_numreqs) == 0);
393         }
394
395         if (rc == 0)
396                 rc = iobuf->dr_error;
397         RETURN(rc);
398 }
399
400 static int osd_map_remote_to_local(loff_t offset, ssize_t len, int *nrpages,
401                                    struct niobuf_local *lnb)
402 {
403         ENTRY;
404
405         *nrpages = 0;
406
407         while (len > 0) {
408                 int poff = offset & (CFS_PAGE_SIZE - 1);
409                 int plen = CFS_PAGE_SIZE - poff;
410
411                 if (plen > len)
412                         plen = len;
413                 lnb->lnb_file_offset = offset;
414                 lnb->lnb_page_offset = poff;
415                 lnb->len = plen;
416                 /* lb->flags = rnb->flags; */
417                 lnb->flags = 0;
418                 lnb->page = NULL;
419                 lnb->rc = 0;
420
421                 LASSERTF(plen <= len, "plen %u, len %lld\n", plen,
422                          (long long) len);
423                 offset += plen;
424                 len -= plen;
425                 lnb++;
426                 (*nrpages)++;
427         }
428
429         RETURN(0);
430 }
431
432 struct page *osd_get_page(struct dt_object *dt, loff_t offset, int rw)
433 {
434         struct inode      *inode = osd_dt_obj(dt)->oo_inode;
435         struct osd_device *d = osd_obj2dev(osd_dt_obj(dt));
436         struct page       *page;
437
438         LASSERT(inode);
439
440         page = find_or_create_page(inode->i_mapping, offset >> CFS_PAGE_SHIFT,
441                                    GFP_NOFS | __GFP_HIGHMEM);
442         if (unlikely(page == NULL))
443                 lprocfs_counter_add(d->od_stats, LPROC_OSD_NO_PAGE, 1);
444
445         return page;
446 }
447
448 /*
449  * there are following "locks":
450  * journal_start
451  * i_mutex
452  * page lock
453
454  * osd write path
455     * lock page(s)
456     * journal_start
457     * truncate_sem
458
459  * ext4 vmtruncate:
460     * lock pages, unlock
461     * journal_start
462     * lock partial page
463     * i_data_sem
464
465 */
466 int osd_bufs_get(const struct lu_env *env, struct dt_object *d, loff_t pos,
467                  ssize_t len, struct niobuf_local *lnb, int rw,
468                  struct lustre_capa *capa)
469 {
470         struct osd_object   *obj    = osd_dt_obj(d);
471         int npages, i, rc = 0;
472
473         LASSERT(obj->oo_inode);
474
475         osd_map_remote_to_local(pos, len, &npages, lnb);
476
477         for (i = 0; i < npages; i++, lnb++) {
478
479                 /* We still set up for ungranted pages so that granted pages
480                  * can be written to disk as they were promised, and portals
481                  * needs to keep the pages all aligned properly. */
482                 lnb->dentry = (void *) obj;
483
484                 lnb->page = osd_get_page(d, lnb->lnb_file_offset, rw);
485                 if (lnb->page == NULL)
486                         GOTO(cleanup, rc = -ENOMEM);
487
488                 /* DLM locking protects us from write and truncate competing
489                  * for same region, but truncate can leave dirty page in the
490                  * cache. it's possible the writeout on a such a page is in
491                  * progress when we access it. it's also possible that during
492                  * this writeout we put new (partial) data, but then won't
493                  * be able to proceed in filter_commitrw_write(). thus let's
494                  * just wait for writeout completion, should be rare enough.
495                  * -bzzz */
496                 wait_on_page_writeback(lnb->page);
497                 BUG_ON(PageWriteback(lnb->page));
498
499                 lu_object_get(&d->do_lu);
500         }
501         rc = i;
502
503 cleanup:
504         RETURN(rc);
505 }
506
507 static int osd_bufs_put(const struct lu_env *env, struct dt_object *dt,
508                         struct niobuf_local *lnb, int npages)
509 {
510         struct osd_thread_info *oti = osd_oti_get(env);
511         struct osd_iobuf       *iobuf = &oti->oti_iobuf;
512         struct osd_device      *d = osd_obj2dev(osd_dt_obj(dt));
513         int                     i;
514
515         /* to do IO stats, notice we do this here because
516          * osd_do_bio() doesn't wait for write to complete */
517         osd_fini_iobuf(d, iobuf);
518
519         for (i = 0; i < npages; i++) {
520                 if (lnb[i].page == NULL)
521                         continue;
522                 LASSERT(PageLocked(lnb[i].page));
523                 unlock_page(lnb[i].page);
524                 page_cache_release(lnb[i].page);
525                 lu_object_put(env, &dt->do_lu);
526                 lnb[i].page = NULL;
527         }
528         RETURN(0);
529 }
530
531 static int osd_write_prep(const struct lu_env *env, struct dt_object *dt,
532                           struct niobuf_local *lnb, int npages)
533 {
534         struct osd_thread_info *oti   = osd_oti_get(env);
535         struct osd_iobuf       *iobuf = &oti->oti_iobuf;
536         struct inode           *inode = osd_dt_obj(dt)->oo_inode;
537         struct osd_device      *osd   = osd_obj2dev(osd_dt_obj(dt));
538         struct timeval          start;
539         struct timeval          end;
540         unsigned long           timediff;
541         ssize_t                 isize;
542         __s64                   maxidx;
543         int                     rc = 0;
544         int                     i;
545         int                     cache = 0;
546
547         LASSERT(inode);
548
549         osd_init_iobuf(osd, iobuf, 0);
550
551         isize = i_size_read(inode);
552         maxidx = ((isize + CFS_PAGE_SIZE - 1) >> CFS_PAGE_SHIFT) - 1;
553
554         if (osd->od_writethrough_cache)
555                 cache = 1;
556         if (isize > osd->od_readcache_max_filesize)
557                 cache = 0;
558
559         cfs_gettimeofday(&start);
560         for (i = 0; i < npages; i++) {
561
562                 if (cache == 0)
563                         generic_error_remove_page(inode->i_mapping,
564                                                   lnb[i].page);
565
566                 /*
567                  * till commit the content of the page is undefined
568                  * we'll set it uptodate once bulk is done. otherwise
569                  * subsequent reads can access non-stable data
570                  */
571                 ClearPageUptodate(lnb[i].page);
572
573                 if (lnb[i].len == CFS_PAGE_SIZE)
574                         continue;
575
576                 if (maxidx >= lnb[i].page->index) {
577                         osd_iobuf_add_page(iobuf, lnb[i].page);
578                 } else {
579                         long off;
580                         char *p = kmap(lnb[i].page);
581
582                         off = lnb[i].lnb_page_offset;
583                         if (off)
584                                 memset(p, 0, off);
585                         off = (lnb[i].lnb_page_offset + lnb[i].len) &
586                               ~CFS_PAGE_MASK;
587                         if (off)
588                                 memset(p + off, 0, CFS_PAGE_SIZE - off);
589                         kunmap(lnb[i].page);
590                 }
591         }
592         cfs_gettimeofday(&end);
593         timediff = cfs_timeval_sub(&end, &start, NULL);
594         lprocfs_counter_add(osd->od_stats, LPROC_OSD_GET_PAGE, timediff);
595
596         if (iobuf->dr_npages) {
597                 rc = osd->od_fsops->fs_map_inode_pages(inode, iobuf->dr_pages,
598                                                        iobuf->dr_npages,
599                                                        iobuf->dr_blocks,
600                                                        oti->oti_created,
601                                                        0, NULL);
602                 if (likely(rc == 0)) {
603                         rc = osd_do_bio(osd, inode, iobuf);
604                         /* do IO stats for preparation reads */
605                         osd_fini_iobuf(osd, iobuf);
606                 }
607         }
608         RETURN(rc);
609 }
610
611 /* Check if a block is allocated or not */
612 static int osd_is_mapped(struct inode *inode, obd_size offset)
613 {
614         sector_t (*fs_bmap)(struct address_space *, sector_t);
615
616         fs_bmap = inode->i_mapping->a_ops->bmap;
617
618         /* We can't know if we are overwriting or not */
619         if (unlikely(fs_bmap == NULL))
620                 return 0;
621
622         if (i_size_read(inode) == 0)
623                 return 0;
624
625         /* Beyond EOF, must not be mapped */
626         if (((i_size_read(inode) - 1) >> inode->i_blkbits) <
627             (offset >> inode->i_blkbits))
628                 return 0;
629
630         if (fs_bmap(inode->i_mapping, offset >> inode->i_blkbits) == 0)
631                 return 0;
632
633         return 1;
634 }
635
636 static int osd_declare_write_commit(const struct lu_env *env,
637                                     struct dt_object *dt,
638                                     struct niobuf_local *lnb, int npages,
639                                     struct thandle *handle)
640 {
641         const struct osd_device *osd = osd_obj2dev(osd_dt_obj(dt));
642         struct inode            *inode = osd_dt_obj(dt)->oo_inode;
643         struct osd_thandle      *oh;
644         int                      extents = 1;
645         int                      depth;
646         int                      i;
647         int                      newblocks;
648         int                      rc = 0;
649         int                      flags = 0;
650         bool                     ignore_quota = false;
651         long long                quota_space = 0;
652         ENTRY;
653
654         LASSERT(handle != NULL);
655         oh = container_of0(handle, struct osd_thandle, ot_super);
656         LASSERT(oh->ot_handle == NULL);
657
658         newblocks = npages;
659
660         /* calculate number of extents (probably better to pass nb) */
661         for (i = 0; i < npages; i++) {
662                 if (i && lnb[i].lnb_file_offset !=
663                     lnb[i - 1].lnb_file_offset + lnb[i - 1].len)
664                         extents++;
665
666                 if (!osd_is_mapped(inode, lnb[i].lnb_file_offset))
667                         quota_space += CFS_PAGE_SIZE;
668
669                 /* ignore quota for the whole request if any page is from
670                  * client cache or written by root.
671                  *
672                  * XXX we could handle this on per-lnb basis as done by
673                  * grant. */
674                 if ((lnb[i].flags & OBD_BRW_NOQUOTA) ||
675                     !(lnb[i].flags & OBD_BRW_SYNC))
676                         ignore_quota = true;
677         }
678
679         /*
680          * each extent can go into new leaf causing a split
681          * 5 is max tree depth: inode + 4 index blocks
682          * with blockmaps, depth is 3 at most
683          */
684         if (LDISKFS_I(inode)->i_flags & LDISKFS_EXTENTS_FL) {
685                 /*
686                  * many concurrent threads may grow tree by the time
687                  * our transaction starts. so, consider 2 is a min depth
688                  */
689                 depth = ext_depth(inode);
690                 depth = max(depth, 1) + 1;
691                 newblocks += depth;
692                 oh->ot_credits++; /* inode */
693                 oh->ot_credits += depth * 2 * extents;
694         } else {
695                 depth = 3;
696                 newblocks += depth;
697                 oh->ot_credits++; /* inode */
698                 oh->ot_credits += depth * extents;
699         }
700
701         /* quota space for metadata blocks */
702         quota_space += depth * extents * LDISKFS_BLOCK_SIZE(osd_sb(osd));
703
704         /* quota space should be reported in 1K blocks */
705         quota_space = toqb(quota_space);
706
707         /* each new block can go in different group (bitmap + gd) */
708
709         /* we can't dirty more bitmap blocks than exist */
710         if (newblocks > LDISKFS_SB(osd_sb(osd))->s_groups_count)
711                 oh->ot_credits += LDISKFS_SB(osd_sb(osd))->s_groups_count;
712         else
713                 oh->ot_credits += newblocks;
714
715         /* we can't dirty more gd blocks than exist */
716         if (newblocks > LDISKFS_SB(osd_sb(osd))->s_gdb_count)
717                 oh->ot_credits += LDISKFS_SB(osd_sb(osd))->s_gdb_count;
718         else
719                 oh->ot_credits += newblocks;
720
721         /* make sure the over quota flags were not set */
722         lnb[0].flags &= ~(OBD_BRW_OVER_USRQUOTA | OBD_BRW_OVER_GRPQUOTA);
723
724         rc = osd_declare_inode_qid(env, inode->i_uid, inode->i_gid,
725                                    quota_space, oh, true, true, &flags,
726                                    ignore_quota);
727
728         /* we need only to store the overquota flags in the first lnb for
729          * now, once we support multiple objects BRW, this code needs be
730          * revised. */
731         if (flags & QUOTA_FL_OVER_USRQUOTA)
732                 lnb[0].flags |= OBD_BRW_OVER_USRQUOTA;
733         if (flags & QUOTA_FL_OVER_GRPQUOTA)
734                 lnb[0].flags |= OBD_BRW_OVER_GRPQUOTA;
735
736         RETURN(rc);
737 }
738
739 /* Check if a block is allocated or not */
740 static int osd_write_commit(const struct lu_env *env, struct dt_object *dt,
741                             struct niobuf_local *lnb, int npages,
742                             struct thandle *thandle)
743 {
744         struct osd_thread_info *oti = osd_oti_get(env);
745         struct osd_iobuf *iobuf = &oti->oti_iobuf;
746         struct inode *inode = osd_dt_obj(dt)->oo_inode;
747         struct osd_device  *osd = osd_obj2dev(osd_dt_obj(dt));
748         loff_t isize;
749         int rc = 0, i;
750
751         LASSERT(inode);
752
753         osd_init_iobuf(osd, iobuf, 1);
754         isize = i_size_read(inode);
755         ll_vfs_dq_init(inode);
756
757         for (i = 0; i < npages; i++) {
758                 if (lnb[i].rc == -ENOSPC &&
759                     osd_is_mapped(inode, lnb[i].lnb_file_offset)) {
760                         /* Allow the write to proceed if overwriting an
761                          * existing block */
762                         lnb[i].rc = 0;
763                 }
764
765                 if (lnb[i].rc) { /* ENOSPC, network RPC error, etc. */
766                         CDEBUG(D_INODE, "Skipping [%d] == %d\n", i,
767                                lnb[i].rc);
768                         LASSERT(lnb[i].page);
769                         generic_error_remove_page(inode->i_mapping,lnb[i].page);
770                         continue;
771                 }
772
773                 LASSERT(PageLocked(lnb[i].page));
774                 LASSERT(!PageWriteback(lnb[i].page));
775
776                 if (lnb[i].lnb_file_offset + lnb[i].len > isize)
777                         isize = lnb[i].lnb_file_offset + lnb[i].len;
778
779                 /*
780                  * Since write and truncate are serialized by oo_sem, even
781                  * partial-page truncate should not leave dirty pages in the
782                  * page cache.
783                  */
784                 LASSERT(!PageDirty(lnb[i].page));
785
786                 SetPageUptodate(lnb[i].page);
787
788                 osd_iobuf_add_page(iobuf, lnb[i].page);
789         }
790
791         if (OBD_FAIL_CHECK(OBD_FAIL_OST_MAPBLK_ENOSPC)) {
792                 rc = -ENOSPC;
793         } else if (iobuf->dr_npages > 0) {
794                 rc = osd->od_fsops->fs_map_inode_pages(inode, iobuf->dr_pages,
795                                                        iobuf->dr_npages,
796                                                        iobuf->dr_blocks,
797                                                        oti->oti_created,
798                                                        1, NULL);
799         } else {
800                 /* no pages to write, no transno is needed */
801                 thandle->th_local = 1;
802         }
803
804         if (likely(rc == 0)) {
805                 if (isize > i_size_read(inode)) {
806                         i_size_write(inode, isize);
807                         LDISKFS_I(inode)->i_disksize = isize;
808                         inode->i_sb->s_op->dirty_inode(inode);
809                 }
810
811                 rc = osd_do_bio(osd, inode, iobuf);
812                 /* we don't do stats here as in read path because
813                  * write is async: we'll do this in osd_put_bufs() */
814         }
815
816         if (unlikely(rc != 0)) {
817                 /* if write fails, we should drop pages from the cache */
818                 for (i = 0; i < npages; i++) {
819                         if (lnb[i].page == NULL)
820                                 continue;
821                         LASSERT(PageLocked(lnb[i].page));
822                         generic_error_remove_page(inode->i_mapping,lnb[i].page);
823                 }
824         }
825
826         RETURN(rc);
827 }
828
829 static int osd_read_prep(const struct lu_env *env, struct dt_object *dt,
830                          struct niobuf_local *lnb, int npages)
831 {
832         struct osd_thread_info *oti = osd_oti_get(env);
833         struct osd_iobuf *iobuf = &oti->oti_iobuf;
834         struct inode *inode = osd_dt_obj(dt)->oo_inode;
835         struct osd_device *osd = osd_obj2dev(osd_dt_obj(dt));
836         struct timeval start, end;
837         unsigned long timediff;
838         int rc = 0, i, m = 0, cache = 0;
839
840         LASSERT(inode);
841
842         osd_init_iobuf(osd, iobuf, 0);
843
844         if (osd->od_read_cache)
845                 cache = 1;
846         if (i_size_read(inode) > osd->od_readcache_max_filesize)
847                 cache = 0;
848
849         cfs_gettimeofday(&start);
850         for (i = 0; i < npages; i++) {
851
852                 if (i_size_read(inode) <= lnb[i].lnb_file_offset)
853                         /* If there's no more data, abort early.
854                          * lnb->rc == 0, so it's easy to detect later. */
855                         break;
856
857                 if (i_size_read(inode) <
858                     lnb[i].lnb_file_offset + lnb[i].len - 1)
859                         lnb[i].rc = i_size_read(inode) - lnb[i].lnb_file_offset;
860                 else
861                         lnb[i].rc = lnb[i].len;
862                 m += lnb[i].len;
863
864                 lprocfs_counter_add(osd->od_stats, LPROC_OSD_CACHE_ACCESS, 1);
865                 if (PageUptodate(lnb[i].page)) {
866                         lprocfs_counter_add(osd->od_stats,
867                                             LPROC_OSD_CACHE_HIT, 1);
868                 } else {
869                         lprocfs_counter_add(osd->od_stats,
870                                             LPROC_OSD_CACHE_MISS, 1);
871                         osd_iobuf_add_page(iobuf, lnb[i].page);
872                 }
873                 if (cache == 0)
874                         generic_error_remove_page(inode->i_mapping,lnb[i].page);
875         }
876         cfs_gettimeofday(&end);
877         timediff = cfs_timeval_sub(&end, &start, NULL);
878         lprocfs_counter_add(osd->od_stats, LPROC_OSD_GET_PAGE, timediff);
879
880         if (iobuf->dr_npages) {
881                 rc = osd->od_fsops->fs_map_inode_pages(inode, iobuf->dr_pages,
882                                                        iobuf->dr_npages,
883                                                        iobuf->dr_blocks,
884                                                        oti->oti_created,
885                                                        0, NULL);
886                 rc = osd_do_bio(osd, inode, iobuf);
887
888                 /* IO stats will be done in osd_bufs_put() */
889         }
890
891         RETURN(rc);
892 }
893
894 /*
895  * XXX: Another layering violation for now.
896  *
897  * We don't want to use ->f_op->read methods, because generic file write
898  *
899  *         - serializes on ->i_sem, and
900  *
901  *         - does a lot of extra work like balance_dirty_pages(),
902  *
903  * which doesn't work for globally shared files like /last_rcvd.
904  */
905 static int osd_ldiskfs_readlink(struct inode *inode, char *buffer, int buflen)
906 {
907         struct ldiskfs_inode_info *ei = LDISKFS_I(inode);
908
909         memcpy(buffer, (char *)ei->i_data, buflen);
910
911         return  buflen;
912 }
913
914 int osd_ldiskfs_read(struct inode *inode, void *buf, int size, loff_t *offs)
915 {
916         struct buffer_head *bh;
917         unsigned long block;
918         int osize;
919         int blocksize;
920         int csize;
921         int boffs;
922         int err;
923
924         /* prevent reading after eof */
925         spin_lock(&inode->i_lock);
926         if (i_size_read(inode) < *offs + size) {
927                 loff_t diff = i_size_read(inode) - *offs;
928                 spin_unlock(&inode->i_lock);
929                 if (diff < 0) {
930                         CDEBUG(D_EXT2, "size %llu is too short to read @%llu\n",
931                                i_size_read(inode), *offs);
932                         return -EBADR;
933                 } else if (diff == 0) {
934                         return 0;
935                 } else {
936                         size = diff;
937                 }
938         } else {
939                 spin_unlock(&inode->i_lock);
940         }
941
942         blocksize = 1 << inode->i_blkbits;
943         osize = size;
944         while (size > 0) {
945                 block = *offs >> inode->i_blkbits;
946                 boffs = *offs & (blocksize - 1);
947                 csize = min(blocksize - boffs, size);
948                 bh = ldiskfs_bread(NULL, inode, block, 0, &err);
949                 if (!bh) {
950                         CERROR("%s: can't read %u@%llu on ino %lu: rc = %d\n",
951                                LDISKFS_SB(inode->i_sb)->s_es->s_volume_name,
952                                csize, *offs, inode->i_ino, err);
953                         return err;
954                 }
955
956                 memcpy(buf, bh->b_data + boffs, csize);
957                 brelse(bh);
958
959                 *offs += csize;
960                 buf += csize;
961                 size -= csize;
962         }
963         return osize;
964 }
965
966 static ssize_t osd_read(const struct lu_env *env, struct dt_object *dt,
967                         struct lu_buf *buf, loff_t *pos,
968                         struct lustre_capa *capa)
969 {
970         struct inode *inode = osd_dt_obj(dt)->oo_inode;
971         int           rc;
972
973         if (osd_object_auth(env, dt, capa, CAPA_OPC_BODY_READ))
974                 RETURN(-EACCES);
975
976         /* Read small symlink from inode body as we need to maintain correct
977          * on-disk symlinks for ldiskfs.
978          */
979         if (S_ISLNK(dt->do_lu.lo_header->loh_attr) &&
980             (buf->lb_len < sizeof(LDISKFS_I(inode)->i_data)))
981                 rc = osd_ldiskfs_readlink(inode, buf->lb_buf, buf->lb_len);
982         else
983                 rc = osd_ldiskfs_read(inode, buf->lb_buf, buf->lb_len, pos);
984
985         return rc;
986 }
987
988 static ssize_t osd_declare_write(const struct lu_env *env, struct dt_object *dt,
989                                  const loff_t size, loff_t pos,
990                                  struct thandle *handle)
991 {
992         struct osd_thandle *oh;
993         int                 credits;
994         struct inode       *inode;
995         int                 rc;
996         ENTRY;
997
998         LASSERT(handle != NULL);
999
1000         oh = container_of0(handle, struct osd_thandle, ot_super);
1001         LASSERT(oh->ot_handle == NULL);
1002
1003         /* XXX: size == 0 or INT_MAX indicating a catalog header update or
1004          *      llog write, see comment in mdd_declare_llog_record().
1005          *
1006          *      This hack will be removed with llog over OSD landing
1007          */
1008         if (size == DECLARE_LLOG_REWRITE)
1009                 credits = 2;
1010         else if (size == DECLARE_LLOG_WRITE)
1011                 credits = 6;
1012         else
1013                 credits = osd_dto_credits_noquota[DTO_WRITE_BLOCK];
1014
1015         osd_trans_declare_op(env, oh, OSD_OT_WRITE, credits);
1016
1017         inode = osd_dt_obj(dt)->oo_inode;
1018
1019         /* we may declare write to non-exist llog */
1020         if (inode == NULL)
1021                 RETURN(0);
1022
1023         /* dt_declare_write() is usually called for system objects, such
1024          * as llog or last_rcvd files. We needn't enforce quota on those
1025          * objects, so always set the lqi_space as 0. */
1026         rc = osd_declare_inode_qid(env, inode->i_uid, inode->i_gid, 0, oh,
1027                                    true, true, NULL, false);
1028         RETURN(rc);
1029 }
1030
1031 static int osd_ldiskfs_writelink(struct inode *inode, char *buffer, int buflen)
1032 {
1033
1034         memcpy((char *)&LDISKFS_I(inode)->i_data, (char *)buffer, buflen);
1035         LDISKFS_I(inode)->i_disksize = buflen;
1036         i_size_write(inode, buflen);
1037         inode->i_sb->s_op->dirty_inode(inode);
1038
1039         return 0;
1040 }
1041
1042 int osd_ldiskfs_write_record(struct inode *inode, void *buf, int bufsize,
1043                              int write_NUL, loff_t *offs, handle_t *handle)
1044 {
1045         struct buffer_head *bh        = NULL;
1046         loff_t              offset    = *offs;
1047         loff_t              new_size  = i_size_read(inode);
1048         unsigned long       block;
1049         int                 blocksize = 1 << inode->i_blkbits;
1050         int                 err = 0;
1051         int                 size;
1052         int                 boffs;
1053         int                 dirty_inode = 0;
1054
1055         if (write_NUL) {
1056                 /*
1057                  * long symlink write does not count the NUL terminator in
1058                  * bufsize, we write it, and the inode's file size does not
1059                  * count the NUL terminator as well.
1060                  */
1061                 ((char *)buf)[bufsize] = '\0';
1062                 ++bufsize;
1063         }
1064         while (bufsize > 0) {
1065                 if (bh != NULL)
1066                         brelse(bh);
1067
1068                 block = offset >> inode->i_blkbits;
1069                 boffs = offset & (blocksize - 1);
1070                 size = min(blocksize - boffs, bufsize);
1071                 bh = ldiskfs_bread(handle, inode, block, 1, &err);
1072                 if (!bh) {
1073                         CERROR("%s: error reading offset %llu (block %lu): "
1074                                "rc = %d\n",
1075                                inode->i_sb->s_id, offset, block, err);
1076                         break;
1077                 }
1078
1079                 err = ldiskfs_journal_get_write_access(handle, bh);
1080                 if (err) {
1081                         CERROR("journal_get_write_access() returned error %d\n",
1082                                err);
1083                         break;
1084                 }
1085                 LASSERTF(boffs + size <= bh->b_size,
1086                          "boffs %d size %d bh->b_size %lu",
1087                          boffs, size, (unsigned long)bh->b_size);
1088                 memcpy(bh->b_data + boffs, buf, size);
1089                 err = ldiskfs_journal_dirty_metadata(handle, bh);
1090                 if (err)
1091                         break;
1092
1093                 if (offset + size > new_size)
1094                         new_size = offset + size;
1095                 offset += size;
1096                 bufsize -= size;
1097                 buf += size;
1098         }
1099         if (bh)
1100                 brelse(bh);
1101
1102         if (write_NUL)
1103                 --new_size;
1104         /* correct in-core and on-disk sizes */
1105         if (new_size > i_size_read(inode)) {
1106                 spin_lock(&inode->i_lock);
1107                 if (new_size > i_size_read(inode))
1108                         i_size_write(inode, new_size);
1109                 if (i_size_read(inode) > LDISKFS_I(inode)->i_disksize) {
1110                         LDISKFS_I(inode)->i_disksize = i_size_read(inode);
1111                         dirty_inode = 1;
1112                 }
1113                 spin_unlock(&inode->i_lock);
1114                 if (dirty_inode)
1115                         inode->i_sb->s_op->dirty_inode(inode);
1116         }
1117
1118         if (err == 0)
1119                 *offs = offset;
1120         return err;
1121 }
1122
1123 static ssize_t osd_write(const struct lu_env *env, struct dt_object *dt,
1124                          const struct lu_buf *buf, loff_t *pos,
1125                          struct thandle *handle, struct lustre_capa *capa,
1126                          int ignore_quota)
1127 {
1128         struct inode            *inode = osd_dt_obj(dt)->oo_inode;
1129         struct osd_thandle      *oh;
1130         ssize_t                 result;
1131         int                     is_link;
1132
1133         LASSERT(dt_object_exists(dt));
1134
1135         if (osd_object_auth(env, dt, capa, CAPA_OPC_BODY_WRITE))
1136                 return -EACCES;
1137
1138         LASSERT(handle != NULL);
1139         LASSERT(inode != NULL);
1140         ll_vfs_dq_init(inode);
1141
1142         /* XXX: don't check: one declared chunk can be used many times */
1143         /* osd_trans_exec_op(env, handle, OSD_OT_WRITE); */
1144
1145         oh = container_of(handle, struct osd_thandle, ot_super);
1146         LASSERT(oh->ot_handle->h_transaction != NULL);
1147         /* Write small symlink to inode body as we need to maintain correct
1148          * on-disk symlinks for ldiskfs.
1149          * Note: the buf->lb_buf contains a NUL terminator while buf->lb_len
1150          * does not count it in.
1151          */
1152         is_link = S_ISLNK(dt->do_lu.lo_header->loh_attr);
1153         if (is_link && (buf->lb_len < sizeof(LDISKFS_I(inode)->i_data)))
1154                 result = osd_ldiskfs_writelink(inode, buf->lb_buf, buf->lb_len);
1155         else
1156                 result = osd_ldiskfs_write_record(inode, buf->lb_buf,
1157                                                   buf->lb_len, is_link, pos,
1158                                                   oh->ot_handle);
1159         if (result == 0)
1160                 result = buf->lb_len;
1161         return result;
1162 }
1163
1164 static int osd_declare_punch(const struct lu_env *env, struct dt_object *dt,
1165                              __u64 start, __u64 end, struct thandle *th)
1166 {
1167         struct osd_thandle *oh;
1168         struct inode       *inode;
1169         int                 rc;
1170         ENTRY;
1171
1172         LASSERT(th);
1173         oh = container_of(th, struct osd_thandle, ot_super);
1174
1175         /*
1176          * we don't need to reserve credits for whole truncate
1177          * it's not possible as truncate may need to free too many
1178          * blocks and that won't fit a single transaction. instead
1179          * we reserve credits to change i_size and put inode onto
1180          * orphan list. if needed truncate will extend or restart
1181          * transaction
1182          */
1183         osd_trans_declare_op(env, oh, OSD_OT_PUNCH,
1184                              osd_dto_credits_noquota[DTO_ATTR_SET_BASE] + 3);
1185
1186         inode = osd_dt_obj(dt)->oo_inode;
1187         LASSERT(inode);
1188
1189         rc = osd_declare_inode_qid(env, inode->i_uid, inode->i_gid, 0, oh,
1190                                    true, true, NULL, false);
1191         RETURN(rc);
1192 }
1193
1194 static int osd_punch(const struct lu_env *env, struct dt_object *dt,
1195                      __u64 start, __u64 end, struct thandle *th,
1196                      struct lustre_capa *capa)
1197 {
1198         struct osd_thandle *oh;
1199         struct osd_object  *obj = osd_dt_obj(dt);
1200         struct inode       *inode = obj->oo_inode;
1201         handle_t           *h;
1202         tid_t               tid;
1203         int                 rc, rc2 = 0;
1204         ENTRY;
1205
1206         LASSERT(end == OBD_OBJECT_EOF);
1207         LASSERT(dt_object_exists(dt));
1208         LASSERT(osd_invariant(obj));
1209         LASSERT(inode != NULL);
1210         ll_vfs_dq_init(inode);
1211
1212         LASSERT(th);
1213         oh = container_of(th, struct osd_thandle, ot_super);
1214         LASSERT(oh->ot_handle->h_transaction != NULL);
1215
1216         osd_trans_exec_op(env, th, OSD_OT_PUNCH);
1217
1218         tid = oh->ot_handle->h_transaction->t_tid;
1219
1220         rc = vmtruncate(inode, start);
1221
1222         /*
1223          * For a partial-page truncate, flush the page to disk immediately to
1224          * avoid data corruption during direct disk write.  b=17397
1225          */
1226         if (rc == 0 && (start & ~CFS_PAGE_MASK) != 0)
1227                 rc = filemap_fdatawrite_range(inode->i_mapping, start, start+1);
1228
1229         h = journal_current_handle();
1230         LASSERT(h != NULL);
1231         LASSERT(h == oh->ot_handle);
1232
1233         if (tid != h->h_transaction->t_tid) {
1234                 int credits = oh->ot_credits;
1235                 /*
1236                  * transaction has changed during truncate
1237                  * we need to restart the handle with our credits
1238                  */
1239                 if (h->h_buffer_credits < credits) {
1240                         if (ldiskfs_journal_extend(h, credits))
1241                                 rc2 = ldiskfs_journal_restart(h, credits);
1242                 }
1243         }
1244
1245         RETURN(rc == 0 ? rc2 : rc);
1246 }
1247
1248 static int osd_fiemap_get(const struct lu_env *env, struct dt_object *dt,
1249                           struct ll_user_fiemap *fm)
1250 {
1251         struct inode *inode = osd_dt_obj(dt)->oo_inode;
1252         struct osd_thread_info *info   = osd_oti_get(env);
1253         struct dentry          *dentry = &info->oti_obj_dentry;
1254         struct file            *file   = &info->oti_file;
1255         mm_segment_t            saved_fs;
1256         int rc;
1257
1258         LASSERT(inode);
1259         dentry->d_inode = inode;
1260         file->f_dentry = dentry;
1261         file->f_mapping = inode->i_mapping;
1262         file->f_op = inode->i_fop;
1263
1264         saved_fs = get_fs();
1265         set_fs(get_ds());
1266         /* ldiskfs_ioctl does not have a inode argument */
1267         if (inode->i_fop->unlocked_ioctl)
1268                 rc = inode->i_fop->unlocked_ioctl(file, FSFILT_IOC_FIEMAP,
1269                                                   (long)fm);
1270         else
1271                 rc = -ENOTTY;
1272         set_fs(saved_fs);
1273         return rc;
1274 }
1275
1276 /*
1277  * in some cases we may need declare methods for objects being created
1278  * e.g., when we create symlink
1279  */
1280 const struct dt_body_operations osd_body_ops_new = {
1281         .dbo_declare_write = osd_declare_write,
1282 };
1283
1284 const struct dt_body_operations osd_body_ops = {
1285         .dbo_read                 = osd_read,
1286         .dbo_declare_write        = osd_declare_write,
1287         .dbo_write                = osd_write,
1288         .dbo_bufs_get             = osd_bufs_get,
1289         .dbo_bufs_put             = osd_bufs_put,
1290         .dbo_write_prep           = osd_write_prep,
1291         .dbo_declare_write_commit = osd_declare_write_commit,
1292         .dbo_write_commit         = osd_write_commit,
1293         .dbo_read_prep            = osd_read_prep,
1294         .do_declare_punch         = osd_declare_punch,
1295         .do_punch                 = osd_punch,
1296         .dbo_fiemap_get           = osd_fiemap_get,
1297 };
1298