diff options
author | OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> | 2008-11-06 15:53:55 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-11-06 18:41:21 -0500 |
commit | dfc209c0064efef5590f608056a48b61a5cac09c (patch) | |
tree | 1ace2df7370944dd94b3c8f6a53acf6ea76fdd79 /fs/fat/file.c | |
parent | 9183482f5d4a2de00f66641b974e7f351d41b675 (diff) |
fat: Fix ATTR_RO for directory
FAT has the ATTR_RO (read-only) attribute. But on Windows, the ATTR_RO
of the directory will be just ignored actually, and is used by only
applications as flag. E.g. it's setted for the customized folder by
Explorer.
http://msdn2.microsoft.com/en-us/library/aa969337.aspx
This adds "rodir" option. If user specified it, ATTR_RO is used as
read-only flag even if it's the directory. Otherwise, inode->i_mode
is not used to hold ATTR_RO (i.e. fat_mode_can_save_ro() returns 0).
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>
Diffstat (limited to 'fs/fat/file.c')
-rw-r--r-- | fs/fat/file.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/fat/file.c b/fs/fat/file.c index 81b15c623803..f06a4e525ece 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -282,11 +282,18 @@ static int fat_sanitize_mode(const struct msdos_sb_info *sbi, | |||
282 | /* | 282 | /* |
283 | * Of the r and x bits, all (subject to umask) must be present. Of the | 283 | * Of the r and x bits, all (subject to umask) must be present. Of the |
284 | * w bits, either all (subject to umask) or none must be present. | 284 | * w bits, either all (subject to umask) or none must be present. |
285 | * | ||
286 | * If fat_mode_can_hold_ro(inode) is false, can't change w bits. | ||
285 | */ | 287 | */ |
286 | if ((perm & (S_IRUGO | S_IXUGO)) != (inode->i_mode & (S_IRUGO|S_IXUGO))) | 288 | if ((perm & (S_IRUGO | S_IXUGO)) != (inode->i_mode & (S_IRUGO|S_IXUGO))) |
287 | return -EPERM; | 289 | return -EPERM; |
288 | if ((perm & S_IWUGO) && ((perm & S_IWUGO) != (S_IWUGO & ~mask))) | 290 | if (fat_mode_can_hold_ro(inode)) { |
289 | return -EPERM; | 291 | if ((perm & S_IWUGO) && ((perm & S_IWUGO) != (S_IWUGO & ~mask))) |
292 | return -EPERM; | ||
293 | } else { | ||
294 | if ((perm & S_IWUGO) != (S_IWUGO & ~mask)) | ||
295 | return -EPERM; | ||
296 | } | ||
290 | 297 | ||
291 | *mode_ptr &= S_IFMT | perm; | 298 | *mode_ptr &= S_IFMT | perm; |
292 | 299 | ||
@@ -316,8 +323,8 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) | |||
316 | { | 323 | { |
317 | struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); | 324 | struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); |
318 | struct inode *inode = dentry->d_inode; | 325 | struct inode *inode = dentry->d_inode; |
319 | int error = 0; | ||
320 | unsigned int ia_valid; | 326 | unsigned int ia_valid; |
327 | int error; | ||
321 | 328 | ||
322 | /* | 329 | /* |
323 | * Expand the file. Since inode_setattr() updates ->i_size | 330 | * Expand the file. Since inode_setattr() updates ->i_size |
@@ -371,7 +378,8 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) | |||
371 | attr->ia_valid &= ~ATTR_MODE; | 378 | attr->ia_valid &= ~ATTR_MODE; |
372 | } | 379 | } |
373 | 380 | ||
374 | error = inode_setattr(inode, attr); | 381 | if (attr->ia_valid) |
382 | error = inode_setattr(inode, attr); | ||
375 | out: | 383 | out: |
376 | return error; | 384 | return error; |
377 | } | 385 | } |