diff options
author | OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> | 2008-04-28 02:16:26 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 08:58:47 -0700 |
commit | 1ae43f826b6cb951fc5b0f9c92372a8d5b63c7f9 (patch) | |
tree | aea00f01d74a40e026974182006e8af903b0b241 /fs/fat/file.c | |
parent | e97e8de388723f9491514fa0434ddf1fd713a188 (diff) | |
download | linux-1ae43f826b6cb951fc5b0f9c92372a8d5b63c7f9.tar.bz2 |
fat: Add allow_utime option
Normally utime(2) checks current process is owner of the file, or it
has CAP_FOWNER capability. But FAT filesystem doesn't have uid/gid as
on disk info, so normal check is too unflexible.
With this option you can relax it.
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 | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/fs/fat/file.c b/fs/fat/file.c index e73f13a13792..d604bb132422 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -280,11 +280,27 @@ static int fat_check_mode(const struct msdos_sb_info *sbi, struct inode *inode, return 0; } +static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode) +{ + mode_t allow_utime = sbi->options.allow_utime; + + if (current->fsuid != inode->i_uid) { + if (in_group_p(inode->i_gid)) + allow_utime >>= 3; + if (allow_utime & MAY_WRITE) + return 1; + } + + /* use a default check */ + return 0; +} + int fat_setattr(struct dentry *dentry, struct iattr *attr) { struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); struct inode *inode = dentry->d_inode; int mask, error = 0; + unsigned int ia_valid; lock_kernel(); @@ -302,7 +318,15 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) } } + /* Check for setting the inode time. */ + ia_valid = attr->ia_valid; + if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) { + if (fat_allow_set_time(sbi, inode)) + attr->ia_valid &= ~(ATTR_MTIME_SET | ATTR_ATIME_SET); + } + error = inode_change_ok(inode, attr); + attr->ia_valid = ia_valid; if (error) { if (sbi->options.quiet) error = 0; |