diff options
author | Jiri Kosina <jkosina@suse.cz> | 2010-08-11 03:36:51 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2010-08-11 03:36:51 -0400 |
commit | 6396fc3b3ff3f6b942992b653a62df11dcef9bea (patch) | |
tree | db3c7cbe833b43c653adc99f70941431c5ff7c4e /fs/jfs | |
parent | 4785879e4d340e24e54f6de2ccfc42728b912808 (diff) | |
parent | 3d30701b58970425e1d45994d6cb82f828924fdd (diff) |
Merge branch 'master' into for-next
Conflicts:
fs/exofs/inode.c
Diffstat (limited to 'fs/jfs')
-rw-r--r-- | fs/jfs/file.c | 14 | ||||
-rw-r--r-- | fs/jfs/inode.c | 63 | ||||
-rw-r--r-- | fs/jfs/jfs_inode.h | 2 | ||||
-rw-r--r-- | fs/jfs/super.c | 8 | ||||
-rw-r--r-- | fs/jfs/xattr.c | 87 |
5 files changed, 95 insertions, 79 deletions
diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 127263cc8657..c5ce6c1d1ff4 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c | |||
@@ -17,6 +17,7 @@ | |||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/mm.h> | ||
20 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
21 | #include <linux/quotaops.h> | 22 | #include <linux/quotaops.h> |
22 | #include "jfs_incore.h" | 23 | #include "jfs_incore.h" |
@@ -107,11 +108,18 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
107 | return rc; | 108 | return rc; |
108 | } | 109 | } |
109 | 110 | ||
110 | rc = inode_setattr(inode, iattr); | 111 | if ((iattr->ia_valid & ATTR_SIZE) && |
112 | iattr->ia_size != i_size_read(inode)) { | ||
113 | rc = vmtruncate(inode, iattr->ia_size); | ||
114 | if (rc) | ||
115 | return rc; | ||
116 | } | ||
111 | 117 | ||
112 | if (!rc && (iattr->ia_valid & ATTR_MODE)) | 118 | setattr_copy(inode, iattr); |
113 | rc = jfs_acl_chmod(inode); | 119 | mark_inode_dirty(inode); |
114 | 120 | ||
121 | if (iattr->ia_valid & ATTR_MODE) | ||
122 | rc = jfs_acl_chmod(inode); | ||
115 | return rc; | 123 | return rc; |
116 | } | 124 | } |
117 | 125 | ||
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index ed9ba6fe04f5..9978803ceedc 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
@@ -145,31 +145,32 @@ int jfs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
148 | void jfs_delete_inode(struct inode *inode) | 148 | void jfs_evict_inode(struct inode *inode) |
149 | { | 149 | { |
150 | jfs_info("In jfs_delete_inode, inode = 0x%p", inode); | 150 | jfs_info("In jfs_evict_inode, inode = 0x%p", inode); |
151 | 151 | ||
152 | if (!is_bad_inode(inode)) | 152 | if (!inode->i_nlink && !is_bad_inode(inode)) { |
153 | dquot_initialize(inode); | 153 | dquot_initialize(inode); |
154 | 154 | ||
155 | if (!is_bad_inode(inode) && | 155 | if (JFS_IP(inode)->fileset == FILESYSTEM_I) { |
156 | (JFS_IP(inode)->fileset == FILESYSTEM_I)) { | 156 | truncate_inode_pages(&inode->i_data, 0); |
157 | truncate_inode_pages(&inode->i_data, 0); | ||
158 | 157 | ||
159 | if (test_cflag(COMMIT_Freewmap, inode)) | 158 | if (test_cflag(COMMIT_Freewmap, inode)) |
160 | jfs_free_zero_link(inode); | 159 | jfs_free_zero_link(inode); |
161 | 160 | ||
162 | diFree(inode); | 161 | diFree(inode); |
163 | 162 | ||
164 | /* | 163 | /* |
165 | * Free the inode from the quota allocation. | 164 | * Free the inode from the quota allocation. |
166 | */ | 165 | */ |
167 | dquot_initialize(inode); | 166 | dquot_initialize(inode); |
168 | dquot_free_inode(inode); | 167 | dquot_free_inode(inode); |
169 | dquot_drop(inode); | 168 | } |
169 | } else { | ||
170 | truncate_inode_pages(&inode->i_data, 0); | ||
170 | } | 171 | } |
171 | 172 | end_writeback(inode); | |
172 | clear_inode(inode); | 173 | dquot_drop(inode); |
173 | } | 174 | } |
174 | 175 | ||
175 | void jfs_dirty_inode(struct inode *inode) | 176 | void jfs_dirty_inode(struct inode *inode) |
@@ -303,8 +304,17 @@ static int jfs_write_begin(struct file *file, struct address_space *mapping, | |||
303 | loff_t pos, unsigned len, unsigned flags, | 304 | loff_t pos, unsigned len, unsigned flags, |
304 | struct page **pagep, void **fsdata) | 305 | struct page **pagep, void **fsdata) |
305 | { | 306 | { |
306 | return nobh_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 307 | int ret; |
308 | |||
309 | ret = nobh_write_begin(mapping, pos, len, flags, pagep, fsdata, | ||
307 | jfs_get_block); | 310 | jfs_get_block); |
311 | if (unlikely(ret)) { | ||
312 | loff_t isize = mapping->host->i_size; | ||
313 | if (pos + len > isize) | ||
314 | vmtruncate(mapping->host, isize); | ||
315 | } | ||
316 | |||
317 | return ret; | ||
308 | } | 318 | } |
309 | 319 | ||
310 | static sector_t jfs_bmap(struct address_space *mapping, sector_t block) | 320 | static sector_t jfs_bmap(struct address_space *mapping, sector_t block) |
@@ -317,9 +327,24 @@ static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb, | |||
317 | { | 327 | { |
318 | struct file *file = iocb->ki_filp; | 328 | struct file *file = iocb->ki_filp; |
319 | struct inode *inode = file->f_mapping->host; | 329 | struct inode *inode = file->f_mapping->host; |
330 | ssize_t ret; | ||
320 | 331 | ||
321 | return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, | 332 | ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, |
322 | offset, nr_segs, jfs_get_block, NULL); | 333 | offset, nr_segs, jfs_get_block, NULL); |
334 | |||
335 | /* | ||
336 | * In case of error extending write may have instantiated a few | ||
337 | * blocks outside i_size. Trim these off again. | ||
338 | */ | ||
339 | if (unlikely((rw & WRITE) && ret < 0)) { | ||
340 | loff_t isize = i_size_read(inode); | ||
341 | loff_t end = offset + iov_length(iov, nr_segs); | ||
342 | |||
343 | if (end > isize) | ||
344 | vmtruncate(inode, isize); | ||
345 | } | ||
346 | |||
347 | return ret; | ||
323 | } | 348 | } |
324 | 349 | ||
325 | const struct address_space_operations jfs_aops = { | 350 | const struct address_space_operations jfs_aops = { |
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index 11042b1f44b5..155e91eff07d 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h | |||
@@ -27,7 +27,7 @@ extern long jfs_compat_ioctl(struct file *, unsigned int, unsigned long); | |||
27 | extern struct inode *jfs_iget(struct super_block *, unsigned long); | 27 | extern struct inode *jfs_iget(struct super_block *, unsigned long); |
28 | extern int jfs_commit_inode(struct inode *, int); | 28 | extern int jfs_commit_inode(struct inode *, int); |
29 | extern int jfs_write_inode(struct inode *, struct writeback_control *); | 29 | extern int jfs_write_inode(struct inode *, struct writeback_control *); |
30 | extern void jfs_delete_inode(struct inode *); | 30 | extern void jfs_evict_inode(struct inode *); |
31 | extern void jfs_dirty_inode(struct inode *); | 31 | extern void jfs_dirty_inode(struct inode *); |
32 | extern void jfs_truncate(struct inode *); | 32 | extern void jfs_truncate(struct inode *); |
33 | extern void jfs_truncate_nolock(struct inode *, loff_t); | 33 | extern void jfs_truncate_nolock(struct inode *, loff_t); |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index b38f96bef829..ec8c3e4baca3 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -132,11 +132,6 @@ static void jfs_destroy_inode(struct inode *inode) | |||
132 | kmem_cache_free(jfs_inode_cachep, ji); | 132 | kmem_cache_free(jfs_inode_cachep, ji); |
133 | } | 133 | } |
134 | 134 | ||
135 | static void jfs_clear_inode(struct inode *inode) | ||
136 | { | ||
137 | dquot_drop(inode); | ||
138 | } | ||
139 | |||
140 | static int jfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 135 | static int jfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
141 | { | 136 | { |
142 | struct jfs_sb_info *sbi = JFS_SBI(dentry->d_sb); | 137 | struct jfs_sb_info *sbi = JFS_SBI(dentry->d_sb); |
@@ -765,8 +760,7 @@ static const struct super_operations jfs_super_operations = { | |||
765 | .destroy_inode = jfs_destroy_inode, | 760 | .destroy_inode = jfs_destroy_inode, |
766 | .dirty_inode = jfs_dirty_inode, | 761 | .dirty_inode = jfs_dirty_inode, |
767 | .write_inode = jfs_write_inode, | 762 | .write_inode = jfs_write_inode, |
768 | .delete_inode = jfs_delete_inode, | 763 | .evict_inode = jfs_evict_inode, |
769 | .clear_inode = jfs_clear_inode, | ||
770 | .put_super = jfs_put_super, | 764 | .put_super = jfs_put_super, |
771 | .sync_fs = jfs_sync_fs, | 765 | .sync_fs = jfs_sync_fs, |
772 | .freeze_fs = jfs_freeze, | 766 | .freeze_fs = jfs_freeze, |
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index fa96bbb26343..2d7f165d0f1d 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c | |||
@@ -86,46 +86,25 @@ struct ea_buffer { | |||
86 | #define EA_MALLOC 0x0008 | 86 | #define EA_MALLOC 0x0008 |
87 | 87 | ||
88 | 88 | ||
89 | static int is_known_namespace(const char *name) | ||
90 | { | ||
91 | if (strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) && | ||
92 | strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) && | ||
93 | strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) && | ||
94 | strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) | ||
95 | return false; | ||
96 | |||
97 | return true; | ||
98 | } | ||
99 | |||
89 | /* | 100 | /* |
90 | * These three routines are used to recognize on-disk extended attributes | 101 | * These three routines are used to recognize on-disk extended attributes |
91 | * that are in a recognized namespace. If the attribute is not recognized, | 102 | * that are in a recognized namespace. If the attribute is not recognized, |
92 | * "os2." is prepended to the name | 103 | * "os2." is prepended to the name |
93 | */ | 104 | */ |
94 | static inline int is_os2_xattr(struct jfs_ea *ea) | 105 | static int is_os2_xattr(struct jfs_ea *ea) |
95 | { | 106 | { |
96 | /* | 107 | return !is_known_namespace(ea->name); |
97 | * Check for "system." | ||
98 | */ | ||
99 | if ((ea->namelen >= XATTR_SYSTEM_PREFIX_LEN) && | ||
100 | !strncmp(ea->name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | ||
101 | return false; | ||
102 | /* | ||
103 | * Check for "user." | ||
104 | */ | ||
105 | if ((ea->namelen >= XATTR_USER_PREFIX_LEN) && | ||
106 | !strncmp(ea->name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) | ||
107 | return false; | ||
108 | /* | ||
109 | * Check for "security." | ||
110 | */ | ||
111 | if ((ea->namelen >= XATTR_SECURITY_PREFIX_LEN) && | ||
112 | !strncmp(ea->name, XATTR_SECURITY_PREFIX, | ||
113 | XATTR_SECURITY_PREFIX_LEN)) | ||
114 | return false; | ||
115 | /* | ||
116 | * Check for "trusted." | ||
117 | */ | ||
118 | if ((ea->namelen >= XATTR_TRUSTED_PREFIX_LEN) && | ||
119 | !strncmp(ea->name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) | ||
120 | return false; | ||
121 | /* | ||
122 | * Add any other valid namespace prefixes here | ||
123 | */ | ||
124 | |||
125 | /* | ||
126 | * We assume it's OS/2's flat namespace | ||
127 | */ | ||
128 | return true; | ||
129 | } | 108 | } |
130 | 109 | ||
131 | static inline int name_size(struct jfs_ea *ea) | 110 | static inline int name_size(struct jfs_ea *ea) |
@@ -764,13 +743,23 @@ static int can_set_xattr(struct inode *inode, const char *name, | |||
764 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) | 743 | if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) |
765 | return can_set_system_xattr(inode, name, value, value_len); | 744 | return can_set_system_xattr(inode, name, value, value_len); |
766 | 745 | ||
746 | if (!strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) { | ||
747 | /* | ||
748 | * This makes sure that we aren't trying to set an | ||
749 | * attribute in a different namespace by prefixing it | ||
750 | * with "os2." | ||
751 | */ | ||
752 | if (is_known_namespace(name + XATTR_OS2_PREFIX_LEN)) | ||
753 | return -EOPNOTSUPP; | ||
754 | return 0; | ||
755 | } | ||
756 | |||
767 | /* | 757 | /* |
768 | * Don't allow setting an attribute in an unknown namespace. | 758 | * Don't allow setting an attribute in an unknown namespace. |
769 | */ | 759 | */ |
770 | if (strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) && | 760 | if (strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) && |
771 | strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) && | 761 | strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) && |
772 | strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) && | 762 | strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) |
773 | strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) | ||
774 | return -EOPNOTSUPP; | 763 | return -EOPNOTSUPP; |
775 | 764 | ||
776 | return 0; | 765 | return 0; |
@@ -952,19 +941,8 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data, | |||
952 | int xattr_size; | 941 | int xattr_size; |
953 | ssize_t size; | 942 | ssize_t size; |
954 | int namelen = strlen(name); | 943 | int namelen = strlen(name); |
955 | char *os2name = NULL; | ||
956 | char *value; | 944 | char *value; |
957 | 945 | ||
958 | if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { | ||
959 | os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1, | ||
960 | GFP_KERNEL); | ||
961 | if (!os2name) | ||
962 | return -ENOMEM; | ||
963 | strcpy(os2name, name + XATTR_OS2_PREFIX_LEN); | ||
964 | name = os2name; | ||
965 | namelen -= XATTR_OS2_PREFIX_LEN; | ||
966 | } | ||
967 | |||
968 | down_read(&JFS_IP(inode)->xattr_sem); | 946 | down_read(&JFS_IP(inode)->xattr_sem); |
969 | 947 | ||
970 | xattr_size = ea_get(inode, &ea_buf, 0); | 948 | xattr_size = ea_get(inode, &ea_buf, 0); |
@@ -1002,8 +980,6 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data, | |||
1002 | out: | 980 | out: |
1003 | up_read(&JFS_IP(inode)->xattr_sem); | 981 | up_read(&JFS_IP(inode)->xattr_sem); |
1004 | 982 | ||
1005 | kfree(os2name); | ||
1006 | |||
1007 | return size; | 983 | return size; |
1008 | } | 984 | } |
1009 | 985 | ||
@@ -1012,6 +988,19 @@ ssize_t jfs_getxattr(struct dentry *dentry, const char *name, void *data, | |||
1012 | { | 988 | { |
1013 | int err; | 989 | int err; |
1014 | 990 | ||
991 | if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { | ||
992 | /* | ||
993 | * skip past "os2." prefix | ||
994 | */ | ||
995 | name += XATTR_OS2_PREFIX_LEN; | ||
996 | /* | ||
997 | * Don't allow retrieving properly prefixed attributes | ||
998 | * by prepending them with "os2." | ||
999 | */ | ||
1000 | if (is_known_namespace(name)) | ||
1001 | return -EOPNOTSUPP; | ||
1002 | } | ||
1003 | |||
1015 | err = __jfs_getxattr(dentry->d_inode, name, data, buf_size); | 1004 | err = __jfs_getxattr(dentry->d_inode, name, data, buf_size); |
1016 | 1005 | ||
1017 | return err; | 1006 | return err; |