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