aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2008-11-06 15:53:54 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-11-06 18:41:21 -0500
commit9c0aa1b87bf541affef519eb4879ce7c5a5941ae (patch)
tree3bd583d8331c630b59fc01b68ab9cb34bb953d6e
parent45cfbe354785a5bc9a38354754d6f7322f598001 (diff)
fat: Cleanup FAT attribute stuff
This adds three helpers: fat_make_attrs() - makes FAT attributes from inode. fat_make_mode() - makes mode_t from FAT attributes. fat_save_attrs() - saves FAT attributes to inode. Then this replaces: MSDOS_MKMODE() by fat_make_mode(), fat_attr() by fat_make_attrs(), ->i_attrs = attr & ATTR_UNUSED by fat_save_attrs(). And for root inode, those is used with ATTR_DIR instead of bogus ATTR_NONE. Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/fat/fat.h20
-rw-r--r--fs/fat/file.c32
-rw-r--r--fs/fat/inode.c19
-rw-r--r--include/linux/msdos_fs.h5
4 files changed, 40 insertions, 36 deletions
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index 2b8e94c3eef4..3b4753a024e3 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -117,14 +117,32 @@ static inline struct msdos_inode_info *MSDOS_I(struct inode *inode)
117 return container_of(inode, struct msdos_inode_info, vfs_inode); 117 return container_of(inode, struct msdos_inode_info, vfs_inode);
118} 118}
119 119
120/* Convert attribute bits and a mask to the UNIX mode. */
121static inline mode_t fat_make_mode(struct msdos_sb_info *sbi,
122 u8 attrs, mode_t mode)
123{
124 if (attrs & ATTR_RO)
125 mode &= ~S_IWUGO;
126
127 if (attrs & ATTR_DIR)
128 return (mode & ~sbi->options.fs_dmask) | S_IFDIR;
129 else
130 return (mode & ~sbi->options.fs_fmask) | S_IFREG;
131}
132
120/* Return the FAT attribute byte for this inode */ 133/* Return the FAT attribute byte for this inode */
121static inline u8 fat_attr(struct inode *inode) 134static inline u8 fat_make_attrs(struct inode *inode)
122{ 135{
123 return ((inode->i_mode & S_IWUGO) ? ATTR_NONE : ATTR_RO) | 136 return ((inode->i_mode & S_IWUGO) ? ATTR_NONE : ATTR_RO) |
124 (S_ISDIR(inode->i_mode) ? ATTR_DIR : ATTR_NONE) | 137 (S_ISDIR(inode->i_mode) ? ATTR_DIR : ATTR_NONE) |
125 MSDOS_I(inode)->i_attrs; 138 MSDOS_I(inode)->i_attrs;
126} 139}
127 140
141static inline void fat_save_attrs(struct inode *inode, u8 attrs)
142{
143 MSDOS_I(inode)->i_attrs = attrs & ATTR_UNUSED;
144}
145
128static inline unsigned char fat_checksum(const __u8 *name) 146static inline unsigned char fat_checksum(const __u8 *name)
129{ 147{
130 unsigned char s = name[0]; 148 unsigned char s = name[0];
diff --git a/fs/fat/file.c b/fs/fat/file.c
index b21973f266a1..f5a7e907a8fa 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -27,13 +27,7 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp,
27 switch (cmd) { 27 switch (cmd) {
28 case FAT_IOCTL_GET_ATTRIBUTES: 28 case FAT_IOCTL_GET_ATTRIBUTES:
29 { 29 {
30 u32 attr; 30 u32 attr = fat_make_attrs(inode);
31
32 if (inode->i_ino == MSDOS_ROOT_INO)
33 attr = ATTR_DIR;
34 else
35 attr = fat_attr(inode);
36
37 return put_user(attr, user_attr); 31 return put_user(attr, user_attr);
38 } 32 }
39 case FAT_IOCTL_SET_ATTRIBUTES: 33 case FAT_IOCTL_SET_ATTRIBUTES:
@@ -62,20 +56,16 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp,
62 /* Merge in ATTR_VOLUME and ATTR_DIR */ 56 /* Merge in ATTR_VOLUME and ATTR_DIR */
63 attr |= (MSDOS_I(inode)->i_attrs & ATTR_VOLUME) | 57 attr |= (MSDOS_I(inode)->i_attrs & ATTR_VOLUME) |
64 (is_dir ? ATTR_DIR : 0); 58 (is_dir ? ATTR_DIR : 0);
65 oldattr = fat_attr(inode); 59 oldattr = fat_make_attrs(inode);
66 60
67 /* Equivalent to a chmod() */ 61 /* Equivalent to a chmod() */
68 ia.ia_valid = ATTR_MODE | ATTR_CTIME; 62 ia.ia_valid = ATTR_MODE | ATTR_CTIME;
69 ia.ia_ctime = current_fs_time(inode->i_sb); 63 ia.ia_ctime = current_fs_time(inode->i_sb);
70 if (is_dir) { 64 if (is_dir)
71 ia.ia_mode = MSDOS_MKMODE(attr, 65 ia.ia_mode = fat_make_mode(sbi, attr, S_IRWXUGO);
72 S_IRWXUGO & ~sbi->options.fs_dmask) 66 else {
73 | S_IFDIR; 67 ia.ia_mode = fat_make_mode(sbi, attr,
74 } else { 68 S_IRUGO | S_IWUGO | (inode->i_mode & S_IXUGO));
75 ia.ia_mode = MSDOS_MKMODE(attr,
76 (S_IRUGO | S_IWUGO | (inode->i_mode & S_IXUGO))
77 & ~sbi->options.fs_fmask)
78 | S_IFREG;
79 } 69 }
80 70
81 /* The root directory has no attributes */ 71 /* The root directory has no attributes */
@@ -115,7 +105,7 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp,
115 inode->i_flags &= S_IMMUTABLE; 105 inode->i_flags &= S_IMMUTABLE;
116 } 106 }
117 107
118 MSDOS_I(inode)->i_attrs = attr & ATTR_UNUSED; 108 fat_save_attrs(inode, attr);
119 mark_inode_dirty(inode); 109 mark_inode_dirty(inode);
120up: 110up:
121 mnt_drop_write(filp->f_path.mnt); 111 mnt_drop_write(filp->f_path.mnt);
@@ -274,7 +264,7 @@ static int fat_sanitize_mode(const struct msdos_sb_info *sbi,
274 264
275 /* 265 /*
276 * Note, the basic check is already done by a caller of 266 * Note, the basic check is already done by a caller of
277 * (attr->ia_mode & ~MSDOS_VALID_MODE) 267 * (attr->ia_mode & ~FAT_VALID_MODE)
278 */ 268 */
279 269
280 if (S_ISREG(inode->i_mode)) 270 if (S_ISREG(inode->i_mode))
@@ -314,6 +304,8 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode)
314} 304}
315 305
316#define TIMES_SET_FLAGS (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET) 306#define TIMES_SET_FLAGS (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)
307/* valid file mode bits */
308#define FAT_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXUGO)
317 309
318int fat_setattr(struct dentry *dentry, struct iattr *attr) 310int fat_setattr(struct dentry *dentry, struct iattr *attr)
319{ 311{
@@ -356,7 +348,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
356 ((attr->ia_valid & ATTR_GID) && 348 ((attr->ia_valid & ATTR_GID) &&
357 (attr->ia_gid != sbi->options.fs_gid)) || 349 (attr->ia_gid != sbi->options.fs_gid)) ||
358 ((attr->ia_valid & ATTR_MODE) && 350 ((attr->ia_valid & ATTR_MODE) &&
359 (attr->ia_mode & ~MSDOS_VALID_MODE))) 351 (attr->ia_mode & ~FAT_VALID_MODE)))
360 error = -EPERM; 352 error = -EPERM;
361 353
362 if (error) { 354 if (error) {
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 8e1b75c63c7f..7aaa21cf019a 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -337,8 +337,7 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
337 337
338 if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) { 338 if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) {
339 inode->i_generation &= ~1; 339 inode->i_generation &= ~1;
340 inode->i_mode = MSDOS_MKMODE(de->attr, 340 inode->i_mode = fat_make_mode(sbi, de->attr, S_IRWXUGO);
341 S_IRWXUGO & ~sbi->options.fs_dmask) | S_IFDIR;
342 inode->i_op = sbi->dir_ops; 341 inode->i_op = sbi->dir_ops;
343 inode->i_fop = &fat_dir_operations; 342 inode->i_fop = &fat_dir_operations;
344 343
@@ -355,10 +354,9 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
355 inode->i_nlink = fat_subdirs(inode); 354 inode->i_nlink = fat_subdirs(inode);
356 } else { /* not a directory */ 355 } else { /* not a directory */
357 inode->i_generation |= 1; 356 inode->i_generation |= 1;
358 inode->i_mode = MSDOS_MKMODE(de->attr, 357 inode->i_mode = fat_make_mode(sbi, de->attr,
359 ((sbi->options.showexec && !is_exec(de->name + 8)) 358 ((sbi->options.showexec && !is_exec(de->name + 8))
360 ? S_IRUGO|S_IWUGO : S_IRWXUGO) 359 ? S_IRUGO|S_IWUGO : S_IRWXUGO));
361 & ~sbi->options.fs_fmask) | S_IFREG;
362 MSDOS_I(inode)->i_start = le16_to_cpu(de->start); 360 MSDOS_I(inode)->i_start = le16_to_cpu(de->start);
363 if (sbi->fat_bits == 32) 361 if (sbi->fat_bits == 32)
364 MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16); 362 MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
@@ -374,7 +372,8 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
374 if (sbi->options.sys_immutable) 372 if (sbi->options.sys_immutable)
375 inode->i_flags |= S_IMMUTABLE; 373 inode->i_flags |= S_IMMUTABLE;
376 } 374 }
377 MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED; 375 fat_save_attrs(inode, de->attr);
376
378 inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1)) 377 inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
379 & ~((loff_t)sbi->cluster_size - 1)) >> 9; 378 & ~((loff_t)sbi->cluster_size - 1)) >> 9;
380 379
@@ -569,7 +568,7 @@ retry:
569 raw_entry->size = 0; 568 raw_entry->size = 0;
570 else 569 else
571 raw_entry->size = cpu_to_le32(inode->i_size); 570 raw_entry->size = cpu_to_le32(inode->i_size);
572 raw_entry->attr = fat_attr(inode); 571 raw_entry->attr = fat_make_attrs(inode);
573 raw_entry->start = cpu_to_le16(MSDOS_I(inode)->i_logstart); 572 raw_entry->start = cpu_to_le16(MSDOS_I(inode)->i_logstart);
574 raw_entry->starthi = cpu_to_le16(MSDOS_I(inode)->i_logstart >> 16); 573 raw_entry->starthi = cpu_to_le16(MSDOS_I(inode)->i_logstart >> 16);
575 fat_time_unix2fat(sbi, &inode->i_mtime, &raw_entry->time, 574 fat_time_unix2fat(sbi, &inode->i_mtime, &raw_entry->time,
@@ -1105,7 +1104,7 @@ static int fat_read_root(struct inode *inode)
1105 inode->i_gid = sbi->options.fs_gid; 1104 inode->i_gid = sbi->options.fs_gid;
1106 inode->i_version++; 1105 inode->i_version++;
1107 inode->i_generation = 0; 1106 inode->i_generation = 0;
1108 inode->i_mode = (S_IRWXUGO & ~sbi->options.fs_dmask) | S_IFDIR; 1107 inode->i_mode = fat_make_mode(sbi, ATTR_DIR, S_IRWXUGO);
1109 inode->i_op = sbi->dir_ops; 1108 inode->i_op = sbi->dir_ops;
1110 inode->i_fop = &fat_dir_operations; 1109 inode->i_fop = &fat_dir_operations;
1111 if (sbi->fat_bits == 32) { 1110 if (sbi->fat_bits == 32) {
@@ -1122,7 +1121,7 @@ static int fat_read_root(struct inode *inode)
1122 MSDOS_I(inode)->i_logstart = 0; 1121 MSDOS_I(inode)->i_logstart = 0;
1123 MSDOS_I(inode)->mmu_private = inode->i_size; 1122 MSDOS_I(inode)->mmu_private = inode->i_size;
1124 1123
1125 MSDOS_I(inode)->i_attrs = ATTR_NONE; 1124 fat_save_attrs(inode, ATTR_DIR);
1126 inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = 0; 1125 inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = 0;
1127 inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = 0; 1126 inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = 0;
1128 inode->i_nlink = fat_subdirs(inode)+2; 1127 inode->i_nlink = fat_subdirs(inode)+2;
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index 0982fb47a90d..e0a9b207920d 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -46,11 +46,6 @@
46#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */ 46#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */
47#define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG) 47#define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG)
48 48
49/* valid file mode bits */
50#define MSDOS_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)
51/* Convert attribute bits and a mask to the UNIX mode. */
52#define MSDOS_MKMODE(a, m) (m & (a & ATTR_RO ? S_IRUGO|S_IXUGO : S_IRWXUGO))
53
54#define MSDOS_NAME 11 /* maximum name length */ 49#define MSDOS_NAME 11 /* maximum name length */
55#define MSDOS_LONGNAME 256 /* maximum name length */ 50#define MSDOS_LONGNAME 256 /* maximum name length */
56#define MSDOS_SLOTS 21 /* max # of slots for short and long names */ 51#define MSDOS_SLOTS 21 /* max # of slots for short and long names */