aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf/inode.c')
-rw-r--r--fs/udf/inode.c64
1 files changed, 28 insertions, 36 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 8a3fbd177cab..fc48f37aa2dd 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -36,7 +36,6 @@
36#include <linux/pagemap.h> 36#include <linux/pagemap.h>
37#include <linux/buffer_head.h> 37#include <linux/buffer_head.h>
38#include <linux/writeback.h> 38#include <linux/writeback.h>
39#include <linux/quotaops.h>
40#include <linux/slab.h> 39#include <linux/slab.h>
41#include <linux/crc-itu-t.h> 40#include <linux/crc-itu-t.h>
42 41
@@ -69,40 +68,23 @@ static void udf_update_extents(struct inode *,
69static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); 68static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
70 69
71 70
72void udf_delete_inode(struct inode *inode) 71void udf_evict_inode(struct inode *inode)
73{ 72{
74 if (!is_bad_inode(inode)) 73 struct udf_inode_info *iinfo = UDF_I(inode);
75 dquot_initialize(inode); 74 int want_delete = 0;
76 75
77 truncate_inode_pages(&inode->i_data, 0); 76 truncate_inode_pages(&inode->i_data, 0);
78 77
79 if (is_bad_inode(inode)) 78 if (!inode->i_nlink && !is_bad_inode(inode)) {
80 goto no_delete; 79 want_delete = 1;
81 80 inode->i_size = 0;
82 inode->i_size = 0; 81 udf_truncate(inode);
83 udf_truncate(inode); 82 lock_kernel();
84 lock_kernel(); 83 udf_update_inode(inode, IS_SYNC(inode));
85 84 unlock_kernel();
86 udf_update_inode(inode, IS_SYNC(inode)); 85 }
87 udf_free_inode(inode); 86 invalidate_inode_buffers(inode);
88 87 end_writeback(inode);
89 unlock_kernel();
90 return;
91
92no_delete:
93 clear_inode(inode);
94}
95
96/*
97 * If we are going to release inode from memory, we truncate last inode extent
98 * to proper length. We could use drop_inode() but it's called under inode_lock
99 * and thus we cannot mark inode dirty there. We use clear_inode() but we have
100 * to make sure to write inode as it's not written automatically.
101 */
102void udf_clear_inode(struct inode *inode)
103{
104 struct udf_inode_info *iinfo = UDF_I(inode);
105
106 if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && 88 if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB &&
107 inode->i_size != iinfo->i_lenExtents) { 89 inode->i_size != iinfo->i_lenExtents) {
108 printk(KERN_WARNING "UDF-fs (%s): Inode %lu (mode %o) has " 90 printk(KERN_WARNING "UDF-fs (%s): Inode %lu (mode %o) has "
@@ -112,10 +94,13 @@ void udf_clear_inode(struct inode *inode)
112 (unsigned long long)inode->i_size, 94 (unsigned long long)inode->i_size,
113 (unsigned long long)iinfo->i_lenExtents); 95 (unsigned long long)iinfo->i_lenExtents);
114 } 96 }
115
116 dquot_drop(inode);
117 kfree(iinfo->i_ext.i_data); 97 kfree(iinfo->i_ext.i_data);
118 iinfo->i_ext.i_data = NULL; 98 iinfo->i_ext.i_data = NULL;
99 if (want_delete) {
100 lock_kernel();
101 udf_free_inode(inode);
102 unlock_kernel();
103 }
119} 104}
120 105
121static int udf_writepage(struct page *page, struct writeback_control *wbc) 106static int udf_writepage(struct page *page, struct writeback_control *wbc)
@@ -132,9 +117,16 @@ static int udf_write_begin(struct file *file, struct address_space *mapping,
132 loff_t pos, unsigned len, unsigned flags, 117 loff_t pos, unsigned len, unsigned flags,
133 struct page **pagep, void **fsdata) 118 struct page **pagep, void **fsdata)
134{ 119{
135 *pagep = NULL; 120 int ret;
136 return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 121
137 udf_get_block); 122 ret = block_write_begin(mapping, pos, len, flags, pagep, udf_get_block);
123 if (unlikely(ret)) {
124 loff_t isize = mapping->host->i_size;
125 if (pos + len > isize)
126 vmtruncate(mapping->host, isize);
127 }
128
129 return ret;
138} 130}
139 131
140static sector_t udf_bmap(struct address_space *mapping, sector_t block) 132static sector_t udf_bmap(struct address_space *mapping, sector_t block)