Skip to content

Commit

Permalink
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/jack/linux-fs

Pull misc filesystem updates from Jan Kara:
 "udf, ext2, quota, fsnotify fixes & cleanups:

   - udf fixes for handling of media without uid/gid

   - udf fixes for some corner cases in parsing of volume recognition
     sequence

   - improvements of fsnotify handling of ENOMEM

   - new ioctl to allow setting of watch descriptor id for inotify (for
     checkpoint - restart)

   - small ext2, reiserfs, quota cleanups"

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
  quota: Kill an unused extern entry form quota.h
  reiserfs: Remove VLA from fs/reiserfs/reiserfs.h
  udf: fix potential refcnt problem of nls module
  ext2: change return code to -ENOMEM when failing memory allocation
  udf: Do not mark possibly inconsistent filesystems as closed
  fsnotify: Let userspace know about lost events due to ENOMEM
  fanotify: Avoid lost events due to ENOMEM for unlimited queues
  udf: Remove never implemented mount options
  udf: Update mount option documentation
  udf: Provide saner default for invalid uid / gid
  udf: Clean up handling of invalid uid/gid
  udf: Apply uid/gid mount options also to new inodes & chown
  udf: Ignore [ug]id=ignore mount options
  udf: Fix handling of Partition Descriptors
  udf: Unify common handling of descriptors
  udf: Convert descriptor index definitions to enum
  udf: Allow volume descriptor sequence to be terminated by unrecorded block
  udf: Simplify handling of Volume Descriptor Pointers
  udf: Fix off-by-one in volume descriptor sequence length
  inotify: Extend ioctl to allow to request id of new watch descriptor
  • Loading branch information
Linus Torvalds committed Apr 6, 2018

Unverified

No user is associated with the committer email.
2 parents 5e4d659 + b91ed9d commit be88751
Showing 18 changed files with 240 additions and 179 deletions.
26 changes: 7 additions & 19 deletions Documentation/filesystems/udf.txt
Original file line number Diff line number Diff line change
@@ -36,18 +36,14 @@ The following mount options are supported:
iocharset= Set the NLS character set

The uid= and gid= options need a bit more explaining. They will accept a
decimal numeric value which will be used as the default ID for that mount.
They will also accept the string "ignore" and "forget". For files on the disk
that are owned by nobody ( -1 ), they will instead look as if they are owned
by the default ID. The ignore option causes the default ID to override all
IDs on the disk, not just -1. The forget option causes all IDs to be written
to disk as -1, so when the media is later remounted, they will appear to be
owned by whatever default ID it is mounted with at that time.
decimal numeric value and all inodes on that mount will then appear as
belonging to that uid and gid. Mount options also accept the string "forget".
The forget option causes all IDs to be written to disk as -1 which is a way
of UDF standard to indicate that IDs are not supported for these files .

For typical desktop use of removable media, you should set the ID to that
of the interactively logged on user, and also specify both the forget and
ignore options. This way the interactive user will always see the files
on the disk as belonging to him.
For typical desktop use of removable media, you should set the ID to that of
the interactively logged on user, and also specify the forget option. This way
the interactive user will always see the files on the disk as belonging to him.

The remaining are for debugging and disaster recovery:

@@ -57,16 +53,8 @@ The following expect a offset from 0.

session= Set the CDROM session (default= last session)
anchor= Override standard anchor location. (default= 256)
volume= Override the VolumeDesc location. (unused)
partition= Override the PartitionDesc location. (unused)
lastblock= Set the last block of the filesystem/

The following expect a offset from the partition root.

fileset= Override the fileset block location. (unused)
rootdir= Override the root directory location. (unused)
WARNING: overriding the rootdir to a non-directory may
yield highly unpredictable results.
-------------------------------------------------------------------------------


4 changes: 2 additions & 2 deletions fs/ext2/super.c
Original file line number Diff line number Diff line change
@@ -827,15 +827,14 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
unsigned long logic_sb_block;
unsigned long offset = 0;
unsigned long def_mount_opts;
long ret = -EINVAL;
long ret = -ENOMEM;
int blocksize = BLOCK_SIZE;
int db_count;
int i, j;
__le32 features;
int err;
struct ext2_mount_options opts;

err = -ENOMEM;
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi)
goto failed;
@@ -851,6 +850,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
sbi->s_daxdev = dax_dev;

spin_lock_init(&sbi->s_lock);
ret = -EINVAL;

/*
* See what the current blocksize for the device is, and
28 changes: 22 additions & 6 deletions fs/notify/fanotify/fanotify.c
Original file line number Diff line number Diff line change
@@ -139,23 +139,32 @@ static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark,
return false;
}

struct fanotify_event_info *fanotify_alloc_event(struct inode *inode, u32 mask,
struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group,
struct inode *inode, u32 mask,
const struct path *path)
{
struct fanotify_event_info *event;
gfp_t gfp = GFP_KERNEL;

/*
* For queues with unlimited length lost events are not expected and
* can possibly have security implications. Avoid losing events when
* memory is short.
*/
if (group->max_events == UINT_MAX)
gfp |= __GFP_NOFAIL;

if (fanotify_is_perm_event(mask)) {
struct fanotify_perm_event_info *pevent;

pevent = kmem_cache_alloc(fanotify_perm_event_cachep,
GFP_KERNEL);
pevent = kmem_cache_alloc(fanotify_perm_event_cachep, gfp);
if (!pevent)
return NULL;
event = &pevent->fae;
pevent->response = 0;
goto init;
}
event = kmem_cache_alloc(fanotify_event_cachep, GFP_KERNEL);
event = kmem_cache_alloc(fanotify_event_cachep, gfp);
if (!event)
return NULL;
init: __maybe_unused
@@ -210,10 +219,17 @@ static int fanotify_handle_event(struct fsnotify_group *group,
return 0;
}

event = fanotify_alloc_event(inode, mask, data);
event = fanotify_alloc_event(group, inode, mask, data);
ret = -ENOMEM;
if (unlikely(!event))
if (unlikely(!event)) {
/*
* We don't queue overflow events for permission events as
* there the access is denied and so no event is in fact lost.
*/
if (!fanotify_is_perm_event(mask))
fsnotify_queue_overflow(group);
goto finish;
}

fsn_event = &event->fse;
ret = fsnotify_add_event(group, fsn_event, fanotify_merge);
3 changes: 2 additions & 1 deletion fs/notify/fanotify/fanotify.h
Original file line number Diff line number Diff line change
@@ -52,5 +52,6 @@ static inline struct fanotify_event_info *FANOTIFY_E(struct fsnotify_event *fse)
return container_of(fse, struct fanotify_event_info, fse);
}

struct fanotify_event_info *fanotify_alloc_event(struct inode *inode, u32 mask,
struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group,
struct inode *inode, u32 mask,
const struct path *path);
2 changes: 1 addition & 1 deletion fs/notify/fanotify/fanotify_user.c
Original file line number Diff line number Diff line change
@@ -757,7 +757,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
group->fanotify_data.user = user;
atomic_inc(&user->fanotify_listeners);

oevent = fanotify_alloc_event(NULL, FS_Q_OVERFLOW, NULL);
oevent = fanotify_alloc_event(group, NULL, FS_Q_OVERFLOW, NULL);
if (unlikely(!oevent)) {
fd = -ENOMEM;
goto out_destroy_group;
8 changes: 7 additions & 1 deletion fs/notify/inotify/inotify_fsnotify.c
Original file line number Diff line number Diff line change
@@ -99,8 +99,14 @@ int inotify_handle_event(struct fsnotify_group *group,
fsn_mark);

event = kmalloc(alloc_len, GFP_KERNEL);
if (unlikely(!event))
if (unlikely(!event)) {
/*
* Treat lost event due to ENOMEM the same way as queue
* overflow to let userspace know event was lost.
*/
fsnotify_queue_overflow(group);
return -ENOMEM;
}

fsn_event = &event->fse;
fsnotify_init_event(fsn_event, inode, mask);
14 changes: 14 additions & 0 deletions fs/notify/inotify/inotify_user.c
Original file line number Diff line number Diff line change
@@ -307,6 +307,20 @@ static long inotify_ioctl(struct file *file, unsigned int cmd,
spin_unlock(&group->notification_lock);
ret = put_user(send_len, (int __user *) p);
break;
#ifdef CONFIG_CHECKPOINT_RESTORE
case INOTIFY_IOC_SETNEXTWD:
ret = -EINVAL;
if (arg >= 1 && arg <= INT_MAX) {
struct inotify_group_private_data *data;

data = &group->inotify_data;
spin_lock(&data->idr_lock);
idr_set_cursor(&data->idr, (unsigned int)arg);
spin_unlock(&data->idr_lock);
ret = 0;
}
break;
#endif /* CONFIG_CHECKPOINT_RESTORE */
}

return ret;
3 changes: 2 additions & 1 deletion fs/notify/notification.c
Original file line number Diff line number Diff line change
@@ -111,7 +111,8 @@ int fsnotify_add_event(struct fsnotify_group *group,
return 2;
}

if (group->q_len >= group->max_events) {
if (event == group->overflow_event ||
group->q_len >= group->max_events) {
ret = 2;
/* Queue overflow event only if it isn't already queued */
if (!list_empty(&group->overflow_event->list)) {
2 changes: 1 addition & 1 deletion fs/reiserfs/reiserfs.h
Original file line number Diff line number Diff line change
@@ -1916,7 +1916,7 @@ struct reiserfs_de_head {

/* empty directory contains two entries "." and ".." and their headers */
#define EMPTY_DIR_SIZE \
(DEH_SIZE * 2 + ROUND_UP (strlen (".")) + ROUND_UP (strlen ("..")))
(DEH_SIZE * 2 + ROUND_UP (sizeof(".") - 1) + ROUND_UP (sizeof("..") - 1))

/* old format directories have this size when empty */
#define EMPTY_DIR_SIZE_V1 (DEH_SIZE * 2 + 3)
10 changes: 10 additions & 0 deletions fs/udf/file.c
Original file line number Diff line number Diff line change
@@ -257,12 +257,22 @@ const struct file_operations udf_file_operations = {
static int udf_setattr(struct dentry *dentry, struct iattr *attr)
{
struct inode *inode = d_inode(dentry);
struct super_block *sb = inode->i_sb;
int error;

error = setattr_prepare(dentry, attr);
if (error)
return error;

if ((attr->ia_valid & ATTR_UID) &&
UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET) &&
!uid_eq(attr->ia_uid, UDF_SB(sb)->s_uid))
return -EPERM;
if ((attr->ia_valid & ATTR_GID) &&
UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET) &&
!gid_eq(attr->ia_gid, UDF_SB(sb)->s_gid))
return -EPERM;

if ((attr->ia_valid & ATTR_SIZE) &&
attr->ia_size != i_size_read(inode)) {
error = udf_setsize(inode, attr->ia_size);
4 changes: 4 additions & 0 deletions fs/udf/ialloc.c
Original file line number Diff line number Diff line change
@@ -104,6 +104,10 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode)
}

inode_init_owner(inode, dir, mode);
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET))
inode->i_uid = sbi->s_uid;
if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET))
inode->i_gid = sbi->s_gid;

iinfo->i_location.logicalBlockNum = block;
iinfo->i_location.partitionReferenceNum =
23 changes: 13 additions & 10 deletions fs/udf/inode.c
Original file line number Diff line number Diff line change
@@ -1275,6 +1275,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
unsigned int indirections = 0;
int bs = inode->i_sb->s_blocksize;
int ret = -EIO;
uint32_t uid, gid;

reread:
if (iloc->partitionReferenceNum >= sbi->s_partitions) {
@@ -1400,17 +1401,19 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)

ret = -EIO;
read_lock(&sbi->s_cred_lock);
i_uid_write(inode, le32_to_cpu(fe->uid));
if (!uid_valid(inode->i_uid) ||
UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) ||
uid = le32_to_cpu(fe->uid);
if (uid == UDF_INVALID_ID ||
UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_SET))
inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
inode->i_uid = sbi->s_uid;
else
i_uid_write(inode, uid);

i_gid_write(inode, le32_to_cpu(fe->gid));
if (!gid_valid(inode->i_gid) ||
UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_IGNORE) ||
gid = le32_to_cpu(fe->gid);
if (gid == UDF_INVALID_ID ||
UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET))
inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
inode->i_gid = sbi->s_gid;
else
i_gid_write(inode, gid);

if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY &&
sbi->s_fmode != UDF_INVALID_MODE)
@@ -1655,12 +1658,12 @@ static int udf_update_inode(struct inode *inode, int do_sync)
}

if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET))
fe->uid = cpu_to_le32(-1);
fe->uid = cpu_to_le32(UDF_INVALID_ID);
else
fe->uid = cpu_to_le32(i_uid_read(inode));

if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET))
fe->gid = cpu_to_le32(-1);
fe->gid = cpu_to_le32(UDF_INVALID_ID);
else
fe->gid = cpu_to_le32(i_gid_read(inode));

Loading

0 comments on commit be88751

Please sign in to comment.