cache_file->f_pos = clone_file->f_pos;
}
-
static ssize_t currentfs_write (struct file *filp, const char *buf,
size_t count, loff_t *ppos)
{
struct snap_cache *cache;
struct inode *inode = filp->f_dentry->d_inode;
- ssize_t rc;
struct file_operations *fops;
- loff_t pos;
- long block[2]={-1,-1}, mask, i;
+ long block[2]={-1,-1};
struct snap_table *table;
- int slot = 0;
- int index = 0;
- struct address_space_operations *aops;
struct inode *cache_inode = NULL;
struct snapshot_operations *snapops;
+ int slot = 0, index = 0, result = 0;
+ long mask, i;
+ ssize_t rc;
+ loff_t pos;
ENTRY;
if( block[0] == block[1] )
block[1] = -1;
- aops = filter_c2cfaops(cache->cache_filter);
snapops = filter_c2csnapops(cache->cache_filter);
- for( i=0; i<2; i++ ){
- if(block[i]!=-1 && aops->bmap(inode->i_mapping, block[i])) {
- table = &snap_tables[cache->cache_snap_tableno];
- for (slot = table->tbl_count - 1; slot >= 1; slot--) {
- struct address_space_operations *c_aops =
- cache_inode->i_mapping->a_ops;
- cache_inode = NULL;
- index = table->snap_items[slot].index;
- cache_inode = snap_get_indirect(inode, NULL, index);
-
- if ( !cache_inode ) continue;
-
- if (c_aops->bmap(cache_inode->i_mapping, block[i])) {
- CDEBUG(D_SNAP, "find cache_ino %lu\n",
- cache_inode->i_ino);
- if( snapops && snapops->copy_block) {
- snapops->copy_block(inode,
- cache_inode, block[i]);
- }
+ 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);
- break;
- }
- iput(cache_inode);
- }
- }
+ rc = result;
+ goto exit;
+ }
+ }
+ iput(cache_inode);
+ }
}
rc = fops->write(filp, buf, count, ppos);
+exit:
RETURN(rc);
}
table = &snap_tables[cache->cache_snap_tableno];
- for (slot = table->tbl_count - 1; slot >= 1; slot--)
- {
- struct address_space_operations *c_aops =
- cache_inode->i_mapping->a_ops;
+ 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);
int snap_set_indirect(struct inode *pri, ino_t ind_ino,
int index, ino_t parent_ino);
+/*super.c */
+void put_snap_current_mnt(struct super_block *sb);
+void get_snap_current_mnt(struct super_block *sb);
/* inode.c */
extern struct super_operations currentfs_super_ops;
void cleanup_filter_info_cache(void);
dst->i_gid = src->i_gid;
dst->i_mode = src->i_mode;
}
-#ifdef SNAP_DEBUG
+#if 0
extern unsigned int snap_debug_failcode;
#ifdef CONFIG_LOOP_DISCARD
#define BLKDEV_FAIL(dev,fail) loop_discard_io(dev,fail)
__MOD_DEC_USE_COUNT(fs->owner);
}
+static struct vfsmount* get_vfsmount(struct super_block *sb)
+{
+ struct vfsmount *rootmnt, *mnt, *ret = NULL;
+ struct list_head *end, *list;
+
+ rootmnt = mntget(current->fs->rootmnt);
+ end = list = &rootmnt->mnt_list;
+ do {
+ mnt = list_entry(list, struct vfsmount, mnt_list);
+ if (mnt->mnt_sb == sb) {
+ ret = mnt;
+ break;
+ }
+ list = list->next;
+ } while (end != list);
+ mntput(current->fs->rootmnt);
+ return ret;
+}
+
+void get_snap_current_mnt(struct super_block *sb)
+{
+ struct vfsmount *mnt;
+
+ mnt = get_vfsmount(sb);
+ if (mnt)
+ mntget(mnt);
+}
+void put_snap_current_mnt(struct super_block *sb)
+{
+ struct vfsmount *mnt;
+
+ mnt = get_vfsmount(sb);
+ if (mnt)
+ mntput(mnt);
+}
+
/* In get_opt we get options in opt, value in opt_value
* we must remember to free opt and opt_value*/
static char * snapfs_options(char *options, char **cache_type,
CDEBUG(D_SUPER, "sb %lx, &sb->u.generic_sbp: %lx\n",
(ulong) sb, (ulong) &sb->u.generic_sbp);
+
+ get_snap_current_mnt(snap_cache->cache_sb);
out_err:
cleanup_option();
if (err)
/* These are global control options */
#define ENTRY_CNT 3
+int snap_print_entry = 1;
+int snap_debug_level = 0;
+
/* XXX - doesn't seem to be working in 2.2.15 */
static struct ctl_table snapfs_ctltable[] =
{
-#ifdef SNAP_DEBUG
{PSDEV_DEBUG, "debug", &snap_debug_level, sizeof(int), 0644, NULL, &proc_dointvec},
-#endif
{PSDEV_TRACE, "trace", &snap_print_entry, sizeof(int), 0644, NULL, &proc_dointvec},
{0}
};