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