Whamcloud - gitweb
Another very major cleanup:
[fs/lustre-release.git] / lustre / obdfs / rw.c
1 /*
2  * OBDFS Super operations
3  *
4  * This code is issued under the GNU General Public License.
5  * See the file COPYING in this distribution
6  *
7  * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de>
8  * Copryright (C) 1999 Stelias Computing Inc, 
9  *                (author Peter J. Braam <braam@stelias.com>)
10  * Copryright (C) 1999 Seagate Technology Inc.
11 */
12
13
14 #include <linux/config.h>
15 #include <linux/kernel.h>
16 #include <linux/mm.h>
17 #include <linux/string.h>
18 #include <linux/stat.h>
19 #include <linux/errno.h>
20 #include <linux/locks.h>
21 #include <linux/unistd.h>
22
23 #include <asm/system.h>
24 #include <asm/uaccess.h>
25
26 #include <linux/fs.h>
27 #include <linux/stat.h>
28 #include <asm/uaccess.h>
29 #include <linux/vmalloc.h>
30 #include <asm/segment.h>
31 #include <linux/mm.h>
32 #include <linux/pagemap.h>
33 #include <linux/smp_lock.h>
34
35 #include <linux/obd_support.h>
36 #include <linux/obd_ext2.h>
37 #include <linux/obdfs.h>
38
39 void obdfs_change_inode(struct inode *inode);
40
41 /* SYNCHRONOUS I/O to object storage for an inode -- object attr will be updated too */
42 static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create)
43 {
44         obd_count        num_obdo = 1;
45         obd_count        bufs_per_obdo = 1;
46         struct obdo     *oa;
47         obd_size         count = PAGE_SIZE;
48         obd_off          offset = ((obd_off)page->index) << PAGE_SHIFT;
49         obd_flag         flags = create ? OBD_BRW_CREATE : 0;
50         int              err;
51
52         ENTRY;
53         if (IOPS(inode, brw) == NULL) {
54                 printk(KERN_ERR __FUNCTION__ ": no brw method!\n");
55                 EXIT;
56                 return -EIO;
57         }
58
59         oa = obdo_alloc();
60         if ( !oa ) {
61                 EXIT;
62                 return -ENOMEM;
63         }
64         oa->o_valid = OBD_MD_FLNOTOBD;
65         obdfs_from_inode(oa, inode);
66
67         err = IOPS(inode, brw)(rw, IID(inode), num_obdo, &oa, &bufs_per_obdo,
68                                &page, &count, &offset, &flags);
69         if ( !err )
70                 obdfs_to_inode(inode, oa); /* copy o_blocks to i_blocks */
71
72         obdo_free(oa);
73         EXIT;
74         return err;
75 } /* obdfs_brw */
76
77 /* returns the page unlocked, but with a reference */
78 int obdfs_readpage(struct file *file, struct page *page)
79 {
80         struct inode *inode = page->mapping->host;
81         int rc;
82
83         ENTRY;
84
85         if ( ((inode->i_size + PAGE_CACHE_SIZE -1)>>PAGE_SHIFT) 
86              <= page->index) {
87                 memset(kmap(page), 0, PAGE_CACHE_SIZE);
88                 goto readpage_out;
89         }
90
91         if (Page_Uptodate(page)) {
92                 EXIT;
93                 goto readpage_out;
94         }
95
96         rc = obdfs_brw(READ, inode, page, 0);
97         if ( rc ) {
98                 EXIT; 
99                 return rc;
100         } 
101         /* PDEBUG(page, "READ"); */
102
103  readpage_out:
104         SetPageUptodate(page);
105         obd_unlock_page(page);
106         EXIT;
107         return 0;
108 } /* obdfs_readpage */
109
110 int obdfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
111 {
112         struct inode *inode = page->mapping->host;
113         obd_off offset = ((obd_off)page->index) << PAGE_SHIFT;
114         int rc;
115         ENTRY; 
116         
117         kmap(page);
118         /* PDEBUG(page, "READ"); */
119         if (Page_Uptodate(page)) { 
120                 EXIT;
121                 return 0; 
122         }
123
124         if ( (from <= offset) && (to >= offset + PAGE_SIZE) ) {
125                 EXIT;
126                 return 0;
127         }
128         
129         rc = obdfs_brw(READ, inode, page, 0);
130         if ( !rc ) {
131                 SetPageUptodate(page);
132                 /* obd_unlock_page(page); */ 
133         } 
134         /* PDEBUG(page, "READ"); */
135         EXIT;
136         return rc;
137 }
138
139
140
141
142 static kmem_cache_t *obdfs_pgrq_cachep = NULL;
143
144 int obdfs_init_pgrqcache(void)
145 {
146         ENTRY;
147         if (obdfs_pgrq_cachep == NULL) {
148                 CDEBUG(D_CACHE, "allocating obdfs_pgrq_cache\n");
149                 obdfs_pgrq_cachep = kmem_cache_create("obdfs_pgrq",
150                                                       sizeof(struct obdfs_pgrq),
151                                                       0, SLAB_HWCACHE_ALIGN,
152                                                       NULL, NULL);
153                 if (obdfs_pgrq_cachep == NULL) {
154                         EXIT;
155                         return -ENOMEM;
156                 } else {
157                         CDEBUG(D_CACHE, "allocated cache at %p\n",
158                                obdfs_pgrq_cachep);
159                 }
160         } else {
161                 CDEBUG(D_CACHE, "using existing cache at %p\n",
162                        obdfs_pgrq_cachep);
163         }
164         EXIT;
165         return 0;
166 } /* obdfs_init_wreqcache */
167
168 inline void obdfs_pgrq_del(struct obdfs_pgrq *pgrq)
169 {
170         --obdfs_cache_count;
171         CDEBUG(D_INFO, "deleting page %p from list [count %ld]\n",
172                pgrq->rq_page, obdfs_cache_count);
173         list_del(&pgrq->rq_plist);
174         OBDClearCachePage(pgrq->rq_page);
175         kmem_cache_free(obdfs_pgrq_cachep, pgrq);
176 }
177
178 void obdfs_cleanup_pgrqcache(void)
179 {
180         ENTRY;
181         if (obdfs_pgrq_cachep != NULL) {
182                 CDEBUG(D_CACHE, "destroying obdfs_pgrqcache at %p, count %ld\n",
183                        obdfs_pgrq_cachep, obdfs_cache_count);
184                 if (kmem_cache_destroy(obdfs_pgrq_cachep))
185                         printk(KERN_INFO __FUNCTION__
186                                ": unable to free all of cache\n");
187                 obdfs_pgrq_cachep = NULL;
188         } else
189                 printk(KERN_INFO __FUNCTION__ ": called with NULL pointer\n");
190
191         EXIT;
192 } /* obdfs_cleanup_wreqcache */
193
194
195 /* called with the list lock held */
196 static struct page *obdfs_find_page_index(struct inode *inode,
197                                           unsigned long index)
198 {
199         struct list_head *page_list = obdfs_iplist(inode);
200         struct list_head *tmp;
201         struct page *page;
202
203         ENTRY;
204
205         CDEBUG(D_INFO, "looking for inode %ld pageindex %ld\n",
206                inode->i_ino, index);
207         OIDEBUG(inode);
208
209         if (list_empty(page_list)) {
210                 EXIT;
211                 return NULL;
212         }
213         tmp = page_list;
214         while ( (tmp = tmp->next) != page_list ) {
215                 struct obdfs_pgrq *pgrq;
216
217                 pgrq = list_entry(tmp, struct obdfs_pgrq, rq_plist);
218                 page = pgrq->rq_page;
219                 if (index == page->index) {
220                         CDEBUG(D_INFO,
221                                "INDEX SEARCH found page %p, index %ld\n",
222                                page, index);
223                         EXIT;
224                         return page;
225                 }
226         } 
227
228         EXIT;
229         return NULL;
230 } /* obdfs_find_page_index */
231
232
233 /* call and free pages from Linux page cache: called with io lock on inodes */
234 int obdfs_do_vec_wr(struct inode **inodes, obd_count num_io,
235                     obd_count num_obdos, struct obdo **obdos,
236                     obd_count *oa_bufs, struct page **pages, char **bufs,
237                     obd_size *counts, obd_off *offsets, obd_flag *flags)
238 {
239         int err;
240
241         ENTRY;
242         if (IOPS(inodes[0], brw) == NULL) {
243                 printk(KERN_ERR __FUNCTION__ ": no brw method!\n");
244                 EXIT;
245                 return -EIO;
246         }
247
248         CDEBUG(D_INFO, "writing %d page(s), %d obdo(s) in vector\n",
249                num_io, num_obdos);
250         if (obd_debug_level & D_INFO) { /* DEBUGGING */
251                 int i;
252                 printk("OBDOS: ");
253                 for (i = 0; i < num_obdos; i++)
254                         printk("%ld:0x%p ", (long)obdos[i]->o_id, obdos[i]);
255
256                 printk("\nPAGES: ");
257                 for (i = 0; i < num_io; i++)
258                         printk("0x%p ", pages[i]);
259                 printk("\n");
260         }
261
262         err = IOPS(inodes[0], brw)(WRITE, IID(inodes[0]), num_obdos, obdos,
263                                   oa_bufs, pages, counts, offsets, flags);
264
265         CDEBUG(D_INFO, "BRW done\n");
266         /* release the pages from the page cache */
267         while ( num_io > 0 ) {
268                 --num_io;
269                 CDEBUG(D_INFO, "calling put_page for %p, index %ld\n",
270                        pages[num_io], pages[num_io]->index);
271                 /* PDEBUG(pages[num_io], "do_vec_wr"); */
272                 put_page(pages[num_io]);
273                 /* PDEBUG(pages[num_io], "do_vec_wr"); */
274         }
275         CDEBUG(D_INFO, "put_page done\n");
276
277         while ( num_obdos > 0) {
278                 --num_obdos;
279                 CDEBUG(D_INFO, "free obdo %ld\n",(long)obdos[num_obdos]->o_id);
280                 /* copy o_blocks to i_blocks */
281                 obdfs_to_inode(inodes[num_obdos], obdos[num_obdos]);
282                 obdo_free(obdos[num_obdos]);
283         }
284         CDEBUG(D_INFO, "obdo_free done\n");
285         EXIT;
286         return err;
287 }
288
289
290 /*
291  * Add a page to the write request cache list for later writing.
292  * ASYNCHRONOUS write method.
293  */
294 static int obdfs_add_page_to_cache(struct inode *inode, struct page *page)
295 {
296         int err = 0;
297         ENTRY;
298
299         /* The PG_obdcache bit is cleared by obdfs_pgrq_del() BEFORE the page
300          * is written, so at worst we will write the page out twice.
301          *
302          * If the page has the PG_obdcache bit set, then the inode MUST be
303          * on the superblock dirty list so we don't need to check this.
304          * Dirty inodes are removed from the superblock list ONLY when they
305          * don't have any more cached pages.  It is possible to have an inode
306          * with no dirty pages on the superblock list, but not possible to
307          * have an inode with dirty pages NOT on the superblock dirty list.
308          */
309         if (!OBDAddCachePage(page)) {
310                 struct obdfs_pgrq *pgrq;
311                 pgrq = kmem_cache_alloc(obdfs_pgrq_cachep, SLAB_KERNEL);
312                 if (!pgrq) {
313                         OBDClearCachePage(page);
314                         EXIT;
315                         return -ENOMEM;
316                 }
317                 /* not really necessary since we set all pgrq fields here
318                 memset(pgrq, 0, sizeof(*pgrq)); 
319                 */
320                 
321                 pgrq->rq_page = page;
322                 pgrq->rq_jiffies = jiffies;
323                 get_page(pgrq->rq_page);
324
325                 obd_down(&obdfs_i2sbi(inode)->osi_list_mutex);
326                 list_add(&pgrq->rq_plist, obdfs_iplist(inode));
327                 obdfs_cache_count++;
328
329                 /* If inode isn't already on superblock inodes list, add it.
330                  *
331                  * We increment the reference count on the inode to keep it
332                  * from being freed from memory.  This _should_ be an iget()
333                  * with an iput() in both flush_reqs() and put_inode(), but
334                  * since put_inode() is called from iput() we can't call iput()
335                  * again there.  Instead we just increment/decrement i_count,
336                  * which is mostly what iget/iput do for an inode in memory.
337                  */
338                 if ( list_empty(obdfs_islist(inode)) ) {
339                         atomic_inc(&inode->i_count);
340                         CDEBUG(D_INFO,
341                                "adding inode %ld to superblock list %p\n",
342                                inode->i_ino, obdfs_slist(inode));
343                         list_add(obdfs_islist(inode), obdfs_slist(inode));
344                 }
345                 obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
346         }
347
348         /* XXX For testing purposes, we can write out the page here.
349         err = obdfs_flush_reqs(obdfs_slist(inode), ~0UL);
350          */
351
352         EXIT;
353         return err;
354 } /* obdfs_add_page_to_cache */
355
356
357 /* select between SYNC and ASYNC I/O methods */
358 int obdfs_do_writepage(struct page *page, int sync)
359 {
360         struct inode *inode = page->mapping->host;
361         int err;
362
363         ENTRY;
364         /* PDEBUG(page, "WRITEPAGE"); */
365         if ( sync )
366                 err = obdfs_brw(WRITE, inode, page, 1);
367         else {
368                 err = obdfs_add_page_to_cache(inode, page);
369                 CDEBUG(D_INFO, "DO_WR ino: %ld, page %p, err %d, uptodate %d\n",
370                        inode->i_ino, page, err, Page_Uptodate(page));
371         }
372                 
373         if ( !err )
374                 SetPageUptodate(page);
375         /* PDEBUG(page,"WRITEPAGE"); */
376         EXIT;
377         return err;
378 } /* obdfs_do_writepage */
379
380
381
382 /* returns the page unlocked, but with a reference */
383 int obdfs_writepage(struct page *page)
384 {
385         return obdfs_do_writepage(page, 0);
386 }
387
388 int obdfs_commit_write(struct file *file, struct page *page, unsigned from, unsigned to)
389 {
390         int rc;
391         struct inode *inode = page->mapping->host;
392         loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
393         // XXX test with synchronous writes
394         rc = obdfs_do_writepage(page, 1);
395         kunmap(page);
396         if (pos > inode->i_size) {
397                 inode->i_size = pos;
398                 obdfs_change_inode(inode);
399         }
400         return 0;
401 }
402
403
404 /*
405  * This does the "real" work of the write. The generic routine has
406  * allocated the page, locked it, done all the page alignment stuff
407  * calculations etc. Now we should just copy the data from user
408  * space and write it back to the real medium..
409  *
410  * If the writer ends up delaying the write, the writer needs to
411  * increment the page use counts until he is done with the page.
412  *
413  * Return value is the number of bytes written.
414  */
415 int obdfs_write_one_page(struct file *file, struct page *page,
416                          unsigned long offset, unsigned long bytes,
417                          const char * buf)
418 {
419         struct inode *inode = file->f_dentry->d_inode;
420         int err;
421
422         ENTRY;
423         /* We check for complete page writes here, as we then don't have to
424          * get the page before writing over everything anyways.
425          */
426         if ( !Page_Uptodate(page) && (offset != 0 || bytes != PAGE_SIZE) ) {
427                 err = obdfs_brw(READ, inode, page, 0);
428                 if ( err )
429                         return err;
430                 SetPageUptodate(page);
431         }
432
433         if (copy_from_user((u8*)page_address(page) + offset, buf, bytes))
434                 return -EFAULT;
435
436         lock_kernel();
437         err = obdfs_writepage(page);
438         unlock_kernel();
439
440         return (err < 0 ? err : bytes);
441 } /* obdfs_write_one_page */
442
443 /* 
444  * return an up to date page:
445  *  - if locked is true then is returned locked
446  *  - if create is true the corresponding disk blocks are created 
447  *  - page is held, i.e. caller must release the page
448  *
449  * modeled on NFS code.
450  */
451 struct page *obdfs_getpage(struct inode *inode, unsigned long offset,
452                            int create, int locked)
453 {
454         struct page * page;
455         int index;
456         int err;
457
458         ENTRY;
459
460         offset = offset & PAGE_CACHE_MASK;
461         CDEBUG(D_INFO, "ino: %ld, offset %ld, create %d, locked %d\n",
462                inode->i_ino, offset, create, locked);
463         index = offset >> PAGE_CACHE_SHIFT;
464
465         page = grab_cache_page(&inode->i_data, index);
466
467         /* Yuck, no page */
468         if (! page) {
469             printk(KERN_WARNING " grab_cache_page says no dice ...\n");
470             EXIT;
471             return NULL;
472         }
473
474         /* PDEBUG(page, "GETPAGE: got page - before reading\n"); */
475         /* now check if the data in the page is up to date */
476         if ( Page_Uptodate(page)) { 
477                 if (!locked) {
478                         if (PageLocked(page))
479                                 obd_unlock_page(page);
480                 } else {
481                         printk("file %s, line %d: expecting locked page\n",
482                                __FILE__, __LINE__); 
483                 }
484                 EXIT;
485                 return page;
486         } 
487
488
489 #ifdef EXT2_OBD_DEBUG
490         if ((obd_debug_level & D_INFO) && obdfs_find_page_index(inode, index)) {
491                 CDEBUG(D_INFO, "OVERWRITE: found dirty page %p, index %ld\n",
492                        page, page->index);
493         }
494 #endif
495
496         err = obdfs_brw(READ, inode, page, create);
497
498         if ( err ) {
499                 SetPageError(page);
500                 obd_unlock_page(page);
501                 EXIT;
502                 return page;
503         }
504
505         if ( !locked )
506                 obd_unlock_page(page);
507         SetPageUptodate(page);
508         /* PDEBUG(page,"GETPAGE - after reading"); */
509         EXIT;
510         return page;
511 } /* obdfs_getpage */
512
513
514 void obdfs_truncate(struct inode *inode)
515 {
516         struct obdo *oa;
517         int err;
518         ENTRY;
519
520         obdfs_dequeue_pages(inode);
521
522         if (IOPS(inode, punch) == NULL) {
523                 printk(KERN_ERR __FUNCTION__ ": no punch method!\n");
524                 EXIT;
525                 return;
526         }
527         oa = obdo_alloc();
528         if ( !oa ) {
529                 /* XXX This would give an inconsistent FS, so deal with it as
530                  * best we can for now - an obdo on the stack is not pretty.
531                  */
532                 struct obdo obdo;
533
534                 printk(__FUNCTION__ ": obdo_alloc failed - using stack!\n");
535
536                 obdo.o_valid = OBD_MD_FLNOTOBD;
537                 obdfs_from_inode(&obdo, inode);
538
539                 err = IOPS(inode, punch)(IID(inode), &obdo, obdo.o_size, 0);
540         } else {
541                 oa->o_valid = OBD_MD_FLNOTOBD;
542                 obdfs_from_inode(oa, inode);
543
544                 CDEBUG(D_INFO, "calling punch for %ld (%Lu bytes at 0)\n",
545                        (long)oa->o_id, oa->o_size);
546                 err = IOPS(inode, punch)(IID(inode), oa, oa->o_size, 0);
547
548                 obdo_free(oa);
549         }
550
551         if (err) {
552                 printk(__FUNCTION__ ": obd_truncate fails (%d)\n", err);
553                 EXIT;
554                 return;
555         }
556         EXIT;
557 } /* obdfs_truncate */