diff options
Diffstat (limited to 'fs/inode.c')
-rw-r--r-- | fs/inode.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/fs/inode.c b/fs/inode.c index fb59ba7967f1..f96d2a6f88cc 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -1898,3 +1898,34 @@ void inode_dio_done(struct inode *inode) | |||
1898 | wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); | 1898 | wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); |
1899 | } | 1899 | } |
1900 | EXPORT_SYMBOL(inode_dio_done); | 1900 | EXPORT_SYMBOL(inode_dio_done); |
1901 | |||
1902 | /* | ||
1903 | * inode_set_flags - atomically set some inode flags | ||
1904 | * | ||
1905 | * Note: the caller should be holding i_mutex, or else be sure that | ||
1906 | * they have exclusive access to the inode structure (i.e., while the | ||
1907 | * inode is being instantiated). The reason for the cmpxchg() loop | ||
1908 | * --- which wouldn't be necessary if all code paths which modify | ||
1909 | * i_flags actually followed this rule, is that there is at least one | ||
1910 | * code path which doesn't today --- for example, | ||
1911 | * __generic_file_aio_write() calls file_remove_suid() without holding | ||
1912 | * i_mutex --- so we use cmpxchg() out of an abundance of caution. | ||
1913 | * | ||
1914 | * In the long run, i_mutex is overkill, and we should probably look | ||
1915 | * at using the i_lock spinlock to protect i_flags, and then make sure | ||
1916 | * it is so documented in include/linux/fs.h and that all code follows | ||
1917 | * the locking convention!! | ||
1918 | */ | ||
1919 | void inode_set_flags(struct inode *inode, unsigned int flags, | ||
1920 | unsigned int mask) | ||
1921 | { | ||
1922 | unsigned int old_flags, new_flags; | ||
1923 | |||
1924 | WARN_ON_ONCE(flags & ~mask); | ||
1925 | do { | ||
1926 | old_flags = ACCESS_ONCE(inode->i_flags); | ||
1927 | new_flags = (old_flags & ~mask) | flags; | ||
1928 | } while (unlikely(cmpxchg(&inode->i_flags, old_flags, | ||
1929 | new_flags) != old_flags)); | ||
1930 | } | ||
1931 | EXPORT_SYMBOL(inode_set_flags); | ||