aboutsummaryrefslogtreecommitdiffstats
path: root/fs/isofs/inode.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/isofs/inode.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'fs/isofs/inode.c')
-rw-r--r--fs/isofs/inode.c221
1 files changed, 135 insertions, 86 deletions
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 5a44811b5027..b3cc8586984e 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -17,7 +17,6 @@
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/nls.h> 18#include <linux/nls.h>
19#include <linux/ctype.h> 19#include <linux/ctype.h>
20#include <linux/smp_lock.h>
21#include <linux/statfs.h> 20#include <linux/statfs.h>
22#include <linux/cdrom.h> 21#include <linux/cdrom.h>
23#include <linux/parser.h> 22#include <linux/parser.h>
@@ -27,16 +26,32 @@
27 26
28#define BEQUIET 27#define BEQUIET
29 28
30static int isofs_hashi(struct dentry *parent, struct qstr *qstr); 29static int isofs_hashi(const struct dentry *parent, const struct inode *inode,
31static int isofs_hash(struct dentry *parent, struct qstr *qstr); 30 struct qstr *qstr);
32static int isofs_dentry_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b); 31static int isofs_hash(const struct dentry *parent, const struct inode *inode,
33static int isofs_dentry_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b); 32 struct qstr *qstr);
33static int isofs_dentry_cmpi(const struct dentry *parent,
34 const struct inode *pinode,
35 const struct dentry *dentry, const struct inode *inode,
36 unsigned int len, const char *str, const struct qstr *name);
37static int isofs_dentry_cmp(const struct dentry *parent,
38 const struct inode *pinode,
39 const struct dentry *dentry, const struct inode *inode,
40 unsigned int len, const char *str, const struct qstr *name);
34 41
35#ifdef CONFIG_JOLIET 42#ifdef CONFIG_JOLIET
36static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr); 43static int isofs_hashi_ms(const struct dentry *parent, const struct inode *inode,
37static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr); 44 struct qstr *qstr);
38static int isofs_dentry_cmpi_ms(struct dentry *dentry, struct qstr *a, struct qstr *b); 45static int isofs_hash_ms(const struct dentry *parent, const struct inode *inode,
39static int isofs_dentry_cmp_ms(struct dentry *dentry, struct qstr *a, struct qstr *b); 46 struct qstr *qstr);
47static int isofs_dentry_cmpi_ms(const struct dentry *parent,
48 const struct inode *pinode,
49 const struct dentry *dentry, const struct inode *inode,
50 unsigned int len, const char *str, const struct qstr *name);
51static int isofs_dentry_cmp_ms(const struct dentry *parent,
52 const struct inode *pinode,
53 const struct dentry *dentry, const struct inode *inode,
54 unsigned int len, const char *str, const struct qstr *name);
40#endif 55#endif
41 56
42static void isofs_put_super(struct super_block *sb) 57static void isofs_put_super(struct super_block *sb)
@@ -44,11 +59,7 @@ static void isofs_put_super(struct super_block *sb)
44 struct isofs_sb_info *sbi = ISOFS_SB(sb); 59 struct isofs_sb_info *sbi = ISOFS_SB(sb);
45 60
46#ifdef CONFIG_JOLIET 61#ifdef CONFIG_JOLIET
47 lock_kernel();
48
49 unload_nls(sbi->s_nls_iocharset); 62 unload_nls(sbi->s_nls_iocharset);
50
51 unlock_kernel();
52#endif 63#endif
53 64
54 kfree(sbi); 65 kfree(sbi);
@@ -70,11 +81,18 @@ static struct inode *isofs_alloc_inode(struct super_block *sb)
70 return &ei->vfs_inode; 81 return &ei->vfs_inode;
71} 82}
72 83
73static void isofs_destroy_inode(struct inode *inode) 84static void isofs_i_callback(struct rcu_head *head)
74{ 85{
86 struct inode *inode = container_of(head, struct inode, i_rcu);
87 INIT_LIST_HEAD(&inode->i_dentry);
75 kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode)); 88 kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode));
76} 89}
77 90
91static void isofs_destroy_inode(struct inode *inode)
92{
93 call_rcu(&inode->i_rcu, isofs_i_callback);
94}
95
78static void init_once(void *foo) 96static void init_once(void *foo)
79{ 97{
80 struct iso_inode_info *ei = foo; 98 struct iso_inode_info *ei = foo;
@@ -165,7 +183,7 @@ struct iso9660_options{
165 * Compute the hash for the isofs name corresponding to the dentry. 183 * Compute the hash for the isofs name corresponding to the dentry.
166 */ 184 */
167static int 185static int
168isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms) 186isofs_hash_common(const struct dentry *dentry, struct qstr *qstr, int ms)
169{ 187{
170 const char *name; 188 const char *name;
171 int len; 189 int len;
@@ -186,7 +204,7 @@ isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms)
186 * Compute the hash for the isofs name corresponding to the dentry. 204 * Compute the hash for the isofs name corresponding to the dentry.
187 */ 205 */
188static int 206static int
189isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms) 207isofs_hashi_common(const struct dentry *dentry, struct qstr *qstr, int ms)
190{ 208{
191 const char *name; 209 const char *name;
192 int len; 210 int len;
@@ -211,100 +229,94 @@ isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms)
211} 229}
212 230
213/* 231/*
214 * Case insensitive compare of two isofs names. 232 * Compare of two isofs names.
215 */
216static int isofs_dentry_cmpi_common(struct dentry *dentry, struct qstr *a,
217 struct qstr *b, int ms)
218{
219 int alen, blen;
220
221 /* A filename cannot end in '.' or we treat it like it has none */
222 alen = a->len;
223 blen = b->len;
224 if (ms) {
225 while (alen && a->name[alen-1] == '.')
226 alen--;
227 while (blen && b->name[blen-1] == '.')
228 blen--;
229 }
230 if (alen == blen) {
231 if (strnicmp(a->name, b->name, alen) == 0)
232 return 0;
233 }
234 return 1;
235}
236
237/*
238 * Case sensitive compare of two isofs names.
239 */ 233 */
240static int isofs_dentry_cmp_common(struct dentry *dentry, struct qstr *a, 234static int isofs_dentry_cmp_common(
241 struct qstr *b, int ms) 235 unsigned int len, const char *str,
236 const struct qstr *name, int ms, int ci)
242{ 237{
243 int alen, blen; 238 int alen, blen;
244 239
245 /* A filename cannot end in '.' or we treat it like it has none */ 240 /* A filename cannot end in '.' or we treat it like it has none */
246 alen = a->len; 241 alen = name->len;
247 blen = b->len; 242 blen = len;
248 if (ms) { 243 if (ms) {
249 while (alen && a->name[alen-1] == '.') 244 while (alen && name->name[alen-1] == '.')
250 alen--; 245 alen--;
251 while (blen && b->name[blen-1] == '.') 246 while (blen && str[blen-1] == '.')
252 blen--; 247 blen--;
253 } 248 }
254 if (alen == blen) { 249 if (alen == blen) {
255 if (strncmp(a->name, b->name, alen) == 0) 250 if (ci) {
256 return 0; 251 if (strnicmp(name->name, str, alen) == 0)
252 return 0;
253 } else {
254 if (strncmp(name->name, str, alen) == 0)
255 return 0;
256 }
257 } 257 }
258 return 1; 258 return 1;
259} 259}
260 260
261static int 261static int
262isofs_hash(struct dentry *dentry, struct qstr *qstr) 262isofs_hash(const struct dentry *dentry, const struct inode *inode,
263 struct qstr *qstr)
263{ 264{
264 return isofs_hash_common(dentry, qstr, 0); 265 return isofs_hash_common(dentry, qstr, 0);
265} 266}
266 267
267static int 268static int
268isofs_hashi(struct dentry *dentry, struct qstr *qstr) 269isofs_hashi(const struct dentry *dentry, const struct inode *inode,
270 struct qstr *qstr)
269{ 271{
270 return isofs_hashi_common(dentry, qstr, 0); 272 return isofs_hashi_common(dentry, qstr, 0);
271} 273}
272 274
273static int 275static int
274isofs_dentry_cmp(struct dentry *dentry,struct qstr *a,struct qstr *b) 276isofs_dentry_cmp(const struct dentry *parent, const struct inode *pinode,
277 const struct dentry *dentry, const struct inode *inode,
278 unsigned int len, const char *str, const struct qstr *name)
275{ 279{
276 return isofs_dentry_cmp_common(dentry, a, b, 0); 280 return isofs_dentry_cmp_common(len, str, name, 0, 0);
277} 281}
278 282
279static int 283static int
280isofs_dentry_cmpi(struct dentry *dentry,struct qstr *a,struct qstr *b) 284isofs_dentry_cmpi(const struct dentry *parent, const struct inode *pinode,
285 const struct dentry *dentry, const struct inode *inode,
286 unsigned int len, const char *str, const struct qstr *name)
281{ 287{
282 return isofs_dentry_cmpi_common(dentry, a, b, 0); 288 return isofs_dentry_cmp_common(len, str, name, 0, 1);
283} 289}
284 290
285#ifdef CONFIG_JOLIET 291#ifdef CONFIG_JOLIET
286static int 292static int
287isofs_hash_ms(struct dentry *dentry, struct qstr *qstr) 293isofs_hash_ms(const struct dentry *dentry, const struct inode *inode,
294 struct qstr *qstr)
288{ 295{
289 return isofs_hash_common(dentry, qstr, 1); 296 return isofs_hash_common(dentry, qstr, 1);
290} 297}
291 298
292static int 299static int
293isofs_hashi_ms(struct dentry *dentry, struct qstr *qstr) 300isofs_hashi_ms(const struct dentry *dentry, const struct inode *inode,
301 struct qstr *qstr)
294{ 302{
295 return isofs_hashi_common(dentry, qstr, 1); 303 return isofs_hashi_common(dentry, qstr, 1);
296} 304}
297 305
298static int 306static int
299isofs_dentry_cmp_ms(struct dentry *dentry,struct qstr *a,struct qstr *b) 307isofs_dentry_cmp_ms(const struct dentry *parent, const struct inode *pinode,
308 const struct dentry *dentry, const struct inode *inode,
309 unsigned int len, const char *str, const struct qstr *name)
300{ 310{
301 return isofs_dentry_cmp_common(dentry, a, b, 1); 311 return isofs_dentry_cmp_common(len, str, name, 1, 0);
302} 312}
303 313
304static int 314static int
305isofs_dentry_cmpi_ms(struct dentry *dentry,struct qstr *a,struct qstr *b) 315isofs_dentry_cmpi_ms(const struct dentry *parent, const struct inode *pinode,
316 const struct dentry *dentry, const struct inode *inode,
317 unsigned int len, const char *str, const struct qstr *name)
306{ 318{
307 return isofs_dentry_cmpi_common(dentry, a, b, 1); 319 return isofs_dentry_cmp_common(len, str, name, 1, 1);
308} 320}
309#endif 321#endif
310 322
@@ -549,6 +561,34 @@ static unsigned int isofs_get_last_session(struct super_block *sb, s32 session)
549} 561}
550 562
551/* 563/*
564 * Check if root directory is empty (has less than 3 files).
565 *
566 * Used to detect broken CDs where ISO root directory is empty but Joliet root
567 * directory is OK. If such CD has Rock Ridge extensions, they will be disabled
568 * (and Joliet used instead) or else no files would be visible.
569 */
570static bool rootdir_empty(struct super_block *sb, unsigned long block)
571{
572 int offset = 0, files = 0, de_len;
573 struct iso_directory_record *de;
574 struct buffer_head *bh;
575
576 bh = sb_bread(sb, block);
577 if (!bh)
578 return true;
579 while (files < 3) {
580 de = (struct iso_directory_record *) (bh->b_data + offset);
581 de_len = *(unsigned char *) de;
582 if (de_len == 0)
583 break;
584 files++;
585 offset += de_len;
586 }
587 brelse(bh);
588 return files < 3;
589}
590
591/*
552 * Initialize the superblock and read the root inode. 592 * Initialize the superblock and read the root inode.
553 * 593 *
554 * Note: a check_disk_change() has been done immediately prior 594 * Note: a check_disk_change() has been done immediately prior
@@ -823,6 +863,7 @@ root_found:
823 sbi->s_utf8 = opt.utf8; 863 sbi->s_utf8 = opt.utf8;
824 sbi->s_nocompress = opt.nocompress; 864 sbi->s_nocompress = opt.nocompress;
825 sbi->s_overriderockperm = opt.overriderockperm; 865 sbi->s_overriderockperm = opt.overriderockperm;
866 mutex_init(&sbi->s_mutex);
826 /* 867 /*
827 * It would be incredibly stupid to allow people to mark every file 868 * It would be incredibly stupid to allow people to mark every file
828 * on the disk as suid, so we merely allow them to set the default 869 * on the disk as suid, so we merely allow them to set the default
@@ -847,6 +888,18 @@ root_found:
847 goto out_no_root; 888 goto out_no_root;
848 889
849 /* 890 /*
891 * Fix for broken CDs with Rock Ridge and empty ISO root directory but
892 * correct Joliet root directory.
893 */
894 if (sbi->s_rock == 1 && joliet_level &&
895 rootdir_empty(s, sbi->s_firstdatazone)) {
896 printk(KERN_NOTICE
897 "ISOFS: primary root directory is empty. "
898 "Disabling Rock Ridge and switching to Joliet.");
899 sbi->s_rock = 0;
900 }
901
902 /*
850 * If this disk has both Rock Ridge and Joliet on it, then we 903 * If this disk has both Rock Ridge and Joliet on it, then we
851 * want to use Rock Ridge by default. This can be overridden 904 * want to use Rock Ridge by default. This can be overridden
852 * by using the norock mount option. There is still one other 905 * by using the norock mount option. There is still one other
@@ -886,17 +939,18 @@ root_found:
886 goto out_iput; 939 goto out_iput;
887 } 940 }
888 941
889 /* get the root dentry */
890 s->s_root = d_alloc_root(inode);
891 if (!(s->s_root))
892 goto out_no_root;
893
894 table = 0; 942 table = 0;
895 if (joliet_level) 943 if (joliet_level)
896 table += 2; 944 table += 2;
897 if (opt.check == 'r') 945 if (opt.check == 'r')
898 table++; 946 table++;
899 s->s_root->d_op = &isofs_dentry_ops[table]; 947
948 s->s_d_op = &isofs_dentry_ops[table];
949
950 /* get the root dentry */
951 s->s_root = d_alloc_root(inode);
952 if (!(s->s_root))
953 goto out_no_root;
900 954
901 kfree(opt.iocharset); 955 kfree(opt.iocharset);
902 956
@@ -920,7 +974,7 @@ out_no_inode:
920out_no_read: 974out_no_read:
921 printk(KERN_WARNING "%s: bread failed, dev=%s, iso_blknum=%d, block=%d\n", 975 printk(KERN_WARNING "%s: bread failed, dev=%s, iso_blknum=%d, block=%d\n",
922 __func__, s->s_id, iso_blknum, block); 976 __func__, s->s_id, iso_blknum, block);
923 goto out_freesbi; 977 goto out_freebh;
924out_bad_zone_size: 978out_bad_zone_size:
925 printk(KERN_WARNING "ISOFS: Bad logical zone size %ld\n", 979 printk(KERN_WARNING "ISOFS: Bad logical zone size %ld\n",
926 sbi->s_log_zone_size); 980 sbi->s_log_zone_size);
@@ -935,6 +989,7 @@ out_unknown_format:
935 989
936out_freebh: 990out_freebh:
937 brelse(bh); 991 brelse(bh);
992 brelse(pri_bh);
938out_freesbi: 993out_freesbi:
939 kfree(opt.iocharset); 994 kfree(opt.iocharset);
940 kfree(sbi); 995 kfree(sbi);
@@ -966,27 +1021,23 @@ static int isofs_statfs (struct dentry *dentry, struct kstatfs *buf)
966 * or getblk() if they are not. Returns the number of blocks inserted 1021 * or getblk() if they are not. Returns the number of blocks inserted
967 * (-ve == error.) 1022 * (-ve == error.)
968 */ 1023 */
969int isofs_get_blocks(struct inode *inode, sector_t iblock_s, 1024int isofs_get_blocks(struct inode *inode, sector_t iblock,
970 struct buffer_head **bh, unsigned long nblocks) 1025 struct buffer_head **bh, unsigned long nblocks)
971{ 1026{
972 unsigned long b_off; 1027 unsigned long b_off = iblock;
973 unsigned offset, sect_size; 1028 unsigned offset, sect_size;
974 unsigned int firstext; 1029 unsigned int firstext;
975 unsigned long nextblk, nextoff; 1030 unsigned long nextblk, nextoff;
976 long iblock = (long)iblock_s;
977 int section, rv, error; 1031 int section, rv, error;
978 struct iso_inode_info *ei = ISOFS_I(inode); 1032 struct iso_inode_info *ei = ISOFS_I(inode);
979 1033
980 lock_kernel();
981
982 error = -EIO; 1034 error = -EIO;
983 rv = 0; 1035 rv = 0;
984 if (iblock < 0 || iblock != iblock_s) { 1036 if (iblock != b_off) {
985 printk(KERN_DEBUG "%s: block number too large\n", __func__); 1037 printk(KERN_DEBUG "%s: block number too large\n", __func__);
986 goto abort; 1038 goto abort;
987 } 1039 }
988 1040
989 b_off = iblock;
990 1041
991 offset = 0; 1042 offset = 0;
992 firstext = ei->i_first_extent; 1043 firstext = ei->i_first_extent;
@@ -1004,8 +1055,9 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
1004 * I/O errors. 1055 * I/O errors.
1005 */ 1056 */
1006 if (b_off > ((inode->i_size + PAGE_CACHE_SIZE - 1) >> ISOFS_BUFFER_BITS(inode))) { 1057 if (b_off > ((inode->i_size + PAGE_CACHE_SIZE - 1) >> ISOFS_BUFFER_BITS(inode))) {
1007 printk(KERN_DEBUG "%s: block >= EOF (%ld, %ld)\n", 1058 printk(KERN_DEBUG "%s: block >= EOF (%lu, %llu)\n",
1008 __func__, iblock, (unsigned long) inode->i_size); 1059 __func__, b_off,
1060 (unsigned long long)inode->i_size);
1009 goto abort; 1061 goto abort;
1010 } 1062 }
1011 1063
@@ -1031,9 +1083,9 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
1031 if (++section > 100) { 1083 if (++section > 100) {
1032 printk(KERN_DEBUG "%s: More than 100 file sections ?!?" 1084 printk(KERN_DEBUG "%s: More than 100 file sections ?!?"
1033 " aborting...\n", __func__); 1085 " aborting...\n", __func__);
1034 printk(KERN_DEBUG "%s: block=%ld firstext=%u sect_size=%u " 1086 printk(KERN_DEBUG "%s: block=%lu firstext=%u sect_size=%u "
1035 "nextblk=%lu nextoff=%lu\n", __func__, 1087 "nextblk=%lu nextoff=%lu\n", __func__,
1036 iblock, firstext, (unsigned) sect_size, 1088 b_off, firstext, (unsigned) sect_size,
1037 nextblk, nextoff); 1089 nextblk, nextoff);
1038 goto abort; 1090 goto abort;
1039 } 1091 }
@@ -1054,7 +1106,6 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
1054 1106
1055 error = 0; 1107 error = 0;
1056abort: 1108abort:
1057 unlock_kernel();
1058 return rv != 0 ? rv : error; 1109 return rv != 0 ? rv : error;
1059} 1110}
1060 1111
@@ -1108,7 +1159,6 @@ static sector_t _isofs_bmap(struct address_space *mapping, sector_t block)
1108 1159
1109static const struct address_space_operations isofs_aops = { 1160static const struct address_space_operations isofs_aops = {
1110 .readpage = isofs_readpage, 1161 .readpage = isofs_readpage,
1111 .sync_page = block_sync_page,
1112 .bmap = _isofs_bmap 1162 .bmap = _isofs_bmap
1113}; 1163};
1114 1164
@@ -1475,17 +1525,16 @@ struct inode *isofs_iget(struct super_block *sb,
1475 return inode; 1525 return inode;
1476} 1526}
1477 1527
1478static int isofs_get_sb(struct file_system_type *fs_type, 1528static struct dentry *isofs_mount(struct file_system_type *fs_type,
1479 int flags, const char *dev_name, void *data, struct vfsmount *mnt) 1529 int flags, const char *dev_name, void *data)
1480{ 1530{
1481 return get_sb_bdev(fs_type, flags, dev_name, data, isofs_fill_super, 1531 return mount_bdev(fs_type, flags, dev_name, data, isofs_fill_super);
1482 mnt);
1483} 1532}
1484 1533
1485static struct file_system_type iso9660_fs_type = { 1534static struct file_system_type iso9660_fs_type = {
1486 .owner = THIS_MODULE, 1535 .owner = THIS_MODULE,
1487 .name = "iso9660", 1536 .name = "iso9660",
1488 .get_sb = isofs_get_sb, 1537 .mount = isofs_mount,
1489 .kill_sb = kill_block_super, 1538 .kill_sb = kill_block_super,
1490 .fs_flags = FS_REQUIRES_DEV, 1539 .fs_flags = FS_REQUIRES_DEV,
1491}; 1540};