Whamcloud - gitweb
git://git.whamcloud.com
/
fs
/
lustre-release.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
| inline |
side by side
- bump OST_MAX_THREADS to 48 for benchmarking
[fs/lustre-release.git]
/
lustre
/
snapfs
/
file.c
diff --git
a/lustre/snapfs/file.c
b/lustre/snapfs/file.c
index
32b7041
..
a8a8860
100644
(file)
--- a/
lustre/snapfs/file.c
+++ b/
lustre/snapfs/file.c
@@
-21,29
+21,38
@@
static int has_pages(struct inode *inode, int index)
{
unsigned long offset = index << PAGE_CACHE_SHIFT;
unsigned long blk_start = offset >> inode->i_sb->s_blocksize_bits;
- unsigned long blk_end = (offset + PAGE_CACHE_SIZE) >>
inode->i_sb->s_blocksize_bits;
- int inside = 0;
+ unsigned long blk_end = (offset + PAGE_CACHE_SIZE) >>
+ inode->i_sb->s_blocksize_bits;
while (blk_start <= blk_end) {
if (inode->i_mapping && inode->i_mapping->a_ops) {
- inside = inode->i_mapping->a_ops->bmap(inode->i_mapping, blk_start);
+ if (inode->i_mapping->a_ops->bmap(inode->i_mapping,
+ blk_start))
+ return 1;
}
blk_start++;
}
- return
inside
;
+ return
0
;
}
-static int copy_back_page(struct inode *dst, struct inode *src,
- int index)
+static int copy_back_page(struct inode *dst,
+ struct inode *src,
+ unsigned long start,
+ unsigned long end)
{
char *kaddr_src, *kaddr_dst;
struct snap_cache *cache;
struct address_space_operations *c_aops;
- struct page *src_page, *dst_page;
+ struct page *src_page = NULL, *dst_page = NULL;
+ unsigned long index, offset, bytes;
int err = 0;
ENTRY;
- if (!has_pages(src, index))
+ offset = (start & (PAGE_CACHE_SIZE -1)); /* Within page */
+ bytes = end - start;
+ index = start >> PAGE_CACHE_SHIFT;
+
+ if (!has_pages(src, index) || bytes > 4096)
RETURN(0);
cache = snap_find_cache(src->i_dev);
@@
-56,7
+65,7
@@
static int copy_back_page(struct inode *dst, struct inode *src,
src_page = grab_cache_page(src->i_mapping, index);
if (!src_page) {
- CERROR("copy block %
d
from %lu to %lu ENOMEM \n",
+ CERROR("copy block %
lu
from %lu to %lu ENOMEM \n",
index, src->i_ino, dst->i_ino);
RETURN(-ENOMEM);
}
@@
-66,27
+75,29
@@
static int copy_back_page(struct inode *dst, struct inode *src,
kaddr_src = kmap(src_page);
if (!Page_Uptodate(src_page)) {
- CERROR("Can not read page index %
d
of inode %lu\n",
+ CERROR("Can not read page index %
lu
of inode %lu\n",
index, src->i_ino);
err = -EIO;
goto unlock_src_page;
}
dst_page = grab_cache_page(dst->i_mapping, index);
if (!dst_page) {
- CERROR("copy block %
d
from %lu to %lu ENOMEM \n",
+ CERROR("copy block %
lu
from %lu to %lu ENOMEM \n",
index, src->i_ino, dst->i_ino);
err = -ENOMEM;
goto unlock_src_page;
}
kaddr_dst = kmap(dst_page);
- err = c_aops->prepare_write(NULL, dst_page,
0, PAGE_CACHE_SIZE
);
+ err = c_aops->prepare_write(NULL, dst_page,
offset, offset + bytes
);
if (err)
goto unlock_dst_page;
memcpy(kaddr_dst, kaddr_src, PAGE_CACHE_SIZE);
flush_dcache_page(dst_page);
- err = c_aops->commit_write(NULL, dst_page, 0, PAGE_CACHE_SIZE);
+ err = c_aops->commit_write(NULL, dst_page, offset, offset + bytes);
+ CDEBUG(D_SNAP, "copy back pages %p index %lu src %lu dst %lu \n",
+ dst_page, dst_page->index, src->i_ino, dst->i_ino);
if (err)
goto unlock_dst_page;
err = 1;
@@
-106,7
+117,7
@@
static ssize_t currentfs_write (struct file *filp, const char *buf,
struct snap_cache *cache;
struct inode *inode = filp->f_dentry->d_inode;
struct file_operations *fops;
- long
page
[2]={-1,-1};
+ long
start[2]={-1,-1}, end
[2]={-1,-1};
struct snap_table *table;
struct inode *cache_inode = NULL;
int slot = 0, index = 0, result = 0;
@@
-123,81
+134,48
@@
static ssize_t currentfs_write (struct file *filp, const char *buf,
if ( !cache )
RETURN(-EINVAL);
+ down(&inode->i_sem);
+
if ( snap_needs_cow(inode) != -1 ) {
CDEBUG(D_SNAP, "snap_needs_cow for ino %lu \n",inode->i_ino);
snap_do_cow(inode, filp->f_dentry->d_parent->d_inode->i_ino, 0);
}
fops = filter_c2cffops(cache->cache_filter);
- if (!fops || !fops->write)
- RETURN(-EINVAL);
-
+ if (!fops || !fops->write) {
+ up(&inode->i_sem);
+ RETURN(-EINVAL);
+ }
if (filp->f_flags & O_APPEND)
pos = inode->i_size;
else {
pos = *ppos;
- if (pos != *ppos)
+ if (pos != *ppos){
+ up(&inode->i_sem);
RETURN(-EINVAL);
+ }
}
-
- /*
- * we only need to copy back the first and last blocks
- */
-#if 0
- mask = inode->i_sb->s_blocksize-1;
- if( pos & mask )
- block[0] = pos >> inode->i_sb->s_blocksize_bits;
- pos += count - 1;
- if( (pos+1) & mask )
- block[1] = pos >> inode->i_sb->s_blocksize_bits;
- if( block[0] == block[1] )
- block[1] = -1;
- snapops = filter_c2csnapops(cache->cache_filter);
-
- for (i = 0; i < 2; i++) {
- if (block[i] == -1)
- continue;
- table = &snap_tables[cache->cache_snap_tableno];
- /*Find the nearest block in snaptable and copy back it*/
- for (slot = table->tbl_count - 1; slot >= 1; slot--) {
- cache_inode = NULL;
- index = table->snap_items[slot].index;
- cache_inode = snap_get_indirect(inode, NULL, index);
-
- if (!cache_inode) continue;
-
- CDEBUG(D_SNAP, "find cache_ino %lu\n", cache_inode->i_ino);
-
- if (snapops && snapops->copy_block) {
- result = snapops->copy_block(inode, cache_inode, block[i]);
- if (result == 1) {
- CDEBUG(D_SNAP, "copy block %lu back from ind %lu to %lu\n",
- block[i], cache_inode->i_ino, inode->i_ino);
- iput(cache_inode);
- result = 0;
- break;
- }
- if (result < 0) {
- iput(cache_inode);
- rc = result;
- goto exit;
- }
- }
- iput(cache_inode);
- }
+ CDEBUG(D_SNAP, "write offset %lld count %u \n", pos, count);
+
+ if (pos & (PAGE_CACHE_SIZE - 1)) {
+ start[0] = pos & PAGE_CACHE_MASK;
+ end[0] = pos;
}
-#else
- if (pos & PAGE_CACHE_MASK)
- page[0] = pos >> PAGE_CACHE_SHIFT;
pos += count - 1;
- if ((pos+1) & PAGE_CACHE_MASK)
- page[1] = pos >> PAGE_CACHE_SHIFT;
- if (page[0] == page[1])
- page[1] = -1;
-
+ if ((pos+1) & (PAGE_CACHE_SIZE - 1)) {
+ start[1] = pos;
+ end[1] = PAGE_CACHE_ALIGN(pos);
+ }
+
+ if (((start[0] >> PAGE_CACHE_SHIFT) == (start[1] >> PAGE_CACHE_SHIFT)) ||
+ pos > inode->i_size)
+ start[1] = -1;
+
+ CDEBUG(D_SNAP, "copy back start[0] %ld end[0] %ld start[1] %ld end[1] %ld \n",
+ start[0], end[0], start[1], end[1]);
for (i = 0; i < 2; i++) {
- if (
page
[i] == -1)
+ if (
start
[i] == -1)
continue;
table = &snap_tables[cache->cache_snap_tableno];
/*Find the nearest page in snaptable and copy back it*/
@@
-210,10
+188,12
@@
static ssize_t currentfs_write (struct file *filp, const char *buf,
CDEBUG(D_SNAP, "find cache_ino %lu\n", cache_inode->i_ino);
- result = copy_back_page(inode, cache_inode,
page
[i]);
+ result = copy_back_page(inode, cache_inode,
start[i], end
[i]);
if (result == 1) {
CDEBUG(D_SNAP, "copy page%lu back from ind %lu to %lu\n",
- page[i], cache_inode->i_ino, inode->i_ino);
+ (start[i] >> PAGE_CACHE_SHIFT),
+ cache_inode->i_ino,
+ inode->i_ino);
iput(cache_inode);
result = 0;
break;
@@
-221,12
+201,14
@@
static ssize_t currentfs_write (struct file *filp, const char *buf,
if (result < 0) {
iput(cache_inode);
rc = result;
+ up(&inode->i_sem);
goto exit;
}
iput(cache_inode);
}
}
-#endif
+
+ up(&inode->i_sem);
rc = fops->write(filp, buf, count, ppos);
exit:
RETURN(rc);
@@
-254,7
+236,7
@@
static int currentfs_readpage(struct file *file, struct page *page)
c_aops = filter_c2cfaops(cache->cache_filter);
- block =
page->index
>> inode->i_sb->s_blocksize_bits;
+ block =
(page->index << PAGE_CACHE_SHIFT)
>> inode->i_sb->s_blocksize_bits;
/* if there is a block in the cache, return the cache readpage */
if(c_aops->bmap(inode->i_mapping, block) ) {
@@
-279,7
+261,6
@@
static int currentfs_readpage(struct file *file, struct page *page)
table = &snap_tables[cache->cache_snap_tableno];
for (slot = table->tbl_count - 1; slot >= 1; slot--) {
- cache_inode = NULL;
index = table->snap_items[slot].index;
cache_inode = snap_get_indirect(inode, NULL, index);
@@
-292,12
+273,19
@@
static int currentfs_readpage(struct file *file, struct page *page)
if (!search_older && c_aops->bmap(cache_inode->i_mapping, block))
break;
iput(cache_inode);
+ cache_inode = NULL;
}
if (pri_inode) iput(pri_inode);
- if (!cache_inode )
- RETURN(-EINVAL);
-
+ if (!cache_inode) {
+ CDEBUG(D_SNAP, "block %lu is a hole of inode %lu \n",
+ block, inode->i_ino);
+ memset(kmap(page), 0, PAGE_CACHE_SIZE);
+ flush_dcache_page(page);
+ GOTO(exit, rc = 0);
+ }
+ CDEBUG(D_INODE, "readpage ino %lu icount %d \n", cache_inode->i_ino,
+ atomic_read(&cache_inode->i_count));
down(&cache_inode->i_sem);
/*Here we have changed a file to read,
@@
-317,13
+305,14
@@
static int currentfs_readpage(struct file *file, struct page *page)
GOTO(exit_release, rc = -EIO);
memcpy(kmap(page), kmap(cache_page), PAGE_CACHE_SIZE);
+ flush_dcache_page(page);
kunmap(cache_page);
page_cache_release(cache_page);
up(&cache_inode->i_sem);
iput(cache_inode);
-
+exit:
kunmap(page);
SetPageUptodate(page);
UnlockPage(page);
@@
-348,6
+337,8
@@
struct file_operations currentfs_file_fops = {
};
struct inode_operations currentfs_file_iops = {
- revalidate: NULL,
+ setattr: currentfs_setattr,
+ setxattr: currentfs_setxattr,
+ removexattr: currentfs_removexattr,
};