Skip to content

Commit

Permalink
Changes representative of linux-3.10.0-693.1.1.el7.tar.xz
Browse files Browse the repository at this point in the history
  • Loading branch information
da-x committed Aug 3, 2017
1 parent 3a36cf3 commit 5fd18bf
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 44 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ EXTRAVERSION =
NAME = Unicycling Gorilla
RHEL_MAJOR = 7
RHEL_MINOR = 4
RHEL_RELEASE = 693
RHEL_RELEASE = 693.1.1

#
# DRM backport version
Expand Down
41 changes: 41 additions & 0 deletions fs/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,47 @@ static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *c
return dentry_string_cmp(cs, ct, tcount);
}

void take_dentry_name_snapshot(struct name_snapshot *name, struct dentry *dentry)
{
size_t size = 0;
char *buf = NULL;

if (unlikely(dname_external(dentry))) {
size = READ_ONCE(dentry->d_name.len);
retry:
/* Pre allocate buffer */
name->name = buf = kmalloc(size + 1, GFP_KERNEL);
if (!buf)
return;
}

spin_lock(&dentry->d_lock);
if (unlikely(dname_external(dentry))) {
if (size < dentry->d_name.len) {
/* Raced with rename and need to redo the allocation */
size = dentry->d_name.len;
spin_unlock(&dentry->d_lock);
kfree(buf);
goto retry;
}
strcpy(buf, dentry->d_name.name);
buf = NULL;
} else {
memcpy(name->inline_name, dentry->d_iname, DNAME_INLINE_LEN);
name->name = name->inline_name;
}
spin_unlock(&dentry->d_lock);
kfree(buf);
}
EXPORT_SYMBOL(take_dentry_name_snapshot);

void release_dentry_name_snapshot(struct name_snapshot *name)
{
if (unlikely(name->name != name->inline_name))
kfree(name->name);
}
EXPORT_SYMBOL(release_dentry_name_snapshot);

static void __d_free(struct rcu_head *head)
{
struct dentry *dentry = container_of(
Expand Down
10 changes: 5 additions & 5 deletions fs/debugfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
{
int error;
struct dentry *dentry = NULL, *trap;
const char *old_name;
struct name_snapshot old_name;

trap = lock_rename(new_dir, old_dir);
/* Source or destination directories don't exist? */
Expand All @@ -616,19 +616,19 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
if (IS_ERR(dentry) || dentry == trap || dentry->d_inode)
goto exit;

old_name = fsnotify_oldname_init(old_dentry->d_name.name);
take_dentry_name_snapshot(&old_name, old_dentry);

error = simple_rename(old_dir->d_inode, old_dentry, new_dir->d_inode,
dentry);
if (error) {
fsnotify_oldname_free(old_name);
release_dentry_name_snapshot(&old_name);
goto exit;
}
d_move(old_dentry, dentry);
fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name.name,
S_ISDIR(old_dentry->d_inode->i_mode),
NULL, old_dentry);
fsnotify_oldname_free(old_name);
release_dentry_name_snapshot(&old_name);
unlock_rename(new_dir, old_dir);
dput(dentry);
return old_dentry;
Expand Down
11 changes: 10 additions & 1 deletion fs/direct-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,16 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
}
}

/* Once we sampled i_size check for reads beyond EOF */
dio->i_size = i_size_read(inode);
if (rw == READ && offset >= dio->i_size) {
if (dio->flags & DIO_LOCKING)
mutex_unlock(&inode->i_mutex);
kmem_cache_free(dio_cache, dio);
retval = 0;
goto out;
}

/*
* For file extending writes updating i_size before data writeouts
* complete can expose uninitialized blocks in dumb filesystems.
Expand Down Expand Up @@ -1286,7 +1296,6 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
sdio.next_block_for_io = -1;

dio->iocb = iocb;
dio->i_size = i_size_read(inode);

spin_lock_init(&dio->bio_lock);
dio->refcount = 1;
Expand Down
8 changes: 4 additions & 4 deletions fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -4136,11 +4136,11 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
{
int error;
bool is_dir = d_is_dir(old_dentry);
const unsigned char *old_name;
struct inode *source = old_dentry->d_inode;
struct inode *target = new_dentry->d_inode;
bool new_is_dir = false;
unsigned max_links = new_dir->i_sb->s_max_links;
struct name_snapshot old_name;
iop_rename2_t rename2;

/*
Expand Down Expand Up @@ -4196,7 +4196,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
if (error)
return error;

old_name = fsnotify_oldname_init(old_dentry->d_name.name);
take_dentry_name_snapshot(&old_name, old_dentry);
dget(new_dentry);
if (!is_dir || (flags & RENAME_EXCHANGE))
lock_two_nondirectories(source, target);
Expand Down Expand Up @@ -4257,14 +4257,14 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
mutex_unlock(&target->i_mutex);
dput(new_dentry);
if (!error) {
fsnotify_move(old_dir, new_dir, old_name, is_dir,
fsnotify_move(old_dir, new_dir, old_name.name, is_dir,
!(flags & RENAME_EXCHANGE) ? target : NULL, old_dentry);
if (flags & RENAME_EXCHANGE) {
fsnotify_move(new_dir, old_dir, old_dentry->d_name.name,
new_is_dir, NULL, new_dentry);
}
}
fsnotify_oldname_free(old_name);
release_dentry_name_snapshot(&old_name);

return error;
}
Expand Down
8 changes: 6 additions & 2 deletions fs/notify/fsnotify.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,20 @@ int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask
if (unlikely(!fsnotify_inode_watches_children(p_inode)))
__fsnotify_update_child_dentry_flags(p_inode);
else if (p_inode->i_fsnotify_mask & mask) {
struct name_snapshot name;

/* we are notifying a parent so come up with the new mask which
* specifies these are events which came from a child. */
mask |= FS_EVENT_ON_CHILD;

take_dentry_name_snapshot(&name, dentry);
if (path)
ret = fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH,
dentry->d_name.name, 0);
name.name, 0);
else
ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
dentry->d_name.name, 0);
name.name, 0);
release_dentry_name_snapshot(&name);
}

dput(parent);
Expand Down
7 changes: 7 additions & 0 deletions include/linux/dcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -568,4 +568,11 @@ static inline struct dentry *d_backing_dentry(struct dentry *upper)
return upper;
}

struct name_snapshot {
const char *name;
char inline_name[DNAME_INLINE_LEN];
};
void take_dentry_name_snapshot(struct name_snapshot *, struct dentry *);
void release_dentry_name_snapshot(struct name_snapshot *);

#endif /* __LINUX_DCACHE_H */
31 changes: 0 additions & 31 deletions include/linux/fsnotify.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,35 +314,4 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
}
}

#if defined(CONFIG_FSNOTIFY) /* notify helpers */

/*
* fsnotify_oldname_init - save off the old filename before we change it
*/
static inline const unsigned char *fsnotify_oldname_init(const unsigned char *name)
{
return kstrdup(name, GFP_KERNEL);
}

/*
* fsnotify_oldname_free - free the name we got from fsnotify_oldname_init
*/
static inline void fsnotify_oldname_free(const unsigned char *old_name)
{
kfree(old_name);
}

#else /* CONFIG_FSNOTIFY */

static inline const char *fsnotify_oldname_init(const unsigned char *name)
{
return NULL;
}

static inline void fsnotify_oldname_free(const unsigned char *old_name)
{
}

#endif /* CONFIG_FSNOTIFY */

#endif /* _LINUX_FS_NOTIFY_H */

0 comments on commit 5fd18bf

Please sign in to comment.