diff options
Diffstat (limited to 'fs/udf/inode.c')
-rw-r--r-- | fs/udf/inode.c | 64 |
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 *, | |||
69 | static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); | 68 | static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); |
70 | 69 | ||
71 | 70 | ||
72 | void udf_delete_inode(struct inode *inode) | 71 | void 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 | |||
92 | no_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 | */ | ||
102 | void 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 | ||
121 | static int udf_writepage(struct page *page, struct writeback_control *wbc) | 106 | static 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 | ||
140 | static sector_t udf_bmap(struct address_space *mapping, sector_t block) | 132 | static sector_t udf_bmap(struct address_space *mapping, sector_t block) |