diff options
| -rw-r--r-- | fs/namei.c | 1 | ||||
| -rw-r--r-- | fs/overlayfs/copy_up.c | 23 | ||||
| -rw-r--r-- | fs/overlayfs/inode.c | 19 | ||||
| -rw-r--r-- | fs/overlayfs/overlayfs.h | 3 |
4 files changed, 15 insertions, 31 deletions
diff --git a/fs/namei.c b/fs/namei.c index d84d7c7515fc..0c3974cd3ecd 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -1996,7 +1996,6 @@ static const char *path_init(struct nameidata *nd, unsigned flags) | |||
| 1996 | nd->last_type = LAST_ROOT; /* if there are only slashes... */ | 1996 | nd->last_type = LAST_ROOT; /* if there are only slashes... */ |
| 1997 | nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT; | 1997 | nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT; |
| 1998 | nd->depth = 0; | 1998 | nd->depth = 0; |
| 1999 | nd->total_link_count = 0; | ||
| 2000 | if (flags & LOOKUP_ROOT) { | 1999 | if (flags & LOOKUP_ROOT) { |
| 2001 | struct dentry *root = nd->root.dentry; | 2000 | struct dentry *root = nd->root.dentry; |
| 2002 | struct inode *inode = root->d_inode; | 2001 | struct inode *inode = root->d_inode; |
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 871fcb67be97..0a8983492d91 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c | |||
| @@ -195,8 +195,7 @@ int ovl_set_attr(struct dentry *upperdentry, struct kstat *stat) | |||
| 195 | 195 | ||
| 196 | static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, | 196 | static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, |
| 197 | struct dentry *dentry, struct path *lowerpath, | 197 | struct dentry *dentry, struct path *lowerpath, |
| 198 | struct kstat *stat, struct iattr *attr, | 198 | struct kstat *stat, const char *link) |
| 199 | const char *link) | ||
| 200 | { | 199 | { |
| 201 | struct inode *wdir = workdir->d_inode; | 200 | struct inode *wdir = workdir->d_inode; |
| 202 | struct inode *udir = upperdir->d_inode; | 201 | struct inode *udir = upperdir->d_inode; |
| @@ -240,8 +239,6 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, | |||
| 240 | 239 | ||
| 241 | mutex_lock(&newdentry->d_inode->i_mutex); | 240 | mutex_lock(&newdentry->d_inode->i_mutex); |
| 242 | err = ovl_set_attr(newdentry, stat); | 241 | err = ovl_set_attr(newdentry, stat); |
| 243 | if (!err && attr) | ||
| 244 | err = notify_change(newdentry, attr, NULL); | ||
| 245 | mutex_unlock(&newdentry->d_inode->i_mutex); | 242 | mutex_unlock(&newdentry->d_inode->i_mutex); |
| 246 | if (err) | 243 | if (err) |
| 247 | goto out_cleanup; | 244 | goto out_cleanup; |
| @@ -286,8 +283,7 @@ out_cleanup: | |||
| 286 | * that point the file will have already been copied up anyway. | 283 | * that point the file will have already been copied up anyway. |
| 287 | */ | 284 | */ |
| 288 | int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, | 285 | int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, |
| 289 | struct path *lowerpath, struct kstat *stat, | 286 | struct path *lowerpath, struct kstat *stat) |
| 290 | struct iattr *attr) | ||
| 291 | { | 287 | { |
| 292 | struct dentry *workdir = ovl_workdir(dentry); | 288 | struct dentry *workdir = ovl_workdir(dentry); |
| 293 | int err; | 289 | int err; |
| @@ -345,26 +341,19 @@ int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, | |||
| 345 | } | 341 | } |
| 346 | upperdentry = ovl_dentry_upper(dentry); | 342 | upperdentry = ovl_dentry_upper(dentry); |
| 347 | if (upperdentry) { | 343 | if (upperdentry) { |
| 348 | unlock_rename(workdir, upperdir); | 344 | /* Raced with another copy-up? Nothing to do, then... */ |
| 349 | err = 0; | 345 | err = 0; |
| 350 | /* Raced with another copy-up? Do the setattr here */ | 346 | goto out_unlock; |
| 351 | if (attr) { | ||
| 352 | mutex_lock(&upperdentry->d_inode->i_mutex); | ||
| 353 | err = notify_change(upperdentry, attr, NULL); | ||
| 354 | mutex_unlock(&upperdentry->d_inode->i_mutex); | ||
| 355 | } | ||
| 356 | goto out_put_cred; | ||
| 357 | } | 347 | } |
| 358 | 348 | ||
| 359 | err = ovl_copy_up_locked(workdir, upperdir, dentry, lowerpath, | 349 | err = ovl_copy_up_locked(workdir, upperdir, dentry, lowerpath, |
| 360 | stat, attr, link); | 350 | stat, link); |
| 361 | if (!err) { | 351 | if (!err) { |
| 362 | /* Restore timestamps on parent (best effort) */ | 352 | /* Restore timestamps on parent (best effort) */ |
| 363 | ovl_set_timestamps(upperdir, &pstat); | 353 | ovl_set_timestamps(upperdir, &pstat); |
| 364 | } | 354 | } |
| 365 | out_unlock: | 355 | out_unlock: |
| 366 | unlock_rename(workdir, upperdir); | 356 | unlock_rename(workdir, upperdir); |
| 367 | out_put_cred: | ||
| 368 | revert_creds(old_cred); | 357 | revert_creds(old_cred); |
| 369 | put_cred(override_cred); | 358 | put_cred(override_cred); |
| 370 | 359 | ||
| @@ -406,7 +395,7 @@ int ovl_copy_up(struct dentry *dentry) | |||
| 406 | ovl_path_lower(next, &lowerpath); | 395 | ovl_path_lower(next, &lowerpath); |
| 407 | err = vfs_getattr(&lowerpath, &stat); | 396 | err = vfs_getattr(&lowerpath, &stat); |
| 408 | if (!err) | 397 | if (!err) |
| 409 | err = ovl_copy_up_one(parent, next, &lowerpath, &stat, NULL); | 398 | err = ovl_copy_up_one(parent, next, &lowerpath, &stat); |
| 410 | 399 | ||
| 411 | dput(parent); | 400 | dput(parent); |
| 412 | dput(next); | 401 | dput(next); |
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index ec0c2a050043..4060ffde8722 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c | |||
| @@ -12,8 +12,7 @@ | |||
| 12 | #include <linux/xattr.h> | 12 | #include <linux/xattr.h> |
| 13 | #include "overlayfs.h" | 13 | #include "overlayfs.h" |
| 14 | 14 | ||
| 15 | static int ovl_copy_up_last(struct dentry *dentry, struct iattr *attr, | 15 | static int ovl_copy_up_truncate(struct dentry *dentry) |
| 16 | bool no_data) | ||
| 17 | { | 16 | { |
| 18 | int err; | 17 | int err; |
| 19 | struct dentry *parent; | 18 | struct dentry *parent; |
| @@ -30,10 +29,8 @@ static int ovl_copy_up_last(struct dentry *dentry, struct iattr *attr, | |||
| 30 | if (err) | 29 | if (err) |
| 31 | goto out_dput_parent; | 30 | goto out_dput_parent; |
| 32 | 31 | ||
| 33 | if (no_data) | 32 | stat.size = 0; |
| 34 | stat.size = 0; | 33 | err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat); |
| 35 | |||
| 36 | err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat, attr); | ||
| 37 | 34 | ||
| 38 | out_dput_parent: | 35 | out_dput_parent: |
| 39 | dput(parent); | 36 | dput(parent); |
| @@ -49,13 +46,13 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 49 | if (err) | 46 | if (err) |
| 50 | goto out; | 47 | goto out; |
| 51 | 48 | ||
| 52 | upperdentry = ovl_dentry_upper(dentry); | 49 | err = ovl_copy_up(dentry); |
| 53 | if (upperdentry) { | 50 | if (!err) { |
| 51 | upperdentry = ovl_dentry_upper(dentry); | ||
| 52 | |||
| 54 | mutex_lock(&upperdentry->d_inode->i_mutex); | 53 | mutex_lock(&upperdentry->d_inode->i_mutex); |
| 55 | err = notify_change(upperdentry, attr, NULL); | 54 | err = notify_change(upperdentry, attr, NULL); |
| 56 | mutex_unlock(&upperdentry->d_inode->i_mutex); | 55 | mutex_unlock(&upperdentry->d_inode->i_mutex); |
| 57 | } else { | ||
| 58 | err = ovl_copy_up_last(dentry, attr, false); | ||
| 59 | } | 56 | } |
| 60 | ovl_drop_write(dentry); | 57 | ovl_drop_write(dentry); |
| 61 | out: | 58 | out: |
| @@ -353,7 +350,7 @@ struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags) | |||
| 353 | return ERR_PTR(err); | 350 | return ERR_PTR(err); |
| 354 | 351 | ||
| 355 | if (file_flags & O_TRUNC) | 352 | if (file_flags & O_TRUNC) |
| 356 | err = ovl_copy_up_last(dentry, NULL, true); | 353 | err = ovl_copy_up_truncate(dentry); |
| 357 | else | 354 | else |
| 358 | err = ovl_copy_up(dentry); | 355 | err = ovl_copy_up(dentry); |
| 359 | ovl_drop_write(dentry); | 356 | ovl_drop_write(dentry); |
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index ea5a40b06e3a..e17154aeaae4 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h | |||
| @@ -194,7 +194,6 @@ void ovl_cleanup(struct inode *dir, struct dentry *dentry); | |||
| 194 | /* copy_up.c */ | 194 | /* copy_up.c */ |
| 195 | int ovl_copy_up(struct dentry *dentry); | 195 | int ovl_copy_up(struct dentry *dentry); |
| 196 | int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, | 196 | int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, |
| 197 | struct path *lowerpath, struct kstat *stat, | 197 | struct path *lowerpath, struct kstat *stat); |
| 198 | struct iattr *attr); | ||
| 199 | int ovl_copy_xattr(struct dentry *old, struct dentry *new); | 198 | int ovl_copy_xattr(struct dentry *old, struct dentry *new); |
| 200 | int ovl_set_attr(struct dentry *upper, struct kstat *stat); | 199 | int ovl_set_attr(struct dentry *upper, struct kstat *stat); |
