aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exofs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exofs')
-rw-r--r--fs/exofs/exofs.h3
-rw-r--r--fs/exofs/file.c1
-rw-r--r--fs/exofs/inode.c127
-rw-r--r--fs/exofs/ios.c2
-rw-r--r--fs/exofs/super.c2
5 files changed, 56 insertions, 79 deletions
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h
index 22721b2fd890..2dc925fa1010 100644
--- a/fs/exofs/exofs.h
+++ b/fs/exofs/exofs.h
@@ -256,7 +256,6 @@ static inline int exofs_oi_read(struct exofs_i_info *oi,
256} 256}
257 257
258/* inode.c */ 258/* inode.c */
259void exofs_truncate(struct inode *inode);
260int exofs_setattr(struct dentry *, struct iattr *); 259int exofs_setattr(struct dentry *, struct iattr *);
261int exofs_write_begin(struct file *file, struct address_space *mapping, 260int exofs_write_begin(struct file *file, struct address_space *mapping,
262 loff_t pos, unsigned len, unsigned flags, 261 loff_t pos, unsigned len, unsigned flags,
@@ -264,7 +263,7 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,
264extern struct inode *exofs_iget(struct super_block *, unsigned long); 263extern struct inode *exofs_iget(struct super_block *, unsigned long);
265struct inode *exofs_new_inode(struct inode *, int); 264struct inode *exofs_new_inode(struct inode *, int);
266extern int exofs_write_inode(struct inode *, struct writeback_control *wbc); 265extern int exofs_write_inode(struct inode *, struct writeback_control *wbc);
267extern void exofs_delete_inode(struct inode *); 266extern void exofs_evict_inode(struct inode *);
268 267
269/* dir.c: */ 268/* dir.c: */
270int exofs_add_link(struct dentry *, struct inode *); 269int exofs_add_link(struct dentry *, struct inode *);
diff --git a/fs/exofs/file.c b/fs/exofs/file.c
index aa1fd1a372cf..68cb23e3bb98 100644
--- a/fs/exofs/file.c
+++ b/fs/exofs/file.c
@@ -91,6 +91,5 @@ const struct file_operations exofs_file_operations = {
91}; 91};
92 92
93const struct inode_operations exofs_file_inode_operations = { 93const struct inode_operations exofs_file_inode_operations = {
94 .truncate = exofs_truncate,
95 .setattr = exofs_setattr, 94 .setattr = exofs_setattr,
96}; 95};
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
index fbf9f34554e0..eb7368ebd8cd 100644
--- a/fs/exofs/inode.c
+++ b/fs/exofs/inode.c
@@ -694,6 +694,13 @@ static int exofs_writepage(struct page *page, struct writeback_control *wbc)
694 return write_exec(&pcol); 694 return write_exec(&pcol);
695} 695}
696 696
697/* i_mutex held using inode->i_size directly */
698static void _write_failed(struct inode *inode, loff_t to)
699{
700 if (to > inode->i_size)
701 truncate_pagecache(inode, to, inode->i_size);
702}
703
697int exofs_write_begin(struct file *file, struct address_space *mapping, 704int exofs_write_begin(struct file *file, struct address_space *mapping,
698 loff_t pos, unsigned len, unsigned flags, 705 loff_t pos, unsigned len, unsigned flags,
699 struct page **pagep, void **fsdata) 706 struct page **pagep, void **fsdata)
@@ -707,7 +714,7 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,
707 fsdata); 714 fsdata);
708 if (ret) { 715 if (ret) {
709 EXOFS_DBGMSG("simple_write_begin faild\n"); 716 EXOFS_DBGMSG("simple_write_begin faild\n");
710 return ret; 717 goto out;
711 } 718 }
712 719
713 page = *pagep; 720 page = *pagep;
@@ -722,6 +729,9 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,
722 EXOFS_DBGMSG("__readpage_filler faild\n"); 729 EXOFS_DBGMSG("__readpage_filler faild\n");
723 } 730 }
724 } 731 }
732out:
733 if (unlikely(ret))
734 _write_failed(mapping->host, pos + len);
725 735
726 return ret; 736 return ret;
727} 737}
@@ -747,6 +757,10 @@ static int exofs_write_end(struct file *file, struct address_space *mapping,
747 int ret; 757 int ret;
748 758
749 ret = simple_write_end(file, mapping,pos, len, copied, page, fsdata); 759 ret = simple_write_end(file, mapping,pos, len, copied, page, fsdata);
760 if (unlikely(ret))
761 _write_failed(inode, pos + len);
762
763 /* TODO: once simple_write_end marks inode dirty remove */
750 if (i_size != inode->i_size) 764 if (i_size != inode->i_size)
751 mark_inode_dirty(inode); 765 mark_inode_dirty(inode);
752 return ret; 766 return ret;
@@ -803,87 +817,55 @@ static inline int exofs_inode_is_fast_symlink(struct inode *inode)
803 return S_ISLNK(inode->i_mode) && (oi->i_data[0] != 0); 817 return S_ISLNK(inode->i_mode) && (oi->i_data[0] != 0);
804} 818}
805 819
806/*
807 * get_block_t - Fill in a buffer_head
808 * An OSD takes care of block allocation so we just fake an allocation by
809 * putting in the inode's sector_t in the buffer_head.
810 * TODO: What about the case of create==0 and @iblock does not exist in the
811 * object?
812 */
813static int exofs_get_block(struct inode *inode, sector_t iblock,
814 struct buffer_head *bh_result, int create)
815{
816 map_bh(bh_result, inode->i_sb, iblock);
817 return 0;
818}
819
820const struct osd_attr g_attr_logical_length = ATTR_DEF( 820const struct osd_attr g_attr_logical_length = ATTR_DEF(
821 OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8); 821 OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8);
822 822
823static int _do_truncate(struct inode *inode) 823static int _do_truncate(struct inode *inode, loff_t newsize)
824{ 824{
825 struct exofs_i_info *oi = exofs_i(inode); 825 struct exofs_i_info *oi = exofs_i(inode);
826 loff_t isize = i_size_read(inode);
827 int ret; 826 int ret;
828 827
829 inode->i_mtime = inode->i_ctime = CURRENT_TIME; 828 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
830 829
831 nobh_truncate_page(inode->i_mapping, isize, exofs_get_block); 830 ret = exofs_oi_truncate(oi, (u64)newsize);
831 if (likely(!ret))
832 truncate_setsize(inode, newsize);
832 833
833 ret = exofs_oi_truncate(oi, (u64)isize); 834 EXOFS_DBGMSG("(0x%lx) size=0x%llx ret=>%d\n",
834 EXOFS_DBGMSG("(0x%lx) size=0x%llx\n", inode->i_ino, isize); 835 inode->i_ino, newsize, ret);
835 return ret; 836 return ret;
836} 837}
837 838
838/* 839/*
839 * Truncate a file to the specified size - all we have to do is set the size 840 * Set inode attributes - update size attribute on OSD if needed,
840 * attribute. We make sure the object exists first. 841 * otherwise just call generic functions.
841 */
842void exofs_truncate(struct inode *inode)
843{
844 struct exofs_i_info *oi = exofs_i(inode);
845 int ret;
846
847 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
848 || S_ISLNK(inode->i_mode)))
849 return;
850 if (exofs_inode_is_fast_symlink(inode))
851 return;
852 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
853 return;
854
855 /* if we are about to truncate an object, and it hasn't been
856 * created yet, wait
857 */
858 if (unlikely(wait_obj_created(oi)))
859 goto fail;
860
861 ret = _do_truncate(inode);
862 if (ret)
863 goto fail;
864
865out:
866 mark_inode_dirty(inode);
867 return;
868fail:
869 make_bad_inode(inode);
870 goto out;
871}
872
873/*
874 * Set inode attributes - just call generic functions.
875 */ 842 */
876int exofs_setattr(struct dentry *dentry, struct iattr *iattr) 843int exofs_setattr(struct dentry *dentry, struct iattr *iattr)
877{ 844{
878 struct inode *inode = dentry->d_inode; 845 struct inode *inode = dentry->d_inode;
879 int error; 846 int error;
880 847
848 /* if we are about to modify an object, and it hasn't been
849 * created yet, wait
850 */
851 error = wait_obj_created(exofs_i(inode));
852 if (unlikely(error))
853 return error;
854
881 error = inode_change_ok(inode, iattr); 855 error = inode_change_ok(inode, iattr);
882 if (error) 856 if (unlikely(error))
883 return error; 857 return error;
884 858
885 error = inode_setattr(inode, iattr); 859 if ((iattr->ia_valid & ATTR_SIZE) &&
886 return error; 860 iattr->ia_size != i_size_read(inode)) {
861 error = _do_truncate(inode, iattr->ia_size);
862 if (unlikely(error))
863 return error;
864 }
865
866 setattr_copy(inode, iattr);
867 mark_inode_dirty(inode);
868 return 0;
887} 869}
888 870
889static const struct osd_attr g_attr_inode_file_layout = ATTR_DEF( 871static const struct osd_attr g_attr_inode_file_layout = ATTR_DEF(
@@ -1320,7 +1302,7 @@ static void delete_done(struct exofs_io_state *ios, void *p)
1320 * from the OSD here. We make sure the object was created before we try and 1302 * from the OSD here. We make sure the object was created before we try and
1321 * delete it. 1303 * delete it.
1322 */ 1304 */
1323void exofs_delete_inode(struct inode *inode) 1305void exofs_evict_inode(struct inode *inode)
1324{ 1306{
1325 struct exofs_i_info *oi = exofs_i(inode); 1307 struct exofs_i_info *oi = exofs_i(inode);
1326 struct super_block *sb = inode->i_sb; 1308 struct super_block *sb = inode->i_sb;
@@ -1330,30 +1312,27 @@ void exofs_delete_inode(struct inode *inode)
1330 1312
1331 truncate_inode_pages(&inode->i_data, 0); 1313 truncate_inode_pages(&inode->i_data, 0);
1332 1314
1333 if (is_bad_inode(inode)) 1315 /* TODO: should do better here */
1316 if (inode->i_nlink || is_bad_inode(inode))
1334 goto no_delete; 1317 goto no_delete;
1335 1318
1336 mark_inode_dirty(inode);
1337 exofs_update_inode(inode, inode_needs_sync(inode));
1338
1339 inode->i_size = 0; 1319 inode->i_size = 0;
1340 if (inode->i_blocks) 1320 end_writeback(inode);
1341 exofs_truncate(inode);
1342 1321
1343 clear_inode(inode); 1322 /* if we are deleting an obj that hasn't been created yet, wait */
1323 if (!obj_created(oi)) {
1324 BUG_ON(!obj_2bcreated(oi));
1325 wait_event(oi->i_wq, obj_created(oi));
1326 /* ignore the error attempt a remove anyway */
1327 }
1344 1328
1329 /* Now Remove the OSD objects */
1345 ret = exofs_get_io_state(&sbi->layout, &ios); 1330 ret = exofs_get_io_state(&sbi->layout, &ios);
1346 if (unlikely(ret)) { 1331 if (unlikely(ret)) {
1347 EXOFS_ERR("%s: exofs_get_io_state failed\n", __func__); 1332 EXOFS_ERR("%s: exofs_get_io_state failed\n", __func__);
1348 return; 1333 return;
1349 } 1334 }
1350 1335
1351 /* if we are deleting an obj that hasn't been created yet, wait */
1352 if (!obj_created(oi)) {
1353 BUG_ON(!obj_2bcreated(oi));
1354 wait_event(oi->i_wq, obj_created(oi));
1355 }
1356
1357 ios->obj.id = exofs_oi_objno(oi); 1336 ios->obj.id = exofs_oi_objno(oi);
1358 ios->done = delete_done; 1337 ios->done = delete_done;
1359 ios->private = sbi; 1338 ios->private = sbi;
@@ -1369,5 +1348,5 @@ void exofs_delete_inode(struct inode *inode)
1369 return; 1348 return;
1370 1349
1371no_delete: 1350no_delete:
1372 clear_inode(inode); 1351 end_writeback(inode);
1373} 1352}
diff --git a/fs/exofs/ios.c b/fs/exofs/ios.c
index 5a1960500c8a..6550bf70e41d 100644
--- a/fs/exofs/ios.c
+++ b/fs/exofs/ios.c
@@ -579,7 +579,7 @@ static int _sbi_write_mirror(struct exofs_io_state *ios, int cur_comp)
579 } else { 579 } else {
580 bio = master_dev->bio; 580 bio = master_dev->bio;
581 /* FIXME: bio_set_dir() */ 581 /* FIXME: bio_set_dir() */
582 bio->bi_rw |= (1 << BIO_RW); 582 bio->bi_rw |= REQ_WRITE;
583 } 583 }
584 584
585 osd_req_write(or, &ios->obj, per_dev->offset, bio, 585 osd_req_write(or, &ios->obj, per_dev->offset, bio,
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index 50cb1745e29c..047e92fa3af8 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -742,7 +742,7 @@ static const struct super_operations exofs_sops = {
742 .alloc_inode = exofs_alloc_inode, 742 .alloc_inode = exofs_alloc_inode,
743 .destroy_inode = exofs_destroy_inode, 743 .destroy_inode = exofs_destroy_inode,
744 .write_inode = exofs_write_inode, 744 .write_inode = exofs_write_inode,
745 .delete_inode = exofs_delete_inode, 745 .evict_inode = exofs_evict_inode,
746 .put_super = exofs_put_super, 746 .put_super = exofs_put_super,
747 .write_super = exofs_write_super, 747 .write_super = exofs_write_super,
748 .sync_fs = exofs_sync_fs, 748 .sync_fs = exofs_sync_fs,